当前位置: 首页 > news >正文

音视频入门基础:WAV专题(3)——FFmpeg源码中,判断某文件是否为WAV音频文件的实现

一、引言

通过FFmpeg命令:

./ffmpeg -i XXX.wav

可以判断出某个文件是否为WAV格式的音频文件:

所以FFmpeg是怎样判断出某个文件是否为WAV格式的音频文件呢?它内部其实是通过wav_probe函数来判断的。从文章《FFmpeg源码:av_probe_input_format3函数分析》中我们可以知道:

FFmpeg中实现容器格式检测的函数是av_probe_input_format3函数,其内部通过循环while ((fmt1 = av_demuxer_iterate(&i))) 拿到所有容器格式对应的AVInputFormat结构,然后通过score = fmt1->read_probe(&lpd)语句执行不同容器格式对应的解析函数,根据是否能被解析,以及匹配程度,来判断出这是哪种容器格式。而WAV格式的音频文件对应的解析函数就是wav_probe函数。

二、wav_probe函数的定义

wav_probe函数定义在FFmpeg源码(本文演示用的FFmpeg源码版本为5.0.3)的源文件libavformat/wavdec.c中:

static int wav_probe(const AVProbeData *p)
{/* check file header */if (p->buf_size <= 32)return 0;if (!memcmp(p->buf + 8, "WAVE", 4)) {if (!memcmp(p->buf, "RIFF", 4) || !memcmp(p->buf, "RIFX", 4))/* Since the ACT demuxer has a standard WAV header at the top of* its own, the returned score is decreased to avoid a probe* conflict between ACT and WAV. */return AVPROBE_SCORE_MAX - 1;else if ((!memcmp(p->buf,      "RF64", 4) ||!memcmp(p->buf,      "BW64", 4)) &&!memcmp(p->buf + 12, "ds64", 4))return AVPROBE_SCORE_MAX;}return 0;
}

其作用就是检测某个文件是否为WAV格式的音频文件。

形参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的文件中读取出来的二进制数据”的缓冲区。

p->buf_size:缓冲区p->buf的大小,单位为字节。注:FFmpeg判断某个文件的格式时不会读取完整个文件,只会读取它前面的一部分,比如最开始的2048个字节。只要根据前面的这些字节就足够判断出它的格式了,所以p->buf_size的值一般就是2048。

p->mime_type:一般为NULL,可忽略。

返回值:返回一个类型为整形的分值。返回0表示该文件完全不符合WAV格式。返回一个大于0的值表示该文件比较符合WAV格式,但还需要在av_probe_input_format3函数中执行其它容器格式对应的解析函数来进行对比,最终通过最高分来确定到底是哪种容器格式。

三、wav_probe函数的内部实现原理

wav_probe函数中,首先有如下判断逻辑:如果能读取到的文件中的二进制数据量小于32个字节,远远小于WAV Header中必须包含的数据量,wav_probe函数返回0,表示该文件完全不符合WAV格式:

/* check file header */if (p->buf_size <= 32)return 0;

由《音视频入门基础:WAV专题(2)——WAV格式简介》可以知道,WAV文件的第0到3字节为“区块编号”,内容必须为“RIFF”或“RIFX”;第8到11字节为“档案格式”,内容必须固定为“WAVE”。所以通过下面代码来判断该文件是否符合上述条件,如果符合返回AVPROBE_SCORE_MAX - 1(也就是返回99分),意味着该文件比较符合WAV格式。 从文章《FFmpeg源码:av_probe_input_format3函数分析》中我们可以知道容器格式探测函数的分值最高为100分,100分才是完全符合这种格式。所以为什么下面代码中不是返回100分只是返回99分呢?因为ACT音频格式可能会包含一个标准的WAV文件头,所以FFmpeg将分值减小来避免探测ACT和WAV格式时产生的冲突:

f (!memcmp(p->buf + 8, "WAVE", 4)) {if (!memcmp(p->buf, "RIFF", 4) || !memcmp(p->buf, "RIFX", 4))/* Since the ACT demuxer has a standard WAV header at the top of* its own, the returned score is decreased to avoid a probe* conflict between ACT and WAV. */return AVPROBE_SCORE_MAX - 1;

如果不符合上述的判断,通过下面代码判断该文件是否为WAVE 64位扩展格式Wave64,如果符合,返回AVPROBE_SCORE_MAX(也就是返回100分),意味着该文件完全符合WAV格式。FFmpeg内部把WAV和Wave64当成一种文件格式来处理:

else if ((!memcmp(p->buf,      "RF64", 4) ||!memcmp(p->buf,      "BW64", 4)) &&!memcmp(p->buf + 12, "ds64", 4))return AVPROBE_SCORE_MAX;

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 决策树算法介绍:原理与案例实现
  • 线性代数|机器学习-P25线性规划和两人零和博弈
  • Linux 动静态库
  • 13.2 MongoDB
  • git连接远程仓库
  • VS2019打开《喜缺全书算法册》附带代码的方法
  • java Collections.singletonList方法介绍
  • 全网最详细的postman接口测试教程,一篇文章满足你
  • 流量录制与回放:jvm-sandbox-repeater工具详解
  • 将控制台内容输出到文本文件
  • HarmonyOS 质量、测试、上架速浏
  • Redis 7.x 系列【30】集群管理命令
  • Android中集成前端页面探索(Capacitor 或 Cordova 插件)待完善......
  • Hadoop 重要监控指标
  • 机械学习—零基础学习日志(高数13——函数类型)
  • github从入门到放弃(1)
  • GraphQL学习过程应该是这样的
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • Median of Two Sorted Arrays
  • mysql_config not found
  • mysql常用命令汇总
  • node 版本过低
  • PAT A1120
  • spring security oauth2 password授权模式
  • Web设计流程优化:网页效果图设计新思路
  • 关于 Cirru Editor 存储格式
  • 免费小说阅读小程序
  • 判断客户端类型,Android,iOS,PC
  • 在weex里面使用chart图表
  • #鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行
  • $forceUpdate()函数
  • %check_box% in rails :coditions={:has_many , :through}
  • (1)Jupyter Notebook 下载及安装
  • (31)对象的克隆
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (delphi11最新学习资料) Object Pascal 学习笔记---第5章第5节(delphi中的指针)
  • (办公)springboot配置aop处理请求.
  • (附源码)node.js知识分享网站 毕业设计 202038
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (附源码)计算机毕业设计SSM智能化管理的仓库管理
  • (函数)颠倒字符串顺序(C语言)
  • (三)Hyperledger Fabric 1.1安装部署-chaincode测试
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • (转)Sql Server 保留几位小数的两种做法
  • .bat批处理(六):替换字符串中匹配的子串
  • .dwp和.webpart的区别
  • .NET Core IdentityServer4实战-开篇介绍与规划
  • .NET Core 通过 Ef Core 操作 Mysql
  • .NET MVC之AOP
  • .NET/C# 使窗口永不激活(No Activate 永不获得焦点)
  • .NET程序集编辑器/调试器 dnSpy 使用介绍
  • .w文件怎么转成html文件,使用pandoc进行Word与Markdown文件转化
  • @Mapper作用
  • @Validated和@Valid校验参数区别