太仓苏州网站建设,wordpress需要编程技术嘛,企业网站备案价格,企业画册vi设计一、引言
通过FFmpeg命令#xff1a;
./ffmpeg -i XXX.flv
可以判断出某个文件是否为FLV文件#xff1a; 所以FFmpeg是怎样判断出某个文件是否为FLV文件呢#xff1f;它内部其实是通过flv_probe函数来判断的。从《FFmpeg源码#xff1a;av_probe_input_format3函数和AVI…一、引言
通过FFmpeg命令
./ffmpeg -i XXX.flv
可以判断出某个文件是否为FLV文件 所以FFmpeg是怎样判断出某个文件是否为FLV文件呢它内部其实是通过flv_probe函数来判断的。从《FFmpeg源码av_probe_input_format3函数和AVInputFormat结构体分析FFmpeg源码5.0.3版本》和《7.0.1版本的FFmpeg源码中av_probe_input_format3函数和AVInputFormat结构体的改变》中我们可以知道
FFmpeg源码中实现容器格式检测的函数是av_probe_input_format3函数其内部通过循环while ((fmt1 av_demuxer_iterate(i))) 拿到所有容器格式对应的AVInputFormat结构然后通过score fmt1-read_probe(lpd)语句执行不同容器格式对应的解析函数根据是否能被解析以及匹配程度来判断出这是哪种容器格式。而FLV文件对应的解析函数就是flv_probe函数。 二、flv_probe函数的定义
flv_probe函数定义在FFmpeg源码本文演示用的FFmpeg源码版本为7.0.1的源文件libavformat/flvdec.c中可以看到flv_probe函数内部调用了probe函数
static int flv_probe(const AVProbeData *p)
{return probe(p, 0);
} 三、probe函数的定义
probe函数也定义在libavformat/flvdec.c中
static int probe(const AVProbeData *p, int live)
{const uint8_t *d p-buf;unsigned offset AV_RB32(d 5);if (d[0] F d[1] L d[2] V d[3] 5 d[5] 0 offset 100 p-buf_size offset 8) {int is_live !memcmp(d offset 40, NGINX RTMP, 10);if (live is_live)return AVPROBE_SCORE_MAX;}return 0;
}
probe函数的作用就是检测某个文件是否为flv文件或flv格式的直播流。 形参pd输入型参数为AVProbeData类型的指针。
AVProbeData结构体声明在libavformat/avformat.h中
/*** This structure contains the data a format has to probe a file.*/
typedef struct AVProbeData {const char *filename;unsigned char *buf; /** Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero. */int buf_size; /** Size of buf except extra allocated bytes */const char *mime_type; /** mime_type, when known. */
} AVProbeData; p-filename为需要被推测格式的文件/直播流的路径。
p-buf指向“存放从路径为p-filename的FLV文件/直播流中读取出来的二进制数据”的缓冲区。
p-buf_size缓冲区p-buf的大小单位为字节。注FFmpeg判断某个文件的格式时不会读取完整个文件只会读取它前面的一部分比如最开始的2048个字节。只要根据前面的这些字节就足够判断出它的格式了所以p-buf_size的值一般就是2048。
p-mime_type一般为NULL可忽略。
返回值返回一个类型为整形的分值。返回0表示该文件/直播流完全不符合FLV格式。返回AVPROBE_SCORE_MAX100表示该文件/直播流完全符合FLV格式。 形参live值为1表示需要被推测格式的是直播流值为0表示需要被推测格式的是本地媒体文件。 四、probe函数的内部实现原理
下面以需要被推测格式的是FLV文件为例讲解probe函数的内部实现原理。FLV文件对应的解析函数是flv_probe函数flv_probe函数内部调用了probe函数这时probe函数的形参live的值为0。 probe函数内部由于FLV文件的开头就是FLV header所以指针d指向FLV header const uint8_t *d p-buf; 通过AV_RB32宏定义读取FLV header中的DataOffset属性得到整个FLV header的以字节为单位的长度赋值给局部变量offset。关于AV_RB32宏定义的用法可以参考《FFmpeg源码AV_RB32、AV_RB16、AV_RB8宏定义分析》 unsigned offset AV_RB32(d 5); 从《音视频入门基础FLV专题3——FLV header简介》可以知道FLV header的前3个字节固定为“FLV”所有判断d[0] F d[1] L d[2] VFLV header的第4个字节为Version对于FLV格式值必须为1所以判断d[3] 5整个FLV header的长度固定为9所以判断offset 8。不满足条件probe函数返回0表示完全不符合FLV格式 if (d[0] F d[1] L d[2] V d[3] 5 d[5] 0 offset 100 p-buf_size offset 8) {//...}return 0; 判断是否为直播流变量is_live的值为1表示是直播流值为0表示是FLV文件 int is_live !memcmp(d offset 40, NGINX RTMP, 10); 返回AVPROBE_SCORE_MAX100表示该文件/直播流完全符合FLV格式。 if (live is_live)return AVPROBE_SCORE_MAX;