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

一、引言

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

bash 复制代码
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命令:

bash 复制代码
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中:

cpp 复制代码
#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中

cpp 复制代码
/**
 * 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":

cpp 复制代码
av_strstart(p, "c=IN IP", NULL)

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

cpp 复制代码
return AVPROBE_SCORE_EXTENSION

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

cpp 复制代码
#define AVPROBE_SCORE_EXTENSION  50 ///< score for file extension
相关推荐
ACP广源盛139246256732 小时前
Qwen3.8‑2.4T 开源落地@ACP#国产 Serdes 长距离视频传输芯片 GSV5800 在私有化 AI 服务中的价值与应用场景
大数据·数据库·人工智能·嵌入式硬件·矩阵·开源·音视频
深圳市宝华视联3 小时前
院感约束下,手术室音视频布线与设备摆放实施注意事项
嵌入式硬件·音视频·实时音视频·视频编解码·嵌入式实时数据库
东莞市奥普新音频技术有限公司4 小时前
国产音频分析仪怎么选?从性能参数、测试软件到自动化能力
人工智能·科技·测试工具·自动化·音视频·音频
hz567894 小时前
视频会议终端的核心功能与采购指南
运维·音视频·信息与通信·智能硬件
美狐美颜sdk5 小时前
从开发角度分析直播APP:视频美颜SDK接入过程中的技术难点
大数据·人工智能·音视频·美颜sdk·美颜api
EAIReport5 小时前
字节Seedance 2.5深度解析:长时序4K视频生成技术突破与产业落地赋能
大数据·人工智能·音视频
视频技术分享6 小时前
技术拆解与实战优化:国产化视频会议系统核心原理与落地策略
其他·重构·架构·实时互动·音视频
老王的笔记v6 小时前
42期 鼠鼠格式转换工具整合图片文档音视频转换,Windows和Mac免费使用
windows·开源·github·音视频
zone_z6 小时前
07 · 等待事件与 OWI 方法:从 OSW 到 BUG 的完整破案实录
linux·数据库·oracle·ffmpeg·bug·troubleshooting