您好,登錄后才能下訂單哦!
AVInputFormat結(jié)構(gòu)體
AVInputFormat 每種碼流輸入格式(例如h364,FLV, MKV, MP4, AVI)對應(yīng)一個(gè)結(jié)構(gòu)體,用來保存視音頻的解碼參數(shù),目前以h364碼流格式為例,描述結(jié)構(gòu)體成員:
name:封裝格式名稱簡寫(short_name)[h364]
long_name:碼流輸入格式的長名稱[raw H.264 video]
extensions:碼流輸入格式的擴(kuò)展名[h36l,h364,264,avc]
raw_codec_id:碼流輸入格式ID[28]
read_packet:avformat-57.dll!0x000007fee101ca90 (加載符號以獲取其他信息)
read_header:avformat-57.dll!0x000007fee101cb70 (加載符號以獲取其他信息)
關(guān)鍵函數(shù):int (*read_packet)(struct AVFormatContext *, AVPacket *pkt);
read_packet函數(shù)讀取一個(gè)AVPacket,然后放在pkt,這個(gè)函數(shù)在進(jìn)行分幀
av_read_frame函數(shù)的里面會(huì)被調(diào)用到,調(diào)用相應(yīng)的×××獲取一幀的完整數(shù)據(jù)
問題:各種碼流輸入格式是什么時(shí)候被加載的?
回答:當(dāng)?shù)谝淮握{(diào)用av_register_all的時(shí)候就會(huì)注冊復(fù)用器,其中就包含了各種碼流的輸入格式的處理函數(shù)
查看調(diào)用關(guān)系
av_register_all
?? ?register_all
?? ??? ?REGISTER_MUXDEMUX(H264,???????????? h364);
?? ??? ??? ?#define REGISTER_MUXDEMUX(X, x) REGISTER_MUXER(X, x); REGISTER_DEMUXER(X, x)
#define REGISTER_MUXER(X, x)??????????????????????????????????????????? \
??? {?????????????????????????????????????????????????????????????????? \
??????? extern AVOutputFormat ff_##x##_muxer;?????????????????????????? \
??????? if (CONFIG_##X##_MUXER)???????????????????????????????????????? \
??????????? av_register_output_format(&ff_##x##_muxer);???????????????? \
??? }
#define REGISTER_DEMUXER(X, x)????????????????????????????????????????? \
??? {?????????????????????????????????????????????????????????????????? \
??????? extern AVInputFormat ff_##x##_demuxer;????????????????????????? \
??????? if (CONFIG_##X##_DEMUXER)?????????????????????????????????????? \
??????????? av_register_input_format(&ff_##x##_demuxer);??????????????? \
??? }
看看注冊碼流輸入格式的函數(shù)
void av_register_input_format(AVInputFormat *format)
{
??? AVInputFormat **p = last_iformat;
??? // Note, format could be added after the first 2 checks but that implies that *p is no longer NULL
??? while(p != &format->next && !format->next && avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format))
??????? p = &(*p)->next;
??? if (!format->next)
??????? last_iformat = &format->next;
}
其中關(guān)鍵的全局變量是
static AVInputFormat *first_iformat = NULL;
static AVInputFormat **last_iformat = &first_iformat;
保存了所有碼流格式
AVInputFormat *av_iformat_next(const AVInputFormat *f)
{
??? if (f)
??????? return f->next;
??? else
??????? return first_iformat;
}
AVInputFormat *av_find_input_format(const char *short_name)
{
??? AVInputFormat *fmt = NULL;
??? while ((fmt = av_iformat_next(fmt)))//獲取×××的鏈表指針,
??????? if (av_match_name(short_name, fmt->name))//根據(jù)輸入的碼流格式簡寫,輪詢鏈表查找×××
??????????? return fmt;
??? return NULL;
}
在avformat_open_input函數(shù)優(yōu)化篇就直接指定碼流的輸入格式,從而減少了探測碼流格式的時(shí)間
參考
http://blog.csdn.net/leixiaohua1020/article/details/12677129
http://blog.csdn.net/neustar1/article/details/38231937
AVFMT_NOFILE宏定義剖析
使用說明
??? 當(dāng)前為了避免在調(diào)用init_input函數(shù)的時(shí)候,讀取緩存區(qū)的數(shù)據(jù),從而設(shè)置了該標(biāo)志位,但是最終在avformat_open_input的其他地方還是讀取了緩沖區(qū)的數(shù)據(jù)
??????? pAVInputFormat = av_find_input_format("h364");
??????? pAVInputFormat->flags |= AVFMT_NOFILE;
宏定義
/// Demuxer will use avio_open, no opened file should be provided by the caller.
//解復(fù)用器將調(diào)用avio_open函數(shù),調(diào)用者提供一個(gè)沒有打開的文件,估計(jì)是打開的文件會(huì)被占用
#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
當(dāng)設(shè)置了AVFMT_NOFILE標(biāo)志,將不會(huì)攜帶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結(jié)構(gòu)體中的read_packet函數(shù)
??? //如果碼流格式已經(jīng)指定并且指定了標(biāo)志位,直接返回
??? 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;
??? }
?? //這里探測碼流的方式,企圖通過通過進(jìn)來的文件名稱
?? //如果碼流格式已經(jīng)指定并且指定了標(biāo)志位,直接返回
?? //這里非常明顯網(wǎng)絡(luò)RTSP流,肯定是不會(huì)走到這里
??? if ((s->iformat && s->iformat->flags & AVFMT_NOFILE) ||
??????? (!s->iformat && (s->iformat = av_probe_input_format2(&pd, 0, &score))))
??????? return score;
??? //如果指定了iformat結(jié)構(gòu)體,并且沒有設(shè)置標(biāo)志位,肯定執(zhí)行下面的語句,該語句會(huì)調(diào)用read_packet函數(shù)
??? //進(jìn)行分析碼流
??? 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);
}
從下面的說明可以得知,當(dāng)添加了AVFMT_NOFILE標(biāo)志位,AVIOContext *pb會(huì)設(shè)置為空
??? /**
???? * 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);
?
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。