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

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 "concatpyld.h"
  36. const UINT32 MinPacketDuration = 200;
  37. HXConcatenatePayloadFormat::HXConcatenatePayloadFormat() :
  38.     m_lRefCount(0),
  39.     m_pCCF(NULL),
  40.     m_pHeader(NULL),
  41.     m_pFinishedPkt(NULL),
  42.     m_bHaveFirstPkt(FALSE),
  43.     m_ulTimestamp(0),
  44.     m_uStream(0),
  45.     m_uASMFlags(0),
  46.     m_uASMRule(0),
  47.     m_ulByteCount(0),
  48.     m_bPendingFlush(FALSE)
  49. {}
  50. HXConcatenatePayloadFormat::~HXConcatenatePayloadFormat()
  51. {
  52.     Close();
  53. }
  54. HX_RESULT 
  55. HXConcatenatePayloadFormat::CreateInstance(REF(IHXPayloadFormatObject*) pPyld)
  56. {
  57.     HX_RESULT res = HXR_OUTOFMEMORY;
  58.     pPyld = new HXConcatenatePayloadFormat();
  59.     if (pPyld)
  60.     {
  61.         pPyld->AddRef();
  62.         res = HXR_OK;
  63.     }
  64.     return res;
  65. }
  66. /*
  67.  *      IUnknown methods
  68.  */
  69. STDMETHODIMP HXConcatenatePayloadFormat::QueryInterface(THIS_
  70.                                                         REFIID riid,
  71.                                                         void** ppvObj)
  72. {
  73.     HX_RESULT retVal = HXR_NOINTERFACE;
  74.     QInterfaceList qiList[] =
  75.     {
  76.         { GET_IIDHANDLE(IID_IUnknown), this },
  77.         { GET_IIDHANDLE(IID_IHXPayloadFormatObject), (IHXPayloadFormatObject*) this },
  78.     };
  79.     if (ppvObj)
  80.     {
  81.         *ppvObj = NULL;
  82.         return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  83.     }
  84.     return retVal;
  85. }
  86. STDMETHODIMP_(ULONG32) HXConcatenatePayloadFormat::AddRef(THIS)
  87. {
  88.     return InterlockedIncrement(&m_lRefCount);
  89. }
  90. STDMETHODIMP_(ULONG32) HXConcatenatePayloadFormat::Release(THIS)
  91. {
  92.     if (InterlockedDecrement(&m_lRefCount) > 0)
  93.     {
  94.         return m_lRefCount;
  95.     }
  96.     
  97.     delete this;
  98.     return 0;
  99. }
  100. /*
  101.  *      IHXPayloadFormatObject methods
  102.  */
  103. STDMETHODIMP HXConcatenatePayloadFormat::Init(THIS_
  104.                                               IUnknown* pContext,
  105.                                               BOOL bPacketize)
  106. {
  107.     HX_RESULT res = HXR_UNEXPECTED;
  108.     if (bPacketize && pContext)
  109.     {
  110.         res = pContext->QueryInterface(IID_IHXCommonClassFactory,
  111.                                        (void**)&m_pCCF);
  112.     }
  113.     return res;
  114. }
  115. STDMETHODIMP HXConcatenatePayloadFormat::Close(THIS)
  116. {
  117.     Reset();
  118.     HX_RELEASE(m_pCCF);
  119.     return HXR_OK;
  120. }
  121. STDMETHODIMP HXConcatenatePayloadFormat::Reset(THIS)
  122. {
  123.     HX_RELEASE(m_pFinishedPkt);
  124.     m_bHaveFirstPkt = FALSE;
  125.     ClearBufferList();
  126.     return HXR_OK;
  127. }
  128. STDMETHODIMP HXConcatenatePayloadFormat::SetStreamHeader(THIS_
  129.                                                          IHXValues* pHeader)
  130. {
  131.     HX_RESULT res = HXR_FAILED;
  132.     
  133.     HX_RELEASE(m_pHeader);
  134.     if (pHeader)
  135.     {   
  136.         m_pHeader = pHeader;
  137.         m_pHeader->AddRef();
  138.         res = HXR_OK;
  139.     }
  140.     return res;
  141. }
  142. STDMETHODIMP HXConcatenatePayloadFormat::GetStreamHeader(THIS_
  143.                                                        REF(IHXValues*) pHeader)
  144. {
  145.     pHeader = m_pHeader;
  146.     return (m_pHeader) ? HXR_OK : HXR_FAILED;
  147. }
  148. STDMETHODIMP HXConcatenatePayloadFormat::SetPacket(THIS_
  149.                                                    IHXPacket* pPacket)
  150. {
  151.     HX_RESULT res = HXR_OK;
  152.     if (!pPacket)
  153.     {
  154.         res = HXR_UNEXPECTED;
  155.     }
  156.     else if (m_bHaveFirstPkt)
  157.     {
  158.         UINT32 ulTimeDelta = pPacket->GetTime() - m_ulTimestamp;
  159.         if (!MatchesFirstPacket(pPacket) || (ulTimeDelta >= MinPacketDuration))
  160.         {
  161.             HX_RESULT tmpRes = CreateFinishedPkt();
  162.             if (HXR_OK == tmpRes)
  163.             {
  164. OnFirstPacket(pPacket);
  165.             }
  166.             else if (HXR_OUTOFMEMORY == tmpRes)
  167.             {
  168.                 res = HXR_OUTOFMEMORY;
  169.             }
  170.     else
  171.     {
  172. /* Any other errors will just
  173.  * cause this packet to get
  174.  * queued in the buffer list.
  175.  */
  176.     }
  177.         }
  178.     }
  179.     else
  180.     {
  181. OnFirstPacket(pPacket);
  182.     }
  183.     if (HXR_OK == res)
  184.     {
  185. res = AddToBufferList(pPacket);
  186.     }
  187.     return res;
  188. }
  189. STDMETHODIMP HXConcatenatePayloadFormat::GetPacket(THIS_
  190.                                                    REF(IHXPacket*) pPacket)
  191. {
  192.     HX_RESULT res = HXR_OK;
  193.     if (m_bPendingFlush && !m_pFinishedPkt)
  194.     {
  195.         /* Handle the pending flush*/
  196.         res = CreateFinishedPkt();
  197.     }
  198.     if (m_pFinishedPkt)
  199.     {
  200.         /* Transfering ownership here */
  201.         pPacket = m_pFinishedPkt;
  202.         m_pFinishedPkt = NULL;
  203.     }
  204.     else if (HXR_OK == res)
  205.     {
  206.         /* We don't have a finished
  207.          * packet here. We need more
  208.          * packets.
  209.          */
  210.         res = HXR_INCOMPLETE;
  211.     }
  212.     return res;
  213. }
  214. STDMETHODIMP HXConcatenatePayloadFormat::Flush(THIS)
  215. {
  216.     HX_RESULT res = HXR_OK;
  217.     if (m_pFinishedPkt)
  218.     {
  219.         m_bPendingFlush = TRUE;
  220.     }
  221.     else
  222.     {
  223.         res = CreateFinishedPkt();
  224.     }
  225.     return res;
  226. }
  227. HX_RESULT HXConcatenatePayloadFormat::CreateFinishedPkt()
  228. {
  229.     HX_RESULT res = HXR_UNEXPECTED;
  230.     if (!m_pFinishedPkt && m_pCCF && m_bHaveFirstPkt)
  231.     {
  232.         IHXPacket* pNewPkt = NULL;
  233.         IHXBuffer* pBuf = NULL;
  234.         if ((HXR_OK == m_pCCF->CreateInstance(CLSID_IHXPacket,
  235.                                           (void**)&pNewPkt)) &&
  236.             (HXR_OK == m_pCCF->CreateInstance(CLSID_IHXBuffer, 
  237.                                               (void**)&pBuf)) &&
  238.             (HXR_OK == pBuf->SetSize(m_ulByteCount)))
  239.         {
  240.             UCHAR* pCurPos = pBuf->GetBuffer();
  241.             
  242.             /* Copy the buffers in the buffer list */
  243.             LISTPOSITION pos = m_bufferList.GetHeadPosition();
  244.             while(pos)
  245.             {
  246.                 IHXBuffer* pTmpBuf = (IHXBuffer*)m_bufferList.GetNext(pos);
  247.                 memcpy(pCurPos, pTmpBuf->GetBuffer(), pTmpBuf->GetSize());
  248.                 pCurPos += pTmpBuf->GetSize();
  249.             }
  250.             res = pNewPkt->Set(pBuf, m_ulTimestamp, m_uStream, m_uASMFlags,
  251.                                m_uASMRule);
  252.             if (HXR_OK == res)
  253.             {
  254.                 m_bPendingFlush = FALSE;
  255.                 m_pFinishedPkt = pNewPkt;
  256.                 m_pFinishedPkt->AddRef();
  257. m_bHaveFirstPkt = FALSE;
  258.                 ClearBufferList();
  259.             }
  260.         }
  261.         HX_RELEASE(pNewPkt);
  262.         HX_RELEASE(pBuf);
  263.     }
  264.     return res;
  265. }
  266. HX_RESULT HXConcatenatePayloadFormat::AddToBufferList(IHXPacket* pPacket)
  267. {
  268.     IHXBuffer* pBuf = pPacket->GetBuffer();
  269.     if (pBuf)
  270.     {
  271.         m_ulByteCount += pBuf->GetSize();
  272.         
  273.         /* Transfering ownership here.
  274.          * We don't need to call HX_RELEASE()
  275.          * on pBuf
  276.          */
  277.         m_bufferList.AddTail(pBuf);
  278.     }
  279.     return HXR_OK;
  280. }
  281. void HXConcatenatePayloadFormat::ClearBufferList()
  282. {
  283.     while(!m_bufferList.IsEmpty())
  284.     {
  285.         IHXBuffer* pBuf = (IHXBuffer*)m_bufferList.RemoveHead();
  286.         HX_RELEASE(pBuf);
  287.     }
  288.     m_ulByteCount = 0;
  289. }
  290. BOOL HXConcatenatePayloadFormat::MatchesFirstPacket(IHXPacket* pPacket)
  291. {
  292.     BOOL bRet = FALSE;
  293.     if (m_bHaveFirstPkt && pPacket &&
  294.         (pPacket->GetStreamNumber() == m_uStream) &&
  295.         (pPacket->GetASMRuleNumber() == m_uASMRule) &&
  296.         (pPacket->GetASMFlags() == m_uASMFlags))
  297.     {
  298.         bRet = TRUE;
  299.     }
  300.     return bRet;
  301. }
  302. void HXConcatenatePayloadFormat::OnFirstPacket(IHXPacket* pPacket)
  303. {
  304.     m_bHaveFirstPkt = TRUE;
  305.     m_ulTimestamp = pPacket->GetTime();
  306.     m_uStream = pPacket->GetStreamNumber();
  307.     m_uASMFlags = pPacket->GetASMFlags();
  308.     m_uASMRule = pPacket->GetASMRuleNumber();
  309. }