1. 程式人生 > >使用ffmpeg進行音視訊編解碼時用到的函式介紹

使用ffmpeg進行音視訊編解碼時用到的函式介紹

/**

* Initialize libavcodec.

* If called more than once, does nothing.

*

* @warning This function must be called before any other libavcodec

* function.

*

* @warning This function is not thread-safe.

*/

void avcodec_init(void);

// 初始化libavcodec,一般最先呼叫該函式

// 引入標頭檔案: #include "libavcodec/avcodec.h"

// 實現在: \ffmpeg\libavcodec\utils.c

// 該函式必須在呼叫libavcodec裡的其它函式前呼叫,一般在程式啟動或模組初始化時呼叫,如果你呼叫了多次也無所謂,因為後面的呼叫不會做任何事情.從函式的實現裡你可以發現,程式碼中對多次呼叫進行了控制.

// 該函式是非執行緒安全的

2 av_register_all()

/**

* Initialize libavformat and register all the muxers, demuxers and

* protocols. If you do not call this function, then you can select

* exactly which formats you want to support.

*

* @see av_register_input_format()

* @see av_register_output_format()

* @see av_register_protocol()

*/

void av_register_all(void);

// 初始化 libavformat和註冊所有的muxers、demuxers和protocols,

// 一般在呼叫avcodec_init後呼叫該方法

// 引入標頭檔案:#include "libavformat/avformat.h"

// 實現在:\ffmpeg\libavformat\allformats.c

// 其中會呼叫avcodec_register_all()註冊多種音視訊格式的編解碼器,並註冊各種檔案的編解複用器

// 當然,你也可以不呼叫該函式,而通過選擇呼叫特定的方法來提供支援

3 avformat_alloc_context()

/**

* Allocate an AVFormatContext.

* avformat_free_context() can be used to free the context and everything

* allocated by the framework within it.

*/

AVFormatContext *avformat_alloc_context(void);

// 分配一個AVFormatContext結構

// 引入標頭檔案:#include "libavformat/avformat.h"

// 實現在:\ffmpeg\libavformat\options.c

// 其中負責申請一個AVFormatContext結構的記憶體,並進行簡單初始化

// avformat_free_context()可以用來釋放該結構裡的所有東西以及該結構本身

// 也是就說使用 avformat_alloc_context()分配的結構,需要使用avformat_free_context()來釋放

// 有些版本中函式名可能為: av_alloc_format_context();

4 avformat_free_context()

/**

* Free an AVFormatContext and all its streams.

* @param s context to free

*/

void avformat_free_context(AVFormatContext *s);

// 釋放一個AVFormatContext結構

// 引入標頭檔案:#include "libavformat/avformat.h"

// 實現在:\ffmpeg\libavformat\utils.c

// 使用 avformat_alloc_context()分配的結構,採用該函式進行釋放,除釋放AVFormatContext結構本身記憶體之外,AVFormatContext中指標所指向的記憶體也會一併釋放

// 有些版本中函式名猜測可能為: av_free_format_context();

5 AVFormatContext 結構

/**

* Format I/O context.

* New fields can be added to the end with minor version bumps.

* Removal, reordering and changes to existing fields require a major

* version bump.

* sizeof(AVFormatContext) must not be used outside libav*.

*/

typedef struct AVFormatContext {

    struct AVInputFormat *iformat;

    struct AVOutputFormat *oformat;

    AVIOContext *pb;

    unsigned int nb_streams;

    AVStream **streams;

    char filename[1024]; /**< input or output filename */

    ....

} AVFormatContext;

// AVFormatContext在FFMpeg裡是一個非常重要的的結構,是其它輸入、輸出相關資訊的一個容器

// 引入標頭檔案:#include "libavformat/avformat.h"

// 以上只列出了其中的部分成員

// 作為輸入容器時 struct AVInputFormat *iformat; 不能為空, 其中包含了輸入檔案的音視訊流資訊,程式從輸入容器從讀出音視訊包進行解碼處理

