织梦CMS - 轻松建站从此开始!

罗索

SIP与RTP综合应用5-RTP解包过程(2)

落鹤生 发布于 2010-09-17 09:14 点击:次 
然后,进入video\MPEG4-ffmpeg目录下看mpeg4.cxx,这里包含了完整的RFC解包重组及MPEG4解码的源码。直接编译可能通不过,好在代码写的非常整齐,提取出来就是
TAG:

然后,进入video\MPEG4-ffmpeg目录下看mpeg4.cxx,这里包含了完整的RFC解包重组及MPEG4解码的源码。直接编译可能通不过,好在代码写的非常整齐,提取出来就是了。解包解码只要看这一个函数:

  1. bool MPEG4DecoderContext::DecodeFrames(const BYTE * src, unsigned & srcLen, 
  2.  BYTE * dst, unsigned & dstLen, 
  3.  unsigned int & flags)
  4.     if (!FFMPEGLibraryInstance.IsLoaded()) 
  5.         return 0; 
  6.  
  7.     // Creates our frames 
  8.     RTPFrame srcRTP(src, srcLen); 
  9.     RTPFrame dstRTP(dst, dstLen, RTP_DYNAMIC_PAYLOAD); 
  10.     dstLen = 0; 
  11.     flags = 0; 
  12.     
  13.     int srcPayloadSize = srcRTP.GetPayloadSize(); 
  14.     SetDynamicDecodingParams(true); // Adjust dynamic settings, restart allowed 
  15.     
  16.     // Don't exceed buffer limits.  _encFrameLen set by ResizeDecodingFrame 
  17.     if(_lastPktOffset + srcPayloadSize < _encFrameLen) 
  18.     { 
  19.         // Copy the payload data into the buffer and update the offset 
  20.         memcpy(_encFrameBuffer + _lastPktOffset, srcRTP.GetPayloadPtr(), 
  21.                srcPayloadSize); 
  22.         _lastPktOffset += srcPayloadSize; 
  23.     } 
  24.     else { 
  25.  
  26.         // Likely we dropped the marker packet, so at this point we have a 
  27.         // full buffer with some of the frame we wanted and some of the next 
  28.         // frame.  
  29.  
  30.         //I'm on the fence about whether to send the data to the 
  31.         // decoder and hope for the best, or to throw it all away and start 
  32.         // again. 
  33.  
  34.  
  35.         // throw the data away and ask for an IFrame 
  36.         TRACE(1, "MPEG4\tDecoder\tWaiting for an I-Frame"); 
  37.         _lastPktOffset = 0; 
  38.         flags = (_gotAGoodFrame ? PluginCodec_ReturnCoderRequestIFrame : 0); 
  39.         _gotAGoodFrame = false
  40.         return 1; 
  41.     } 
  42.  
  43.     // decode the frame if we got the marker packet 
  44.     int got_picture = 0; 
  45.     if (srcRTP.GetMarker()) { 
  46.         _frameNum++; 
  47.         int len = FFMPEGLibraryInstance.AvcodecDecodeVideo 
  48.                         (_avcontext, _avpicture, &got_picture, 
  49.                          _encFrameBuffer, _lastPktOffset); 
  50.  
  51.         if (len >= 0 && got_picture) { 
  52. #ifdef LIBAVCODEC_HAVE_SOURCE_DIR 
  53.             if (DecoderError(_keyRefreshThresh)) { 
  54.                 // ask for an IFrame update, but still show what we've got 
  55.                 flags = (_gotAGoodFrame ? PluginCodec_ReturnCoderRequestIFrame : 0); 
  56.                 _gotAGoodFrame = false
  57.             } 
  58. #endif 
  59.             TRACE_UP(4, "MPEG4\tDecoder\tDecoded " << len << " bytes" << 
  60. ", Resolution: " << _avcontext->width << "x" << _avcontext->height); 
  61.             // If the decoding size changes on us, we can catch it and resize 
  62.             if (!_disableResize 
  63.                 && (_frameWidth != (unsigned)_avcontext->width 
  64.                    || _frameHeight != (unsigned)_avcontext->height)) 
  65.             { 
  66.                 // Set the decoding width to what avcodec says it is 
  67.                 _frameWidth  = _avcontext->width; 
  68.                 _frameHeight = _avcontext->height; 
  69.                 // Set dynamic settings (framesize), restart as needed 
  70.                 SetDynamicDecodingParams(true); 
  71.                 return true
  72.             } 
  73.  
  74.             // it's stride time 
  75.             int frameBytes = (_frameWidth * _frameHeight * 3) / 2; 
  76.             PluginCodec_Video_FrameHeader * header 
  77.                 = (PluginCodec_Video_FrameHeader *)dstRTP.GetPayloadPtr(); 
  78.             header->x = header->y = 0; 
  79.             header->width = _frameWidth; 
  80.             header->height = _frameHeight; 
  81.             unsigned char *dstData = OPAL_VIDEO_FRAME_DATA_PTR(header); 
  82.             for (int i=0; i<3; i ++) { 
  83.                 unsigned char *srcData = _avpicture->data[i]; 
  84.                 int dst_stride = i ? _frameWidth >> 1 : _frameWidth; 
  85.                 int src_stride = _avpicture->linesize[i]; 
  86.                 int h = i ? _frameHeight >> 1 : _frameHeight; 
  87.                 if (src_stride==dst_stride) { 
  88.                     memcpy(dstData, srcData, dst_stride*h); 
  89.                     dstData += dst_stride*h; 
  90.                 } 
  91.                 else 
  92.                 { 
  93.                     while (h--) { 
  94.                         memcpy(dstData, srcData, dst_stride); 
  95.                         dstData += dst_stride; 
  96.                         srcData += src_stride; 
  97.                     } 
  98.                 } 
  99.             } 
  100.             // Treating the screen as an RTP is weird 
  101.             dstRTP.SetPayloadSize(sizeof(PluginCodec_Video_FrameHeader) 
  102.                                   + frameBytes); 
  103.             dstRTP.SetPayloadType(RTP_DYNAMIC_PAYLOAD); 
  104.             dstRTP.SetTimestamp(srcRTP.GetTimestamp()); 
  105.             dstRTP.SetMarker(true); 
  106.             dstLen = dstRTP.GetFrameLen(); 
  107.             flags = PluginCodec_ReturnCoderLastFrame; 
  108.             _gotAGoodFrame = true
  109.         } 
  110.         else { 
  111.             TRACE(1, "MPEG4\tDecoder\tDecoded "<< len << 
  112. " bytes without getting a Picture..."); 
  113.             // decoding error, ask for an IFrame update 
  114.             flags = (_gotAGoodFrame ? PluginCodec_ReturnCoderRequestIFrame : 0); 
  115.             _gotAGoodFrame = false
  116.         } 
  117.         _lastPktOffset = 0; 
  118.     } 
  119.     return true

写的非常非常的明白:if (srcRTP.GetMarker()),到了这里表示收满了一包,开始去解码。

mpeg4-es的RFC还原重组就这么简单,下一步的解码,就涉及到用libavcodec.dll了。

(sxcong)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201009/10170.html]
本文出处:CSDN博客 作者:sxcong
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容