ffmpeg(2) 关于AVFMT_NOFILE

来源:互联网 发布:java 线程 wait 编辑:程序博客网 时间:2024/06/08 10:24

在学习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使用的问题。


Come on!~~~

   




0 0
原创粉丝点击