可能你一直有疑问,ffmpeg的avformat是怎么提前知道码流是编码格式或者容器?恭喜你,看到这里,你找到答案了,在这里,ffmpeg通过这些probe函数来提前获取码流的编码格式。
看到下面的avs2_probe没有,这个就是es流进来后,avformat通过后缀avs/avs2来探测的,可能你觉得我说的前言不搭后语,对不起了,后面有时间慢慢来整理吧。
FF_DEF_RAWVIDEO_DEMUXER(avs2, "raw AVS2-P2/IEEE1857.4", avs2_probe, "avs,avs2", AV_CODEC_ID_AVS2)
下面的截图暂时了ES流进来后通过这个probe来探测是否正确
其实这个宏是用来定义AVInputFormat的,
#define FF_DEF_RAWVIDEO_DEMUXER(shortname, longname, probe, ext, id)\
FF_DEF_RAWVIDEO_DEMUXER2(shortname, longname, probe, ext, id, AVFMT_GENERIC_INDEX)
#define FF_DEF_RAWSUB_DEMUXER(shortname, longname, probe, ext, id, flag)\
const AVInputFormat ff_ ## shortname ## _demuxer = {\
.name = #shortname,\
.long_name = NULL_IF_CONFIG_SMALL(longname),\
.read_probe = probe,\
.read_header = ff_raw_subtitle_read_header,\
.read_packet = ff_raw_read_partial_packet,\
.extensions = ext,\
.flags = flag,\
.raw_codec_id = id,\
.priv_data_size = sizeof(FFRawDemuxerContext),\
.priv_class = &ff_raw_demuxer_class,\
};
另外我们可以看看MP4的定义
static const AVClass mov_class = {
.class_name = "mov,mp4,m4a,3gp,3g2,mj2",
.item_name = av_default_item_name,
.option = mov_options,
.version = LIBAVUTIL_VERSION_INT,
};
const AVInputFormat ff_mov_demuxer = {
.name = "mov,mp4,m4a,3gp,3g2,mj2",
.long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
.priv_class = &mov_class,
.priv_data_size = sizeof(MOVContext),
.extensions = "mov,mp4,m4a,3gp,3g2,mj2,psp,m4b,ism,ismv,isma,f4v",
.flags_internal = FF_FMT_INIT_CLEANUP,
.read_probe = mov_probe,
.read_header = mov_read_header,
.read_packet = mov_read_packet,
.read_close = mov_read_close,
.read_seek = mov_read_seek,
.flags = AVFMT_NO_BYTE_SEEK | AVFMT_SEEK_TO_PTS | AVFMT_SHOW_IDS,
};
好了就到此为止,单独列出来说的主要原因是这个probe非常重要,可以说决定了后面容器demux和codec的选择。