FFmpeg AVFMT_NOFILE宏定義剖析

使用說明
    當前爲了避免在調用init_input函數的時候,讀取緩存區的數據,從而設置了該標誌位,但是最終在avformat_open_input的其他地方還是讀取了緩衝區的數據

        pAVInputFormat = av_find_input_format("h264");
        pAVInputFormat->flags |= AVFMT_NOFILE;

宏定義
/// Demuxer will use avio_open, no opened file should be provided by the caller.
//解複用器將調用avio_open函數,調用者提供一個沒有打開的文件,估計是打開的文件會被佔用
#define AVFMT_NOFILE        0x0001
#define AVFMT_NEEDNUMBER    0x0002 /**< Needs '%d' in filename. */
#define AVFMT_SHOW_IDS      0x0008 /**< Show format stream IDs numbers. */


AVFMT_NOFILE formats will not have a AVIOContext
當設置了AVFMT_NOFILE標誌,將不會攜帶AVIOContext


/* Open input file and probe the format if necessary. */
static int init_input(AVFormatContext *s, const char *filename,
                      AVDictionary **options)
{
    int ret;
    AVProbeData pd = { filename, NULL, 0 };
    int score = AVPROBE_SCORE_RETRY;

    //這裏探測碼流的方式,企圖通過AVIOContext結構體中的read_packet函數
    //如果碼流格式已經指定並且指定了標誌位,直接返回
    if (s->pb) {
        s->flags |= AVFMT_FLAG_CUSTOM_IO;
    //如果沒有指定輸入格式,開始探測碼流格式
        if (!s->iformat)
            return av_probe_input_buffer2(s->pb, &s->iformat, filename,
                                         s, 0, s->format_probesize);
        else if (s->iformat->flags & AVFMT_NOFILE)
            av_log(s, AV_LOG_WARNING, "Custom AVIOContext makes no sense and "
                                      "will be ignored with AVFMT_NOFILE format.\n");
        return 0;
    }
   //這裏探測碼流的方式,企圖通過通過進來的文件名稱
   //如果碼流格式已經指定並且指定了標誌位,直接返回
   //這裏非常明顯網絡RTSP流,肯定是不會走到這裏
    if ((s->iformat && s->iformat->flags & AVFMT_NOFILE) ||
        (!s->iformat && (s->iformat = av_probe_input_format2(&pd, 0, &score))))
        return score;

    //如果指定了iformat結構體,並且沒有設置標誌位,肯定執行下面的語句,該語句會調用read_packet函數
    //進行分析碼流
    if ((ret = s->io_open(s, &s->pb, filename, AVIO_FLAG_READ | s->avio_flags, options)) < 0)
        return ret;

    if (s->iformat)
        return 0;
    return av_probe_input_buffer2(s->pb, &s->iformat, filename,
                                 s, 0, s->format_probesize);
}


從下面的說明可以得知,當添加了AVFMT_NOFILE標誌位,AVIOContext *pb會設置爲空
    /**
     * I/O context.
     *
     * - demuxing: either set by the user before avformat_open_input() (then
     *             the user must close it manually) or set by avformat_open_input().
     * - muxing: set by the user before avformat_write_header(). The caller must
     *           take care of closing / freeing the IO context.
     *
     * 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;

    /**
     * Custom interrupt callbacks for the I/O layer.
     *
     * demuxing: set by the user before avformat_open_input().
     * muxing: 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;

/**
 * Guess the file format.
 *
 * @param pd        data to be probed
 * @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);
AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max);
AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score_ret);

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章