Today, I found a strange problem. I can call the SIP client of the lower computer by using the Linphone client of the upper computer to work normally, but in turn there is a problem. Packet Capture found that Linphone sent a large number of IP fragmentation data packets, so google knows that when the data found is larger than MTU, it will generate IP fragmentation data packets. I have already split the RTP package? This should not happen normally.
Linphone uses RTP to package h264 in rfc3984.c. The packaging function is as follows:
void rfc3984_pack(Rfc3984Context *ctx, MSQueue *naluq, MSQueue *rtpq, uint32_t ts){switch(ctx->mode){case 0:rfc3984_pack_mode_0(ctx,naluq,rtpq,ts);break;case 1:rfc3984_pack_mode_1(ctx,naluq,rtpq,ts);break;default:ms_error("Bad or unsupported mode %i",ctx->mode);}}
It seems that the program defines two packaging modes to see the differences between the two modes.
static void rfc3984_pack_mode_0(Rfc3984Context *ctx, MSQueue *naluq, MSQueue *rtpq, uint32_t ts){mblk_t *m;bool_t end;int size;while((m=ms_queue_get(naluq))!=NULL){end=ms_queue_empty(naluq);size=m->b_wptr-m->b_rptr;if (size>ctx->maxsz){ms_warning("This H264 packet does not fit into mtu: size=%i",size);}send_packet(rtpq,ts,m,end);}}
/*process NALUs and pack them into rtp payloads */static void rfc3984_pack_mode_1(Rfc3984Context *ctx, MSQueue *naluq, MSQueue *rtpq, uint32_t ts){mblk_t *m,*prevm=NULL;int prevsz=0,sz;bool_t end;while((m=ms_queue_get(naluq))!=NULL){end=ms_queue_empty(naluq);sz=m->b_wptr-m->b_rptr;if (ctx->stap_a_allowed){if (prevm!=NULL){if ((prevsz+sz)<(ctx->maxsz-2)){prevm=concat_nalus(prevm,m);m=NULL;prevsz+=sz+2;/*+2 for the stapa size field*/continue;}else{/*send prevm packet: either single nal or STAP-A*/if (prevm->b_cont!=NULL){ms_debug("Sending STAP-A");}elsems_debug("Sending previous msg as single NAL");send_packet(rtpq,ts,prevm,FALSE);prevm=NULL;prevsz=0;}}if (sz<(ctx->maxsz/2)){/*try to aggregate it with next packet*/prevm=m;prevsz=sz+3; /*STAP-A header + size*/m=NULL;}else{/*send as single nal or FU-A*/if (sz>ctx->maxsz){ms_debug("Sending FU-A packets");frag_nalu_and_send(rtpq,ts,m,end, ctx->maxsz);}else{ms_debug("Sending Single NAL");send_packet(rtpq,ts,m,end);}}}else{if (sz>ctx->maxsz){ms_debug("Sending FU-A packets");frag_nalu_and_send(rtpq,ts,m,end, ctx->maxsz);}else{ms_debug("Sending Single NAL");send_packet(rtpq,ts,m,end);}}}if (prevm){ms_debug("Sending Single NAL (2)");send_packet(rtpq,ts,prevm,TRUE);}}
In Mode 0, we didn't even perform the RTP multipart packaging operation, but directly sent it out. It's no wonder that the IP protocol automatically performs the multipart processing. Therefore, we thought it would be enough to set the RTP packaging mode to 1. Later we found that we could directly use the packetization-mode in SDP to specify the RTP packaging mode. The strange problem in the project is that Linphone uses Mode 1 packaging by default, while packetization-mode is not specified in the SDP information sent by the lower computer. Set packetization-mode to 1 in the SDP to solve the problem.
Reprinted from: http://blog.csdn.net/gavinr/article/details/7388295