基于ffmpeg的rtsp拉流代码分析流水账

概念

RTP: Real-time Transport Protocol,实时传输协议,一般用于多媒体数据的传输。

RTCP: RTP Control Protocol,实时传输控制协议,同RTP一起用于数据传输的监视,控制功能。

RTSP: Real Time Streaming Protocol,实时流协议,用于多媒体数据流的控制,如播放,暂停等。

RTP/RTCP相对于底层传输层,和RTSP,SIP等上层协议一起可以实现视频会议,视频直播等应用

RTP/RTSP/RTCP的区别 用一句简单的话总结:RTSP发起/终结流媒体、RTP传输流媒体数据 、RTCP对RTP进行控制,同步。

UDP:

TCP:

HTTP:

SDP:

rtsp服务器配置

基本流程 rtsp服务器配置
但是有一点需要主要的

将此mkv文件复制到和上面live555MediaServer可执行文件的同一个目录,

这里不需要将媒体文件放在live555MediaServer同一个目录,具体是看执行live555MediaServer进程的所在文件夹
例如:

Download $ ~/vendor/live/mediaServer/live555MediaServer

这时视频是Download目录下的

  • live555MediaServer传输1080p视频
    默认配置,在terminal会打印如下错误
MultiFramedRTPSink::afterGettingFrame1(): The input frame data was too large for our buffer size (100452).  27300 bytes of trailing data was dropped!  Correct this by increasing "OutPacketBuffer::maxSize" to at least 127300, *before* creating this 'RTPSink'.  (Current value is 100000.)

OutPacketBuffer::maxSize默认大小为100000
需要修改DynamicRTSPServer的代码

} else if (strcmp(extension, ".264") == 0) {
    // Assumed to be a H.264 Video Elementary Stream file:
    NEW_SMS("H.264 Video");
    OutPacketBuffer::maxSize = 157300; // allow for some possibly large H.264 frames
    sms->addSubsession(H264VideoFileServerMediaSubsession::createNew(env, fileName, reuseSource));
  } 

然后重新编译

  • 如何使用rtp over tcp
    在ffmpeg 命令中
 -rtsp_transport tcp -i rtsp://192.168.0.172:8554/bb.264  ./bbo.264

在ffmpeg 代码中

  if (av_stristart(filename, "rtsp", NULL)) {
        av_dict_set(&o->g->format_opts, "rtsp_transport", "tcp", 0);
    }

err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);
  • rtsp over http
    这时候就不要使用live555MediaServer开启时打印信息中的http端口
    例如
(We use port 8000 for optional RTSP-over-HTTP tunneling, or for HTTP live streaming (for indexed Transport Stream files only).)

把url的端口号换一下

  if (av_stristart(filename, "rtsp", NULL)) {
        av_dict_set(&o->g->format_opts, "rtsp_transport", "tcp", 0);
    }

err = avformat_open_input(&ic, filename, file_iformat, &o->g->format_opts);

ffmpeg代码分析

  • ffmpeg rtsp代码位置
    liveformat/rtsp.c 这个是udp里面的实现
    liveformat/rtspdec.c

avformat_open_input

avformat_open_input >>
 rtsp_read_header >>
ff_rtsp_connect>>
ff_rtsp_setup_input_streams

rtsp连接 ff_rtsp_connect

rtsp的控制方式
RTSP_MODE_PLAIN 普通rtsp
RTSP_MODE_TUNNEL 基于HTTP

  • 分割url:proto, auth, host ,port ,path

  • rtsp HTTP打开连接
    ffmpeg会在http的请求报文头发送如下格式

"x-sessioncookie: %s\r\n"
                 "Accept: application/x-rtsp-tunnelled\r\n"
                 "Pragma: no-cache\r\n"
                 "Cache-Control: no-cache\r\n",

x-sessioncookie:只是一个随机的值
即使不看方法体也能猜出来

     snprintf(sessioncookie, sizeof(sessioncookie), "%08x%08x",
                 av_get_random_seed(), av_get_random_seed());
  • rtsp tcp打开连接
    简单的建立信道

  • rtsp 发送OPTIONS命令,获取支持的命令
    rtsp 传输方式

RAW/RAW ::Support receiving plain data over UDP without any RTP encapsulation
RTP/AVP: RTP transport / audio , video , control protocol
x-pn-tng: 不懂

  • rtsp 发送 SETUP命令 ff_rtsp_make_setup_request()函数
    status_code = 461 /* Unsupported protocol */
    status_
    验证c s两端的协议,必须一致(大概是怕我们乱改代码)