// 作為輸出容器時 struct AVOutputFormat *oformat; 不能為空, 程式把編碼好的音視訊包寫入到輸出容器中

// AVIOContext *pb: I/O上下文,通過對該變數賦值可以改變輸入源或輸出目的

// unsigned int nb_streams; 音視訊流數量

// AVStream **streams; 音視訊流

6 AVIOContext 結構

/**

* Bytestream IO Context.

* New fields can be added to the end with minor version bumps.

* Removal, reordering and changes to existing fields require a major

* version bump.

* sizeof(AVIOContext) must not be used outside libav*.

*

* @note None of the function pointers in AVIOContext should be called

*       directly, they should only be set by the client application

*       when implementing custom I/O. Normally these are set to the

*       function pointers specified in avio_alloc_context()

*/

typedef struct {

    unsigned char *buffer;  /**< Start of the buffer. */

    int buffer_size;        /**< Maximum buffer size */

    unsigned char *buf_ptr; /**< Current position in the buffer */

    unsigned char *buf_end; /**< End of the data, may be less than

buffer+buffer_size if the read function returned

less data than requested, e.g. for streams where

no more data has been received yet. */

    void *opaque;           /**< A private pointer, passed to the read/write/seek/...

functions. */

    int (*read_packet)(void *opaque, uint8_t *buf,int buf_size);

    int (*write_packet)(void *opaque, uint8_t *buf,int buf_size);

    int64_t (*seek)(void *opaque, int64_t offset,int whence);

    int64_t pos;            /**< position in the file of the current buffer */

    int must_flush;         /**< true if the next seek should flush */

    int eof_reached;        /**< true if eof reached */

    int write_flag;         /**< true if open for writing */

#if FF_API_OLD_AVIO

    attribute_deprecated int is_streamed;

#endif

    int max_packet_size;

    unsigned long checksum;

    unsigned char *checksum_ptr;

    unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size);

    int error;              /**< contains the error code or 0 if no error happened */

    /**

* Pause or resume playback for network streaming protocols - e.g. MMS.

*/

    int (*read_pause)(void *opaque,int pause);

    /**

* Seek to a given timestamp in stream with the specified stream_index.

* Needed for some network streaming protocols which don't support seeking

* to byte position.

*/

    int64_t (*read_seek)(void *opaque,int stream_index,

                         int64_t timestamp, int flags);

    /**

* A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.

*/

    int seekable;

} AVIOContext;

// 位元組流 I/O 上下文

// 在結構的尾部增加變數可以減少版本衝突

// 移除、排序和修改已經存在的變數將會導致較大的版本衝突

// sizeof(AVIOContext)在libav*.外部不可使用

// AVIOContext裡的函式指標不能直接呼叫,通常使用avio_alloc_context()函式來設定其中的函式指標

// unsigned char *buffer: 快取的起始指標

// int buffer_size: 快取的最大值

// void *opaque: 在回撥函式中使用的指標

// int (*read_packet)(void *opaque, uint8_t *buf,int buf_size): 讀檔案回撥方法

// int (*write_packet)(void *opaque, uint8_t *buf,int buf_size): 寫檔案回撥方法

// int64_t (*seek)(void *opaque, int64_t offset,int whence): seek檔案回撥方法

7 avio_alloc_context()

/**

* Allocate and initialize an AVIOContext for buffered I/O. It must be later

* freed with av_free().

*

* @param buffer Memory block for input/output operations via AVIOContext.

*        The buffer must be allocated with av_malloc() and friends.

* @param buffer_size The buffer size is very important for performance.

*        For protocols with fixed blocksize it should be set to this blocksize.

*        For others a typical size is a cache page, e.g. 4kb.

* @param write_flag Set to 1 if the buffer should be writable, 0 otherwise.

* @param opaque An opaque pointer to user-specific data.

* @param read_packet  A function for refilling the buffer, may be NULL.

* @param write_packet A function for writing the buffer contents, may be NULL.

* @param seek A function for seeking to specified byte position, may be NULL.

*

* @return Allocated AVIOContext or NULL on failure.

*/

