h263pyld.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:13k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: RCSL 1.0/RPSL 1.0
  3.  *
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
  5.  *
  6.  * The contents of this file, and the files included with this file, are
  7.  * subject to the current version of the RealNetworks Public Source License
  8.  * Version 1.0 (the "RPSL") available at
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed
  10.  * the file under the RealNetworks Community Source License Version 1.0
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
  12.  * in which case the RCSL will apply. You may also obtain the license terms
  13.  * directly from RealNetworks.  You may not use this file except in
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or
  16.  * RCSL for the rights, obligations and limitations governing use of the
  17.  * contents of the file.
  18.  *
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the
  20.  * developer of the Original Code and owns the copyrights in the portions
  21.  * it created.
  22.  *
  23.  * This file, and the files included with this file, is distributed and made
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  28.  *
  29.  * Technology Compatibility Kit Test Suite(s) Location:
  30.  *    http://www.helixcommunity.org/content/tck
  31.  *
  32.  * Contributor(s):
  33.  *
  34.  * ***** END LICENSE BLOCK ***** */
  35. #include "h263pyld.h"
  36. #include "debug.h"
  37. #include "ihxpckts.h"
  38. #include <string.h>
  39. #include "rfc2190hlpr.h"
  40. #include "rfc2429hlpr.h"
  41. #include "bitstream.h"
  42. #include "bitpack.h"
  43. #define D_H263 0 // D_INFO
  44. CH263PayloadFormat::CH263PayloadFormat() :
  45.     m_lRefCount(0),
  46.     m_pCCF(0),
  47.     m_state(NeedPSC),
  48.     m_ulFrameSize(0),
  49.     m_ulTimestamp(0),
  50.     m_pDepackHlpr(0)
  51. {
  52. #ifdef DEBUG
  53.     debug_level() |= D_H263;
  54. #endif /* DEBUG */
  55. }
  56. CH263PayloadFormat::~CH263PayloadFormat()
  57. {
  58.     HX_RELEASE(m_pCCF);
  59.     FlushInput();
  60.     FlushOutput();
  61.     delete m_pDepackHlpr;
  62.     m_pDepackHlpr = 0;
  63. }
  64. /*
  65.  * IUnknown methods
  66.  */
  67. STDMETHODIMP CH263PayloadFormat::QueryInterface(REFIID riid,
  68.    void** ppvObj)
  69. {
  70.     HX_RESULT res = HXR_NOINTERFACE;
  71.     *ppvObj = NULL;
  72.     if (IsEqualIID(riid, IID_IUnknown))
  73.     {
  74. AddRef();
  75. *ppvObj = this;
  76. res = HXR_OK;
  77.     }
  78.     else if (IsEqualIID(riid, IID_IHXPayloadFormatObject))
  79.     {
  80. AddRef();
  81. *ppvObj = (IHXPayloadFormatObject*)this;
  82. res = HXR_OK;
  83.     }
  84.     return res;
  85. }
  86. STDMETHODIMP_(ULONG32) CH263PayloadFormat::AddRef()
  87. {
  88.     return InterlockedIncrement(&m_lRefCount);
  89. }
  90. STDMETHODIMP_(ULONG32) CH263PayloadFormat::Release()
  91. {
  92.     if (InterlockedDecrement(&m_lRefCount) > 0)
  93.     {
  94.         return m_lRefCount;
  95.     }
  96.     delete this;
  97.     return 0;
  98. }
  99. /*
  100.  * IHXPayloadFormatObject methods
  101.  */
  102. STDMETHODIMP CH263PayloadFormat::Init(THIS_
  103.       IUnknown* pContext,
  104.       BOOL bPacketize)
  105. {
  106.     DPRINTF(D_H263, ("CH263PayloadFormat::Init(%p, %d)n",
  107.      pContext, bPacketize));
  108.     HX_RESULT res = HXR_UNEXPECTED;
  109.     if (!bPacketize)
  110.     {
  111. // Currently we only support depacketization
  112. res = pContext->QueryInterface(IID_IHXCommonClassFactory,
  113.        (void**)&m_pCCF);
  114.     }
  115.     return res;
  116. }
  117. STDMETHODIMP CH263PayloadFormat::Close()
  118. {
  119.     DPRINTF(D_H263, ("CH263PayloadFormat::Close()n"));
  120.     Flush();
  121.     return HXR_OK;
  122. }
  123. STDMETHODIMP CH263PayloadFormat::Reset()
  124. {
  125.     // Called on Seeks
  126.     DPRINTF(D_H263, ("CH263PayloadFormat::Reset()n"));
  127.     FlushInput();
  128.     FlushOutput();
  129.     m_state = NeedPSC;
  130.     return HXR_OK;
  131. }
  132. STDMETHODIMP CH263PayloadFormat::SetStreamHeader(IHXValues* pHeader)
  133. {
  134.     DPRINTF(D_H263, ("CH263PayloadFormat::SetStreamHeader()n"));
  135.     return HXR_OK;
  136. }
  137. STDMETHODIMP CH263PayloadFormat::GetStreamHeader(REF(IHXValues*) pHeader)
  138. {
  139.     DPRINTF(D_H263, ("CH263PayloadFormat::GetStreamHeader()n"));
  140.     return HXR_OK;
  141. }
  142. STDMETHODIMP CH263PayloadFormat::SetPacket(IHXPacket* pPacket)
  143. {
  144.     DPRINTF(D_H263, ("CH263PayloadFormat::SetPacket()n"));
  145.     HX_RESULT res = HXR_UNEXPECTED;
  146.     if (!pPacket->IsLost())
  147.     {
  148. IHXBuffer* pBuf = pPacket->GetBuffer();
  149. const UINT8* pData = 0;
  150. ULONG32 ulDataSize = 0;
  151. BOOL bP = FALSE;
  152. res = HXR_OK;
  153. if (!m_pDepackHlpr)
  154.     res = CreateHelper(pBuf->GetBuffer(), pBuf->GetSize());
  155. if (SUCCEEDED(res) &&
  156.     SUCCEEDED(res = m_pDepackHlpr->OnPacket(pBuf->GetBuffer(),
  157.     pBuf->GetSize())))
  158. {
  159.     BOOL bDone = FALSE;
  160.     BOOL bPacketAdded = FALSE;
  161.     /* Cache values since ProcessPacket() uses
  162.      * m_pDepackHlpr and can change it's state.
  163.      */
  164.     UINT32 ulDataSize = m_pDepackHlpr->DataSize();
  165.     BOOL bIsPictureStart = m_pDepackHlpr->IsPictureStart();
  166.     while(!bDone && SUCCEEDED(res))
  167.     {
  168. switch(m_state) {
  169. case NeedPSC:
  170.     // See if this packet has a PSC
  171.     if (bIsPictureStart)
  172.     {
  173. m_ulFrameSize = 0; // Make sure the frame size is 0
  174. // Add the packet to the input queue
  175. res = AddPacket(ulDataSize, pPacket);
  176. // Signal that we added this packet
  177. bPacketAdded = TRUE;
  178. // Cache the timestamp for this frame
  179. m_ulTimestamp = pPacket->GetTime();
  180. // Change state
  181. m_state = GotPSC;
  182.     }
  183.     else
  184.     {
  185. // Signal that we are done handling this packet
  186. bDone = TRUE;
  187.     }
  188.     break;
  189. case GotPSC:
  190.     if (pPacket->GetTime() == m_ulTimestamp)
  191.     {
  192. // See if the packet has been added yet
  193. if (!bPacketAdded)
  194. {
  195.     DPRINTF (D_H263,("Multi-packetn"));
  196.     // Add the packet to the input queue
  197.     res = AddPacket(ulDataSize, pPacket);
  198.     // Signal that we added this packet
  199.     bPacketAdded = TRUE;
  200. }
  201. // Check for the marker bit. The marker bit
  202. // is always mapped to odd ASM rule numbers
  203. if ((pPacket->GetASMRuleNumber() & 0x1) == 1)
  204.     m_state = GotFrame;
  205. else
  206.     bDone = TRUE;
  207.     }
  208.     else
  209.     {
  210. // This appears to be a different frame.
  211. // Goto the GotFrame state so that we
  212. // process the current frame
  213. m_state = GotFrame;
  214.     }
  215.     break;
  216. case GotFrame:
  217.     if (!m_inputQueue.IsEmpty())
  218.     {
  219. // Process the packets in the input queue
  220. res = ProcessPackets();
  221.     }
  222.     // Change to the NeedPSC state
  223.     m_state = NeedPSC;
  224.     if (bPacketAdded)
  225. bDone = TRUE;
  226. };
  227.     }
  228. }
  229. if (!SUCCEEDED(res))
  230. {
  231.     /* Something unexpected happened.
  232.      * Flush everything.
  233.      */
  234.     FlushInput();
  235. }
  236. HX_RELEASE(pBuf);
  237.     }
  238.     else
  239.     {
  240. FlushInput();
  241. res = HXR_OK;
  242.     }
  243.     return res;
  244. }
  245. STDMETHODIMP CH263PayloadFormat::GetPacket(REF(IHXPacket*) pPacket)
  246. {
  247.     DPRINTF(D_H263, ("CH263PayloadFormat::GetPacket()n"));
  248.     HX_RESULT res = HXR_FAILED;
  249.     if (!m_outputQueue.IsEmpty())
  250.     {
  251. pPacket = (IHXPacket*)m_outputQueue.RemoveHead();
  252. res = HXR_OK;
  253.     }
  254.     DPRINTF(D_H263, ("CH263PayloadFormat::GetPacket() : %08xn", res));
  255.     return res;
  256. }
  257. STDMETHODIMP CH263PayloadFormat::Flush()
  258. {
  259.     // Called at the end of the clip
  260.     DPRINTF(D_H263, ("CH263PayloadFormat::Flush()n"));
  261.     FlushInput();
  262.     return HXR_OK;
  263. }
  264. static HX_RESULT GetH263FrameSize(int fmt, HXxSize &FrameDim)
  265. {
  266.     HX_RESULT res = HXR_NO_DATA;
  267.     if (fmt == 1)
  268.     {
  269. FrameDim.cx = 128;
  270. FrameDim.cy = 96;
  271. res = HXR_OK;
  272.     }
  273.     else if ((fmt >= 2) && (fmt < 6))
  274.     {
  275. FrameDim.cx = 176;
  276. FrameDim.cy = 144;
  277. for(;fmt > 2; fmt--)
  278. {
  279.     FrameDim.cx <<= 1;
  280.     FrameDim.cy <<= 1;
  281. }
  282. res = HXR_OK;
  283.     }
  284.     else
  285. HX_ASSERT(FALSE);
  286.     return res;
  287. }
  288. static HX_RESULT HandleH263Plus(Bitstream& bs, HXxSize &FrameDim)
  289. {
  290.     HX_RESULT res = HXR_UNEXPECTED;
  291.     if (bs.GetBits(3) == 1) // UFEP
  292.     {
  293. int fmt = bs.GetBits(3); // OPPTYPE (bits 1-3)
  294. if (fmt != 0x6)
  295.     res = GetH263FrameSize(fmt, FrameDim);
  296. else
  297. {
  298.     // This frame has custom dimensions
  299.     bs.GetBits(11) ; // OPPTYPE (bits 4-14)
  300.     if (bs.GetBits(4) == 0x8) // OPPTYPE (bits 15-18)
  301.     {
  302. bs.GetBits(6); // MPPTYPE (bits 1-6)
  303. if (bs.GetBits(3) == 0x1) // MPPTYPE (bits 7-9)
  304. {
  305.     if (bs.GetBits(1)) // CPM
  306. bs.GetBits(2); // PSBI
  307.     bs.GetBits(4); // CPFMT (bits 1-4)
  308.     int pwi = (bs.GetBits(9) + 1) * 4;
  309.     if (bs.GetBits(1)) // CPFMT (bit 14)
  310.     {
  311. int phi = (bs.GetBits(9)) * 4;
  312. if ((phi >= 1) && (phi <= 288))
  313. {
  314.     FrameDim.cx = pwi;
  315.     FrameDim.cy = phi;
  316.     res = HXR_OK;
  317. }
  318.     }
  319. }
  320.     }
  321. }
  322.     }
  323.     return res;
  324. }
  325. HX_RESULT CH263PayloadFormat::GetFrameDimensions(IHXBuffer* pBuffer,
  326.  HXxSize &FrameDim)
  327. {
  328.     DPRINTF(D_H263, ("CH263PayloadFormat::GetFrameDimensions()n"));
  329.     HX_RESULT res = HXR_UNEXPECTED;
  330.     Bitstream bs;
  331.     if (pBuffer->GetSize() >= 5)
  332.     {
  333. bs.SetBuffer(pBuffer->GetBuffer());
  334. if (bs.GetBits(22) == 0x20) // Check PSC
  335. {
  336.     bs.GetBits(8); // Skip TR
  337.     if (bs.GetBits(2) == 0x02) // PTYPE(bits 1 & 2)
  338.     {
  339. bs.GetBits(3); // PTYPE(bits 3-5)
  340. int fmt = bs.GetBits(3); // Get Format
  341. if (fmt != 0x7)
  342. {
  343.     res = GetH263FrameSize(fmt, FrameDim);
  344. }
  345. else if (pBuffer->GetSize() >= 13)
  346. {
  347.     // This has an extended PTYPE
  348.     res = HandleH263Plus(bs, FrameDim);
  349. }
  350.     }
  351. }
  352.     }
  353.     DPRINTF(D_H263, ("CH263PayloadFormat::GetFrameDimensions() : %dn", res));
  354.     return res;
  355. }
  356. HX_RESULT CH263PayloadFormat::ProcessPackets()
  357. {
  358.     HX_RESULT res = HXR_UNEXPECTED;
  359.     if (m_pCCF)
  360.     {
  361. IHXBuffer* pBuf = 0;
  362. IHXRTPPacket* pOutRTPPkt = 0;
  363. ULONG32 ulFrameBytes = (m_ulFrameSize + 7) >> 3;
  364. if (!m_pDepackHlpr)
  365.     res = CreateHelper(pBuf->GetBuffer(), pBuf->GetSize());
  366. else
  367.     res = HXR_OK;
  368. if (SUCCEEDED(res) &&
  369.     SUCCEEDED((res = m_pCCF->CreateInstance(IID_IHXBuffer,
  370.     (void**)(&pBuf)))) &&
  371.     SUCCEEDED((res = pBuf->SetSize(ulFrameBytes))) &&
  372.     SUCCEEDED((res = m_pCCF->CreateInstance(IID_IHXRTPPacket,
  373.     (void**)(&pOutRTPPkt)))))
  374. {
  375.     BitPacker bp(pBuf->GetBuffer(), pBuf->GetSize());
  376.     LISTPOSITION pos = m_inputQueue.GetHeadPosition();
  377.     while((pos != 0) && SUCCEEDED(res))
  378.     {
  379. IHXPacket* pPacket = (IHXPacket*)m_inputQueue.GetNext(pos);
  380. IHXBuffer* pPktBuf = pPacket->GetBuffer();
  381. res = m_pDepackHlpr->OnPacket(pPktBuf->GetBuffer(),
  382.       pPktBuf->GetSize());
  383. if (SUCCEEDED(res))
  384.     res = m_pDepackHlpr->CopyPayload(bp);
  385. ULONG32 used = bp.BytesUsed();
  386. HX_ASSERT(used <= ulFrameBytes);
  387. // Release the packet buffer
  388. HX_RELEASE(pPktBuf);
  389.     }
  390.     if (SUCCEEDED(res))
  391.     {
  392. IHXPacket* pFirstPkt = (IHXPacket*)m_inputQueue.GetHead();
  393. IHXRTPPacket* pRTPPkt = 0;
  394. if (SUCCEEDED(pFirstPkt->QueryInterface(IID_IHXRTPPacket,
  395. (void**)&pRTPPkt)))
  396. {
  397.     res = pOutRTPPkt->SetRTP(pBuf,
  398.      pRTPPkt->GetTime(),
  399.      pRTPPkt->GetRTPTime(),
  400.      pRTPPkt->GetStreamNumber(),
  401.      pRTPPkt->GetASMFlags(),
  402.      pRTPPkt->GetASMRuleNumber());
  403. }
  404. else
  405. {
  406.     res = pOutRTPPkt->Set(pBuf,
  407.   pFirstPkt->GetTime(),
  408.   pFirstPkt->GetStreamNumber(),
  409.   pFirstPkt->GetASMFlags(),
  410.   pFirstPkt->GetASMRuleNumber());
  411. }
  412. IHXPacket* pOutPkt = 0;
  413. res = pOutRTPPkt->QueryInterface(IID_IHXPacket,
  414.  (void**)&pOutPkt);
  415. if (SUCCEEDED(res))
  416.     m_outputQueue.AddTail(pOutPkt);
  417. HX_RELEASE(pRTPPkt);
  418.     }
  419. }
  420. HX_RELEASE(pBuf);
  421. HX_RELEASE(pOutRTPPkt);
  422.     }
  423.     FlushInput();
  424.     return res;
  425. }
  426. HX_RESULT CH263PayloadFormat::AddPacket(ULONG32 ulDataSize, IHXPacket* pPacket)
  427. {
  428.     HX_RESULT res = HXR_OUTOFMEMORY;
  429.     if (m_inputQueue.AddTail(pPacket))
  430.     {
  431. m_ulFrameSize += ulDataSize;
  432. pPacket->AddRef();
  433. res = HXR_OK;
  434.     }
  435.     return res;
  436. }
  437. void CH263PayloadFormat::FlushInput()
  438. {
  439.     LISTPOSITION pos = m_inputQueue.GetHeadPosition();
  440.     while(pos != 0)
  441.     {
  442. IHXPacket* pPacket = (IHXPacket*)m_inputQueue.GetNext(pos);
  443. HX_RELEASE(pPacket);
  444.     }
  445.     m_inputQueue.RemoveAll();
  446.     m_ulFrameSize = 0;
  447.     m_state = NeedPSC;
  448. }
  449. void CH263PayloadFormat::FlushOutput()
  450. {
  451.     LISTPOSITION pos = m_outputQueue.GetHeadPosition();
  452.     while(pos != 0)
  453.     {
  454. IHXPacket* pPacket = (IHXPacket*)m_outputQueue.GetNext(pos);
  455. HX_RELEASE(pPacket);
  456.     }
  457.     m_outputQueue.RemoveAll();
  458. }
  459. HX_RESULT CH263PayloadFormat::CreateHelper(const UINT8* pBuf,
  460.                                            ULONG32 ulBufSize)
  461. {
  462.     HX_RESULT res = HXR_UNEXPECTED;
  463. #if defined(HELIX_FEATURE_H263_RFC2429)
  464.     // Try the RFC2429 helper first
  465.     if (FAILED(res))
  466.     {
  467.         HX_DELETE(m_pDepackHlpr);
  468.         m_pDepackHlpr = new CRFC2429Helper();
  469.         if (m_pDepackHlpr)
  470.         {
  471.             res = m_pDepackHlpr->OnPacket(pBuf, ulBufSize);
  472.         }
  473.     }
  474. #endif
  475. #if defined(HELIX_FEATURE_H263_RFC2190)
  476.     // If the RFC2429 helper didn't succeed, then
  477.     // try the RFC2190 helper next.
  478.     if (FAILED(res))
  479.     {
  480.         HX_DELETE(m_pDepackHlpr);
  481.         m_pDepackHlpr = new CRFC2190Helper();
  482.         if (m_pDepackHlpr)
  483.         {
  484.             res = m_pDepackHlpr->OnPacket(pBuf, ulBufSize);
  485.         }
  486.     }
  487. #endif
  488.     return res;
  489. }