频道栏目
首页 > 程序开发 > 综合编程 > 其他综合 > 正文
RTP通话:视频流的传输
2012-12-25 13:04:52           
收藏   我要投稿
#define PLOAD_TYPE 98

#define DefaultTimestampIncrement 90000/25

static RTPSession sess;

//创建rtp会话

static int  RtpSetup( uint16_t portbase)

{

    int status;

 

    RTPUDPv4TransmissionParams transparams;

    RTPSessionParams sessparams;

    sessparams.SetOwnTimestampUnit(1.0/90000.0);

    sessparams.SetMaximumPacketSize(1200);

    transparams.SetPortbase(portbase);

    sess.SetDefaultPayloadType(PLOAD_TYPE);

    sess.SetDefaultMark(false);

    sess.SetDefaultTimestampIncrement(DefaultTimestampIncrement);

    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字节,直接发送

    if(valid_len <= MAX_STREAM_SLICE)

    {

        status = sess.SendPacket((void *)&val[4],valid_len,PLOAD_TYPE,true,DefaultTimestampIncrement);

        checkerror(status);

    }

    else

    {

        int k=0,l=0,len=valid_len,pos=0;

        k=len/MAX_STREAM_SLICE;  //切分为很多个包:包的个数

        l=len%MAX_STREAM_SLICE;   

        int t=0;

        while(t<=k)

        {

            if(t==0)

            {//发送第1包     

                sendStartAddr=(char *)(val+4);//发送数据的起始地址

                sendStartAddr[pos-1]=(NALU&0x60)|28;

                sendStartAddr[pos]=(NALU&0x1f)|0x80;

                send_length=MAX_STREAM_SLICE+1;//要发送数据的长度

                status = sess.SendPacket(sendStartAddr-1,send_length,PLOAD_TYPE,false,DefaultTimestampIncrement);

                checkerror(status);

                if(status<0)

                {

                    goto end;

                }

                pos+=MAX_STREAM_SLICE;

            }

            else if(k==t&&l!=0)

            {//最后一包

                sendStartAddr[pos-2]=(NALU&0x60)|28;

                sendStartAddr[pos-1]=(NALU&0x1f)|0x40;

                send_length=l+2;//要发送数据的长度

                status = sess.SendPacket(sendStartAddr+pos-2,send_length,PLOAD_TYPE,true,0);

                checkerror(status);

                if(status<0)

                {

                    goto end;

                }

                 pos+=l;

            }

            else if(t<k&&0!=t)

            {//发送第2包--倒数第2包

                if(l==0&&t==k-1)

                {

                     sendStartAddr[pos-2]=(NALU&0x60)|28;

                     sendStartAddr[pos-1]=(NALU&0x1f)|0x40;                

               }

               else

               {

                  sendStartAddr[pos-2]=(NALU&0x60)|28;

                  sendStartAddr[pos-1]=(NALU&0x1f);               

               }

               send_length=MAX_STREAM_SLICE+2;//要发送数据的长度

               status = sess.SendPacket(sendStartAddr+pos-2,send_length,PLOAD_TYPE,false,0);

               checkerror(status);

               if(status<0)

               {

                      goto end;

               } 

               pos+=MAX_STREAM_SLICE;

           }

           t++;

       }

    }

    checkerror(status);

end:

    return status;

}

  附: NALU(Network Abstract Layer Unit):H264标准中的比特流是以NAL为单位,每个NAL单元包含一个RBSP(raw byte sequence payload,原始字节序列载荷),NALU的头信息定义了RBSP所属类型。类型一般包括序列参数集(SPS)、图像参数集(PPS)、增强信息(SEI)、条带(Slice)等,其中,SPS和PPS属于参数集,两标准采用参数集机制是为了将一些主要的序列、图像参数(解码图像尺寸、片组数、参考帧数、量化和滤波参数标记等)与其他参数分离,通过解码器先解码出来。此外,为了增强图像的清晰度,AVS-M添加了图像头(Picture head)信息。读取NALU流程中,每个NALU前有一个起始码0x000001,为防止内部0x000001序列竞争,H.264编码器在最后一字节前插入一个新的字节——0x03,所以解码器检测到该序列时,需将0x03删掉,而AVS-M只需识别出起始码0x000001。

 

 

因为程序是在Hi3515开发板上运行,所以我的工作是把编码后的视频发送出去就ok了。

在windows下,写了一个脚本xxx.dsp,内容如下:

     m=video 1234 RTP/AVP 98

     a=rtpmap:98 H264/90000; 

     a=decode_buf=300;

     c=IN IP4 192.168.2.105   //板子的ip

然后把脚本拖到VLCPortable.exe软件中,就能显示摄像头获取的视频,就说明rtp传输没问题,我的工作就完成了。

点击复制链接 与好友分享!回本站首页
相关TAG标签 视频流
上一篇:Foundation和Core Foundation掺杂使用桥接 Toll-Free Bridging
下一篇:在centos6.3上编译netfilter_queue的configure问题及其解决方法
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站