日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ffmpeg的IO操作

發布時間:2023/12/20 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ffmpeg的IO操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

ffmpeg的IO操作主要在libavformat庫中實現,部分實現用到了libavutl中的工具。網上有一些介紹ffmpeg的IO的文章,但是有些比較老了,并且一些現在ffmpeg結構已經一些變化,比如ByteIOContext已經改名為AVIOContext,本文章主要介紹IO基礎,以及一些ffmpeg對于一些內存操作的方法。

所謂IO就是數據的存取,主要的途徑也就是文件或者網絡。數據IO是基于文件格式的,與具體的編碼標準無關。


ffmpeg對各種協議實現了封裝,使用同樣的接口,完成對不同數據的讀取。比較屌。

ffmpeg所有的協議的注冊是在av_register_all中完成的。協議保存在鏈表first_protocol中。

ffmpeg的IO層次,不同的封裝層次:


URLContext層次的操作主要有:url_open,url_read,url_write,url_seek,url_close等

AVIOContext層次的操作主要有:avio_open,avio_clse,avio_rxxx,avio_wxxx。事實上這是對URLContext層次的上層操作。或者更高層次的抽象封裝。

avio_rxxx和avio_wxxx簡介的調用ffurl_read,ffurl_write,實現讀寫操作,而avio_open根據文件名來實現avio_rxxx和avio_wxxx和不用媒介的操作函數ffurl_read,ffurl_write的綁定。

avio_rxxx和avio_wxxx實現的是對內存緩沖區中數據的操作,當緩沖區中數據不足或者緩沖區將要溢出時,調用flush_buffer和fill_buffer將數據把數據讀到媒介中。

實現IO的重要的結構:

ffmpeg的針對不同的媒介的數據操作方法稱為url_xxx并記錄在URLProtocol中

URLProtocol:用于各種數據傳輸協議,結構中定義了一系列的接口(回調函數),包括協議的打開,讀,寫,定位等。

typedef struct URLProtocol {const char *name;//協議名稱int (*url_open)( URLContext *h, const char *url, int flags);//打開協議的函數int (*url_open2)(URLContext *h, const char *url, int flags, AVDictionary **options);//int (*url_read)( URLContext *h, unsigned char *buf, int size);//讀int (*url_write)(URLContext *h, const unsigned char *buf, int size);//int64_t (*url_seek)( URLContext *h, int64_t pos, int whence);int (*url_close)(URLContext *h);struct URLProtocol *next;int (*url_read_pause)(URLContext *h, int pause);int64_t (*url_read_seek)(URLContext *h, int stream_index, int64_t timestamp, int flags);int (*url_get_file_handle)(URLContext *h);int (*url_get_multi_file_handle)(URLContext *h, int **handles, int *numhandles);int (*url_shutdown)(URLContext *h, int flags);int priv_data_size;const AVClass *priv_data_class;int flags;int (*url_check)(URLContext *h, int mask); } URLProtocol; URLContext 協議的上下文:可以看成某種協議的載體,在打開一個協議的時候,全局函數url_open會根據文件的前綴來判斷使用的協議,并為該協議分配好資源,在調用url_connect來打開具體的協議,即調用prot->url_open

typedef struct URLContext {const AVClass *av_class; /**< information for av_log(). Set by url_open(). */struct URLProtocol *prot;void *priv_data;char *filename; /**< specified URL */int flags;int max_packet_size; /**< if non zero, the stream is packetized with this max packet size */int is_streamed; /**< true if streamed (no seek possible), default = false */int is_connected;AVIOInterruptCB interrupt_callback;int64_t rw_timeout; /**< maximum time to wait for (network) read/write operation completion, in mcs */ } URLContext;
比如file協議:

URLProtocol ff_file_protocol = {.name = "file",.url_open = file_open,.url_read = file_read,.url_write = file_write,.url_seek = file_seek,.url_close = file_close,.url_get_file_handle = file_get_handle,.url_check = file_check,.priv_data_size = sizeof(FileContext),.priv_data_class = &file_class, };
AVIOContext:

typedef struct AVIOContext {const AVClass *av_class;unsigned char *buffer; int buffer_size; unsigned char *buf_ptr; unsigned char *buf_end;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);int64_t pos; int must_flush; int eof_reached; int write_flag; 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; int (*read_pause)(void *opaque, int pause);int64_t (*read_seek)(void *opaque, int stream_index, int64_t timestamp, int flags);int seekable;int64_t maxsize;int direct;int64_t bytes_read;int seek_count;int writeout_count;int orig_buffer_size; } AVIOContext; AVIOContext和URLContext的關系:

我們知道數據源頭肯定是URLProtocol,而URLContext是對URLProtocol的封裝,所以AVIOContext肯定和URLContext有某種關系。在url_fopen中,調用了url_fdopen對AVIOContext進行初始化。將read_packet,write_packet,seek_packet分別設置為ffurl_read, ffurl_write,ffurl_seek。

*s = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE, h,(void*)ffurl_read, (void*)ffurl_write, (void*)ffurl_seek);


avio_open/avio_open2函數的作用

int avio_open2(AVIOContext **s, const char *filename, int flags,const AVIOInterruptCB *int_cb, AVDictionary **options) {URLContext *h;int err;err = ffurl_open(&h, filename, flags, int_cb, options);//通過解析文件名,找到對應的操作集URLProtocolif (err < 0)return err;/**調用ffio_init_context把URLProtocol中的ffurl_read, ffurl_write, ffurl_seek,注冊到AVIOContext結構體中,成為read_packet, write_packet的回調函數*/err = ffio_fdopen(s, h);if (err < 0) {ffurl_close(h);return err;}return 0; }
解析文件名,找到對應的操作集URLProtocol
int ffurl_open(URLContext **puc, const char *filename, int flags,const AVIOInterruptCB *int_cb, AVDictionary **options) {int ret = ffurl_alloc(puc, filename, flags, int_cb);//文件名的解析在該函數中實現的if (ret < 0)return ret;if (options && (*puc)->prot->priv_data_class &&(ret = av_opt_set_dict((*puc)->priv_data, options)) < 0)goto fail;if ((ret = av_opt_set_dict(*puc, options)) < 0)goto fail;ret = ffurl_connect(*puc, options);if (!ret)return 0; fail:ffurl_close(*puc);*puc = NULL;return ret; }


未完待續。。。。








總結

以上是生活随笔為你收集整理的ffmpeg的IO操作的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。