转自:http://blog.csdn.net/xiruanliuwei/article/details/20325467
在学习ffmpeg源码时,常常看到一个Flag:AVFMT_NOFILE,这个Flag非常重要,其在avformat.h中定义:#define AVFMT_NOFILE 0x0001
在整个工程中搜索AVFMT_NOFILE,能够看到ff_alsa_demuxer、ff_bktr_demuxer、ff_dshow_demuxer、ff_dv1394_demuxer、ff_fbdev_demuxer、ff_image2_demuxer等部分
AVInputFormat类型的变量,其结构体成员flags的值被设置为AVFMT_NOFILE,当然,不是只有AVInputFormat类型的变量,部分AVOutputFormat类型的变量,其结构体成员
flags的值也被设置为AVFMT_NOFILE,查看AVFMT_NOFILE的搜索结果,对其稍微详细的解释在avdevice.h中:
/**
* @defgroup lavd Special devices muxing/demuxing library
* @{
* Libavdevice is a complementary library to @ref libavf "libavformat". It
* provides various "special" platform-specific muxers and demuxers, e.g. for
* grabbing devices, audio capture and playback etc. As a consequence, the
* (de)muxers in libavdevice are of the AVFMT_NOFILE type (they use their own
* I/O functions). The filename passed to avformat_open_input() often does not
* refer to an actually existing file, but has some special device-specific
* meaning - e.g. for x11grab it is the display name.
*
* To use libavdevice, simply call avdevice_register_all() to register all
* compiled muxers and demuxers. They all use standard libavformat API.
* @}
*/
libavdevice目录中的内容是libavformat目录中内容的补充,libavdevice提供的是各种特殊平台专用的muxers和demuxers,例如grabbing devices、audio capture、playback等,
因此,libavdevice中的muxers和demuxers,都是AVFMT_NOFILE类型的,这些muxers和demuxers都使用它们自己的I/O函数,传递给avformat_open_input()函数的函数filename,
通常不是指一个实际存在的文件,而是根据特定的设备确定,例如,x11grab,就是display name?显示器名字?
在AVFormatContext结构体中:
/**
* I/O context.
*
* decoding: either set by the user before avformat_open_input() (then
* the user must close it manually) or set by avformat_open_input().
* encoding: set by the user.
*
* Do NOT set this field if AVFMT_NOFILE flag is set in
* iformat/oformat.flags. In such a case, the (de)muxer will handle
* I/O in some other way and this field will be NULL.
*/
AVIOContext *pb;
AVIOContext表示字节流输入/输出的上下文,在muxers和demuxers的数据成员flags有设置AVFMT_NOFILE时,这个成员变量pb就不需要设置,因为muxers和demuxers会
使用其它的方式处理输入/输出。
/**
* Custom interrupt callbacks for the I/O layer.
*
* decoding: set by the user before avformat_open_input().
* encoding: set by the user before avformat_write_header()
* (mainly useful for AVFMT_NOFILE formats). The callback
* should also be passed to avio_open2() if it's used to
* open the file.
*/
AVIOInterruptCB interrupt_callback;
AVIOInterruptCB在cflags有设置AVFMT_NOFILE时使用,传递给函数avio_open2使用。
/**
* Callback for checking whether to abort blocking functions.
* AVERROR_EXIT is returned in this case by the interrupted
* function. During blocking operations, callback is called with
* opaque as parameter. If the callback returns 1, the
* blocking operation will be aborted.
*
* No members can be added to this struct without a major bump, if
* new elements have been added after this struct in AVFormatContext
* or AVIOContext.
*/
typedef struct AVIOInterruptCB
{
int (*callback)(void*);
void *opaque;
} AVIOInterruptCB;
另外,就是:
/**
* Guess the file format.
*
* @param is_opened Whether the file is already opened; determines whether
* demuxers with or without AVFMT_NOFILE are probed.
*/
AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened);
/**
* Guess the file format.
*
* @param is_opened Whether the file is already opened; determines whether
* demuxers with or without AVFMT_NOFILE are probed.
* @param score_max A probe score larger that this is required to accept a
* detection, the variable is set to the actual detection
* score afterwards.
* If the score is <= AVPROBE_SCORE_MAX / 4 it is recommended
* to retry with a larger probe buffer.
*/
AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max);
参数is_opened,与muxers和demuxers有关系。
关于avio_open2:
/**
* Create and initialize a AVIOContext for accessing the
* resource indicated by url.
* @note When the resource indicated by url has been opened in
* read+write mode, the AVIOContext can be used only for writing.
*
* @param s Used to return the pointer to the created AVIOContext.
* In case of failure the pointed to value is set to NULL.
* @param flags flags which control how the resource indicated by url
* is to be opened
* @param int_cb an interrupt callback to be used at the protocols level
* @param options A dictionary filled with protocol-private options. On return
* this parameter will be destroyed and replaced with a dict containing options
* that were not found. May be NULL.
* @return >= 0 in case of success, a negative value corresponding to an
* AVERROR code in case of failure
*/
int avio_open2(AVIOContext **s, const char *url, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options);
参数const AVIOInterruptCB *int_cb,经过层层调用,最终在函数url_alloc_for_protocol中,赋值给新分配的URLContext类型变量的数据成员AVIOInterruptCB interrupt_callback;
static int url_alloc_for_protocol(URLContext **puc, struct URLProtocol *up,
const char *filename, int flags,
const AVIOInterruptCB *int_cb)
{
URLContext *uc;
...
uc = av_mallocz(sizeof(URLContext) + strlen(filename) + 1);
...
if (int_cb)
uc->interrupt_callback = *int_cb;
...
接下来要做的事情,就是理清楚,在有AVFMT_NOFILE和没有AVFMT_NOFILE的两种情况下,avformat input open分别的流程,以及二者之间有什么差别?
另外,还有AVIOInterruptCB使用的问题。