5950
- 收藏
- 点赞
- 分享
- 举报
嵌入式 RTP通话:视频流(H.264)的传输
从摄像头获取的视频数据,经过编码后(当然,也可以不编码,如果你觉得也很ok的话),既可以视频录制,同时如果需要,当然也可以视频远程传输咯,而实时传输协议(Real-time Transport Protocol,RTP)是在Internet上处理多媒体数据流的一种网络协议,利用它能够在一对一(unicast,单播)或者一对多(multicast,多播)的网络环境中实现传流媒体数据的实时传输(不需要下载完毕后才能看视频)。RTP通常使用UDP来进行多媒体数据的传输,但如果需要的话可以使用TCP等其它协议,整个RTP协议由两个密切相关的部分组成:RTP数据协议和RTCP控制协议。
RTP数据协议负责对流媒体数据进行封包并实现媒体流的实时传输,每一个RTP数据报都由头部(Header)和负载(Payload)两个部分组成,其中头部前12个字节的含义是固定的,而负载则可以是音频或者视频数据。
RTCP 控制协议需要与RTP数据协议一起配合使用,当应用程序启动一个RTP会话时将同时占用两个端口,分别供RTP和RTCP使用。 RTP本身并不能为按序传输数据包提供可靠的保证,也不提供流量控制和拥塞控制,这些都由RTCP来负责完成。通常RTCP会采用与RTP相同的分发机 制,向会话中的所有成员周期性地发送控制信息,应用程序通过接收这些数据,从中获取会话参与者的相关资料,以及网络状况、分组丢失概率等反馈信息,从而能 够对服务质量进行控制或者对网络状况进行诊断。
实时流协议(RealTime Streaming Protocol,RTSP),它的意义在于使得实时流媒体数据的受控和点播变得可能。总的说来,RTSP是一个流媒体表示协议, 主要用来控制具有实时特性的数据发送,但它本身并不传输数据,而是必须依赖于下层传输协议所提供的某些服务。RTSP 可以对流媒体提供诸如播放、暂停、快进等操作,它负责定义具体的控制消息、操作方法、状态码等,此外还描述了与RTP间的交互操作。
一、JRTPLIB库的安装
Linux:
rtp的运行当然少不了JRTPLIB库的支持,JRTPLIB是一个面向对象的RTP封装库,安装过程如下:
1)下载开发包解压。这里用的是jrtplib-3.7.1,下载地址:http://download.csdn.net/detail/huangminqiang201209/4925142 。
2) 解压后出现两个目录,一个是jrtplib-3.7.1,一个是jthread-1.2.1。JRTPLib是一个开源的RTP库。JThread是一个开源的线程类。
3)进入jthead解压目录,运行./configure配置环境. 配置完毕后运行make, 接着安装make install。
4)jrtplib安装同上。装好以后系统环境如下,静态动态库安装到了/usr/local/lib目录下,包括libjrtplib-3.7.1.so和libjthread-1.2.1.so等。头文件在/usr/local/include目录jrtplib*目录下。
5)Linux默认会在路径为/lib和/usr/lib下的库文件收缩,而上面的库文件在/usr/local/lib下,可以在/lib或者在/usr/lib下创建该库的快捷方式: ln -s /usr/local/lib/libjrtp-3.7.1.so /usr/lib/libjrtp-3.7.1.so
6)在jrtplib源代码目录里有例子程序,make文件都是写好的,试验一下编译example1.cpp,使用静态库libjrtp.a链接,编译语句如下:g++ -o example1 example1.cpp -I /usr/local/include/jrtplib3/ -ljrtp。
7)最后执行命令:ldconfig,更新库的信息,这样执行文件./example1,就可以了
Windows:
1)解压 jrtplib-3.7.1和 jthread-1.2.1
2)用 VC打开工程文件jthread.dsw
3)编译 jrtplib.lib和jthread.lib需要注意VC6要求安装Vs6sp6,在编译jrtplib.lib和jthread.lib前,在 project——settings——C/C++——Codegeneration:use run-time library中,对于 debug,选择:DebugMultithreaded DLL,对于release,则选择:Multithreaded DLL。
4)首先编译 jthread 库,然后将 jthread-1.2.1\src内的"jmutex.h"和"jthread.h"两个头文件放入jrtplib-3.7.1\src目录下,然后将 jrtplib-3.7.1\src 文件夹下所有头文件中的和语句修改为"jmutex.h"和"jthread.h",需要修改的文件为 rtpudpv4transmitter.h、rtpsession.h和 rtppollthread.h。编译时注意编译方式和 jthread.lib一致。
5)编译生成的 jthread.lib 和 jrtplib.lib 拷贝到系统目录:C:\Program Files\Microsoft Visual Studio\VC98\Lib 下,将 jrtplib-3.7.1\src下所有的.h 头文件复制到 C:\Program Files\MicrosoftVisual Studio\VC98\Include,以便以后使用。
6)现在我们就可以编译 jrtplib-3.7.1\examples 下的实例程序了。建立 VC 工程,打开example1.c,在 Project Settings 的 link 页添加 jthread.lib jrtplib.lib ws2_32.lib,在project——settings——C/C++——Code generation:use run-time library 中,对于 debug,选择:DebugMultithreaded DLL,对于 release,则选择:Multithreaded DLL。
7)编译源程序,运行就OK 啦
二、H.264 RTP PAYLOAD
在传输前,先要了解H.264 RTP PAYLOAD 格式(负载格式):
2.分片封包模式(核心代码即为该模式,以及单个NAL单元包): 而当 NALU 的长度超过 MTU (1024)时, 就必须对 NALU 单元进行分片封包. 也称为 Fragmentation Units (FUs).
详情见本文作者原文:http://www.cppblog.com/czanyou/archive/2009/12/25/67940.html
三、数据(无摄像头,即黑屏数据)
1)H.246部分数据:
这是一个序列参数集 NAL 单元. [00 00 00 01] 是四个字节的开始码, 67 是 NALU 头, 42 开始的数据是NALU内容.
2)rtp,即sendpacket()发送的部分数据:
FU indicator:0x7c (NALU&0x60)|28 ==(0110 0111 & 0110 0000) | 28 == 01100000 | 0001 1100 == 0111 1100 ==0x7c
FU header:0x87 (NALU&0x1f)|0x80 == (0110 0111 &0001 1111) | 0x80 == 0000 0111 | 1000 0000 == 1000 0111 == 0x87
这2个字节取代了开始码[00 00 00 01] 。其他的都一样。
NALU:0x67: 0 11 00111(7)
FU indicator:0x7C:0 11 11100(28)
3)网络抓包数据
14 E6 E4 1C C9 7A06 ED B5 C3 AA 23 0800 45 00 00 30 00 00 40 00 40 11 B6 B8 C0 A8 01 42 C0 A801 72 3E D0 04 D200 1CF5 DA 80E2 A8C1 8C 94F8 DD 31 1F06 D7 61 E2 0B 14 28 00 C6 30(62字节)
14 E6 E4 1C C9 7A06 ED B5 C3 AA 23 0800 45 00 00 31 00 00 40 00 40 11 B6B7 C0 A8 01 42 C0 A8 01 72 3E D0 04 D2 00 1D CE BE 80 E2 A8 D4 8C 96 04 0D 31 1F 06 D7 61E8 01 5C 50 A003 18 C0(63字节)
14 E6 E4 1C C9 7A06 ED B5 C3 AA 23 0800 45 00 04 29 00 00 40 00 40 11 B2 BF C0 A8 01 42 C0 A8 01 72 3E D0 04 D2 04 15 5A 5B 80 62 A8 C08C 94 EA CD 31 1F 06 D77C 8742E0 1E DB 02 C0 49 1000 00 00 01 68 CE 30 A4 80 0000 00 01 06 E5 01 DB 80 00 00 00 01 65 B8 00 02 7C 80 6C50 A2 62 80 00 90 3D F7 DF 7DF7 DF 7D F7 DF 7D F7 DF 7D F7 DF 7D F7 DF 7D F7 DF 7D F7 DF 7D F7 DF 7D F7 DF7D F7 DF 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75(第一个包,1079字节)
四、RTP视频传输代码
#define PLOAD_TYPE 98
#define DefaultTimestampIncrement 90000/25
static RTPSession sess;
//创建rtp会话
static int RtpSetup( uint16_t portbase)
{
int status;
*******************************
*******************************
status = sess.Create(sessparams,&transparams);
checkerror(status);
return status;
}
//错误判断
void checkerror(int err)
{
if (err < 0)
{
char* errstr = RTPGetErrorString(err);
printf("Error:%s\\n", errstr);
exit(-1);
}
}
//增加rtp传输目标ip地址,参数为目标ip和端口
int AddDestination(uint32_t ipaddr, uint16_t destport)
{
int status;
RTPIPv4Address addr(ipaddr,destport);
status = sess.AddDestination(addr);
checkerror(status);
return status;
}
//rtp视频传输,val为一帧数据流(264的原始数据),包含0x00 0x00 0x00 0x01信息,length为数据的长度
int H264SendPacket(unsigned char *val, uint32_t length)
{
int status=0;
uint32_t TimestampIncrement;
uint32_t send_length,valid_len=length-4;
char NALU=val[4],*sendStartAddr=NULL;
#define MAX_STREAM_SLICE 1024
//获取默认设置
TimestampIncrement=sess.GetDefaultTimestampIncrement();
//如果数据小于1024字节,直接发送:单一NAL单元模式
if(valid_len <= MAX_STREAM_SLICE)
{
status = sess.SendPacket((void *)&val[4],valid_len,PLOAD_TYPE,true,DefaultTimestampIncrement);
checkerror(status);
}
else
{
//切分为很多个包发送,每个包前要对头进行处理,如第一个包
sendStartAddr=(char *)(val+4);//发送数据的起始地址
sendStartAddr[pos-1]=(NALU&0x60)|28;//FU indicator
sendStartAddr[pos]=(NALU&0x1f)|0x80;//FU header
send_length=MAX_STREAM_SLICE+1;//要发送数据的长度,1025字节
………………………………
//第二个至倒数第二个包
………………………………
//最后一个包
}
checkerror(status);
end:
return status;
}
对了,记得要连接rtp库哦!!!!
五、SDP参数
因为程序是在Hi35XX开发板上运行,所以我的工作是把编码后的视频发送出去就ok了。
在windows下,写了一个脚本xxx.dsp,内容如下:
m=video 1234 RTP/AVP 98
a=rtpmap:98 H264/90000;
a=decode_buf=300;
a=framerate:15
c=IN IP4 192.168.2.105 //板子的ip
注:
1)"m=" 行中的媒体名必须是 "video",端口为1234.
2)"a=rtpmap" 行中的编码名称必须是 "H264".时钟频率必须是 90000.
然后把脚本拖到VLCPortable.exe软件中(VLC是一个标准),就能显示摄像头获取的视频,就说明rtp传输没问题
RTP数据协议负责对流媒体数据进行封包并实现媒体流的实时传输,每一个RTP数据报都由头部(Header)和负载(Payload)两个部分组成,其中头部前12个字节的含义是固定的,而负载则可以是音频或者视频数据。
RTCP 控制协议需要与RTP数据协议一起配合使用,当应用程序启动一个RTP会话时将同时占用两个端口,分别供RTP和RTCP使用。 RTP本身并不能为按序传输数据包提供可靠的保证,也不提供流量控制和拥塞控制,这些都由RTCP来负责完成。通常RTCP会采用与RTP相同的分发机 制,向会话中的所有成员周期性地发送控制信息,应用程序通过接收这些数据,从中获取会话参与者的相关资料,以及网络状况、分组丢失概率等反馈信息,从而能 够对服务质量进行控制或者对网络状况进行诊断。
实时流协议(RealTime Streaming Protocol,RTSP),它的意义在于使得实时流媒体数据的受控和点播变得可能。总的说来,RTSP是一个流媒体表示协议, 主要用来控制具有实时特性的数据发送,但它本身并不传输数据,而是必须依赖于下层传输协议所提供的某些服务。RTSP 可以对流媒体提供诸如播放、暂停、快进等操作,它负责定义具体的控制消息、操作方法、状态码等,此外还描述了与RTP间的交互操作。
一、JRTPLIB库的安装
Linux:
rtp的运行当然少不了JRTPLIB库的支持,JRTPLIB是一个面向对象的RTP封装库,安装过程如下:
1)下载开发包解压。这里用的是jrtplib-3.7.1,下载地址:http://download.csdn.net/detail/huangminqiang201209/4925142 。
2) 解压后出现两个目录,一个是jrtplib-3.7.1,一个是jthread-1.2.1。JRTPLib是一个开源的RTP库。JThread是一个开源的线程类。
3)进入jthead解压目录,运行./configure配置环境. 配置完毕后运行make, 接着安装make install。
4)jrtplib安装同上。装好以后系统环境如下,静态动态库安装到了/usr/local/lib目录下,包括libjrtplib-3.7.1.so和libjthread-1.2.1.so等。头文件在/usr/local/include目录jrtplib*目录下。
5)Linux默认会在路径为/lib和/usr/lib下的库文件收缩,而上面的库文件在/usr/local/lib下,可以在/lib或者在/usr/lib下创建该库的快捷方式: ln -s /usr/local/lib/libjrtp-3.7.1.so /usr/lib/libjrtp-3.7.1.so
6)在jrtplib源代码目录里有例子程序,make文件都是写好的,试验一下编译example1.cpp,使用静态库libjrtp.a链接,编译语句如下:g++ -o example1 example1.cpp -I /usr/local/include/jrtplib3/ -ljrtp。
7)最后执行命令:ldconfig,更新库的信息,这样执行文件./example1,就可以了
Windows:
1)解压 jrtplib-3.7.1和 jthread-1.2.1
2)用 VC打开工程文件jthread.dsw
3)编译 jrtplib.lib和jthread.lib需要注意VC6要求安装Vs6sp6,在编译jrtplib.lib和jthread.lib前,在 project——settings——C/C++——Codegeneration:use run-time library中,对于 debug,选择:DebugMultithreaded DLL,对于release,则选择:Multithreaded DLL。
4)首先编译 jthread 库,然后将 jthread-1.2.1\src内的"jmutex.h"和"jthread.h"两个头文件放入jrtplib-3.7.1\src目录下,然后将 jrtplib-3.7.1\src 文件夹下所有头文件中的和语句修改为"jmutex.h"和"jthread.h",需要修改的文件为 rtpudpv4transmitter.h、rtpsession.h和 rtppollthread.h。编译时注意编译方式和 jthread.lib一致。
5)编译生成的 jthread.lib 和 jrtplib.lib 拷贝到系统目录:C:\Program Files\Microsoft Visual Studio\VC98\Lib 下,将 jrtplib-3.7.1\src下所有的.h 头文件复制到 C:\Program Files\MicrosoftVisual Studio\VC98\Include,以便以后使用。
6)现在我们就可以编译 jrtplib-3.7.1\examples 下的实例程序了。建立 VC 工程,打开example1.c,在 Project Settings 的 link 页添加 jthread.lib jrtplib.lib ws2_32.lib,在project——settings——C/C++——Code generation:use run-time library 中,对于 debug,选择:DebugMultithreaded DLL,对于 release,则选择:Multithreaded DLL。
7)编译源程序,运行就OK 啦
二、H.264 RTP PAYLOAD
在传输前,先要了解H.264 RTP PAYLOAD 格式(负载格式):
2.分片封包模式(核心代码即为该模式,以及单个NAL单元包): 而当 NALU 的长度超过 MTU (1024)时, 就必须对 NALU 单元进行分片封包. 也称为 Fragmentation Units (FUs).
详情见本文作者原文:http://www.cppblog.com/czanyou/archive/2009/12/25/67940.html
三、数据(无摄像头,即黑屏数据)
1)H.246部分数据:
这是一个序列参数集 NAL 单元. [00 00 00 01] 是四个字节的开始码, 67 是 NALU 头, 42 开始的数据是NALU内容.
2)rtp,即sendpacket()发送的部分数据:
FU indicator:0x7c (NALU&0x60)|28 ==(0110 0111 & 0110 0000) | 28 == 01100000 | 0001 1100 == 0111 1100 ==0x7c
FU header:0x87 (NALU&0x1f)|0x80 == (0110 0111 &0001 1111) | 0x80 == 0000 0111 | 1000 0000 == 1000 0111 == 0x87
这2个字节取代了开始码[00 00 00 01] 。其他的都一样。
NALU:0x67: 0 11 00111(7)
FU indicator:0x7C:0 11 11100(28)
3)网络抓包数据
14 E6 E4 1C C9 7A06 ED B5 C3 AA 23 0800 45 00 00 30 00 00 40 00 40 11 B6 B8 C0 A8 01 42 C0 A801 72 3E D0 04 D200 1CF5 DA 80E2 A8C1 8C 94F8 DD 31 1F06 D7 61 E2 0B 14 28 00 C6 30(62字节)
14 E6 E4 1C C9 7A06 ED B5 C3 AA 23 0800 45 00 00 31 00 00 40 00 40 11 B6B7 C0 A8 01 42 C0 A8 01 72 3E D0 04 D2 00 1D CE BE 80 E2 A8 D4 8C 96 04 0D 31 1F 06 D7 61E8 01 5C 50 A003 18 C0(63字节)
14 E6 E4 1C C9 7A06 ED B5 C3 AA 23 0800 45 00 04 29 00 00 40 00 40 11 B2 BF C0 A8 01 42 C0 A8 01 72 3E D0 04 D2 04 15 5A 5B 80 62 A8 C08C 94 EA CD 31 1F 06 D77C 8742E0 1E DB 02 C0 49 1000 00 00 01 68 CE 30 A4 80 0000 00 01 06 E5 01 DB 80 00 00 00 01 65 B8 00 02 7C 80 6C50 A2 62 80 00 90 3D F7 DF 7DF7 DF 7D F7 DF 7D F7 DF 7D F7 DF 7D F7 DF 7D F7 DF 7D F7 DF 7D F7 DF 7D F7 DF7D F7 DF 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D75D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D75 D7 5D 75 D7 5D 75 D7 5D 75 D7 5D 75(第一个包,1079字节)
四、RTP视频传输代码
#define PLOAD_TYPE 98
#define DefaultTimestampIncrement 90000/25
static RTPSession sess;
//创建rtp会话
static int RtpSetup( uint16_t portbase)
{
int status;
*******************************
*******************************
status = sess.Create(sessparams,&transparams);
checkerror(status);
return status;
}
//错误判断
void checkerror(int err)
{
if (err < 0)
{
char* errstr = RTPGetErrorString(err);
printf("Error:%s\\n", errstr);
exit(-1);
}
}
//增加rtp传输目标ip地址,参数为目标ip和端口
int AddDestination(uint32_t ipaddr, uint16_t destport)
{
int status;
RTPIPv4Address addr(ipaddr,destport);
status = sess.AddDestination(addr);
checkerror(status);
return status;
}
//rtp视频传输,val为一帧数据流(264的原始数据),包含0x00 0x00 0x00 0x01信息,length为数据的长度
int H264SendPacket(unsigned char *val, uint32_t length)
{
int status=0;
uint32_t TimestampIncrement;
uint32_t send_length,valid_len=length-4;
char NALU=val[4],*sendStartAddr=NULL;
#define MAX_STREAM_SLICE 1024
//获取默认设置
TimestampIncrement=sess.GetDefaultTimestampIncrement();
//如果数据小于1024字节,直接发送:单一NAL单元模式
if(valid_len <= MAX_STREAM_SLICE)
{
status = sess.SendPacket((void *)&val[4],valid_len,PLOAD_TYPE,true,DefaultTimestampIncrement);
checkerror(status);
}
else
{
//切分为很多个包发送,每个包前要对头进行处理,如第一个包
sendStartAddr=(char *)(val+4);//发送数据的起始地址
sendStartAddr[pos-1]=(NALU&0x60)|28;//FU indicator
sendStartAddr[pos]=(NALU&0x1f)|0x80;//FU header
send_length=MAX_STREAM_SLICE+1;//要发送数据的长度,1025字节
………………………………
//第二个至倒数第二个包
………………………………
//最后一个包
}
checkerror(status);
end:
return status;
}
对了,记得要连接rtp库哦!!!!
五、SDP参数
因为程序是在Hi35XX开发板上运行,所以我的工作是把编码后的视频发送出去就ok了。
在windows下,写了一个脚本xxx.dsp,内容如下:
m=video 1234 RTP/AVP 98
a=rtpmap:98 H264/90000;
a=decode_buf=300;
a=framerate:15
c=IN IP4 192.168.2.105 //板子的ip
注:
1)"m=" 行中的媒体名必须是 "video",端口为1234.
2)"a=rtpmap" 行中的编码名称必须是 "H264".时钟频率必须是 90000.
然后把脚本拖到VLCPortable.exe软件中(VLC是一个标准),就能显示摄像头获取的视频,就说明rtp传输没问题
我来回答
回答7个
时间排序
认可量排序
认可0
认可0
认可0
认可0
认可0
认可0
认可0
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币
Markdown 语法
- 加粗**内容**
- 斜体*内容*
- 删除线~~内容~~
- 引用> 引用内容
- 代码`代码`
- 代码块```编程语言↵代码```
- 链接[链接标题](url)
- 无序列表- 内容
- 有序列表1. 内容
- 缩进内容
- 图片![alt](url)
相关问答
-
2015-03-09 16:56:23
-
2016-12-08 13:04:57
-
2016-10-24 20:45:58
-
2018-07-06 16:02:29
-
2017-06-05 15:20:33
-
02016-06-22 23:45:46
-
252014-12-29 14:49:27
-
2016-10-09 16:53:39
-
2016-08-20 19:50:06
-
2018-07-04 16:22:17
-
02008-08-14 00:23:28
-
02008-07-12 19:17:39
-
82017-12-07 16:55:14
-
2020-10-06 12:09:23
-
02013-11-18 15:31:11
-
02008-07-19 12:55:54
-
2020-12-15 09:08:09
-
2017-02-05 14:42:55
-
2015-09-05 18:32:24
无更多相似问答 去提问
点击登录
-- 积分
-- E币
提问
—
收益
—
被采纳
—
我要提问
切换马甲
上一页
下一页
悬赏问答
-
5Hi3516CV610 如何使用SD卡升级固件
-
5cat /dev/logmpp 报错 <3>[ vi] [func]:vi_send_frame_node [line]:99 [info]:vi pic queue is full!
-
50如何获取vpss chn的图像修改后发送至vo
-
5FPGA通过Bt1120传YUV422数据过来,vi接收不到数据——3516dv500
-
50SS928 运行PQtools 拼接 推到设备里有一半画面会异常
-
53536AV100的sample_vdec输出到CVBS显示
-
10海思板子mpp怎么在vi阶段改变视频数据尺寸
-
10HI3559AV100 多摄像头同步模式
-
9海思ss928单路摄像头vio中加入opencv处理并显示
-
10EB-RV1126-BC-191板子运行自己编码的程序
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
提醒
你的问题还没有最佳答案,是否结题,结题后将扣除20%的悬赏金
取消
确认
提醒
你的问题还没有最佳答案,是否结题,结题后将根据回答情况扣除相应悬赏金(1回答=1E币)
取消
确认