ffmpeg的IO操作

ffmpeg 可以通过IO操作将数据读取和存储在文件或网络中 作为数据的读取和写入地址,数据被存放在file,http,

ffmpeg 不仅可以编解常用的音视频格式,还可以将数据导入/导出到各种媒介中。 当进行数据压缩时,流媒体数据可以从文件中获取,也可以借助各种专用网络协议从网络中获取。 当进行数据解压时,数据可以存放在文件中,也可以通过网路协议发送到远端。

在ffmpeg中针对不同媒介的数据操作方法被抽象为url_xxx,并记录在结构体 URLProtocol 中。 以文件操作为例:

/libavformat/file.c 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, }; 再比如网络协议rtsp操作: /libavformat/rtpproto.c URLProtocol ff_rtp_protocol = {     .name                = "rtp",     .url_open            = rtp_open,     .url_read            = rtp_read,     .url_write           = rtp_write,     .url_close           = rtp_close,     .url_get_file_handle = rtp_get_file_handle, };

这些操作集通过REGISTER_PROTOCOL ();被注册到系统中,以ffplayer为例, av_register_all 会负责调用REGISTER_PROTOCOL()注册操作集

为了保证IO 操作的一致性,ffmpeg  muxer/demuxer 调用函数一组avio_xxx 进行io操作,包括: avio_rxxx() avio_wxxx() avio_open() avio_close()

...

它们实际上是对  url_open url_read url_write url_cloge

...

的更高一层的抽象,使用avio_xxx 将隔离具体媒介的差异。

avio_rxx 和avio_wxxx  间接的调用ffurl_write 和 ffurl_read,实现读写操作。 而avio_open 则根据文件名判断并实现avio_rxx ,avio_wxxx 和 不同媒介的操作函数 ffurl_read, ffurl_read 之间的邦定。

 

avio_rxx 和avio_wxxx函数实际上只是对内存缓冲区中的数据进行操作,当缓冲区数据不足或将要溢出时, 调用flush_buffer() 或 fill_buffer() 把数据读写到媒介中。

avio_rxxx() 调用fill_buffer(AVIOContext *s)  avio_wxxx() 调用flush_buffer(AVIOContext *s)

flush_buffer() 的实现主要通过回调函数s->write_packet fill_buffer()  的实现主要通过回调函数s->read_packet

在调用avio_open时: 1.  ffurl_open 通过解析文件名,找出对应的操作集  URLProtocol 2.  ffio_fdopen 调用ffio_init_context 把 URLProtocol 中的 ffurl_read ,ffurl_write , ffurl_seek注册到AVIOContext 结构体中 成为将回调函数write_packet ,read_packet和 seek

转自:http://blog.csdn.net/zhangxizhicn/article/details/6781339

posted @ 2013-08-27 20:21  遥望星空  阅读(2170)  评论(0编辑  收藏  举报