mp4vpyld.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:29k
源码类别:

Symbian

开发平台:

Visual 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. /****************************************************************************
  36.  *  Defines
  37.  */
  38. // #define _APPEND_VOL_HEADER
  39. // #define _DONOT_SEGMENT
  40. // #define _ASSERT_ON_LOSS
  41. // #define _DUMP_FIRST_NFRAMES 5
  42. #define _OVERALLOC_CODEC_DATA 3
  43. #define MP4V_RN_PAYLOAD_MIME_TYPE     "video/X-RN-MP4"
  44. #define MP4V_3016_PAYLOAD_MIME_TYPE     "video/MP4V-ES"
  45. #define MP4V_RN_3GPP_H263_PAYLOAD_MIME_TYPE "video/X-RN-3GPP-H263"
  46. #define FLUSH_ALL_PACKETS   0xFFFFFFFF
  47. #define MAX_FRAME_SEGMENTS 1024
  48. #define NUM_OVERLAP_SEGMENTS 256
  49. #define DLFT_MAX_PACKET_DATA_SIZE   0x7FFFFFFF
  50. #define CHAR_LF 0x0a
  51. #define CHAR_CR 0x0d
  52. #define MAX_INT_TEXT_LENGTH 10
  53. /****************************************************************************
  54.  *  Includes
  55.  */
  56. #include "hxtypes.h"
  57. #include "hxwintyp.h"
  58. #include "hxcom.h"
  59. #include "hxcomm.h"
  60. #include "hxassert.h"
  61. #include "hxslist.h"
  62. #include "hxstrutl.h"
  63. #include "hxcomm.h"
  64. #include "ihxpckts.h"
  65. #include "hxformt.h"
  66. #include "hxrendr.h"
  67. #include "hxformt.h"
  68. #include "hxengin.h"
  69. #include "sdptools.h"
  70. #include "mp4desc.h"
  71. #include "mp4vpyld.h"
  72. #include "mp4pyldutil.h"
  73. MP4VPayloadFormat::MP4VPayloadFormat(CHXBufferMemoryAllocator* pAllocator)
  74.     : m_lRefCount (0)
  75.     , m_pClassFactory (NULL)
  76.     , m_pStreamHeader (NULL)
  77.     , m_pVOLHeader (NULL)
  78.     , m_ulVOLHeaderSize (0)
  79.     , m_ulSamplesPerSecond(1000)
  80.     , m_bFlushed (FALSE)
  81.     , m_bFirstPacket (TRUE)
  82.     , m_bFirstFrame (TRUE)
  83.     , m_bUsesRTPPackets (FALSE)
  84.     , m_bRTPPacketTested(FALSE)
  85.     , m_pAllocator (pAllocator)
  86.     , m_bPacketize (FALSE)
  87.     , m_ulFrameCount (0)
  88.     , m_uSeqNumber (0)
  89.     , m_bPictureStarted (FALSE)
  90.     , m_ulMaxPacketDataSize(DLFT_MAX_PACKET_DATA_SIZE)
  91.     , m_PayloadID (PYID_X_HX_MP4)
  92. {
  93.     if (m_pAllocator)
  94.     {
  95. m_pAllocator->AddRef();
  96.     }
  97. }
  98. MP4VPayloadFormat::~MP4VPayloadFormat()
  99. {
  100.     FlushPackets(FLUSH_ALL_PACKETS);
  101.     HX_VECTOR_DELETE(m_pVOLHeader);
  102.     if (m_pAllocator)
  103.     {
  104.         m_pAllocator->Release();
  105.         m_pAllocator = NULL;
  106.     }
  107.     HX_RELEASE(m_pClassFactory);
  108.     HX_RELEASE(m_pStreamHeader);
  109. }
  110. // *** IUnknown methods ***
  111. /////////////////////////////////////////////////////////////////////////
  112. //  Method:
  113. // IUnknown::QueryInterface
  114. //  Purpose:
  115. // Implement this to export the interfaces supported by your
  116. // object.
  117. //
  118. STDMETHODIMP
  119. MP4VPayloadFormat::QueryInterface(REFIID riid, void** ppvObj)
  120. {
  121.     QInterfaceList qiList[] =
  122.     {
  123. { GET_IIDHANDLE(IID_IUnknown), this },
  124. { GET_IIDHANDLE(IID_IHXPayloadFormatObject), (IHXPayloadFormatObject*) this },
  125.     };
  126.     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  127. }
  128. /////////////////////////////////////////////////////////////////////////
  129. //  Method:
  130. // IUnknown::AddRef
  131. //  Purpose:
  132. // Everyone usually implements this the same... feel free to use
  133. // this implementation.
  134. //
  135. STDMETHODIMP_(ULONG32)
  136. MP4VPayloadFormat::AddRef()
  137. {
  138.     return InterlockedIncrement(&m_lRefCount);
  139. }
  140. /////////////////////////////////////////////////////////////////////////
  141. //  Method:
  142. // IUnknown::Release
  143. //  Purpose:
  144. // Everyone usually implements this the same... feel free to use
  145. // this implementation.
  146. //
  147. STDMETHODIMP_(ULONG32)
  148. MP4VPayloadFormat::Release()
  149. {
  150.     if (InterlockedDecrement(&m_lRefCount) > 0)
  151.     {
  152.         return m_lRefCount;
  153.     }
  154.     delete this;
  155.     return 0;
  156. }
  157. STDMETHODIMP
  158. MP4VPayloadFormat::Init(IUnknown* pContext,
  159. BOOL bPacketize)
  160. {
  161.     HX_RESULT retVal = HXR_OK;
  162.     HX_RELEASE(m_pClassFactory);
  163.     m_bPacketize = bPacketize;
  164.     if (SUCCEEDED(retVal))
  165.     {
  166. retVal = pContext->QueryInterface(IID_IHXCommonClassFactory,
  167.   (void**) &m_pClassFactory);
  168.     }
  169.     return retVal;
  170. }
  171. STDMETHODIMP
  172. MP4VPayloadFormat::Reset()
  173. {
  174.     // Release all input packets we have stored
  175.     FlushPackets(FLUSH_ALL_PACKETS);
  176.     m_bFlushed = FALSE;
  177.     m_bFirstPacket = TRUE;
  178.     m_bFirstFrame = TRUE;
  179.     m_bPictureStarted = FALSE;
  180.     m_bUsesRTPPackets = FALSE;
  181.     m_bRTPPacketTested = FALSE;
  182.     m_ulFrameCount = 0;
  183.     m_uSeqNumber = 0;
  184.     m_TSConverter.Reset();
  185.     return HXR_OK;
  186. }
  187. STDMETHODIMP
  188. MP4VPayloadFormat::SetStreamHeader(IHXValues* pHeader)
  189. {
  190.     HX_RESULT retVal = HXR_OK;
  191.     HX_ASSERT(pHeader);
  192.     HX_RELEASE(m_pStreamHeader);
  193.     m_pStreamHeader = pHeader;
  194.     if (m_pStreamHeader)
  195.     {
  196. m_pStreamHeader->AddRef();
  197.     }
  198.     if (m_bPacketize)
  199.     {
  200. retVal = SetPacketizerHeader(pHeader);
  201.     }
  202.     else
  203.     {
  204. retVal = SetAssemblerHeader(pHeader);
  205.     }
  206.     return retVal;
  207. }
  208. HX_RESULT MP4VPayloadFormat::SetPacketizerHeader(IHXValues* pHeader)
  209. {
  210.     IHXBuffer* pMimeType = NULL;
  211.     const char* pMimeTypeData = NULL;
  212.     HX_RESULT retVal = HXR_OK;
  213.     if (SUCCEEDED(retVal))
  214.     {
  215. retVal = pHeader->GetPropertyCString("MimeType", pMimeType);
  216.     }
  217.     if (SUCCEEDED(retVal))
  218.     {
  219. pMimeTypeData = (char*) pMimeType->GetBuffer();
  220. retVal = HXR_FAIL;
  221. if (pMimeTypeData)
  222. {
  223.     retVal = HXR_OK;
  224. }
  225.     }
  226.     if (SUCCEEDED(retVal))
  227.     {
  228. if (strcasecmp(pMimeTypeData, MP4V_3016_PAYLOAD_MIME_TYPE) == 0)
  229. {
  230.     m_PayloadID = PYID_MP4V_ES;
  231.     if (DLFT_MAX_PACKET_DATA_SIZE != m_ulMaxPacketDataSize)
  232.     {
  233. retVal = pHeader->SetPropertyULONG32
  234.     ("MaxPacketSize", m_ulMaxPacketDataSize);
  235.     }
  236. }
  237. else if (strcasecmp(pMimeTypeData, MP4V_RN_PAYLOAD_MIME_TYPE) == 0)
  238. {
  239.     m_PayloadID = PYID_X_HX_MP4;
  240. }
  241. else if (strcasecmp(pMimeTypeData, MP4V_RN_3GPP_H263_PAYLOAD_MIME_TYPE) == 0)
  242. {
  243.     m_PayloadID = PYID_X_HX_3GPP_H263;
  244. }
  245.     }
  246.     HX_RELEASE(pMimeType);
  247.     return retVal;
  248. }
  249. HX_RESULT MP4VPayloadFormat::SetAssemblerHeader(IHXValues* pHeader)
  250. {
  251.     IHXBuffer* pMimeType = NULL;
  252.     const char* pMimeTypeData = NULL;
  253.     HX_RESULT retVal = HXR_OK;
  254.     HX_VECTOR_DELETE(m_pVOLHeader);
  255.     m_ulVOLHeaderSize = 0;
  256.     if (SUCCEEDED(retVal))
  257.     {
  258. retVal = pHeader->GetPropertyCString("MimeType", pMimeType);
  259.     }
  260.     if (SUCCEEDED(retVal))
  261.     {
  262. pMimeTypeData = (char*) pMimeType->GetBuffer();
  263. retVal = HXR_FAIL;
  264. if (pMimeTypeData)
  265. {
  266.     retVal = HXR_OK;
  267. }
  268.     }
  269.     if (SUCCEEDED(retVal))
  270.     {
  271. if (strcasecmp(pMimeTypeData, MP4V_3016_PAYLOAD_MIME_TYPE) == 0)
  272. {
  273.     m_PayloadID = PYID_MP4V_ES;
  274.     retVal = SetAssembler3016Header(pHeader);
  275. }
  276. else if (strcasecmp(pMimeTypeData, MP4V_RN_PAYLOAD_MIME_TYPE) == 0)
  277. {
  278.     m_PayloadID = PYID_X_HX_MP4;
  279.     retVal = SetAssemblerHXHeader(pHeader);
  280. }
  281. else if (strcasecmp(pMimeTypeData, MP4V_RN_3GPP_H263_PAYLOAD_MIME_TYPE) == 0)
  282. {
  283.     m_PayloadID = PYID_X_HX_3GPP_H263;
  284.     retVal = SetAssemblerHX3GPPH263Header(pHeader);
  285. }
  286.     }
  287.     if (SUCCEEDED(retVal))
  288.     {
  289. m_ulSamplesPerSecond = 0;
  290. m_pStreamHeader->GetPropertyULONG32("SamplesPerSecond",
  291.     m_ulSamplesPerSecond);
  292.     }
  293.     HX_RELEASE(pMimeType);
  294.     return retVal;
  295. }
  296. HX_RESULT MP4VPayloadFormat::SetAssembler3016Header(IHXValues* pHeader)
  297. {
  298.     ULONG32 ulTryIdx = 0;
  299.     char *pData = NULL;
  300.     IHXBuffer* pConfigBuffer = NULL;
  301.     char* pConfigStringData;
  302.     HX_RESULT retVal = HXR_NO_DATA;
  303.     retVal = CHXMP4PayloadUtil::GetFMTPConfig(pHeader, m_pClassFactory,
  304.       pConfigBuffer);
  305.     if (retVal == HXR_OK)
  306.     {
  307. m_ulVOLHeaderSize = pConfigBuffer->GetSize();
  308. if (m_ulVOLHeaderSize > 0)
  309. {
  310.     m_pVOLHeader = new UINT8 [m_ulVOLHeaderSize];
  311.     if (m_pVOLHeader)
  312.     {
  313. memcpy(m_pVOLHeader, pConfigBuffer->GetBuffer(),
  314.        m_ulVOLHeaderSize);
  315.     }
  316.     else
  317.     {
  318. m_ulVOLHeaderSize = 0;
  319. retVal = HXR_OUTOFMEMORY;
  320.     }
  321. }
  322.     }
  323.     HX_RELEASE(pConfigBuffer);
  324.     return retVal;
  325. }
  326. HX_RESULT MP4VPayloadFormat::SetAssemblerHXHeader(IHXValues* pHeader)
  327. {
  328.     ES_Descriptor ESDesc;
  329.     DecoderConfigDescriptor* pDCDesc = NULL;
  330.     DecoderSpecifcInfo* pDSIDesc = NULL;
  331.     IHXBuffer* pESDescriptor = NULL;
  332.     UINT8* pESDescData;
  333.     ULONG32 ulESDescSize;
  334.     HX_RESULT retVal = HXR_OK;
  335.     HX_VECTOR_DELETE(m_pVOLHeader);
  336.     m_ulVOLHeaderSize = 0;
  337.     retVal = m_pStreamHeader->GetPropertyBuffer("OpaqueData",
  338. pESDescriptor);
  339.     if (SUCCEEDED(retVal))
  340.     {
  341. retVal = HXR_INVALID_PARAMETER;
  342. if (pESDescriptor)
  343. {
  344.     retVal = HXR_OK;
  345. }
  346.     }
  347.     if (SUCCEEDED(retVal))
  348.     {
  349. pESDescData = pESDescriptor->GetBuffer();
  350. ulESDescSize = pESDescriptor->GetSize();
  351. retVal = ESDesc.Unpack(pESDescData, ulESDescSize);
  352.     }
  353.     HX_RELEASE(pESDescriptor);
  354.     if (SUCCEEDED(retVal))
  355.     {
  356. retVal = HXR_FAIL;
  357. pDCDesc = ESDesc.m_pDecConfigDescr;
  358. if (pDCDesc)
  359. {
  360.     pDSIDesc = pDCDesc->m_pDecSpecificInfo;
  361.     retVal = HXR_OK;
  362. }
  363.     }
  364.     if (SUCCEEDED(retVal) && pDSIDesc)
  365.     {
  366. m_ulVOLHeaderSize = pDSIDesc->m_ulLength;
  367. if (m_ulVOLHeaderSize > 0)
  368. {
  369.     m_pVOLHeader = new UINT8 [m_ulVOLHeaderSize];
  370.     if (m_pVOLHeader == NULL)
  371.     {
  372. m_ulVOLHeaderSize = 0;
  373. retVal = HXR_OUTOFMEMORY;
  374.     }
  375. }
  376.     }
  377.     if (SUCCEEDED(retVal))
  378.     {
  379. if (m_ulVOLHeaderSize > 0)
  380. {
  381.     memcpy(m_pVOLHeader, pDSIDesc->m_pData, m_ulVOLHeaderSize); /* Flawfinder: ignore */
  382. }
  383.     }
  384.     return retVal;
  385. }
  386. HX_RESULT MP4VPayloadFormat::SetAssemblerHX3GPPH263Header(IHXValues* pHeader)
  387. {
  388.     HX_RESULT retVal = HXR_OK;
  389.     // We'll let H263 decoder initialize with in-band bitstream
  390.     HX_VECTOR_DELETE(m_pVOLHeader);
  391.     m_ulVOLHeaderSize = 0;
  392.     return retVal;
  393. }
  394. STDMETHODIMP
  395. MP4VPayloadFormat::GetStreamHeader(REF(IHXValues*) pHeader)
  396. {
  397.     HX_ASSERT(m_pStreamHeader);
  398.     pHeader = m_pStreamHeader;
  399.     pHeader->AddRef();
  400.     return HXR_OK;
  401. }
  402. STDMETHODIMP
  403. MP4VPayloadFormat::SetPacket(IHXPacket* pPacket)
  404. {
  405.     HX_RESULT retVal;
  406.     HX_ASSERT(pPacket);
  407.     if (!m_bRTPPacketTested)
  408.     {
  409. IHXRTPPacket* pRTPPacket = NULL;
  410. m_bUsesRTPPackets = (pPacket->QueryInterface(
  411. IID_IHXRTPPacket,
  412. (void**) &pRTPPacket)
  413.     == HXR_OK);
  414. m_bRTPPacketTested = TRUE;
  415. HX_RELEASE(pRTPPacket);
  416. if (!m_bUsesRTPPackets)
  417. {
  418.     m_ulSamplesPerSecond = 1000; // RDT time stamp
  419. }
  420. HX_ASSERT(m_ulSamplesPerSecond != 0);
  421. m_TSConverter.SetBase(m_ulSamplesPerSecond,
  422.       1000);
  423.     }
  424.     // Add this packet to our list of input packets
  425.     pPacket->AddRef();
  426.     m_InputPackets.AddTail(pPacket);
  427.     if (m_bPacketize)
  428.     {
  429. retVal = SetPacketizerPacket(pPacket);
  430.     }
  431.     else
  432.     {
  433. retVal = SetAssemblerPacket(pPacket);
  434.     }
  435.     return retVal;
  436. }
  437. HX_RESULT MP4VPayloadFormat::SetPacketizerPacket(IHXPacket* pPacket)
  438. {
  439.     if (m_bFirstFrame)
  440.     {
  441. m_bFirstFrame = FALSE;
  442.     }
  443.     return HXR_OK;
  444. }
  445. HX_RESULT MP4VPayloadFormat::SetAssemblerPacket(IHXPacket* pPacket)
  446. {
  447.     BOOL bNewPictureStart;
  448.     if (!pPacket->IsLost())
  449.     {
  450. bNewPictureStart = IsPictureStart(pPacket);
  451. if (m_bFirstPacket)
  452. {
  453.     m_bFirstPacket = FALSE;
  454.     m_ulFrameTime = GetPacketTime(pPacket);
  455. }
  456. if ((GetPacketTime(pPacket) != m_ulFrameTime) ||
  457.     (bNewPictureStart && m_bPictureStarted))
  458. {
  459.     m_ulFrameCount++;
  460.     m_ulFrameTime = GetPacketTime(pPacket);
  461. }
  462. if (pPacket->GetASMRuleNumber() == 1)
  463. {
  464.     m_ulFrameCount++;
  465.     m_bFirstPacket = TRUE;
  466.     m_bPictureStarted = FALSE;
  467. }
  468. else if (!m_bPictureStarted)
  469. {
  470.     m_bPictureStarted = bNewPictureStart;
  471. }
  472.     }
  473.     return HXR_OK;
  474. }
  475. STDMETHODIMP
  476. MP4VPayloadFormat::GetPacket(REF(IHXPacket*) pOutPacket)
  477. {
  478.     HX_RESULT retVal = HXR_OK;
  479.     IHXPacket* pPacket = NULL;
  480.     if (m_InputPackets.IsEmpty())
  481.     {
  482. if (m_bFlushed)
  483. {
  484.     // We have used up all available input
  485.     retVal = HXR_STREAM_DONE;
  486. }
  487. else
  488. {
  489.     // We don't have enough input
  490.     // data to produce a packet
  491.     retVal = HXR_INCOMPLETE;
  492. }
  493.     }
  494.     else
  495.     {
  496. if (m_bPacketize)
  497. {
  498.     retVal = GetPacketizerPacket(pOutPacket);
  499. }
  500. else
  501. {
  502.     retVal = GetAssemblerPacket(pOutPacket);
  503. }
  504.     }
  505.     return retVal;
  506. }
  507. HX_RESULT MP4VPayloadFormat::GetPacketizerPacket(IHXPacket* &pOutPacket)
  508. {
  509.     HX_RESULT retVal = HXR_INCOMPLETE;
  510.     if (m_OutputPackets.GetCount() > 0)
  511.     {
  512. pOutPacket = (IHXPacket*) m_OutputPackets.RemoveHead();
  513. retVal = HXR_OK;
  514.     }
  515.     if (retVal == HXR_INCOMPLETE)
  516.     {
  517. IHXPacket* pRawPacket = NULL;
  518. do
  519. {
  520.     HX_RELEASE(pRawPacket);
  521.     retVal = GetRawPacketizerPacket(pRawPacket);
  522. } while ((retVal == HXR_OK) && (!IsValidPacket(pRawPacket)));
  523. if (retVal == HXR_OK)
  524. {
  525.     retVal = FragmentPacket(pRawPacket);
  526.     pRawPacket->Release();
  527. }
  528. if (retVal == HXR_OK)
  529. {
  530.     HX_ASSERT(m_OutputPackets.GetCount() > 0);
  531.     retVal = HXR_INCOMPLETE;
  532.     if (m_OutputPackets.GetCount() > 0)
  533.     {
  534. pOutPacket = (IHXPacket*) m_OutputPackets.RemoveHead();
  535. retVal = HXR_OK;
  536.     }
  537. }
  538.     }
  539.     return retVal;
  540. }
  541. HX_RESULT MP4VPayloadFormat::FragmentPacket(IHXPacket* pPacket)
  542. {
  543.     HX_RESULT retVal = HXR_OK;
  544.     IHXBuffer* pPacketBuffer = pPacket->GetBuffer();
  545.     ULONG32 ulRemainingSize = pPacketBuffer->GetSize();
  546.     if (ulRemainingSize > m_ulMaxPacketDataSize)
  547.     {
  548. UINT8* pRemainingData = pPacketBuffer->GetBuffer();
  549. ULONG32 ulFragmentSize = m_ulMaxPacketDataSize;
  550. IHXPacket* pNewPacket = NULL;
  551. IHXBuffer* pNewBuffer = NULL;
  552. IHXRTPPacket* pRTPPacket = NULL;
  553. if (m_bUsesRTPPackets)
  554. {
  555.     if (SUCCEEDED(retVal))
  556.     {
  557. retVal = pPacket->QueryInterface(IID_IHXRTPPacket,
  558.     (void**) &pRTPPacket);
  559.     }
  560. }
  561. do
  562. {
  563.     // Create new packet
  564.     if (SUCCEEDED(retVal))
  565.     {
  566. if (m_bUsesRTPPackets)
  567. {
  568.     retVal = m_pClassFactory->CreateInstance(CLSID_IHXRTPPacket,
  569.      (void**) &pNewPacket);
  570. }
  571. else
  572. {
  573.     retVal = m_pClassFactory->CreateInstance(CLSID_IHXPacket,
  574.      (void**) &pNewPacket);
  575. }
  576.     }
  577.     // Create new buffer
  578.     if (SUCCEEDED(retVal))
  579.     {
  580. retVal = m_pClassFactory->CreateInstance(CLSID_IHXBuffer,
  581.  (void**) &pNewBuffer);
  582.     }
  583.     // Set Buffer
  584.     if (SUCCEEDED(retVal))
  585.     {
  586. retVal = pNewBuffer->Set(pRemainingData, ulFragmentSize);
  587.     }
  588.     // Set the new packet
  589.     if (SUCCEEDED(retVal))
  590.     {
  591. if (SUCCEEDED(retVal))
  592. {
  593.     if (m_bUsesRTPPackets)
  594.     {
  595. retVal = ((IHXRTPPacket*) pNewPacket)->SetRTP(
  596.     pNewBuffer,
  597.     pRTPPacket->GetTime(),
  598.     pRTPPacket->GetRTPTime(),
  599.     pRTPPacket->GetStreamNumber(),
  600.     pRTPPacket->GetASMFlags(),
  601.     (ulRemainingSize > m_ulMaxPacketDataSize) ?
  602. 0 : pRTPPacket->GetASMRuleNumber());
  603.     }
  604.     else
  605.     {
  606. retVal = ((IHXRTPPacket*) pNewPacket)->Set(
  607.     pNewBuffer,
  608.     pPacket->GetTime(),
  609.     pPacket->GetStreamNumber(),
  610.     pPacket->GetASMFlags(),
  611.     (ulRemainingSize > m_ulMaxPacketDataSize) ?
  612. 0 : pPacket->GetASMRuleNumber());
  613.     }
  614. }
  615.     }
  616.     pRemainingData += ulFragmentSize;
  617.     ulRemainingSize -= ulFragmentSize;
  618.     if (ulRemainingSize < ulFragmentSize)
  619.     {
  620. ulFragmentSize = ulRemainingSize;
  621.     }
  622.     if (SUCCEEDED(retVal))
  623.     {
  624. pNewPacket->AddRef();
  625. m_OutputPackets.AddTail(pNewPacket);
  626.     }
  627.     HX_RELEASE(pNewBuffer);
  628.     HX_RELEASE(pNewPacket);
  629. } while (SUCCEEDED(retVal) && (ulRemainingSize > 0));
  630. HX_RELEASE(pRTPPacket);
  631.     }
  632.     else
  633.     {
  634. pPacket->AddRef();
  635. m_OutputPackets.AddTail(pPacket);
  636.     }
  637.     HX_RELEASE(pPacketBuffer);
  638.     return retVal;
  639. }
  640. HX_RESULT MP4VPayloadFormat::GetRawPacketizerPacket(IHXPacket* &pOutPacket)
  641. {
  642.     IHXPacket* pPacket;
  643.     IHXPacket* pAfterPacket = NULL;
  644.     IHXRTPPacket* pRTPPacket = NULL;
  645.     UINT16 uASMRuleNumber;
  646.     BOOL bMarker = TRUE;
  647.     BOOL bNewPictureStart = TRUE;
  648.     HX_RESULT retVal = HXR_INCOMPLETE;
  649.     if ((m_InputPackets.GetCount() > 1) ||
  650. m_bFlushed)
  651.     {
  652. retVal = HXR_OK;
  653. pPacket = (IHXPacket*) m_InputPackets.RemoveHead();
  654. if (!m_bPictureStarted)
  655. {
  656.     m_bPictureStarted = IsPictureStart(pPacket);
  657. }
  658. if (m_bFirstPacket)
  659. {
  660.     m_bFirstPacket = FALSE;
  661. }
  662. // Determine marker usage
  663. if (m_InputPackets.GetCount() > 0)
  664. {
  665.     pAfterPacket = (IHXPacket*) m_InputPackets.GetHead();
  666. }
  667. if (pAfterPacket)
  668. {
  669.     bNewPictureStart = IsPictureStart(pAfterPacket);
  670.     bMarker = ((GetPacketTime(pPacket) != GetPacketTime(pAfterPacket)) ||
  671.        (bNewPictureStart && m_bPictureStarted));
  672.     if (bMarker)
  673.     {
  674. m_bPictureStarted = bNewPictureStart;
  675.     }
  676. }
  677. else
  678. {
  679.     bMarker = m_bFlushed;
  680. }
  681. uASMRuleNumber = bMarker ? 1 : 0;
  682. // If rule number must change, create new packet
  683. if (uASMRuleNumber != pPacket->GetASMRuleNumber())
  684. {
  685.     IHXPacket* pNewPacket = NULL;
  686.     if (m_bUsesRTPPackets)
  687.     {
  688. retVal = m_pClassFactory->CreateInstance(CLSID_IHXRTPPacket,
  689.  (void**) &pNewPacket);
  690. if (SUCCEEDED(retVal))
  691. {
  692.     retVal = pPacket->QueryInterface(IID_IHXRTPPacket,
  693.      (void**) &pRTPPacket);
  694. }
  695.     }
  696.     else
  697.     {
  698. retVal = m_pClassFactory->CreateInstance(CLSID_IHXPacket,
  699.  (void**) &pNewPacket);
  700.     }
  701.     if (SUCCEEDED(retVal))
  702.     {
  703. IHXBuffer* pBuffer = pPacket->GetBuffer();
  704. if (m_bUsesRTPPackets)
  705. {
  706.     retVal = ((IHXRTPPacket*) pNewPacket)->SetRTP(
  707. pBuffer,
  708. pRTPPacket->GetTime(),
  709. pRTPPacket->GetRTPTime(),
  710. pRTPPacket->GetStreamNumber(),
  711. pRTPPacket->GetASMFlags(),
  712. uASMRuleNumber);
  713. }
  714. else
  715. {
  716.     retVal = ((IHXRTPPacket*) pNewPacket)->Set(
  717. pBuffer,
  718. pPacket->GetTime(),
  719. pPacket->GetStreamNumber(),
  720. pPacket->GetASMFlags(),
  721. uASMRuleNumber);
  722. }
  723. HX_RELEASE(pBuffer);
  724.     }
  725.     pPacket->Release();
  726.     pPacket = NULL;
  727.     if (SUCCEEDED(retVal))
  728.     {
  729. pPacket = pNewPacket;
  730. pNewPacket = NULL;
  731.     }
  732.     HX_RELEASE(pNewPacket);
  733.     HX_RELEASE(pRTPPacket);
  734. }
  735. if (SUCCEEDED(retVal))
  736. {
  737.     pOutPacket = pPacket;
  738. }
  739.     }
  740.     return retVal;
  741. }
  742. HX_RESULT MP4VPayloadFormat::GetAssemblerPacket(IHXPacket* &pOutPacket)
  743. {
  744.     HX_RESULT retVal = HXR_NOTIMPL;
  745.     return retVal;
  746. }
  747. void MP4VPayloadFormat::FlushPackets(ULONG32 ulCount)
  748. {
  749.     IHXPacket* pDeadPacket;
  750.     while ((ulCount > 0) && (!m_InputPackets.IsEmpty()))
  751.     {
  752. pDeadPacket = (IHXPacket*) m_InputPackets.RemoveHead();
  753. HX_RELEASE(pDeadPacket);
  754. if (ulCount != FLUSH_ALL_PACKETS)
  755. {
  756.     ulCount--;
  757. }
  758.     }
  759. }
  760. ULONG32 MP4VPayloadFormat::CountValidPackets(ULONG32 ulCount)
  761. {
  762.     IHXPacket* pPacket;
  763.     LISTPOSITION listPos;
  764.     ULONG32 ulValidCount = 0;
  765.     listPos = m_InputPackets.GetHeadPosition();
  766.     while ((ulCount > 0) && (listPos != NULL))
  767.     {
  768. pPacket = (IHXPacket*) m_InputPackets.GetNext(listPos);
  769. HX_ASSERT(pPacket);
  770. if (!pPacket->IsLost())
  771. {
  772.     ulValidCount++;
  773. }
  774. ulCount--;
  775.     }
  776.     return ulValidCount;
  777. }
  778. ULONG32 MP4VPayloadFormat::SumPacketSizes(ULONG32 ulCount)
  779. {
  780.     IHXPacket* pPacket;
  781.     IHXBuffer* pBuffer;
  782.     LISTPOSITION listPos;
  783.     ULONG32 ulSize = 0;
  784.     listPos = m_InputPackets.GetHeadPosition();
  785.     while ((ulCount > 0) && (listPos != NULL))
  786.     {
  787. pPacket = (IHXPacket*) m_InputPackets.GetNext(listPos);
  788. HX_ASSERT(pPacket);
  789. if (!pPacket->IsLost())
  790. {
  791.     pBuffer = pPacket->GetBuffer();
  792.     if (pBuffer)
  793.     {
  794. ulSize += pBuffer->GetSize();
  795. pBuffer->Release();
  796.     }
  797. }
  798. ulCount--;
  799.     }
  800.     return ulSize;
  801. }
  802. HX_RESULT MP4VPayloadFormat::CreateHXCodecPacket(UINT32* &pHXCodecDataOut)
  803. {
  804.     HX_RESULT retVal = HXR_INCOMPLETE;
  805.     if (m_ulFrameCount > 0)
  806.     {
  807. // Compute frame size and count segments
  808. ULONG32 ulFrameSize = 0;
  809. ULONG32 ulSegmentCount = 0;
  810. ULONG32 ulSegmentSize;
  811. ULONG32 ulFrameTime = 0;
  812. ULONG32 ulValidSegmentCount = 0;
  813. IHXPacket* pPacket;
  814. IHXBuffer* pBuffer = NULL;
  815. LISTPOSITION listPos;
  816. ULONG32 ulIdx;
  817. BOOL bIsLost;
  818. BOOL bPictureStarted = FALSE;
  819. BOOL bNewPictureStart;
  820. HXCODEC_DATA* pHXCodecData = NULL;
  821. HXCODEC_SEGMENTINFO* pHXCodecSegmentInfo;
  822. ULONG32* pData = NULL;
  823. retVal = HXR_OK;
  824. // Gather Frame Information - until valid frame detected
  825. do
  826. {
  827.     listPos = m_InputPackets.GetHeadPosition();
  828.             if( listPos == NULL )
  829.             {
  830.                 return HXR_OUTOFMEMORY;
  831.             }
  832.     do
  833.     {
  834. if (ulSegmentCount >= MAX_FRAME_SEGMENTS)
  835. {
  836.     HX_ASSERT(pPacket);
  837.     FlushPackets(ulSegmentCount - NUM_OVERLAP_SEGMENTS);
  838.     ulSegmentCount = NUM_OVERLAP_SEGMENTS;
  839.     ulFrameSize = SumPacketSizes(NUM_OVERLAP_SEGMENTS);
  840.     ulValidSegmentCount = CountValidPackets(NUM_OVERLAP_SEGMENTS);
  841. }
  842. pPacket = (IHXPacket*) m_InputPackets.GetNext(listPos);
  843. if (!pPacket->IsLost())
  844. {
  845.     bNewPictureStart = IsPictureStart(pPacket);
  846.     if (ulValidSegmentCount > 0)
  847.     {
  848. if ((GetPacketTime(pPacket) != ulFrameTime) ||
  849.     (bPictureStarted && bNewPictureStart))
  850. {
  851.     break;
  852. }
  853.     }
  854.     else
  855.     {
  856. ulFrameTime = GetPacketTime(pPacket);
  857.     }
  858.     if (!bPictureStarted)
  859.     {
  860. bPictureStarted = bNewPictureStart;
  861.     }
  862.     ulValidSegmentCount++;
  863.     pBuffer = pPacket->GetBuffer();
  864. }
  865. if (pBuffer)
  866. {
  867.     ulFrameSize += pBuffer->GetSize();
  868.     pBuffer->Release();
  869.     pBuffer = NULL;
  870. }
  871. ulSegmentCount++;
  872.     } while (pPacket->GetASMRuleNumber() != 1);
  873.     m_ulFrameCount--;
  874. } while ((ulValidSegmentCount == 0) &&
  875.  (m_ulFrameCount > 0));
  876. if (ulValidSegmentCount == 0)
  877. {
  878.     retVal = HXR_INCOMPLETE;
  879. }
  880. // Allocate codec data header
  881. if (retVal == HXR_OK)
  882. {
  883.     HX_ASSERT(ulSegmentCount != 0);
  884.     HX_ASSERT(ulValidSegmentCount != 0);
  885. #ifdef _APPEND_VOL_HEADER
  886.     if (m_bFirstFrame)
  887.     {
  888. ulFrameSize += m_ulVOLHeaderSize;
  889.     }
  890. #endif // _APPEND_VOL_HEADER
  891.     pData = new ULONG32[(sizeof(HXCODEC_DATA) +
  892.          sizeof(HXCODEC_SEGMENTINFO) *
  893.          (ulSegmentCount - 1)) / 4 + 1];
  894.     retVal = HXR_OUTOFMEMORY;
  895.     if (pData)
  896.     {
  897. retVal = HXR_OK;
  898.     }
  899. }
  900. // Init. codec data header
  901. if (retVal == HXR_OK)
  902. {
  903.     pHXCodecData = (HXCODEC_DATA*) pData;
  904.     pHXCodecData->dataLength = ulFrameSize;
  905.     pHXCodecData->timestamp = ulFrameTime;
  906.     pHXCodecData->sequenceNum = m_uSeqNumber;
  907.     pHXCodecData->flags = 0;
  908.     pHXCodecData->lastPacket = FALSE;
  909.     pHXCodecData->numSegments = ulSegmentCount;
  910.     pHXCodecData->data = NULL;
  911.     if ((ulFrameSize > 0)
  912. #ifndef _OVERALLOC_CODEC_DATA
  913. &&
  914. (
  915.  (ulValidSegmentCount > 1) ||
  916.  (m_pAllocator == NULL)
  917. #ifdef _APPEND_VOL_HEADER
  918.  || m_bFirstFrame
  919. #endif // _APPEND_VOL_HEADER
  920.         )
  921. #endif // _OVERALLOC_CODEC_DATA
  922.        )
  923.     {
  924. #ifdef _OVERALLOC_CODEC_DATA
  925. ulFrameSize += _OVERALLOC_CODEC_DATA;   // over allocate since codec reads 24bits at a time
  926. #endif // _OVERALLOC_CODEC_DATA
  927. if (m_pAllocator)
  928. {
  929.     IHXUnknown* pIUnkn = NULL;
  930.     HX20ALLOCPROPS allocRequest;
  931.     HX20ALLOCPROPS allocActual;
  932.     allocRequest.uBufferSize = ulFrameSize;
  933.     allocRequest.nNumBuffers = 0;
  934.     m_pAllocator->SetProperties(&allocRequest, &allocActual);
  935.     pHXCodecData->data = m_pAllocator->GetPacketBuffer(&pIUnkn);
  936. }
  937. else
  938. {
  939.     pHXCodecData->data = (UINT8*) new ULONG32 [ulFrameSize / 4 + 1];
  940. }
  941. if (pHXCodecData->data == NULL)
  942. {
  943.     retVal = HXR_OUTOFMEMORY;
  944. }
  945.     }
  946. }
  947. // Build Codec Data
  948. if (retVal == HXR_OK)
  949. {
  950.     BOOL bNoneLost = TRUE;
  951.     pHXCodecSegmentInfo = (HXCODEC_SEGMENTINFO*) &(pHXCodecData->Segments[0]);
  952.     ulFrameSize = 0;
  953.     for (ulIdx = 0; ulIdx < ulSegmentCount; ulIdx++)
  954.     {
  955. HX_ASSERT(!m_InputPackets.IsEmpty());
  956. pPacket = (IHXPacket*) m_InputPackets.RemoveHead();
  957. HX_ASSERT(pPacket);
  958. ulSegmentSize = 0;
  959. pHXCodecSegmentInfo[ulIdx].ulSegmentOffset = ulFrameSize;
  960. bIsLost = pPacket->IsLost();
  961. if (!bIsLost)
  962. {
  963.     pBuffer = pPacket->GetBuffer();
  964.     if (pHXCodecData->data)
  965.     {
  966. if (m_bFirstFrame)
  967. {
  968. #ifdef _APPEND_VOL_HEADER
  969.     memcpy(pHXCodecData->data, m_pVOLHeader, m_ulVOLHeaderSize); /* Flawfinder: ignore */
  970.     ulFrameSize += m_ulVOLHeaderSize;
  971. #endif // _APPEND_VOL_HEADER
  972.     m_bFirstFrame = FALSE;
  973. }
  974. if (pBuffer)
  975. {
  976.     ulSegmentSize = pBuffer->GetSize();
  977.     HX_ASSERT(pHXCodecData->dataLength >= (ulFrameSize + ulSegmentSize));
  978.     memcpy(pHXCodecData->data + ulFrameSize, /* Flawfinder: ignore */
  979.    pBuffer->GetBuffer(),
  980.    ulSegmentSize);
  981.     pBuffer->Release();
  982. }
  983.     }
  984.     else
  985.     {
  986. HX_ASSERT(m_pAllocator);
  987. HX_ASSERT(ulValidSegmentCount == 1);
  988. #ifdef _APPEND_VOL_HEADER
  989. HX_ASSERT(m_bFirstFrame == FALSE);
  990. #endif // _APPEND_VOL_HEADER
  991. if (pBuffer)
  992. {
  993.     ulSegmentSize = pBuffer->GetSize();
  994.     pHXCodecData->data = m_pAllocator->AddBuffer(pBuffer);
  995.     pBuffer->Release();
  996. }
  997.     }
  998.     ulFrameSize += ulSegmentSize;
  999. }
  1000. pHXCodecSegmentInfo[ulIdx].bIsValid = !bIsLost;
  1001. bNoneLost = (bNoneLost && (!bIsLost));
  1002. pPacket->Release();
  1003.     }
  1004.     if (bNoneLost)
  1005.     {
  1006. pHXCodecData->numSegments = 1;
  1007.     }
  1008. #ifdef _ASSERT_ON_LOSS
  1009.     else
  1010.     {
  1011. HX_ASSERT(FALSE);
  1012.     }
  1013. #endif // _ASSERT_ON_LOSS
  1014. #ifdef _DONOT_SEGMENT
  1015.     pHXCodecData->numSegments = 1;
  1016.     pHXCodecSegmentInfo[0].bIsValid = bNoneLost;
  1017. #endif // _DONOT_SEGMENT
  1018. }
  1019. // Finalize Results
  1020. if (retVal == HXR_OK)
  1021. {
  1022.     pHXCodecDataOut = pData;
  1023. }
  1024. else
  1025. {
  1026.     if (pHXCodecData && pHXCodecData->data)
  1027.     {
  1028. m_pAllocator->ReleasePacketPtr(pHXCodecData->data);
  1029.     }
  1030.     HX_VECTOR_DELETE(pData);
  1031. }
  1032. #ifdef _DUMP_FIRST_NFRAMES
  1033. if (m_uSeqNumber < _DUMP_FIRST_NFRAMES)
  1034. {
  1035.     char pFileName[100]; /* Flawfinder: ignore */
  1036.     SafeSprintf(pFileName, 100, "%s%d", "c:\fframe.bin", m_uSeqNumber);
  1037.     FILE* pFile = fopen(pFileName, "wb");
  1038.     if (pFile)
  1039.     {
  1040. fprintf(pFile, "T=%ld;B=%ld:", pHXCodecData->timestamp, pHXCodecData->dataLength);
  1041. fwrite(pHXCodecData->data, sizeof(UINT8), pHXCodecData->dataLength, pFile);
  1042. fclose(pFile);
  1043.     }
  1044. }
  1045. #endif // _DUMP_FIRST_NFRAMES
  1046. m_uSeqNumber++;
  1047.     }
  1048.     return retVal;
  1049. }
  1050. STDMETHODIMP
  1051. MP4VPayloadFormat::Flush()
  1052. {
  1053.     m_bFlushed = TRUE;
  1054.     return HXR_OK;
  1055. }
  1056. BOOL MP4VPayloadFormat::IsPictureStart(IHXPacket* pPacket)
  1057. {
  1058.     if (m_PayloadID == PYID_X_HX_MP4)
  1059.     {
  1060. ULONG32 ulIdx;
  1061. ULONG32 ulSize = 0;
  1062. UINT8* pData = NULL;
  1063. IHXBuffer* pBuffer;
  1064. pBuffer = pPacket->GetBuffer();
  1065. if (pBuffer)
  1066. {
  1067.     ulSize = pBuffer->GetSize();
  1068.     if (ulSize >= 4)
  1069.     {
  1070. ulSize -= 4;
  1071. pData = pBuffer->GetBuffer();
  1072.     }
  1073.     pBuffer->Release();
  1074. }
  1075. if (pData)
  1076. {
  1077.     ulIdx = 0;
  1078.     do
  1079.     {
  1080. if (pData[ulIdx++] == 0x00)
  1081. {
  1082.     if (pData[ulIdx++] == 0x00)
  1083.     {
  1084. if (pData[ulIdx] == 0x01)
  1085. {
  1086.     ulIdx++;
  1087.     if (pData[ulIdx] == 0xb6)
  1088.     {
  1089. return TRUE;
  1090.     }
  1091. }
  1092. else
  1093. {
  1094.     ulIdx--;
  1095. }
  1096.     }
  1097. }
  1098.     } while (ulIdx < ulSize);
  1099. }
  1100.     }
  1101.     return FALSE;
  1102. }
  1103. BOOL MP4VPayloadFormat::IsValidPacket(IHXPacket* pPacket)
  1104. {
  1105.     if (m_PayloadID == PYID_X_HX_MP4)
  1106.     {
  1107. ULONG32 ulSize;
  1108. UINT8* pData = NULL;
  1109. IHXBuffer* pBuffer = pPacket->GetBuffer();
  1110. if (pBuffer)
  1111. {
  1112.     ulSize = pBuffer->GetSize();
  1113.     if (ulSize >= 4)
  1114.     {
  1115. ulSize -= 4;
  1116. pData = pBuffer->GetBuffer();
  1117.     }
  1118.     pBuffer->Release();
  1119. }
  1120. if (pData)
  1121. {
  1122.     // Should be more sophisiticated here and fully parse the
  1123.     // headeres and make sure there is no data of substance
  1124.     // following the headers - for this prototype code it
  1125.     // is good enough
  1126.     if ((pData[0] == 0x00) &&
  1127. (pData[1] == 0x00) &&
  1128. (pData[2] == 0x01) &&
  1129. ((pData[3] == 0x00) ||
  1130. (pData[3] == 0x20)))
  1131.     {
  1132. return FALSE;
  1133.     }
  1134. }
  1135.     }
  1136.     return TRUE;
  1137. }
  1138. ULONG32 MP4VPayloadFormat::GetPacketTime(IHXPacket* pPacket)
  1139. {
  1140.     ULONG32 ulTime;
  1141.     HX_ASSERT(pPacket);
  1142.     if (m_bUsesRTPPackets && (m_ulSamplesPerSecond != 0))
  1143.     {
  1144. ulTime = ((IHXRTPPacket*) pPacket)->GetRTPTime();
  1145. ulTime = m_TSConverter.Convert(ulTime);
  1146.     }
  1147.     else
  1148.     {
  1149. ulTime = pPacket->GetTime();
  1150.     }
  1151.     return ulTime;
  1152. }