interleaved :
The channel identifier is defined in the Transport header with the
interleaved parameter(Section 12.39).
个人理解,tcp是一个持续的流,所以需要一个interleaved来分割包

ff_rtsp_make_setup_request

  • ffmpeg会执行三个动作
    OPTIONS
    查看支持命令
    这里的live555并没有收到任何的报文信息

DESCRIBE 获取视频信息 --就是SDP报文
SETUP 建立RTP通道

rtsp_read_play

ff_read_packet

rtsp_read_packet >> ff_rtsp_fetch_packet

rtp playload格式

参考链接:
http://blog.rongpmcu.com/rtpxue-xi/

packetization-mode 0 : 单一NALU

单NAL单元包(Single NAL Unit Packet):负载中只包含单一的NAL单元。NAL头的类型等同于原始的NAL单元类型,也就是,1~23的范围。此种包必须只包含单个NAL单元,聚合包和分片单元都不能在这种包内使用。必须按解码顺序发送.

packetization-mode 1 : non-interleaved 非交错封包模式

用于聚合多个NAL单元为单个RTP负载。这种包存在四种版本:单时间聚合包(STAP-A),单时间聚合包(STAP-B),多时间聚合包(MTAP)带16位偏移(MTAP16),多时间聚合包(MTAP)带24位偏移(MTAP24). NAL类型号分配给STAP-A,STAP-B,MTAP16和MTAP24分别为24,25,26,27。

packetization-mode 2 : interleaved 交错封包模式

用于分割单一的NAL单元为多个RTP包,共有两个版本,FU-A和FU-B. 它们的NAL类型号分别为28,29.
分片的原因是为了传输大于64KB的NAL单元。
分片针对单个NAL单元,而不是聚合包。
FU不能嵌套。
FU的时戳设置为被分片NAL单元的NALU时间
FU-A包括一个字节的FU indicator+一个字节的FU header+FU payload

FU-B比FU-A多了一个字节的decoding order number(DON).
FU-B必须只被用在交叉包装模式下NAL分片的第一片。换句话说,在交叉包装模式,每个NALU被分片为FU-B+FU-A+FU-A+...+FU-A

ff_rtsp_fetch_packet

ff_rtsp_fetch_packet 根据lower_transport 调用不同协议read_packet的方法

执行流程
OPTIONS-> DESCRIBE->RTSP/SDP

  • SDP(Session Description Protocol)
    SDP 会话描述协议

  • 简单报文分析

v=0 协议版本
o=- 1476286318262307 1 IN IP4 192.168.31.194 (所有者/创建者和会话标识符)
s=H.264 Video, streamed by the LIVE555 Media Server (会话名称)
i=bb.264(会话信息)
t=0 0(会话活动时间)
a=tool:LIVE555 Streaming Media v2016.09.22
a=type:broadcast 
a=control:*
a=range:npt=0-
a=x-qt-text-nam:H.264 Video, streamed by the LIVE555 Media Server
a=x-qt-text-inf:bb.264
m=video 0 RTP/AVP 96(媒体名称和传输地址)
c=IN IP4 0.0.0.0(连接信息 ― 如果包含在所有媒体中,则不需要该字段)
b=AS:500(带宽信息)
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1;profile-level-id=640028;sprop-parametersets=Z2QAKKzZQHgCJ+WEAAADAAQAAAMA8Dxgxlg=,aOvjyyLA
a=control:track1
  • a=rtpmap
    H264 编码名称
    90000 时钟频率
    96 dynamically assigned
    "a=rtpmap" 行中的编码名称必须是 "H264".
    "a=rtpmap" 行中的时钟频率必须是 90000.
  • packetization-mode:表示支持的封包模式.
    当 packetization-mode 的值为 0 时或不存在时, 必须使用单一 NALU 单元模式.
    当 packetization-mode 的值为 1 时必须使用非交错(non-interleaved)封包模式.
    当 packetization-mode 的值为 2 时必须使用交错(interleaved)封包模式.

  • sprop-parameter-sets: SPS,PPS
    这个参数可以用于传输 H.264 的序列参数集和图像参数 NAL 单元. 这个参数的值
    采用 Base64 进行编码. 不同的参数集间用","号隔开

  • profile-level-id:
    这个参数用于指示 H.264 流的 profile 类型和级别. 由 Base16(十六进制) 表示的 3 个字节. 第一个字节表示 H.264 的 Profile 类型, 第三个字节表示 H.264 的 Profile 级别:

参考资料

用实例分析H264 RTP payload

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容