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

embedded/2025/1/19 17:41:32/

一、引言

执行《音视频入门基础:RTP专题(2)——使用FFmpeg命令生成RTP流》中的“媒体文件转推RTP的FFmpeg命令”会生成一个SDP文件,该文件内容如下:

v=0
o=- 0 0 IN IP4 127.0.0.1
s=No Name
t=0 0
a=tool:libavformat 61.7.100
m=video 6005 RTP/AVP 96
c=IN IP4 192.168.0.102
b=AS:1327
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1; sprop-parameter-sets=Z2QAH6zZgFAFuwFqAgICgAAAAwCAAAAZB4wYzQ==,aOl7LIs=; profile-level-id=64001F
m=audio 7005 RTP/AVP 97
c=IN IP4 192.168.0.102
b=AS:160
a=rtpmap:97 MPEG4-GENERIC/48000/2
a=fmtp:97 profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3; config=1190

通过FFmpeg命令:

ffmpeg -protocol_whitelist "file,rtp,udp" -i XXX.sdp

可以判断出该文件是否为SDP文件:

所以FFmpeg是怎样判断出某个文件是否为SDP文件呢?它内部其实是通过sdp_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)语句执行不同容器格式对应的解析函数,根据是否能被解析,以及匹配程度,来判断出这是哪种容器格式。而SDP文件对应的解析函数就是sdp_probe函数。

二、sdp_probe函数的定义

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

#if CONFIG_SDP_DEMUXER
static int sdp_probe(const AVProbeData *p1)
{const char *p = p1->buf, *p_end = p1->buf + p1->buf_size;/* we look for a line beginning "c=IN IP" */while (p < p_end && *p != '\0') {if (sizeof("c=IN IP") - 1 < p_end - p &&av_strstart(p, "c=IN IP", NULL))return AVPROBE_SCORE_EXTENSION;while (p < p_end - 1 && *p != '\n') p++;if (++p >= p_end)break;if (*p == '\r')p++;}return 0;
}

该函数的作用就是检测某个文件是否为SDP文件。

形参p:输入型参数,为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的SDP文件中读取出来的二进制数据”的缓冲区。

p->buf_size:缓冲区p->buf的大小,单位为字节。即SDP文件的大小。

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

返回值:返回一个类型为整形的分值。返回0表示该文件完全不符合SDP格式。返回的值越接近100表示该文件越符合SDP格式。

三、sdp_probe函数的内部实现分析

sdp_probe函数中最关键的语句就是通过av_strstart函数判断该文件中是否包含字符串“c=IN IP”:

av_strstart(p, "c=IN IP", NULL)

如果包含字符串“c=IN IP”,返回宏定义AVPROBE_SCORE_EXTENSION:

return AVPROBE_SCORE_EXTENSION

宏定义AVPROBE_SCORE_EXTENSION的值为50。由于其它格式的媒体文件可能也会包含字符串“c=IN IP”,所以这种判断方法并不是特别准确。故最终返回的最高分值只是50,表示匹配SDP文件的程度一般:

#define AVPROBE_SCORE_EXTENSION  50 ///< score for file extension


http://www.ppmy.cn/embedded/155281.html

相关文章

软考高级5个资格、中级常考4个资格简介及难易程度排序

一、软考高级5个资格 01、网络规划设计师 资格简介&#xff1a;网络规划设计师要求考生具备全面的网络规划、设计、部署和管理能力&#xff1b;该资格考试适合那些在网络规划和设计方面具有较好理论基础和较丰富从业经验的人员参加。 02、系统分析师 资格简介&#xff1a;系统分…

2.使用Spring BootSpring AI快速构建AI应用程序

Spring AI 是基于 Spring Boot3.x 框架构建&#xff0c;Spring Boot官方提供了非常便捷的工具Spring Initializr帮助开发者快速的搭建Spring Boot应用程序,IDEA也集成了此工具。本文使用的开发工具IDEASpring Boot 3.4Spring AI 1.0.0-SNAPSHOTMaven。 1.创建Spring Boot项目 …

ACL基础理论

ACL ——访问控制列表 ACL属于策略的一种 ACL访问控制列表的作用&#xff1a; 访问控制&#xff1a;在路由器流量流入或流出的接口上&#xff0c;匹配流量&#xff0c;然后执行设定好的动作&#xff1a;permit&#xff08;允许&#xff09;、deny&#xff08;拒绝&#xff…

Ei Scopus双检索 | 2025年第五届机器人与人工智能国际会议(JCRAI 2025)

会议简介 Brief Introduction 2025年第五届机器人与人工智能国际会议(JCRAI 2025) 会议时间&#xff1a;2025年7月11-13日 召开地点&#xff1a;中国银川 大会官网&#xff1a;www.jcrai.org 人工智能和机器人技术在过去几十年里得到了长足的发展&#xff0c;为未来的机器人应用…

JavaScript前端高效性能优化策略:防抖和节流的详细介绍

一、前言 防抖和节流是我们前端开发性能优化中经常用到的一个手段&#xff0c;目的就是为了减少/限制函数执行的频率&#xff0c;用来提升系统性能和用户体验。本篇文章将深入探讨防抖和节流这两种函数优化手段&#xff0c;防抖在函数频繁触发时只在最后一次且规定时间内无再次…

Three.js贴图加载与环境遮蔽贴图强度设置(五)

在Three.js中&#xff0c;贴图加载与环境遮蔽贴图强度设置是创建逼真3D视觉效果的关键步骤。通过利用Three.js的TextureLoader&#xff0c;开发者可以轻松加载各种纹理贴图&#xff0c;如颜色贴图、透明度贴图以及环境遮蔽&#xff08;Ambient Occlusion, AO&#xff09;贴图&a…

神经网络中的“池化”是什么意思?

目录 一、为什么叫“池化”&#xff1f; 二、池化的作用 三、常见的池化方法 四、为什么不叫“过滤”或“压缩”&#xff1f; 池化&#xff08;Pooling&#xff09;之所以叫作“池化”&#xff0c;是因为它的操作过程和结果类似于从一个“池子”中提取或汇总信息的过程。这…

Java List过滤 Stream API filter() 应用

Java 8 前用 for-each 循环或 Iterator 处理集合&#xff0c;引入 Stream API 后可更简洁、声明式地处理集合&#xff0c;在复杂数据处理时更便捷 1. Stream与Filter基础 Stream 是从支持数据源获取数据的序列&#xff0c;有强大 API 可执行中间和最终操作&#xff0c;能内部…