8566
- 收藏
- 点赞
- 分享
- 举报
用RTP发送H264,VLC接收没反应
[i=s] 本帖最后由 史前小虫 于 2014-12-29 20:40 编辑 [/i]
hi3531的板子,在SAMPLE_COMM_VENC_SaveH264(FILE fpH264File, VENC_STREAM_S pstStream)函数下调用
RTP_Send(pstStream->pstPack[i].pu8Addr[0], pstStream->pstPack[i].u32Len[0]);
VLC播放不了,完全没反应,
m=video 5000 RTP/AVP 96
a=rtpmap:96 H264
a=framerate:25
c=IN IP4 192.168.1.168
a=packetization-mode=1
我是这样设置的,求助!
[code]int RTP_Send(unsigned char *buffer, int len)
{
//NALU_t *n;
unsigned char* nalu_payload;
unsigned char sendbuf[1500];
unsigned short seq_num =0;
int bytes=0;
int valid_len = len - 4;
unsigned char NALU=buffer[4];
int pos = 5;
int packetIndex = 1 ;
int packetNum;
int sendlen = 0;
//GetAnnexbNALU (buffer, len);
printf("buffer[4] = %X\n", buffer[4]);
n->startcodeprefix_len = 4;
n->len = len - 4;
memcpy (n->buf, &buffer[4], n->len);
printf("n->buf = %X\n", n->buf[0]);
n->forbidden_bit = n->buf[0] & 0x80; //1 bit
n->nal_reference_idc = n->buf[0] & 0x60; //2 bit
n->nal_unit_type = (n->buf[0]) & 0x1f; //5 bit
printf("n->buf = %X\n", n->buf[0]);
memset(sendbuf,0,1500);//清空sendbuf;此时会将上次的时间戳清空,因此需要ts_current来保存上次的时间戳值
rtp_hdr =(RTP_FIXED_HEADER*)&sendbuf[0]; //设置RTP HEADER
rtp_hdr->version = 2; //版本号,此版本固定为2
rtp_hdr->marker = 0; //标志位,由具体协议规定其值。
rtp_hdr->payload = 96;//负载类型号,
rtp_hdr->ssrc = htonl(10);//随机指定为10,并且在本RTP会话中全局唯一
//当一个NALU小于1400字节的时候,采用一个单RTP包发送
if(n->len <= UDP_MAX_SIZE){
//设置rtp M 位;
rtp_hdr->marker=1;
rtp_hdr->seq_no = htons(seq_num ++);
//设置NALU HEADER,并将这个HEADER填入sendbuf[12]
nalu_hdr =(NALU_HEADER*)&sendbuf[12]; //将sendbuf[12]的地址赋给nalu_hdr,之后对nalu_hdr的写入就将写入sendbuf中;
nalu_hdr->F=n->forbidden_bit;
nalu_hdr->NRI=n->nal_reference_idc>>5;//有效数据在n->nal_reference_idc的第6,7位,需要右移5位才能将其值赋给nalu_hdr->NRI。
nalu_hdr->TYPE=n->nal_unit_type;
nalu_payload=&sendbuf[13];//同理将sendbuf[13]赋给nalu_payload
memcpy(nalu_payload,n->buf+1,n->len-1);//去掉nalu头的nalu剩余内容写入sendbuf[13]开始的字符串。
rtp_hdr->timestamp=htonl(ts_current);
bytes=n->len + 12 ; //获得sendbuf的长度,为nalu的长度(包含NALU头但除去起始前缀)加上rtp_header的固定长度12字节
ts_current=ts_current+timestamp_increse; //增加时间戳
sendlen = sendto(sock->local,sendbuf,bytes,0,sock->cliaddr,sizeof(struct sockaddr_in));
printf("sendbuf = %d , bytes = %d , sendlen = %d\n",strlen(sendbuf), bytes, sendlen);
//Sleep(100);
}
else
{
packetNum = n->len / UDP_MAX_SIZE; //packetNum为分包的个数
if (n->len % UDP_MAX_SIZE != 0) //加上最后一个
packetNum ++;
int lastPackSize = n->len - (packetNum-1)*UDP_MAX_SIZE;
ts_current=ts_current+timestamp_increse;//时间戳增加
rtp_hdr->timestamp=htonl(ts_current);
//发送第一个的FU,S=1,E=0,R=0
rtp_hdr->seq_no = htons(seq_num ++); //序列号,每发送一个RTP包增1
//设置rtp M 位;
rtp_hdr->marker=0;
//设置FU INDICATOR,并将这个HEADER填入sendbuf[12]
fu_ind =(FU_INDICATOR*)&sendbuf[12]; //将sendbuf[12]的地址赋给fu_ind,之后对fu_ind的写入就将写入sendbuf中;
fu_ind->F=n->forbidden_bit;
fu_ind->NRI=n->nal_reference_idc>>5;
fu_ind->TYPE=28;
//设置FU HEADER,并将这个HEADER填入sendbuf[13]
fu_hdr =(FU_HEADER*)&sendbuf[13];
fu_hdr->S=1;
fu_hdr->E=0;
fu_hdr->R=0;
fu_hdr->TYPE=n->nal_unit_type;
nalu_payload=&sendbuf[14];//同理将sendbuf[14]赋给nalu_payload
memcpy(nalu_payload,n->buf+1,UDP_MAX_SIZE);//去掉NALU头
bytes=UDP_MAX_SIZE+14;//获得sendbuf的长度,为nalu的长度(除去起始前缀和NALU头)加上rtp_header,fu_ind,fu_hdr的固定长度14字节
sendlen = sendto(sock->local,sendbuf,bytes,0,sock->cliaddr,sizeof(struct sockaddr_in));
printf("sendbuf = %d , bytes = %d , sendlen = %d\n",strlen(sendbuf), bytes, sendlen);
//发送中间的FU,S=0,E=0,R=0
for(packetIndex=2;packetIndex<packetNum;packetIndex++)
{
rtp_hdr->seq_no = htons(seq_num ++); //序列号,每发送一个RTP包增1
//设置rtp M 位;
rtp_hdr->marker=0;
//设置FU INDICATOR,并将这个HEADER填入sendbuf[12]
fu_ind =(FU_INDICATOR*)&sendbuf[12]; //将sendbuf[12]的地址赋给fu_ind,之后对fu_ind的写入就将写入sendbuf中;
fu_ind->F=n->forbidden_bit;
fu_ind->NRI=n->nal_reference_idc>>5;
fu_ind->TYPE=28;
//设置FU HEADER,并将这个HEADER填入sendbuf[13]
fu_hdr =(FU_HEADER*)&sendbuf[13];
fu_hdr->S=0;
fu_hdr->E=0;
fu_hdr->R=0;
fu_hdr->TYPE=n->nal_unit_type;
nalu_payload=&sendbuf[14];//同理将sendbuf[14]的地址赋给nalu_payload
memcpy(nalu_payload,n->buf+(packetIndex-1)*UDP_MAX_SIZE+1,UDP_MAX_SIZE);//去掉起始前缀的nalu剩余内容写入sendbuf[14]开始的字符串。
bytes=UDP_MAX_SIZE+14;//获得sendbuf的长度,为nalu的长度(除去原NALU头)加上rtp_header,fu_ind,fu_hdr的固定长度14字节
sendlen = sendto(sock->local,sendbuf,bytes,0,sock->cliaddr,sizeof(struct sockaddr_in));
printf("sendbuf = %d , bytes = %d , sendlen = %d\n",strlen(sendbuf), bytes, sendlen);
pos += UDP_MAX_SIZE;
}
//发送最后一个的FU,S=0,E=1,R=0
rtp_hdr->seq_no = htons(seq_num ++);
//设置rtp M 位;当前传输的是最后一个分片时该位置1
rtp_hdr->marker=1;
//设置FU INDICATOR,并将这个HEADER填入sendbuf[12]
rtp_hdr->seq_no = htons(seq_num ++);
//设置rtp M 位;当前传输的是最后一个分片时该位置1
rtp_hdr->marker=1;
//设置FU INDICATOR,并将这个HEADER填入sendbuf[12]
fu_ind =(FU_INDICATOR*)&sendbuf[12]; //将sendbuf[12]的地址赋给fu_ind,之后对fu_ind的写入就将写入sendbuf中;
fu_ind->F=n->forbidden_bit;
fu_ind->NRI=n->nal_reference_idc>>5;
fu_ind->TYPE=28;
//设置FU HEADER,并将这个HEADER填入sendbuf[13]
fu_hdr =(FU_HEADER*)&sendbuf[13];
fu_hdr->S=0;
fu_hdr->E=1;
fu_hdr->R=0;
fu_hdr->TYPE=n->nal_unit_type;
nalu_payload=&sendbuf[14];
memcpy(nalu_payload,n->buf+(packetIndex-1)*UDP_MAX_SIZE+1,lastPackSize-1);//将nalu最后剩余的-1(去掉了一个字节的NALU头)字节内容写入sendbuf[14]开始的字符串。
bytes=lastPackSize-1+14;//获得sendbuf的长度,为剩余nalu的长度l-1加上rtp_header,FU_INDICATOR,FU_HEADER三个包头共14字节
sendlen = sendto(sock->local,sendbuf,bytes,0,sock->cliaddr,sizeof(struct sockaddr_in));
printf("sendbuf = %d , bytes = %d , sendlen = %d\n",strlen(sendbuf), bytes, sendlen);
}
return 0;
}[/code]
我来回答
回答9个
时间排序
认可量排序
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币
Markdown 语法
- 加粗**内容**
- 斜体*内容*
- 删除线~~内容~~
- 引用> 引用内容
- 代码`代码`
- 代码块```编程语言↵代码```
- 链接[链接标题](url)
- 无序列表- 内容
- 有序列表1. 内容
- 缩进内容
- 图片![alt](url)
相关问答
-
2014-12-24 10:41:00
-
2014-09-04 12:43:59
-
2024-03-04 16:13:49
-
2016-12-27 11:19:32
-
2016-10-24 20:45:58
-
2024-03-04 10:11:38
-
2018-08-10 16:39:24
-
2019-03-25 19:28:48
-
2019-09-10 14:42:18
-
2017-09-15 16:10:57
-
2016-07-10 10:45:05
-
12024-03-15 15:47:47
-
2018-03-09 10:23:40
-
2013-03-16 15:45:23
-
2020-03-24 11:56:33
-
22015-05-21 11:38:42
-
392015-12-18 15:47:06
-
42014-09-30 11:20:02
-
2014-10-25 08:36:59
无更多相似问答 去提问
点击登录
-- 积分
-- E币
提问
—
收益
—
被采纳
—
我要提问
切换马甲
上一页
下一页
悬赏问答
-
20帮忙交叉编译个源码
-
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处理并显示
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
提醒
你的问题还没有最佳答案,是否结题,结题后将扣除20%的悬赏金
取消
确认
提醒
你的问题还没有最佳答案,是否结题,结题后将根据回答情况扣除相应悬赏金(1回答=1E币)
取消
确认