AVIOContext *avio_alloc_context(

                  unsigned char *buffer,

                  int buffer_size,

                  int write_flag,

                  void *opaque,

                  int (*read_packet)(void *opaque, uint8_t *buf,int buf_size),

                  int (*write_packet)(void *opaque, uint8_t *buf,int buf_size),

                  int64_t (*seek)(void *opaque, int64_t offset,int whence));

// 為I/0快取申請並初始化一個AVIOContext結構,結束使用時必須使用av_free()進行釋放

// unsigned char *buffer: 輸入/輸出快取記憶體塊,必須是使用av_malloc()分配的

// int buffer_size: 快取大小是非常重要的

// int write_flag: 如果快取為可寫則設定為1,否則設定為0

// void *opaque: 指標,用於回撥時使用

// int (*read_packet): 讀包函式指標

// int (*write_packet): 寫包函式指標

// int64_t (*seek): seek檔案函式指標

8 av_open_input_file()

/**

* Open a media file as input. The codecs are not opened. Only the file

* header (if present) is read.

*

* @param ic_ptr The opened media file handle is put here.

* @param filename filename to open

* @param fmt If non-NULL, force the file format to use.

* @param buf_size optional buffer size (zero if default is OK)

* @param ap Additional parameters needed when opening the file

*           (NULL if default).

* @return 0 if OK, AVERROR_xxx otherwise

*

* @deprecated use avformat_open_input instead.

*/

attribute_deprecated int av_open_input_file(AVFormatContext **ic_ptr,constchar *filename,

                       AVInputFormat *fmt,

                       int buf_size,

                       AVFormatParameters *ap);

// 以輸入方式開啟一個媒體檔案,也即原始檔,codecs並沒有開啟,只讀取了檔案的頭資訊.

// 引入標頭檔案:#include "libavformat/avformat.h"

// AVFormatContext **ic_ptr 輸入檔案容器

//constchar *filename 輸入檔名,全路徑,並且保證檔案存在

// AVInputFormat *fmt 輸入檔案格式,填NULL即可

//int buf_size,緩衝區大小,直接填0即可

// AVFormatParameters *ap, 格式引數,添NULL即可

// 成功返回0,其它失敗

// 不贊成使用 avformat_open_input 代替

9 av_close_input_file()

/**

* @deprecated use avformat_close_input()

* Close a media file (but not its codecs).

* @param s media file handle

*/

void av_close_input_file(AVFormatContext *s);

// 關閉使用avformat_close_input()開啟的輸入檔案容器,但並不關係它的codecs

// 引入標頭檔案:#include "libavformat/avformat.h"

// 使用av_open_input_file 開啟的檔案容器,可以使用該函式關閉

// 使用 av_close_input_file 關閉後,就不再需要使用avformat_free_context 進行釋放了

10 av_find_stream_info()

/**

* Read packets of a media file to get stream information. This

* is useful for file formats with no headers such as MPEG. This

* function also computes the real framerate in case of MPEG-2 repeat

* frame mode.

* The logical file position is not changed by this function;

* examined packets may be buffered for later processing.

*

* @param ic media file handle

* @return >=0 if OK, AVERROR_xxx on error

* @todo Let the user decide somehow what information is needed so that

*       we do not waste time getting stuff the user does not need.

*/

int av_find_stream_info(AVFormatContext *ic);

// 通過讀取媒體檔案的中的包來獲取媒體檔案中的流資訊,對於沒有頭資訊的檔案如(mpeg)是非常有用的,

// 該函式通常重算類似mpeg-2幀模式的真實幀率,該函式並未改變邏輯檔案的position.

// 引入標頭檔案:#include "libavformat/avformat.h"

