ffmpeg結(jié)構(gòu)體以及函數(shù)介紹(一)
本文對在使用ffmpeg進行音視頻編解碼時使用到的一些函數(shù)做一個簡單介紹,我當(dāng)前使用的ffmpeg版本為:0.8.5,因為本人發(fā)現(xiàn)在不同的版本中,有些函數(shù)名稱會有點小改動,所以在此有必要說明下ffmpeg的版本號,。
ffmpeg本人也是剛接觸,,本文將采用累加的方法逐個介紹我使用到的函數(shù),如有不妥之處,,還望諒解,!
頭文件引入方法:
extern "C" { #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #include "libavutil/avutil.h" #include "libavutil/mem.h" #include "libavutil/fifo.h" #include "libswscale/swscale.h" };
1 avcodec_init()
/** * 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,一般最先調(diào)用該函數(shù) // 引入頭文件: #include "libavcodec/avcodec.h" // 實現(xiàn)在: \ffmpeg\libavcodec\utils.c // 該函數(shù)必須在調(diào)用libavcodec里的其它函數(shù)前調(diào)用,一般在程序啟動或模塊初始化時調(diào)用,如果你調(diào)用了多次也無所謂,因為后面的調(diào)用不會做任何事情.從函數(shù)的實現(xiàn)里你可以發(fā)現(xiàn),代碼中對多次調(diào)用進行了控制. // 該函數(shù)是非線程安全的
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, // 一般在調(diào)用avcodec_init后調(diào)用該方法 // 引入頭文件:#include "libavformat/avformat.h" // 實現(xiàn)在:\ffmpeg\libavformat\allformats.c // 其中會調(diào)用avcodec_register_all()注冊多種音視頻格式的編解碼器,并注冊各種文件的編解復(fù)用器 // 當(dāng)然,,你也可以不調(diào)用該函數(shù),,而通過選擇調(diào)用特定的方法來提供支持
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結(jié)構(gòu) // 引入頭文件:#include "libavformat/avformat.h" // 實現(xiàn)在:\ffmpeg\libavformat\options.c // 其中負(fù)責(zé)申請一個AVFormatContext結(jié)構(gòu)的內(nèi)存,并進行簡單初始化 // avformat_free_context()可以用來釋放該結(jié)構(gòu)里的所有東西以及該結(jié)構(gòu)本身 // 也是就說使用 avformat_alloc_context()分配的結(jié)構(gòu),需要使用avformat_free_context()來釋放 // 有些版本中函數(shù)名可能為: 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結(jié)構(gòu) // 引入頭文件:#include "libavformat/avformat.h" // 實現(xiàn)在:\ffmpeg\libavformat\utils.c // 使用 avformat_alloc_context()分配的結(jié)構(gòu),采用該函數(shù)進行釋放,除釋放AVFormatContext結(jié)構(gòu)本身內(nèi)存之外,AVFormatContext中指針?biāo)赶虻膬?nèi)存也會一并釋放 // 有些版本中函數(shù)名猜測可能為: av_free_format_context();
5 AVFormatContext 結(jié)構(gòu) /** * 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里是一個非常重要的的結(jié)構(gòu),是其它輸入,、輸出相關(guān)信息的一個容器 // 引入頭文件:#include "libavformat/avformat.h" // 以上只列出了其中的部分成員 // 作為輸入容器時 struct AVInputFormat *iformat; 不能為空, 其中包含了輸入文件的音視頻流信息,程序從輸入容器從讀出音視頻包進行解碼處理 // 作為輸出容器時 struct AVOutputFormat *oformat; 不能為空, 程序把編碼好的音視頻包寫入到輸出容器中 // AVIOContext *pb: I/O上下文,通過對該變量賦值可以改變輸入源或輸出目的 // unsigned int nb_streams; 音視頻流數(shù)量 // AVStream **streams; 音視頻流
6 AVIOContext 結(jié)構(gòu) /** * 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; // 字節(jié)流 I/O 上下文 // 在結(jié)構(gòu)的尾部增加變量可以減少版本沖突 // 移除,、排序和修改已經(jīng)存在的變量將會導(dǎo)致較大的版本沖突 // sizeof(AVIOContext)在libav*.外部不可使用 // AVIOContext里的函數(shù)指針不能直接調(diào)用,通常使用avio_alloc_context()函數(shù)來設(shè)置其中的函數(shù)指針 // unsigned char *buffer: 緩存的起始指針 // int buffer_size: 緩存的最大值 // void *opaque: 在回調(diào)函數(shù)中使用的指針 // int (*read_packet)(void *opaque, uint8_t *buf, int buf_size): 讀文件回調(diào)方法 // int (*write_packet)(void *opaque, uint8_t *buf, int buf_size): 寫文件回調(diào)方法 // int64_t (*seek)(void *opaque, int64_t offset, int whence): seek文件回調(diào)方法
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結(jié)構(gòu),結(jié)束使用時必須使用av_free()進行釋放 // unsigned char *buffer: 輸入/輸出緩存內(nèi)存塊,必須是使用av_malloc()分配的 // int buffer_size: 緩存大小是非常重要的 // int write_flag: 如果緩存為可寫則設(shè)置為1,否則設(shè)置為0 // void *opaque: 指針,用于回調(diào)時使用 // int (*read_packet): 讀包函數(shù)指針 // int (*write_packet): 寫包函數(shù)指針 // int64_t (*seek): seek文件函數(shù)指針 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, const char *filename, AVInputFormat *fmt, int buf_size, AVFormatParameters *ap); // 以輸入方式打開一個媒體文件,也即源文件,codecs并沒有打開,只讀取了文件的頭信息. // 引入頭文件:#include "libavformat/avformat.h" // AVFormatContext **ic_ptr 輸入文件容器 // const char *filename 輸入文件名,全路徑,并且保證文件存在 // AVInputFormat *fmt 輸入文件格式,填NULL即可 // int buf_size,緩沖區(qū)大小,直接填0即可 // AVFormatParameters *ap, 格式參數(shù),添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); // 關(guān)閉使用avformat_close_input()打開的輸入文件容器,但并不關(guān)系它的codecs // 引入頭文件:#include "libavformat/avformat.h" // 使用av_open_input_file 打開的文件容器,可以使用該函數(shù)關(guān)閉 // 使用 av_close_input_file 關(guān)閉后,就不再需要使用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)是非常有用的, // 該函數(shù)通常重算類似mpeg-2幀模式的真實幀率,該函數(shù)并未改變邏輯文件的position. // 引入頭文件:#include "libavformat/avformat.h" // 也就是把媒體文件中的音視頻流等信息讀出來,保存在容器中,以便解碼時使用 // 返回>=0時成功,否則失敗 |
|