7684
- 收藏
- 点赞
- 分享
- 举报
RTP传输 实时播放
用海思平台实现1080P 高清h264编码,后获取编码后的流,再通过RTP发送,
发现开始延迟很少,直播约20分钟后,延迟越来越大了
丢帧约20-40帧,
关键部分如下
[code]/******************************************************************************
* funciton : save H264 stream
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_SaveH264(FILE* fpH264File, VENC_STREAM_S *pstStream,int file_num,unsigned char* pucFrameBuffer,NALU_t *n)
{
HI_S32 i;
unsigned char *pTestTemp=NULL;
unsigned int uiFrameLens = 0;
char* nalu_payload=NULL;
char sendbuf[1500]; //多次使用时会不会存在问题?
int bytes=0;
int StartCodeFound;
int rewind;
float framerate = 30;
unsigned int timestamp_increse = (unsigned int)(90000.0 /framerate);
pTestTemp = pucFrameBuffer;
if(pTestTemp ==NULL){
printf("pTestTemp is null.\n");
return;
}
struct sysinfo s_info;
int error;
printf("test.\n");
error = sysinfo(&s_info);
printf("\n\ncode error=%d\n",error);
printf("Uptime = %ds\nLoad: 1 min%d / 5 min %d / 15 min %d\n"
"RAM: total %d / free %d /shared%d\n"
"Memory in buffers = %d\nSwap:total%d/free%d\n"
"Number of processes = %d\n",
s_info.uptime, s_info.loads[0],
s_info.loads[1], s_info.loads[2],
s_info.totalram, s_info.freeram,
s_info.totalswap, s_info.freeswap,
s_info.procs );
for (i = 0; i < pstStream->u32PackCount; i++)
{
uiFrameLens = 0;
memset(pucFrameBuffer,0,NALU_MAX_SIZE*sizeof(unsigned char));
if(file_num == CHN_X_TYPE_STREAM)memcpy(pucFrameBuffer,pstStream->pstPack.pu8Addr[0],pstStream->pstPack.u32Len[0]);
if(file_num == CHN_X_TYPE_STREAM)pucFrameBuffer = pucFrameBuffer+ pstStream->pstPack.u32Len[0];
if(file_num == CHN_X_TYPE_STREAM)uiFrameLens += pstStream->pstPack.u32Len[0];
if (pstStream->pstPack.u32Len[1] > 0)
{
if(file_num == CHN_X_TYPE_STREAM)memcpy(pucFrameBuffer,pstStream->pstPack.pu8Addr[1],pstStream->pstPack.u32Len[1]);
if(file_num == CHN_X_TYPE_STREAM)pucFrameBuffer = pucFrameBuffer+ pstStream->pstPack.u32Len[1];
if(file_num == CHN_X_TYPE_STREAM)uiFrameLens += pstStream->pstPack.u32Len[1];
}
pucFrameBuffer = pTestTemp;
n->startcodeprefix_len = 4;//海思的固定为4个byte
if(uiFrameLens > 4)
{
n->len = uiFrameLens - (n->startcodeprefix_len);
memcpy (n->buf, pucFrameBuffer+4, n->len);
n->forbidden_bit = n->buf[0] & 0x80;
n->nal_reference_idc = n->buf[0] & 0x60;
n->nal_unit_type = (n->buf[0]) & 0x1f;
}else{
FreeNALU(n);
return;
}
memset(sendbuf,0,1500);
rtp_hdr =(RTP_FIXED_HEADER*)&sendbuf[0];
rtp_hdr->payload = H264; //负载类型号,
rtp_hdr->version = 2; //版本号,此版本固定为2
rtp_hdr->marker = 0; //标志位,由具体协议规定其值。
rtp_hdr->ssrc = htonl(10); //随机指定为10,并且在本RTP会话中全局唯一
if((n->nal_unit_type == 1)||(n->nal_unit_type == 7))
{
ts_current=ts_current+timestamp_increse;
}
if(n->len<=1400)
{
rtp_hdr->marker=1;
rtp_hdr->seq_no = htons(seq_num ++); //序列号,每发送一个RTP包增1
nalu_hdr =(NALU_HEADER*)&sendbuf[12];
nalu_hdr->F=n->forbidden_bit;
nalu_hdr->NRI=n->nal_reference_idc>>5;
nalu_hdr->TYPE=n->nal_unit_type;
nalu_payload=&sendbuf[13];
memcpy(nalu_payload,n->buf+1,n->len-1);
rtp_hdr->timestamp=htonl(ts_current);
bytes=n->len + 12 ;
sendto(s,sendbuf,bytes,0,(struct sockaddr *)&adr_srvr,len_inet);
}else{
int k=0,l=0;//得到该nalu需要用多少长度为1400字节的RTP包来发送
k=n->len/1400;//需要k个1400字节的RTP包
l=n->len%1400;//最后一个RTP包的需要装载的字节数
if(l > 0) k++;// 此处理4800, k = 2 ,l=0, 4802 k= 2,l =2,-->k =3,l =2;
int t = 0;//用于指示当前发送的是第几个分片RTP包
rtp_hdr->timestamp=htonl(ts_current);
while(t < k)//k的取值从2开始,
{
rtp_hdr->seq_no = htons(seq_num ++); //序列号,每发送一个RTP包增1
if(!t)
{
rtp_hdr->marker=0;
fu_ind =(FU_INDICATOR*)&sendbuf[12];
fu_ind->F=n->forbidden_bit;
fu_ind->NRI=n->nal_reference_idc>>5;
fu_ind->TYPE=28;
fu_hdr =(FU_HEADER*)&sendbuf[13];//设置FU HEADER,并将这个HEADER填入sendbuf[13]
fu_hdr->R=0;
fu_hdr->S=1;
fu_hdr->E=0;
fu_hdr->TYPE=n->nal_unit_type;
nalu_payload=&sendbuf[14];//同理将sendbuf[14]赋给nalu_payload
memcpy(nalu_payload,n->buf+1,1400);//去掉NALU头
bytes=1400+14;
}else if(t < (k - 1)){
rtp_hdr->marker=0;
fu_ind =(FU_INDICATOR*)&sendbuf[12];
fu_ind->F=n->forbidden_bit;
fu_ind->NRI=n->nal_reference_idc>>5;
fu_ind->TYPE=28;
fu_hdr =(FU_HEADER*)&sendbuf[13];
fu_hdr->R=0;
fu_hdr->S=0;
fu_hdr->E=0;
fu_hdr->TYPE=n->nal_unit_type;
nalu_payload=&sendbuf[14];
memcpy(nalu_payload,n->buf+t*1400+1,1400);
bytes=1400+14;
}else{
rtp_hdr->marker=1;//设置rtp M 位;一个I/P的结尾
fu_ind =(FU_INDICATOR*)&sendbuf[12];
fu_ind->F=n->forbidden_bit;
fu_ind->NRI=n->nal_reference_idc>>5;
fu_ind->TYPE=28;
fu_hdr =(FU_HEADER*)&sendbuf[13];
fu_hdr->R=0;
fu_hdr->S=0;
fu_hdr->E=1;
fu_hdr->TYPE=n->nal_unit_type;
nalu_payload=&sendbuf[14];
if (l==0)l= 1400;
memcpy(nalu_payload,n->buf+t*1400+1,l-1);
bytes=l-1+14;
}
sendto(s,sendbuf,bytes,0,(struct sockaddr *)&adr_srvr,len_inet);
t++;
}
}
}
//FreeNALU(n);
return HI_SUCCESS;
}[/code]
发现开始延迟很少,直播约20分钟后,延迟越来越大了
丢帧约20-40帧,
关键部分如下
[code]/******************************************************************************
* funciton : save H264 stream
******************************************************************************/
HI_S32 SAMPLE_COMM_VENC_SaveH264(FILE* fpH264File, VENC_STREAM_S *pstStream,int file_num,unsigned char* pucFrameBuffer,NALU_t *n)
{
HI_S32 i;
unsigned char *pTestTemp=NULL;
unsigned int uiFrameLens = 0;
char* nalu_payload=NULL;
char sendbuf[1500]; //多次使用时会不会存在问题?
int bytes=0;
int StartCodeFound;
int rewind;
float framerate = 30;
unsigned int timestamp_increse = (unsigned int)(90000.0 /framerate);
pTestTemp = pucFrameBuffer;
if(pTestTemp ==NULL){
printf("pTestTemp is null.\n");
return;
}
struct sysinfo s_info;
int error;
printf("test.\n");
error = sysinfo(&s_info);
printf("\n\ncode error=%d\n",error);
printf("Uptime = %ds\nLoad: 1 min%d / 5 min %d / 15 min %d\n"
"RAM: total %d / free %d /shared%d\n"
"Memory in buffers = %d\nSwap:total%d/free%d\n"
"Number of processes = %d\n",
s_info.uptime, s_info.loads[0],
s_info.loads[1], s_info.loads[2],
s_info.totalram, s_info.freeram,
s_info.totalswap, s_info.freeswap,
s_info.procs );
for (i = 0; i < pstStream->u32PackCount; i++)
{
uiFrameLens = 0;
memset(pucFrameBuffer,0,NALU_MAX_SIZE*sizeof(unsigned char));
if(file_num == CHN_X_TYPE_STREAM)memcpy(pucFrameBuffer,pstStream->pstPack.pu8Addr[0],pstStream->pstPack.u32Len[0]);
if(file_num == CHN_X_TYPE_STREAM)pucFrameBuffer = pucFrameBuffer+ pstStream->pstPack.u32Len[0];
if(file_num == CHN_X_TYPE_STREAM)uiFrameLens += pstStream->pstPack.u32Len[0];
if (pstStream->pstPack.u32Len[1] > 0)
{
if(file_num == CHN_X_TYPE_STREAM)memcpy(pucFrameBuffer,pstStream->pstPack.pu8Addr[1],pstStream->pstPack.u32Len[1]);
if(file_num == CHN_X_TYPE_STREAM)pucFrameBuffer = pucFrameBuffer+ pstStream->pstPack.u32Len[1];
if(file_num == CHN_X_TYPE_STREAM)uiFrameLens += pstStream->pstPack.u32Len[1];
}
pucFrameBuffer = pTestTemp;
n->startcodeprefix_len = 4;//海思的固定为4个byte
if(uiFrameLens > 4)
{
n->len = uiFrameLens - (n->startcodeprefix_len);
memcpy (n->buf, pucFrameBuffer+4, n->len);
n->forbidden_bit = n->buf[0] & 0x80;
n->nal_reference_idc = n->buf[0] & 0x60;
n->nal_unit_type = (n->buf[0]) & 0x1f;
}else{
FreeNALU(n);
return;
}
memset(sendbuf,0,1500);
rtp_hdr =(RTP_FIXED_HEADER*)&sendbuf[0];
rtp_hdr->payload = H264; //负载类型号,
rtp_hdr->version = 2; //版本号,此版本固定为2
rtp_hdr->marker = 0; //标志位,由具体协议规定其值。
rtp_hdr->ssrc = htonl(10); //随机指定为10,并且在本RTP会话中全局唯一
if((n->nal_unit_type == 1)||(n->nal_unit_type == 7))
{
ts_current=ts_current+timestamp_increse;
}
if(n->len<=1400)
{
rtp_hdr->marker=1;
rtp_hdr->seq_no = htons(seq_num ++); //序列号,每发送一个RTP包增1
nalu_hdr =(NALU_HEADER*)&sendbuf[12];
nalu_hdr->F=n->forbidden_bit;
nalu_hdr->NRI=n->nal_reference_idc>>5;
nalu_hdr->TYPE=n->nal_unit_type;
nalu_payload=&sendbuf[13];
memcpy(nalu_payload,n->buf+1,n->len-1);
rtp_hdr->timestamp=htonl(ts_current);
bytes=n->len + 12 ;
sendto(s,sendbuf,bytes,0,(struct sockaddr *)&adr_srvr,len_inet);
}else{
int k=0,l=0;//得到该nalu需要用多少长度为1400字节的RTP包来发送
k=n->len/1400;//需要k个1400字节的RTP包
l=n->len%1400;//最后一个RTP包的需要装载的字节数
if(l > 0) k++;// 此处理4800, k = 2 ,l=0, 4802 k= 2,l =2,-->k =3,l =2;
int t = 0;//用于指示当前发送的是第几个分片RTP包
rtp_hdr->timestamp=htonl(ts_current);
while(t < k)//k的取值从2开始,
{
rtp_hdr->seq_no = htons(seq_num ++); //序列号,每发送一个RTP包增1
if(!t)
{
rtp_hdr->marker=0;
fu_ind =(FU_INDICATOR*)&sendbuf[12];
fu_ind->F=n->forbidden_bit;
fu_ind->NRI=n->nal_reference_idc>>5;
fu_ind->TYPE=28;
fu_hdr =(FU_HEADER*)&sendbuf[13];//设置FU HEADER,并将这个HEADER填入sendbuf[13]
fu_hdr->R=0;
fu_hdr->S=1;
fu_hdr->E=0;
fu_hdr->TYPE=n->nal_unit_type;
nalu_payload=&sendbuf[14];//同理将sendbuf[14]赋给nalu_payload
memcpy(nalu_payload,n->buf+1,1400);//去掉NALU头
bytes=1400+14;
}else if(t < (k - 1)){
rtp_hdr->marker=0;
fu_ind =(FU_INDICATOR*)&sendbuf[12];
fu_ind->F=n->forbidden_bit;
fu_ind->NRI=n->nal_reference_idc>>5;
fu_ind->TYPE=28;
fu_hdr =(FU_HEADER*)&sendbuf[13];
fu_hdr->R=0;
fu_hdr->S=0;
fu_hdr->E=0;
fu_hdr->TYPE=n->nal_unit_type;
nalu_payload=&sendbuf[14];
memcpy(nalu_payload,n->buf+t*1400+1,1400);
bytes=1400+14;
}else{
rtp_hdr->marker=1;//设置rtp M 位;一个I/P的结尾
fu_ind =(FU_INDICATOR*)&sendbuf[12];
fu_ind->F=n->forbidden_bit;
fu_ind->NRI=n->nal_reference_idc>>5;
fu_ind->TYPE=28;
fu_hdr =(FU_HEADER*)&sendbuf[13];
fu_hdr->R=0;
fu_hdr->S=0;
fu_hdr->E=1;
fu_hdr->TYPE=n->nal_unit_type;
nalu_payload=&sendbuf[14];
if (l==0)l= 1400;
memcpy(nalu_payload,n->buf+t*1400+1,l-1);
bytes=l-1+14;
}
sendto(s,sendbuf,bytes,0,(struct sockaddr *)&adr_srvr,len_inet);
t++;
}
}
}
//FreeNALU(n);
return HI_SUCCESS;
}[/code]
我来回答
回答14个
时间排序
认可量排序
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
认可0
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币
Markdown 语法
- 加粗**内容**
- 斜体*内容*
- 删除线~~内容~~
- 引用> 引用内容
- 代码`代码`
- 代码块```编程语言↵代码```
- 链接[链接标题](url)
- 无序列表- 内容
- 有序列表1. 内容
- 缩进内容
- 图片![alt](url)
相关问答
-
2018-06-04 17:41:20
-
2017-09-11 10:02:23
-
2019-09-04 12:13:36
-
2017-03-21 14:47:46
-
2014-08-09 15:15:11
-
2015-03-20 17:32:41
-
2021-07-15 10:59:54
-
2018-02-13 11:04:13
-
2015-12-09 10:52:34
-
2016-01-02 17:22:45
-
2014-06-24 13:42:54
-
2017-02-19 19:49:52
-
2016-06-07 17:41:39
-
2020-09-29 10:31:19
-
2018-11-28 09:16:29
-
2014-09-19 15:18:55
-
2016-03-24 16:48:16
-
2019-03-19 09:40:20
-
2017-10-15 18:52:22
无更多相似问答 去提问
点击登录
-- 积分
-- E币
提问
—
收益
—
被采纳
—
我要提问
切换马甲
上一页
下一页
悬赏问答
-
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板子运行自己编码的程序
-
10求HI3519DV500_SDK_V2.0.1.1
-
5有偿求HI3516DV500 + OV5647驱动
举报反馈
举报类型
- 内容涉黄/赌/毒
- 内容侵权/抄袭
- 政治相关
- 涉嫌广告
- 侮辱谩骂
- 其他
详细说明
提醒
你的问题还没有最佳答案,是否结题,结题后将扣除20%的悬赏金
取消
确认
提醒
你的问题还没有最佳答案,是否结题,结题后将根据回答情况扣除相应悬赏金(1回答=1E币)
取消
确认