// 也就是把媒體檔案中的音視訊流等資訊讀出來,儲存在容器中,以便解碼時使用

// 返回>=0時成功,否則失敗

/***********************************************************/

1 avcodec_find_decoder()

/**

* Find a registered decoder with a matching codec ID.

*

* @param id CodecID of the requested decoder

* @return A decoder if one was found, NULL otherwise.

*/

AVCodec *avcodec_find_decoder(enum CodecID id);

// 通過code ID查詢一個已經註冊的音視訊解碼器

// 引入 #include "libavcodec/avcodec.h"

// 實現在: \ffmpeg\libavcodec\utils.c

// 查詢解碼器之前,必須先呼叫av_register_all註冊所有支援的解碼器

// 查詢成功返回解碼器指標,否則返回NULL

// 音視訊解碼器儲存在一個連結串列中,查詢過程中,函式從頭到尾遍歷連結串列,通過比較解碼器的ID來查詢

2 avcodec_find_decoder_by_name()

/**

* Find a registered decoder with the specified name.

*

* @param name name of the requested decoder

* @return A decoder if one was found, NULL otherwise.

*/

AVCodec *avcodec_find_decoder_by_name(constchar *name);

// 通過一個指定的名稱查詢一個已經註冊的音視訊解碼器

// 引入 #include "libavcodec/avcodec.h"

// 實現在: \ffmpeg\libavcodec\utils.c

// 查詢解碼器之前,必須先呼叫av_register_all註冊所有支援的解碼器

// 查詢成功返回解碼器指標,否則返回NULL

// 音視訊解碼器儲存在一個連結串列中,查詢過程中,函式從頭到尾遍歷連結串列,通過比較解碼器的name來查詢

3 avcodec_find_encoder()

/**

* Find a registered encoder with a matching codec ID.

*

* @param id CodecID of the requested encoder

* @return An encoder if one was found, NULL otherwise.

*/

AVCodec *avcodec_find_encoder(enum CodecID id);

// 通過code ID查詢一個已經註冊的音視訊編碼器

// 引入 #include "libavcodec/avcodec.h"

// 實現在: \ffmpeg\libavcodec\utils.c

// 查詢編碼器之前,必須先呼叫av_register_all註冊所有支援的編碼器

// 查詢成功返回編碼器指標,否則返回NULL

// 音視訊編碼器儲存在一個連結串列中,查詢過程中,函式從頭到尾遍歷連結串列,通過比較編碼器的ID來查詢

4 avcodec_find_encoder_by_name()

/**

* Find a registered encoder with the specified name.

*

* @param name name of the requested encoder

* @return An encoder if one was found, NULL otherwise.

*/

AVCodec *avcodec_find_encoder_by_name(constchar *name);

// 通過一個指定的名稱查詢一個已經註冊的音視訊編碼器

// 引入 #include "libavcodec/avcodec.h"

// 實現在: \ffmpeg\libavcodec\utils.c

// 查詢編碼器之前,必須先呼叫av_register_all註冊所有支援的編碼器

// 查詢成功返回編碼器指標,否則返回NULL

// 音視訊編碼器儲存在一個連結串列中,查詢過程中,函式從頭到尾遍歷連結串列,通過比較編碼器的名稱來查詢

5 avcodec_open()

/**

* Initialize the AVCodecContext to use the given AVCodec. Prior to using this

* function the context has to be allocated.

*

* The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(),

* avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for

* retrieving a codec.

*

* @warning This function is not thread safe!

*

* @code

* avcodec_register_all();

* codec = avcodec_find_decoder(CODEC_ID_H264);

* if (!codec)

*     exit(1);

*

* context = avcodec_alloc_context();

*

* if (avcodec_open(context, codec) < 0)

*     exit(1);

* @endcode

*

* @param avctx The context which will be set up to use the given codec.

* @param codec The codec to use within the context.

* @return zero on success, a negative value on error

* @see avcodec_alloc_context, avcodec_find_decoder, avcodec_find_encoder, avcodec_close

*/

