音视频入门基础: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
相关推荐
可乐鸡翅yeah_4 小时前
FFmpeg 生成 HLS 独立分片 independent‑segments 参数到底有什么用
javascript·ffmpeg·音视频·safari·m3u8
企业数字化笔记6 小时前
视频理解怎样从“看见”变成“判断”?几何规则、轨迹特征与动作模型的选型
音视频
小猴子爱上树12 小时前
跨马翻译:批量图片翻译+视频字幕+智能抠图,跨境电商在线图片翻译工具
大数据·人工智能·python·音视频
阿明副业观察15 小时前
AI视频创作流程怎么做?完整指南与工具推荐
大数据·人工智能·aigc·音视频·ai写作
aichitang202415 小时前
应用数学与音频信号处理
音视频·信号处理
可乐鸡翅yeah_17 小时前
hls.js 缓冲区参数 maxBufferLength、maxBufferSize 通俗讲解与业务调参
开发语言·javascript·ios·音视频·safari·m3u8
企业数字化笔记17 小时前
视觉处理为什么会慢?解码、预处理、模型推理、后处理和编码的性能拆解
ffmpeg·gpu算力
小宋102117 小时前
视频 RAG 从零实现:镜头切分、字幕对齐与时间段引用
人工智能·音视频
Dovis(誓平步青云)17 小时前
导览音频切换太快,旧讲解不能覆盖新展品
android·前端·javascript·ecmascript·音视频·宠物
归秋1421 天前
多轨音频智能混音软件怎么选:从 demo 到更完整作品的 AI 后期工具思路
人工智能·音视频