RTSP_RTP_TCP直播协议,潜入到海思sample_vdec做直播,遇到头疼的花屏、马赛克问题,求助!

码上见真晓 2016-09-13 11:21:34
先说说我的代码框架(具体如下,不足再补):
1、建立tcp socket rtsp对接ipc摄像头(已设定SO_RCVBUF=32*1024*5)
2、创建3条线程
//recv()tcp接收数据
pthread_create(&pVdecThread[1], 0, RECV, (HI_VOID *)&my_struct);
//handlestream解析rtp包,保存解析好的数据
pthread_create(&pVdecThread[2], 0, handle, NULL);
//sendstream调用海思mpp接口播放视频流
pthread_create(&pVdecThread, 0, SAMPLE_COMM_VDEC_SendStream, (HI_VOID *)&pstVdecSend);
3、创建了共有环形缓存区fifo + 共有streambuf=32*1024*5
fifo有80个节点,每个节点32*1024*5,用于每次保存线程recv()到得buf;
用信号量来判断,当有缓存区有数据就调用线程handle进行拆包
同样用信号量来判断,当h264_rtp_unpackage()从fifo取数据解析,解析好数据就保存到Video_Stream,当拼好一帧数据就调用SAMPLE_COMM_VDEC_SendStream()
让海思调用hdmi接口播放视频
这里是拆包函数(目测不知有木有问题)
HI_VOID h264_rtp_unpackage(HI_U8 *bufIn, HI_S32 len) //bufin为fifo->buf去掉tcp4个字节的头剩下一个完整的rtp包,当然一个buf可能有多个rtp包
{
unsigned char recvbuf[1500];
//RTPpacket_t *p = NULL;
RTP_FIXED_HEADER * rtp_hdr = NULL;
NALU_HEADER * nalu_hdr = NULL;
FU_INDICATOR *fu_ind = NULL;
FU_HEADER *fu_hdr= NULL;
unsigned int start_code = 0x01000000;
memcpy(recvbuf,bufIn, len); //复制rtp包

//begin rtp_payload and rtp_header

if ((rtp_hdr = malloc(sizeof(RTP_FIXED_HEADER))) == NULL)
{
printf("RTP_FIXED_HEADER MEMORY ERROR\n");
}

rtp_hdr =(RTP_FIXED_HEADER*)&recvbuf[0];

if ((nalu_hdr = malloc(sizeof(NALU_HEADER))) == NULL)
{
printf("NALU_HEADER MEMORY ERROR\n");
}
//网络传输过来的字节序 ,当存入内存还是和文档描述的相反,只要匹配网络字节序和文档描述即可传输正确。
nalu_hdr =(NALU_HEADER*)&recvbuf[12];

//////////////////////////////////////////////////////////////////////////
//开始解包

if ( nalu_hdr->TYPE == 0 || len < 12 )
{
printf("this packet is worse\n");
return;
}
else if ( nalu_hdr->TYPE > 0 && nalu_hdr->TYPE < 24) //单包
{
memcpy(Video_Stream+total_recved, &start_code, 4); //写进起始字节0x00000001
total_recved += 4;
memcpy(Video_Stream+total_recved, &recvbuf[12], len-12);
total_recved += len-12;
}
else if ( nalu_hdr->TYPE == 28) //FU-A分片包,解码顺序和传输顺序相同
{
if ((fu_ind = malloc(sizeof(FU_INDICATOR))) == NULL)
{
printf("FU_INDICATOR MEMORY ERROR\n");
}
if ((fu_hdr = malloc(sizeof(FU_HEADER))) == NULL)
{
printf("FU_HEADER MEMORY ERROR\n");
}

fu_ind=(FU_INDICATOR*)&recvbuf[12]; //分片包用的是FU_INDICATOR而不是NALU_HEADER

fu_hdr=(FU_HEADER*)&recvbuf[13]; //FU_HEADER赋值

if (rtp_hdr->marker == 1) //分片包最后一个包
{

memcpy(Video_Stream+total_recved, &recvbuf[14], len - 14);
total_recved += len - 14;
First++;
if((First+1) % 2 == 0 )//First 用于判断当前为第几帧
{

sem_post(&my_struct.sem_id4);
pthread_mutex_unlock(&my_struct.H_Mutex);

}

}
else if (rtp_hdr->marker == 0) //分片包 但不是最后一个包
{
if (fu_hdr->S == 1) //分片的第一个包
{

if(First == 0 || (First+1)%2 == 0 )
{
sem_wait(&my_struct.sem_id3);

pthread_mutex_lock(&my_struct.H_Mutex);
memset(Video_Stream, 0, sizeof(Video_Stream));

}
unsigned char F;
unsigned char NRI;
unsigned char TYPE;
unsigned char nh;
memcpy(Video_Stream+total_recved, &start_code, 4); //写起始字节码0x00000001
total_recved += 4;

F = fu_ind->F << 7;
NRI = fu_ind->NRI << 5;
TYPE = fu_hdr->TYPE; //应用的是FU_HEADER的TYPE
nh = F | NRI | TYPE;

//写NAL HEADER
memcpy(Video_Stream+total_recved, &nh, 1);
total_recved += 1;
memcpy(Video_Stream+total_recved, &recvbuf[14], len - 14);
total_recved += len - 14;

}
else //如果不是第一个包
{
//memset(vv->videobuf, 0, 1600);
memcpy(Video_Stream+total_recved, &recvbuf[14], len - 14);
total_recved += len - 14;

}
}
}
else
{
printf("this packet is worse,30-31 havenot meaning\n");
}

memset(recvbuf,0,1500);

return ;
}
我的问题:视频拨出来出现马赛克或者花屏,而且码率越大,问题越严重(有时是一个屏幕的十分之九都是马赛克,只有上方的一小块正常)。直接封装成h264文件,播放问题就没那么严重(这貌似是海思的问题)
1、框架这样写不知道有没有问题
2、细查生成的264文件,关键帧间隔对得上,没有发现丢帧。(有个奇怪的地方,文件开头的第一次关键帧全为零,或者00000001 06这一帧全为零)
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0001 65b8 0000 0b6d
2027 ffb1 c15e a37d 4639 3ec6 1a6d 358c
3、h264_rtp_unpackage()不知道是不是个bug
4、各位觉得可能的问题点,希望能帮我提出来,大家共同解决。
ps:我只是小菜一个,感谢各位前辈的指教。


...全文
3613 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
youlong144 2017-05-24
  • 打赏
  • 举报
回复
请问楼主问题解决没?本人也遇到类似的问题,也有seek就会出现马赛克现象
zhangby629 2016-11-17
  • 打赏
  • 举报
回复
兄弟,问题解决没?

2,275

社区成员

发帖
与我相关
我的任务
社区描述
多媒体/设计/Flash/Silverlight 开发 Flash流媒体开发
社区管理员
  • Flash流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