int avcodec_open(AVCodecContext *avctx, AVCodec *codec);

// 使用給定的AVCodec初始化AVCodecContext

// 引入#include "libavcodec/avcodec.h"

// 方法: avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(), avcodec_find_decoder() and avcodec_find_encoder() 提供了快速獲取一個codec的途徑

// 該方法在編碼和解碼時都會用到

// 返回0時成功,開啟作為輸出時,引數設定不對的話,呼叫會失敗

6 av_guess_format()

/**

* Return the output format in the list of registered output formats

* which best matches the provided parameters, or return NULL if

* there is no match.

*

* @param short_name if non-NULL checks if short_name matches with the

* names of the registered formats

* @param filename if non-NULL checks if filename terminates with the

* extensions of the registered formats

* @param mime_type if non-NULL checks if mime_type matches with the

* MIME type of the registered formats

*/

AVOutputFormat *av_guess_format(constchar *short_name,

                                constchar *filename,

                                constchar *mime_type);

// 返回一個已經註冊的最合適的輸出格式

// 引入#include "libavformat/avformat.h"

// 可以通過 const char *short_name 獲取,如"mpeg"

// 也可以通過 const char *filename 獲取,如"E:\a.mp4"

7 av_new_stream()

/**

* Add a new stream to a media file.

*

* Can only be called in the read_header() function. If the flag

* AVFMTCTX_NOHEADER is in the format context, then new streams

* can be added in read_packet too.

*

* @param s media file handle

* @param id file-format-dependent stream ID

*/

AVStream *av_new_stream(AVFormatContext *s, int id);

// 為媒體檔案新增一個流,一般為作為輸出的媒體檔案容器新增音視訊流

// 引入 #include "libavformat/avformat.h"

// 再開啟原始檔時使用者一般不需要直接呼叫該方法

8 dump_format()

#if FF_API_DUMP_FORMAT

/**

* @deprecated Deprecated in favor of av_dump_format().

*/

attribute_deprecated void dump_format(AVFormatContext *ic,

                                      int index,

                                      constchar *url,

                                      int is_output);

#endif

// 該函式的作用就是檢查下初始化過程中設定的引數是否符合規範 // 有些版本中為 av_dump_format 9 av_set_parameters()

#if FF_API_FORMAT_PARAMETERS

/**

* @deprecated pass the options to avformat_write_header directly.

*/

attribute_deprecated int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap);

#endif // 設定初始化引數 // 不贊成跳過該方法,直接呼叫 avformat_write_header/av_write_header 10 av_write_header()

#if FF_API_FORMAT_PARAMETERS

/**

* Allocate the stream private data and write the stream header to an

* output media file.

* @note: this sets stream time-bases, if possible to stream->codec->time_base

* but for some formats it might also be some other time base

*

* @param s media file handle

* @return 0 if OK, AVERROR_xxx on error

*

* @deprecated use avformat_write_header.

*/

attribute_deprecated int av_write_header(AVFormatContext *s);

#endif

// 把流頭資訊寫入到媒體檔案中 // 返回0成功

/**********************************************************/

1 AVPacket

typedef struct AVPacket {

    /**

* Presentation timestamp in AVStream->time_base units; the time at which

* the decompressed packet will be presented to the user.

* Can be AV_NOPTS_VALUE if it is not stored in the file.

* pts MUST be larger or equal to dts as presentation cannot happen before

* decompression, unless one wants to view hex dumps. Some formats misuse

* the terms dts and pts/cts to mean something different. Such timestamps

* must be converted to true pts/dts before they are stored in AVPacket.

*/

    int64_t pts;

    /**

* Decompression timestamp in AVStream->time_base units; the time at which

* the packet is decompressed.

* Can be AV_NOPTS_VALUE if it is not stored in the file.

*/

    int64_t dts;

    uint8_t *data;

    int   size;

    int   stream_index;

    int   flags;

int   duration;

.

.

.

} AVPacket

