h264码流rtp打包(一)

 一帧image编码完的数据存储在h264buffer中,编码后的h264码流的大小为nH264Size 

    因为对于NALU,并不是一帧对应一个NALU,而是对于SLICE而言,一个slice就封装层一个nal,所以一帧可以有多个slice,即一帧有多个nal。

  具体一帧中有几个nalu则是可以再pps中参数中进行设定的,每遇到一个IDR,则此时就将对应的SPS,PPS进行一个更新,NAL的生成过程:先是对header里面的8个bits进行设定,然后是Payload。

  对于字节流编码的码流编码,去掉每个slice前面的4个前缀码,就是nal的内容了。而对于rtp封装打包不需要前缀码,所以在进行rfc3984_pack进行打包之前需提取nal

为了让处理流程看起来比较顺畅,我把几个处理流程都写在同一函数里头。

[cpp]  view plain copy
  1. //return value: number of the slice  
  2. static int Frame_Slice_Nal_Pro(unsigned char *h264buffer, int nH264Size)  
  3. {  
  4.     int i;  
  5.     int nSliceCount = -1;  
  6.     unsigned char   *pcSliceBuffer[SLICE_NUM];  //存储slice,去掉每个slice前面的4个前缀码,就是nal的内  
  7.   
  8. 容了。  
  9.     int pnSliceSize[SLICE_NUM];   //每个slice的size,即每个nal的大小+4  
  10.       
  11.     for(i=0; i<nH264Size-4; i++)  
  12.     {  
  13.         unsigned char *src = h264buffer + i;  
  14. //这里是进行字节流格式的码流编码,有开始4个前缀码,对于RTP封装则不需要前缀码。  
  15.         if( (*src == 0x00)  
  16.             && (*(src+1) == 0x00)  
  17.             && (*(src+2) == 0x00)  
  18.             && (*(src+3) == 0x01))  
  19.         {  
  20.   
  21.             nSliceCount++;  
  22.             pcSliceBuffer[nSliceCount] = src;  
  23.             pnSliceSize[nSliceCount] = 1;  
  24.         }  
  25.         else  
  26.         {  
  27.             if (nSliceCount >= 0)  
  28.             {  
  29.                 pnSliceSize[nSliceCount]++;  
  30.             }  
  31.         }  
  32.     }  
  33.     if (nSliceCount >= 0)  
  34.     {  
  35.         pnSliceSize[nSliceCount] += 4;  
  36.     }  
  37.   
  38. //提取nal  
  39.    mblk_t *m;  
  40.    MSQueue *nalus;  
  41.    int i;  
  42.    int nNalNum = nSliceCount + 1;  
  43.    for(i=0; i<nNalNum; i++) {  
  44.     m = allocb(pnSliceSize[i] + 10, 0);  
  45. //拷贝nal到mblk中,然后将mblk存于nalus队列里头  
  46.         memcpy(m->b_wptr, pcSliceBuffer[i] + 4, (pnSliceSize[i] - 4));  
  47.         m->b_wptr    += pnSliceSize[i] - 4;  
  48.         ms_queue_put(nalus,m);  
  49.     }  
  50. ..................  
  51. //rtp打包发送出去  
  52.   if(!ms_queue_empty(nalus))  
  53.         rfc3984_pack(d->packer,nalus,f->outputs[0],ts);  
  54. ............  
  55.     return (nSliceCount + 1);  
  56. }  
[cpp]  view plain copy
  1. <pre name="code" class="cpp"><pre name="code" class="cpp"></pre>  
  2. <pre></pre>  
  3. <pre></pre>  
  4. <pre></pre>  
  5. <pre></pre>  
  6. <pre></pre>  
  7. <pre></pre>  
  8. <pre></pre>  
  9. <pre></pre>  
  10. <pre></pre>  
  11. <pre></pre>  
  12. <pre></pre>  
  13. <pre></pre>  
  14. <pre></pre>  
  15. <pre></pre>  
  16. <pre></pre>  
  17. <pre></pre>  
  18. <pre></pre>  
  19.   
  20. </pre>  

你可能感兴趣的:(h264码流rtp打包(一))