linphone中h264的 RTP打包(二)

[html]  view plain copy
  1. 今天发现一个奇怪的问题,用上位机的linphone客户端拨打下位机的sip客户端能够正常工作,但是反过来就出问题了。 抓包发现linphone发送了大量的IP fragmentation 数据包,google才知道,当发现的数据大于MTU时就发产生IP分片的数据包。RTP打包时不是已经进行了分片操作了吗?正常情况应该不会出现这种情况才对。  

    linphone对h264进行RTP打包在rfc3984.c中进行,打包函数如下:


[cpp]  view plain copy
  1. void rfc3984_pack(Rfc3984Context *ctx, MSQueue *naluq, MSQueue *rtpq, uint32_t ts){  
  2.     switch(ctx->mode){  
  3.         case 0:  
  4.             rfc3984_pack_mode_0(ctx,naluq,rtpq,ts);  
  5.             break;  
  6.         case 1:  
  7.             rfc3984_pack_mode_1(ctx,naluq,rtpq,ts);  
  8.             break;  
  9.         default:  
  10.             ms_error("Bad or unsupported mode %i",ctx->mode);  
  11.     }  
  12. }  


看来程序中定义了两种打包模式,看看两种模式有什么区别

[cpp]  view plain copy
  1. static void rfc3984_pack_mode_0(Rfc3984Context *ctx, MSQueue *naluq, MSQueue *rtpq, uint32_t ts){  
  2.     mblk_t *m;  
  3.     bool_t end;  
  4.     int size;  
  5.     while((m=ms_queue_get(naluq))!=NULL){  
  6.         end=ms_queue_empty(naluq);  
  7.         size=m->b_wptr-m->b_rptr;  
  8.         if (size>ctx->maxsz){  
  9.             ms_warning("This H264 packet does not fit into mtu: size=%i",size);  
  10.         }  
  11.         send_packet(rtpq,ts,m,end);  
  12.     }  
  13. }  

[cpp]  view plain copy
  1. /*process NALUs and pack them into rtp payloads */  
  2. static void rfc3984_pack_mode_1(Rfc3984Context *ctx, MSQueue *naluq, MSQueue *rtpq, uint32_t ts){  
  3.     mblk_t *m,*prevm=NULL;  
  4.     int prevsz=0,sz;  
  5.     bool_t end;  
  6.     while((m=ms_queue_get(naluq))!=NULL){  
  7.         end=ms_queue_empty(naluq);  
  8.         sz=m->b_wptr-m->b_rptr;  
  9.         if (ctx->stap_a_allowed){  
  10.             if (prevm!=NULL){  
  11.                 if ((prevsz+sz)<(ctx->maxsz-2)){  
  12.                     prevm=concat_nalus(prevm,m);  
  13.                     m=NULL;  
  14.                     prevsz+=sz+2;/*+2 for the stapa size field*/  
  15.                     continue;  
  16.                 }else{  
  17.                     /*send prevm packet: either single nal or STAP-A*/  
  18.                     if (prevm->b_cont!=NULL){  
  19.                         ms_debug("Sending STAP-A");  
  20.                     }else  
  21.                         ms_debug("Sending previous msg as single NAL");  
  22.                     send_packet(rtpq,ts,prevm,FALSE);  
  23.                     prevm=NULL;  
  24.                     prevsz=0;  
  25.                 }  
  26.             }  
  27.             if (sz<(ctx->maxsz/2)){  
  28.                 /*try to aggregate it with next packet*/  
  29.                 prevm=m;  
  30.                 prevsz=sz+3; /*STAP-A header + size*/  
  31.                 m=NULL;  
  32.             }else{  
  33.                   
  34.                 /*send as single nal or FU-A*/  
  35.                 if (sz>ctx->maxsz){  
  36.                     ms_debug("Sending FU-A packets");  
  37.                     frag_nalu_and_send(rtpq,ts,m,end, ctx->maxsz);  
  38.                 }else{  
  39.                     ms_debug("Sending Single NAL");  
  40.                     send_packet(rtpq,ts,m,end);  
  41.                 }  
  42.             }  
  43.         }else{  
  44.             if (sz>ctx->maxsz){  
  45.                 ms_debug("Sending FU-A packets");  
  46.                 frag_nalu_and_send(rtpq,ts,m,end, ctx->maxsz);  
  47.             }else{  
  48.                 ms_debug("Sending Single NAL");  
  49.                 send_packet(rtpq,ts,m,end);  
  50.             }  
  51.         }  
  52.     }  
  53.     if (prevm){  
  54.         ms_debug("Sending Single NAL (2)");  
  55.         send_packet(rtpq,ts,prevm,TRUE);  
  56.     }  
  57. }  


模式0竟然没有RTP打包分片操作,而是直接send出去了,难怪IP协议自动进行了分片处理。于是想到,将RTP打包模式设置为1应该就可以了,后来发现可以直接通过SDP中的packetization-mode指定RTP打包模式。项目中出现的奇怪问题是因为,linphone默认使用了模式1打包,而下位机发送的SDP信息中没有指定packetization-mode。 在正位的发送的SDP中将packetization-mode指定为1,问题就解决了

你可能感兴趣的:(linphone中h264的 RTP打包(二))