// AVPacket是個很重要的結構,該結構在讀媒體原始檔和寫輸出檔案時都需要用到 // int64_t pts; 顯示時間戳 // int64_t dts; 解碼時間戳 // uint8_t *data; 包資料 // int   size; 包資料長度 // int   stream_index; 包所屬流序號 // int   duration; 時長 // 以上資訊,如果是在讀媒體原始檔那麼avcodec會初始化,如果是輸出檔案,使用者需要對以上資訊賦值 2 av_init_packet()

/**

* Initialize optional fields of a packet with default values.

*

* @param pkt packet

*/

void av_init_packet(AVPacket *pkt);

// 使用預設值初始化AVPacket // 定義AVPacket物件後,請使用av_init_packet進行初始化 3 av_free_packet()

/**

* Free a packet.

*

* @param pkt packet to free

*/

void av_free_packet(AVPacket *pkt);

// 釋放AVPacket物件 av_read_frame()

/**

* Return the next frame of a stream.

* This function returns what is stored in the file, and does not validate

* that what is there are valid frames for the decoder. It will split what is

* stored in the file into frames and return one for each call. It will not

* omit invalid data between valid frames so as to give the decoder the maximum

* information possible for decoding.

*

* The returned packet is valid

* until the next av_read_frame() or until av_close_input_file() and

* must be freed with av_free_packet. For video, the packet contains

* exactly one frame. For audio, it contains an integer number of

* frames if each frame has a known fixed size (e.g. PCM or ADPCM

* data). If the audio frames have a variable size (e.g. MPEG audio),

* then it contains one frame.

*

* pkt->pts, pkt->dts and pkt->duration are always set to correct

* values in AVStream.time_base units (and guessed if the format cannot

* provide them). pkt->pts can be AV_NOPTS_VALUE if the video format

* has B-frames, so it is better to rely on pkt->dts if you do not

* decompress the payload.

*

* @return 0 if OK, < 0 on error or end of file

*/

int av_read_frame(AVFormatContext *s, AVPacket *pkt);

// 從輸入原始檔容器中讀取一個AVPacket資料包

// 該函式讀出的包並不每次都是有效的,對於讀出的包我們都應該進行相應的解碼(視訊解碼/音訊解碼),

// 在返回值>=0時,迴圈呼叫該函式進行讀取,迴圈呼叫之前請呼叫av_free_packet函式清理AVPacket avcodec_decode_video2()

/**

* Decode the video frame of size avpkt->size from avpkt->data into picture.

* Some decoders may support multiple frames in a single AVPacket, such

* decoders would then just decode the first frame.

*

* @warning The input buffer must be FF_INPUT_BUFFER_PADDING_SIZE larger than

* the actual read bytes because some optimized bitstream readers read 32 or 64

* bits at once and could read over the end.

*

* @warning The end of the input buffer buf should be set to 0 to ensure that

* no overreading happens for damaged MPEG streams.

*

* @note You might have to align the input buffer avpkt->data.

* The alignment requirements depend on the CPU: on some CPUs it isn't

* necessary at all, on others it won't work at all if not aligned and on others

* it will work but it will have an impact on performance.

*

* In practice, avpkt->data should have 4 byte alignment at minimum.

*

* @note Some codecs have a delay between input and output, these need to be

* fed with avpkt->data=NULL, avpkt->size=0 at the end to return the remaining frames.

*

* @param avctx the codec context

* @param[out] picture The AVFrame in which the decoded video frame will be stored.

*             Use avcodec_alloc_frame to get an AVFrame, the codec will

*             allocate memory for the actual bitmap.

*             with default get/release_buffer(), the decoder frees/reuses the bitmap as it sees fit.

*             with overridden get/release_buffer() (needs CODEC_CAP_DR1) the user decides into what buffer the decoder

*                   decodes and the decoder tells the user once it does not need the data anymore,

*                   the user app can at this point free/reuse/keep the memory as it sees fit.

*

* @param[in] avpkt The input AVpacket containing the input buffer.

*            You can create such packet with av_init_packet() and by then setting

*            data and size, some decoders might in addition need other fields like

*            flags&AV_PKT_FLAG_KEY. All decoders are designed to use the least

*            fields possible.

* @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero.

* @return On error a negative value is returned, otherwise the number of bytes

* used or zero if no frame could be decompressed.

*/

