Takin

Takin

1个粉丝

41

问答

0

专栏

0

资料

Takin  发布于  2014-09-25 20:42:04
采纳率 0%
41个问答
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]
我来回答
回答14个
时间排序
认可量排序

david

39个粉丝

368

问答

253

专栏

229

资料

david 2014-09-26 10:07:41
认可0
unsigned int timestamp_increse = (unsigned int)(90000.0 /framerate);  仔细 看看这个值。

你说的那个内存不影响。还有memory copy太多。C 的 特性 指针要好好利用下

Takin

1个粉丝

41

问答

0

专栏

0

资料

Takin 2014-09-26 18:27:37
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=8200&ptid=3879]david 发表于 2014-9-26 10:07[/url]
unsigned int timestamp_increse = (unsigned int)(90000.0 /framerate);  仔细 看看这个值。

你说的那 ...[/quote]

谢谢版主,
1,第一个时间戳增量我是从网上找来的不知道是不是影响了性能(浮点运算)
float framerate = 30;  --〉unsigned int framerate = 30;  
--〉unsigned int timestamp_increse = 90000 /framerate
2,还有memory copy太多--〉
   memcpy (n->buf, pucFrameBuffer+4, n->len);
 我这样修改下,先测试下
  n->buf = pucFrameBuffer+4;  

yuino

1个粉丝

6

问答

0

专栏

0

资料

yuino 2014-11-08 14:27:34
认可0
楼主问题解决了吗?

Takin

1个粉丝

41

问答

0

专栏

0

资料

Takin 2014-11-08 23:55:10
认可0
解决了,是解码端的问题

wonrowl

0个粉丝

10

问答

0

专栏

2

资料

wonrowl 2014-11-11 11:56:22
认可0
也是用的rtp发送,在ti上工作正常,在海思上vlc一点反应都没有,一直buffering,同样的代码,郁闷..........:(

scsi

0个粉丝

26

问答

0

专栏

2

资料

scsi 2014-11-12 12:55:05
认可0
受益匪浅!  非常感谢

bwsz

0个粉丝

0

问答

0

专栏

0

资料

bwsz 2014-11-12 21:03:52
认可0
本帖最后由 bwsz 于 2014-11-12 21:14 编辑

谢谢楼主 正在学习这块 不过对RTP还没概念,楼主用的是RTP源码 然后自己编译到程序里面吗?还是用库?

lingxiao911

0个粉丝

10

问答

0

专栏

0

资料

lingxiao911 2014-11-24 17:03:03
认可0
楼主把经验分享一下呗

东篱采菊76152

0个粉丝

0

问答

0

专栏

0

资料

东篱采菊76152 2014-12-17 11:20:50
认可0
学习了     

史前小虫

0个粉丝

7

问答

0

专栏

0

资料

史前小虫 2014-12-24 10:46:19
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=8929&ptid=3879]xjl_hi 发表于 2014-11-8 23:55[/url]
解决了,是解码端的问题[/quote]

楼主,根据这个帖子做了:http://blog.csdn.net/jiaozi07/article/details/41749943
但是在vlc播放的时候,一打开sdp就闪退,有时候能显示一帧或者画面动一下就闪退,这要怎么解决啊?

Takin

1个粉丝

41

问答

0

专栏

0

资料

Takin 2014-12-25 14:32:21
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=10550&ptid=3879]史前小虫 发表于 2014-12-24 10:46[/url]
楼主,根据这个帖子做了:http://blog.csdn.net/jiaozi07/article/details/41749943
但是在vlc播放的时 ...[/quote]

我的方法不是这样,
自己按协义,网上有很多这种参考,
你说有时有一帧,是不是时间戳没有累加,

史前小虫

0个粉丝

7

问答

0

专栏

0

资料

史前小虫 2014-12-25 17:23:14
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=10607&ptid=3879]xjl_hi 发表于 2014-12-25 14:32[/url]
我的方法不是这样,
自己按协义,网上有很多这种参考,
你说有时有一帧,是不是时间戳没有累加,[/quote]

有累加了,在不够1400的时候发送,然后累加,超过1400分包发送完成后累加

史前小虫

0个粉丝

7

问答

0

专栏

0

资料

史前小虫 2014-12-29 10:29:38
认可0
本帖最后由 史前小虫 于 2014-12-29 20:04 编辑

楼主,我换了好几种方法都搞不好,我想按照你这个例子试一试,中间这段
         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];
        }

看不明白,能讲解一下吗?

能加你QQ请教一下吗?

史前小虫

0个粉丝

7

问答

0

专栏

0

资料

史前小虫 2015-01-04 23:51:34
认可0
本帖最后由 史前小虫 于 2015-1-5 15:56 编辑

现在我也遇到你这个问题。。播放久了丢包非常严重。。你说是解码端问题,是VLC的问题?怎么解决啊?
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区