音视频入门基础:RTP专题(15)——FFmpeg源码中,获取RTP的视频信息的实现

一、引言

通过FFmpeg命令可以获取到SDP文件描述的RTP流的视频压缩编码格式、色彩格式(像素格式)、分辨率、帧率信息:

cpp 复制代码
ffmpeg -protocol_whitelist "file,rtp,udp" -i XXX.sdp

本文以H.264为例讲述FFmpeg到底是从哪个地方获取到这些视频信息的。

二、视频压缩编码格式

FFmpeg获取SDP文件描述的RTP流的视频压缩编码格式,是从SDP的"a=rtpmap"这一行获取的。比如SDP文件中某一行的内容为:

cpp 复制代码
a=rtpmap:96 H264/90000

FFmpeg识别到上述"a=rtpmap"这个<type>后,会把后面的字符串"H.264"提取出来,检测是否存在相应的音视频压缩编码格式。如果存在,FFmpeg就会判断该SDP描述的RTP流的视频压缩编码格式为H.264。

具体可以参考:《音视频入门基础:RTP专题(5)------FFmpeg源码中,解析SDP的实现》。

a=rtpmap时,SDP的该行格式为:

a=rtpmap:<payload type> <encoding name>/<clock rate> [/<encoding parameters>],sdp_parse_line函数中会执行下面代码块把SDP中描述的音视频压缩编码格式赋值给st->codecpar->codec_id(即AVCodecParameters的codec_id):

cpp 复制代码
else if (av_strstart(p, "rtpmap:", &p) && s->nb_streams > 0) {
            /* NOTE: rtpmap is only supported AFTER the 'm=' tag */
            get_word(buf1, sizeof(buf1), &p);
            payload_type = atoi(buf1);
            rtsp_st = rt->rtsp_streams[rt->nb_rtsp_streams - 1];
            if (rtsp_st->stream_index >= 0) {
                st = s->streams[rtsp_st->stream_index];
                sdp_parse_rtpmap(s, st, rtsp_st, payload_type, p);
            }
            s1->seen_rtpmap = 1;
            if (s1->seen_fmtp) {
                parse_fmtp(s, rt, payload_type, s1->delayed_fmtp);
            }
        } 

然后在sdp_parse_line函数外部,通过avcodec_parameters_to_context函数将AVCodecParameters的codec_id赋值给AVCodecContext的codec_id:

cpp 复制代码
int avcodec_parameters_to_context(AVCodecContext *codec,
                                  const AVCodecParameters *par)
{
//...
    codec->codec_id   = par->codec_id;
//...
}

然后在dump_stream_format函数中,通过avcodec_string函数中的语句:codec_name = avcodec_get_name(enc->codec_id) 拿到AVCodecContext的codec_id对应的视频压缩编码格式名称。最后再在dump_stream_format函数中将视频压缩编码格式打印出来:

cpp 复制代码
void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode)
{
//...
    codec_name = avcodec_get_name(enc->codec_id);
//...
}

所以FFmpeg获取SDP描述的RTP流的视频压缩编码格式,是从SDP的"a=rtpmap"这一行获取的:

三、视频压缩编码格式的profile

FFmpeg获取SDP文件描述的RTP流的视频压缩编码格式的profile,是从SDP的"a=fmtp"这一行获取的。比如SDP文件中某一行的内容为:

cpp 复制代码
a=fmtp:96 packetization-mode=1; sprop-parameter-sets=Z2QAH6zZgFAFuwFqAgICgAAAAwCAAAAZB4wYzQ==,aOl7LIs=; profile-level-id=64001F

sprop-parameter-sets属性的'='号之后携带以BASE64编码和逗号分隔的SPS和PPS。FFmpeg首先会把SDP中的SPS信息提取出来,进行BASE64解码(具体可以参考:《音视频入门基础:RTP专题(6)------FFmpeg源码中,解析SDP中的packetization-mode、profile-level-id和sprop-parameter-sets实现》),然后通过SPS的profile_idc属性获取视频压缩编码格式的profile(具体可以参考:《音视频入门基础:H.264专题(17)------FFmpeg源码中,获取H.264视频的profile的实现》):

四、视频的色彩格式

如果SDP文件描述的RTP流的视频压缩编码格式为H.264,FFmpeg获取其视频的色彩格式,是通过SPS中的属性chroma_format_idc获取到的,具体可以参考:《音视频入门基础:H.264专题(13)------FFmpeg源码中通过SPS属性获取视频色彩格式的实现》:

五、视频分辨率

如果SDP文件描述的RTP流的视频压缩编码格式为H.264,FFmpeg获取其视频分辨率,是通过SPS中的属性获取的,具体可以参考:《音视频入门基础:H.264专题(12)------FFmpeg源码中通过SPS属性计算视频分辨率的实现》:

六、视频码率

由于SDP中不包含视频码率信息,所以无法通过FFmpeg直接获取到其视频码率。与之对应,由于FLV文件的Script Tag中包含视频码率信息,所以FFmpeg可以直接打印FLV文件的视频码率,具体可以参考:《音视频入门基础:FLV专题(24)------FFmpeg源码中,获取FLV文件视频信息的实现》。

七、视频帧率

如果SDP文件描述的RTP流的视频压缩编码格式为H.264,对其视频进行编解码时,FFmpeg源码内部使用的是通过SPS中的属性计算得到的视频帧率(具体可以参考:《音视频入门基础:H.264专题(15)------FFmpeg源码中通过SPS属性获取视频帧率的实现》):

八、可能遇到的问题

比如,获取RTP流信息时报错:"Could not find codec parameters for stream 0 (Video: h264, none): unspecified size Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (5000000) options"。可以参考《FFmpeg获取RTP流信息时报错:Could not find codec parameters for stream 0 (Video: h264, none)》解决。

相关推荐
Angelina_Jolie28 分钟前
基于 Retinex 的 TempRetinex:适用于不同光照条件下低光视频的无监督增强方法
计算机视觉·音视频
源之缘-专注WPF开发3 小时前
全栈开发实战:WPF+FFmpeg+GIS,打造工业级雷达探测终端
ffmpeg·wpf·gis
山海青风3 小时前
藏文TTS介绍:6 MMS 项目的多语言 TTS
人工智能·python·神经网络·音视频
Everbrilliant897 小时前
FFmpeg解码OpenSL、ANativeWindow播放实现音视频同步
ffmpeg·音视频·opensl音视频同步播放·音视频同步播放·唇音同步·音视频时钟漂移·播放时钟同步
myzzb7 小时前
python调用ffmpeg.exe封装装饰类调用
python·学习·ffmpeg·开发
一点晖光8 小时前
ffmpeg实现图片转视频效果
ffmpeg·音视频
咕噜船长9 小时前
使用Qwen3-VL模型批量标注视频内容(视频理解)
人工智能·pytorch·深度学习·音视频·视频
音视频牛哥9 小时前
内网RTSP直连 + 公网RTMP上云:基于SmartMediakit的 Android双引擎架构设计
音视频·安卓rtsp服务器·安卓轻量级rtsp服务·安卓rtsp摄像头推流·安卓摄像头rtmp推流·安卓 camera2 rtsp·安卓camera2 rtmp
二等饼干~za8986689 小时前
碰一碰发视频系统源码开发搭建--技术分享
java·运维·服务器·重构·django·php·音视频
EasyCVR10 小时前
视频汇聚平台EasyCVR筑牢消防领域可视化监控防线
运维·人工智能·音视频