int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,

                         int *got_picture_ptr,

                         AVPacket *avpkt);

// 解碼視訊流AVPacket // 使用av_read_frame讀取媒體流後需要進行判斷,如果為視訊流則呼叫該函式解碼 // 返回結果<0時失敗,此時程式應該退出檢查原因 // 返回>=0時正常,假設 讀取包為:AVPacket vPacket 返回值為 int vLen; 每次解碼正常時,對vPacket做 // 如下處理: //   vPacket.size -= vLen;
//   vPacket.data += vLen;
// 如果 vPacket.size==0,則繼續讀下一流包,否則繼續排程該方法進行解碼,直到vPacket.size==0 // 返回 got_picture_ptr > 0 時,表示解碼到了AVFrame *picture,其後可以對picture程序處理 avcodec_decode_audio3()

/**

* Decode the audio frame of size avpkt->size from avpkt->data into samples.

* Some decoders may support multiple frames in a single AVPacket, such

* decoders would then just decode the first frame. In this case,

* avcodec_decode_audio3 has to be called again with an AVPacket that contains

* the remaining data in order to decode the second frame etc.

* If no frame

* could be outputted, frame_size_ptr is zero. Otherwise, it is the

* decompressed frame size in bytes.

*

* @warning You must set frame_size_ptr to the allocated size of the

* output buffer before calling avcodec_decode_audio3().

*

* @warning The input buffer must be FF_INPUT_BUFFER_PADDING_SIZE larger than

* the actual read bytes because some optimized bitstream readers read 32 or 64

* bits at once and could read over the end.

*

* @warning The end of the input buffer avpkt->data should be set to 0 to ensure that

* no overreading happens for damaged MPEG streams.

*

* @note You might have to align the input buffer avpkt->data and output buffer

* samples. The alignment requirements depend on the CPU: On some CPUs it isn't

* necessary at all, on others it won't work at all if not aligned and on others

* it will work but it will have an impact on performance.

*

* In practice, avpkt->data should have 4 byte alignment at minimum and

* samples should be 16 byte aligned unless the CPU doesn't need it

* (AltiVec and SSE do).

*

* @param avctx the codec context

* @param[out] samples the output buffer, sample type in avctx->sample_fmt

* @param[in,out] frame_size_ptr the output buffer size in bytes

* @param[in] avpkt The input AVPacket containing the input buffer.

*            You can create such packet with av_init_packet() and by then setting

*            data and size, some decoders might in addition need other fields.

*            All decoders are designed to use the least fields possible though.

* @return On error a negative value is returned, otherwise the number of bytes

* used or zero if no frame data was decompressed (used) from the input AVPacket.

*/

int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,

                         int *frame_size_ptr,

                         AVPacket *avpkt);

// 解碼音訊流AVPacket // 使用av_read_frame讀取媒體流後需要進行判斷,如果為音訊流則呼叫該函式解碼 // 返回結果<0時失敗,此時程式應該退出檢查原因 // 返回>=0時正常,假設 讀取包為:AVPacket vPacket 返回值為 int vLen; 每次解碼正常時,對vPacket做 // 如下處理: //   vPacket.size -= vLen;
//   vPacket.data += vLen;
// 如果 vPacket.size==0,則繼續讀下一流包,否則繼續排程該方法進行解碼,直到vPacket.size==0 轉自:http://blog.csdn.net/leixiaohua1020/article/details/11979565