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

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

一、引言

执行《音视频入门基础: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.kler.cn/a/510090.html

相关文章:

  • protobuf: 通讯录3.1
  • macOS Sequoia 15.3 beta3(24D5055b)发布,附黑、白苹果镜像下载地址
  • Adobe与MIT推出自回归实时视频生成技术CausVid。AI可以边生成视频边实时播放!
  • 面试经验分享-回忆版某小公司
  • PyTorch使用教程(6)一文讲清楚torch.nn和torch.nn.functional的区别
  • Vue2+OpenLayers实现折线绘制功能(提供Gitee源码)
  • Web自动化测试平台设计与落地
  • 2025.1.15——五、时间盲注
  • 音乐播放器实现:前端HTML,CSS,JavaScript综合大项目
  • Python----Python高级(模块与包,Python基本库)
  • java权限修饰符
  • 线上工单引发的思考:Spring Boot 中 @Autowired 与 @Resource 的区别
  • YOLOv10-1.1部分代码阅读笔记-ops.py
  • 【HarmonyOS NAPI 深度探索9】发布到 npm 并管理版本
  • kubuntu24.04配置vmware17.5.1
  • 【Office学习】PPT中的图片如何放清晰地放到论文中
  • 深度学习J9周:Inception v3算法实战与解析
  • git创建分支,推送分支,合并分支,回退
  • 使用 Python 开发一个 AI Agent 自媒体助手示例
  • dbt Semantic Layer 详细教程-6 :指标(metrics)配置规范及示例
  • 认识 MySQL 和 Redis 的数据一致性问题
  • 动态主机配置协议 (DHCPv4)介绍,详细DHCP协议学习笔记
  • LeetCode:47.全排列 II
  • WPS计算机二级•高效操作技巧
  • TCP TIME-WAIT 状态为什么要坚持 2MSL
  • 【MySQL中InnoDB引擎的行锁是怎么实现的?】