vbrdepack.cpp
Upload User: dangjiwu
Upload Date: 2013-07-19
Package Size: 42019k
Code Size: 23k
Category:

Symbian

Development Platform:

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. #include "hxtypes.h"
  36. #include "hxcom.h"
  37. #include "ihxpckts.h"
  38. #include "hxcomm.h"
  39. #include "hxslist.h"
  40. #include "vbrdepack.h"
  41. CVBRSimpleDepacketizer::CVBRSimpleDepacketizer()
  42. {
  43.     m_pCommonClassFactory       = NULL;
  44.     m_pFragQueue                = NULL;
  45.     m_pOutputQueue              = NULL;
  46.     m_dAUDuration               = 0.0;
  47.     m_usStreamNum               = 0;
  48.     m_usKeyFrameRuleNum         = 0;
  49.     m_ulLastQueuedPacketEndTime = 0;
  50.     m_bSeeked                   = FALSE;
  51.     m_bGenerateLossPackets      = TRUE;
  52. }
  53. CVBRSimpleDepacketizer::~CVBRSimpleDepacketizer()
  54. {
  55.     ClearQueue(m_pFragQueue);
  56.     ClearQueue(m_pOutputQueue);
  57.     HX_RELEASE(m_pCommonClassFactory);
  58.     HX_DELETE(m_pFragQueue);
  59.     HX_DELETE(m_pOutputQueue);
  60. }
  61. HX_RESULT CVBRSimpleDepacketizer::Init(IUnknown* pContext, double dAUDuration,
  62.                                        UINT16 usStreamNum, UINT16 usKeyFrameRuleNum,
  63.                                        BOOL bGenerateLossPackets)
  64. {
  65.     HX_RESULT retVal = HXR_FAIL;
  66.     if (pContext)
  67.     {
  68.         // Save the AU duration
  69.         m_dAUDuration = dAUDuration;
  70.         // Save the stream num
  71.         m_usStreamNum = usStreamNum;
  72.         // Save the keyframe rule num
  73.         m_usKeyFrameRuleNum = usKeyFrameRuleNum;
  74.         // Save the loss packets flag
  75.         m_bGenerateLossPackets = bGenerateLossPackets;
  76.         // Get the common class factory
  77.         HX_RELEASE(m_pCommonClassFactory);
  78.         retVal = pContext->QueryInterface(IID_IHXCommonClassFactory,
  79.                                           (void**) &m_pCommonClassFactory);
  80.         if (SUCCEEDED(retVal))
  81.         {
  82.             // Zero out the last queued packet end time
  83.             m_ulLastQueuedPacketEndTime = 0;
  84.             // Clear the seeked flag
  85.             m_bSeeked = FALSE;
  86.         }
  87.     }
  88.     return retVal;
  89. }
  90. HX_RESULT CVBRSimpleDepacketizer::PutPacket(IHXPacket* pPacket)
  91. {
  92.     HX_RESULT retVal = HXR_FAIL;
  93.     if (pPacket)
  94.     {
  95.         // Is the packet lost?
  96.         if (!pPacket->IsLost())
  97.         {
  98.             // Get the IHXBuffer
  99.             IHXBuffer* pBuffer = pPacket->GetBuffer();
  100.             if (pBuffer)
  101.             {
  102.                 // Get the buffer
  103.                 BYTE* pBuf = pBuffer->GetBuffer();
  104.                 if (pBuf)
  105.                 {
  106.                     // Parse the packet
  107.                     UINT32 ulNumAU     = 0;
  108.                     BOOL   bFragmented = FALSE;
  109.                     retVal = ParseVBRPacket(pBuf, pBuffer->GetSize(), ulNumAU, bFragmented);
  110.                     if (SUCCEEDED(retVal))
  111.                     {
  112.                         // Check if we have a gap in timestamps. However, if
  113.                         // we seeked we don't want to interpret this as a
  114.                         // gap in timestamps
  115.                         if (pPacket->GetTime() > (m_ulLastQueuedPacketEndTime + TIMESTAMP_GAP_FUDGE_FACTOR) &&
  116.                             !m_bSeeked)
  117.                         {
  118.                             // We probably had some loss, so we need to queue
  119.                             // some loss packets
  120.                             if (m_bGenerateLossPackets)
  121.                             {
  122.                                 retVal = GenerateAndQueueLossPackets(m_ulLastQueuedPacketEndTime,
  123.                                                                      pPacket->GetTime());
  124.                             }
  125.                             if (SUCCEEDED(retVal))
  126.                             {
  127.                                 // Update the last queued packet end time
  128.                                 m_ulLastQueuedPacketEndTime = pPacket->GetTime();
  129.                             }
  130.                         }
  131.                         // If m_bSeeked == TRUE, then this is the
  132.                         // first packet we've received after the seek.
  133.                         if (m_bSeeked)
  134.                         {
  135.                             // Clear the frag queue
  136.                             ClearQueue(m_pFragQueue);
  137.                             // Set the last queued packet end time to be
  138.                             // the current time. Otherwise, if this packet
  139.                             // is a fragmented packet, then the next packet
  140.                             // will be interpreted as loss.
  141.                             m_ulLastQueuedPacketEndTime = pPacket->GetTime();
  142.                             // Clear the seek flag
  143.                             m_bSeeked = FALSE;
  144.                         }
  145.                         // Is this a fragmented AU?
  146.                         if (bFragmented)
  147.                         {
  148.                             // Remove any packets from the frag queue
  149.                             // which do not have the same timestamp 
  150.                             // as this packet. These were probably packets
  151.                             // which were left over from a previous lost
  152.                             // fragmented AU.
  153.                             RemoveDifferingPackets(pPacket->GetTime());
  154.                             // If this is a fragmented packet, then we
  155.                             // add it to the frag queue
  156.                             retVal = AddToQueue(m_pFragQueue, pPacket);
  157.                             if (SUCCEEDED(retVal))
  158.                             {
  159.                                 // Attempt to defrag the AU from the packets
  160.                                 // on the frag queue
  161.                                 if (CanDefrag())
  162.                                 {
  163.                                     IHXPacket* pOutPacket = NULL;
  164.                                     retVal = Defrag(pOutPacket);
  165.                                     if (SUCCEEDED(retVal))
  166.                                     {
  167.                                         // We successfully generated a defragmented
  168.                                         // packet, so we can clear the frag queue
  169.                                         ClearQueue(m_pFragQueue);
  170.                                         // Add the packet to the output queue
  171.                                         retVal = AddToQueue(m_pOutputQueue, pOutPacket);
  172.                                         if (SUCCEEDED(retVal))
  173.                                         {
  174.                                             // Set the end time of the last packet
  175.                                             // that we put in the output queue
  176.                                             m_ulLastQueuedPacketEndTime = pOutPacket->GetTime() + ((UINT32) m_dAUDuration);
  177.                                         }
  178.                                     }
  179.                                     HX_RELEASE(pOutPacket);
  180.                                 }
  181.                             }
  182.                         }
  183.                         else
  184.                         {
  185.                             // This is NOT a fragmented packet
  186.                             //
  187.                             // We can clear the frag queue. If there was no
  188.                             // loss in the last fragmented AU, then it was
  189.                             // cleared after the packet was created. If there
  190.                             // WAS loss in the last fragmented AU, then we
  191.                             // just handled it by generating loss packets.
  192.                             ClearQueue(m_pFragQueue);
  193.                             // Step through the packet creating packets
  194.                             UINT32 ulAUDataSizeSum = 0;
  195.                             for (UINT32 i = 0; i < ulNumAU && SUCCEEDED(retVal); i++)
  196.                             {
  197.                                 UINT32 ulAUSize   = UnPackUINT16(pBuf + 2 + (i << 1));
  198.                                 UINT32 ulTSOffset = (UINT32) (i * m_dAUDuration);
  199.                                 IHXPacket* pOutPacket = NULL;
  200.                                 retVal = CreatePacket(pBuf + 2 + ulNumAU * 2 + ulAUDataSizeSum,
  201.                                                       ulAUSize,
  202.                                                       pPacket->GetTime() + ulTSOffset,
  203.                                                       FALSE,
  204.                                                       pOutPacket);
  205.                                 if (SUCCEEDED(retVal))
  206.                                 {
  207.                                     // Add the packet to the output queue
  208.                                     retVal = AddToQueue(m_pOutputQueue, pOutPacket);
  209.                                     if (SUCCEEDED(retVal))
  210.                                     {
  211.                                         ulAUDataSizeSum += ulAUSize;
  212.                                     }
  213.                                 }
  214.                                 HX_RELEASE(pOutPacket);
  215.                             }
  216.                             if (SUCCEEDED(retVal))
  217.                             {
  218.                                 // Set the end time of the last packet
  219.                                 // that we put in the output queue
  220.                                 UINT32 ulTSOffset = (UINT32) (ulNumAU * m_dAUDuration);
  221.                                 m_ulLastQueuedPacketEndTime = pPacket->GetTime() + ulTSOffset;
  222.                             }
  223.                         }
  224.                     }
  225.                 }
  226.             }
  227.             HX_RELEASE(pBuffer);
  228.         }
  229.         else
  230.         {
  231.             // The packet is lost, but don't return failure
  232.             retVal = HXR_OK;
  233.         }
  234.     }
  235.     return retVal;
  236. }
  237. HX_RESULT CVBRSimpleDepacketizer::GetPacket(REF(IHXPacket*) rpPacket)
  238. {
  239.     HX_RESULT retVal = HXR_FAIL;
  240.     if (m_pOutputQueue && m_pOutputQueue->GetCount() > 0)
  241.     {
  242.         // Get the head packet
  243.         IHXPacket* pPacket = (IHXPacket*) m_pOutputQueue->RemoveHead();
  244.         if (pPacket)
  245.         {
  246.             HX_RELEASE(rpPacket);
  247.             rpPacket = pPacket;
  248.             rpPacket->AddRef();
  249.             retVal = HXR_OK;
  250.         }
  251.         HX_RELEASE(pPacket);
  252.     }
  253.     return retVal;
  254. }
  255. HX_RESULT CVBRSimpleDepacketizer::OnSeek(UINT32 ulOldTime, UINT32 ulNewTime)
  256. {
  257.     HX_RESULT retVal = HXR_OK;
  258.     // Set the seeked flag
  259.     m_bSeeked = TRUE;
  260.     return retVal;
  261. }
  262. void CVBRSimpleDepacketizer::ClearQueue(CHXSimpleList* pList)
  263. {
  264.     if (pList)
  265.     {
  266.         LISTPOSITION pos = pList->GetHeadPosition();
  267.         while (pos)
  268.         {
  269.             IHXPacket* pPacket = (IHXPacket*) pList->GetNext(pos);
  270.             HX_RELEASE(pPacket);
  271.         }
  272.         pList->RemoveAll();
  273.     }
  274. }
  275. HX_RESULT CVBRSimpleDepacketizer::CreatePacket(BYTE*           pBuf,
  276.                                                UINT32          ulSize,
  277.                                                UINT32          ulTime,
  278.                                                BOOL            bLost,
  279.                                                REF(IHXPacket*) rpPacket)
  280. {
  281.     HX_RESULT retVal = HXR_FAIL;
  282.     if (m_pCommonClassFactory)
  283.     {
  284.         // Create an IHXBuffer.
  285.         IHXBuffer* pBuffer = NULL;
  286.         if (!bLost)
  287.         {
  288.             // Packet was NOT lost so we have to have a buffer
  289.             if (pBuf && ulSize)
  290.             {
  291.                 retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, (void**) &pBuffer);
  292.                 if (SUCCEEDED(retVal))
  293.                 {
  294.                     retVal = pBuffer->Set(pBuf, ulSize);
  295.                 }
  296.             }
  297.         }
  298.         else
  299.         {
  300.             // This is a lost packet, so it's OK not
  301.             // to have a buffer
  302.             retVal = HXR_OK;
  303.         }
  304.         if (SUCCEEDED(retVal))
  305.         {
  306.             // Create an IHXPacket
  307.             IHXPacket* pPacket = NULL;
  308.             retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXPacket, (void**) &pPacket);
  309.             if (SUCCEEDED(retVal))
  310.             {
  311.                 // Set the packet parameters
  312.                 retVal = pPacket->Set(pBuffer,
  313.                                       ulTime,
  314.                                       m_usStreamNum,
  315.                                       HX_ASM_SWITCH_ON,
  316.                                       m_usKeyFrameRuleNum);
  317.                 if (SUCCEEDED(retVal))
  318.                 {
  319.                     // If this is a lost packet, then set
  320.                     // the lost flag
  321.                     if (bLost)
  322.                     {
  323.                         pPacket->SetAsLost();
  324.                     }
  325.                     // Set the out parameter
  326.                     HX_RELEASE(rpPacket);
  327.                     rpPacket = pPacket;
  328.                     rpPacket->AddRef();
  329.                 }
  330.             }
  331.             HX_RELEASE(pPacket);
  332.         }
  333.         HX_RELEASE(pBuffer);
  334.     }
  335.     return retVal;
  336. }
  337. HX_RESULT CVBRSimpleDepacketizer::GenerateAndQueueLossPackets(UINT32 ulFirstPacketStartTime,
  338.                                                               UINT32 ulLastPacketEndTime)
  339. {
  340.     HX_RESULT retVal = HXR_FAIL;
  341.     if (ulLastPacketEndTime > ulFirstPacketStartTime)
  342.     {
  343.         // Compute the difference
  344.         UINT32 ulDiff = ulLastPacketEndTime - ulFirstPacketStartTime;
  345.         // Compute the number of packets
  346.         UINT32 ulNumLossPackets = 0;
  347.         if (m_dAUDuration != 0.0)
  348.         {
  349.             ulNumLossPackets = (UINT32) (ulDiff / m_dAUDuration);
  350.         }
  351.         // Generate loss packets
  352.         retVal = HXR_OK;
  353.         for (UINT32 i = 0; i < ulNumLossPackets && SUCCEEDED(retVal); i++)
  354.         {
  355.             UINT32 ulTSOffset = (UINT32) (i * m_dAUDuration);
  356.             UINT32 ulTime = ulFirstPacketStartTime + ulTSOffset;
  357.             IHXPacket* pPacket = NULL;
  358.             retVal = CreatePacket(NULL, 0, ulTime, TRUE, pPacket);
  359.             if (SUCCEEDED(retVal))
  360.             {
  361.                 retVal = AddToQueue(m_pOutputQueue, pPacket);
  362.             }
  363.             HX_RELEASE(pPacket);
  364.         }
  365.     }
  366.     return retVal;
  367. }
  368. HX_RESULT CVBRSimpleDepacketizer::AddToQueue(REF(CHXSimpleList*) rpList, IHXPacket* pPacket)
  369. {
  370.     HX_RESULT retVal = HXR_FAIL;
  371.     if (!rpList)
  372.     {
  373.         rpList = new CHXSimpleList();
  374.     }
  375.     if (rpList)
  376.     {
  377.         // AddRef the packet before going on the list
  378.         pPacket->AddRef();
  379.         // Put the packet on the list
  380.         rpList->AddTail((void*) pPacket);
  381.         // Clear the return value
  382.         retVal = HXR_OK;
  383.     }
  384.     return retVal;
  385. }
  386. HX_RESULT CVBRSimpleDepacketizer::ParseVBRPacket(BYTE*       pBuf,
  387.                                                  UINT32      ulSize,
  388.                                                  REF(UINT32) rulNumAU,
  389.                                                  REF(BOOL)   rbFragmented)
  390. {
  391.     HX_RESULT retVal = HXR_FAIL;
  392.     if (pBuf && ulSize)
  393.     {
  394.         // Compute the buf limit (for safety)
  395.         BYTE* pBufLimit = pBuf + ulSize;
  396.         HX_ASSERT(pBuf + 2 <= pBufLimit);
  397.         if (pBuf + 2 <= pBufLimit)
  398.         {
  399.             // Get the AU header size in bits
  400.             UINT32 ulAUHeaderSizeBits = UnPackUINT16(pBuf);
  401.             // Convert to bytes (rounding up to next byte)
  402.             UINT32 ulAUHeaderSize = (ulAUHeaderSizeBits + 7) >> 3;
  403.             // Sanity check to make sure that the AU header size is
  404.             // greater than 0 and a multiple of 2 bytes
  405.             HX_ASSERT(ulAUHeaderSize && !(ulAUHeaderSize & 1));
  406.             if (ulAUHeaderSize && !(ulAUHeaderSize & 1))
  407.             {
  408.                 // Since we know that each AU header is 2 bytes, then
  409.                 // we know that the number of AU's in this packet is
  410.                 // ulAUHeaderSize / 2.
  411.                 rulNumAU = ulAUHeaderSize >> 1;
  412.                 // The audio/mpeg-generic spec says that each packet
  413.                 // can either have a complete AU, a fragment of a single
  414.                 // AU, or multiple complete AUs. Therefore, if the
  415.                 // number of AUs is greater than 1, then we know we
  416.                 // have ulNumAU *complete* AUs. Therefore, for more
  417.                 // than one AU, we know what the exact size of the
  418.                 // packet should be, and that should match up with
  419.                 // the data size of the packet.
  420.                 BYTE*  pAUSize      = pBuf + 2;
  421.                 UINT32 ulAUDataSize = 0;
  422.                 for (UINT32 i = 0; i < rulNumAU; i++)
  423.                 {
  424.                     HX_ASSERT(pAUSize + 2 <= pBufLimit);
  425.                     if (pAUSize + 2 <= pBufLimit)
  426.                     {
  427.                         UINT32 ulAUSize = UnPackUINT16(pAUSize);
  428.                         ulAUDataSize += ulAUSize;
  429.                         pAUSize      += 2;
  430.                     }
  431.                 }
  432.                 // Compute the expected size of the packet
  433.                 UINT32 ulExpectedSize = 2 +            // AU header size (16 bits)
  434.                                         rulNumAU * 2 + // AU sizes
  435.                                         ulAUDataSize;  // the AU's themselves
  436.                 // Check this against the actual size. If we have
  437.                 // 1 AU, then the expected size can be greater than
  438.                 // the actual size due to fragmentation. If we have
  439.                 // more than more AU, then the expected size MUST
  440.                 // match the actual size.
  441.                 if (rulNumAU >  1)
  442.                 {
  443.                     if (ulExpectedSize == ulSize)
  444.                     {
  445.                         // Multiple AUs, no fragmentation
  446.                         rbFragmented = FALSE;
  447.                         retVal       = HXR_OK;
  448.                     }
  449.                 }
  450.                 else if (rulNumAU == 1)
  451.                 {
  452.                     if (ulExpectedSize > ulSize)
  453.                     {
  454.                         // Fragmented single AU
  455.                         rbFragmented = TRUE;
  456.                         retVal       = HXR_OK;
  457.                     }
  458.                     else
  459.                     {
  460.                         // Single AU, no fragmentation
  461.                         rbFragmented = FALSE;
  462.                         retVal       = HXR_OK;
  463.                     }
  464.                 }
  465.             }
  466.         }
  467.     }
  468.     HX_ASSERT(SUCCEEDED(retVal));
  469.     return retVal;
  470. }
  471. UINT32 CVBRSimpleDepacketizer::UnPackUINT16(BYTE* pBuf)
  472. {
  473.     return (pBuf[0] << 8) | pBuf[1];
  474. }
  475. void CVBRSimpleDepacketizer::RemoveDifferingPackets(UINT32 ulTime)
  476. {
  477.     if (m_pFragQueue && m_pFragQueue->GetCount() > 0)
  478.     {
  479.         IHXPacket* pPacket = (IHXPacket*) m_pFragQueue->GetHead();
  480.         if (pPacket && pPacket->GetTime() < ulTime)
  481.         {
  482.             // There are packets on the frag queue with
  483.             // timestamps less than this one. Therefore,
  484.             // we need to clear the queue
  485.             ClearQueue(m_pFragQueue);
  486.         }
  487.     }
  488. }
  489. BOOL CVBRSimpleDepacketizer::CanDefrag()
  490. {
  491.     BOOL bRet = FALSE;
  492.     if (m_pFragQueue && m_pFragQueue->GetCount() > 0)
  493.     {
  494.         IHXPacket* pPacket = (IHXPacket*) m_pFragQueue->GetHead();
  495.         UINT32 ulActualAUDataSize = 0;
  496.         UINT32 ulAUDataSize = GetAUSize(pPacket, ulActualAUDataSize);
  497.         UINT32 ulActualAUDataSizeSum = 0;
  498.         LISTPOSITION pos = m_pFragQueue->GetHeadPosition();
  499.         while (pos)
  500.         {
  501.             pPacket = (IHXPacket*) m_pFragQueue->GetNext(pos);
  502.             GetAUSize(pPacket, ulActualAUDataSize);
  503.             ulActualAUDataSizeSum += ulActualAUDataSize;
  504.         }
  505.         // Check that the stated size of the AU
  506.         // is the same as the sum of the actual
  507.         // AU data sizes across all the fragmented packets
  508.         if (ulAUDataSize == ulActualAUDataSizeSum)
  509.         {
  510.             bRet = TRUE;
  511.         }
  512.     }
  513.     return bRet;
  514. }
  515. HX_RESULT CVBRSimpleDepacketizer::Defrag(REF(IHXPacket*) rpPacket)
  516. {
  517.     HX_RESULT retVal = HXR_FAIL;
  518.     if (m_pCommonClassFactory && m_pFragQueue && m_pFragQueue->GetCount() > 0)
  519.     {
  520.         // Get the stated size of the AU
  521.         IHXPacket* pFragPacket = (IHXPacket*) m_pFragQueue->GetHead();
  522.         UINT32 ulTmp = 0;
  523.         UINT32 ulAUSize = GetAUSize(pFragPacket, ulTmp);
  524.         UINT32 ulTime   = pFragPacket->GetTime();
  525.         // Sanity check
  526.         if (ulAUSize > 0)
  527.         {
  528.             // Create a buffer of this size
  529.             BYTE* pBuf = new BYTE [ulAUSize];
  530.             if (pBuf)
  531.             {
  532.                 // Copy all the fragmented packets into this buffer
  533.                 UINT32 ulFragSizeSum = 0;
  534.                 LISTPOSITION pos = m_pFragQueue->GetHeadPosition();
  535.                 while (pos)
  536.                 {
  537.                     pFragPacket = (IHXPacket*) m_pFragQueue->GetNext(pos);
  538.                     if (pFragPacket)
  539.                     {
  540.                         IHXBuffer* pFragBuffer = pFragPacket->GetBuffer();
  541.                         if (pFragBuffer)
  542.                         {
  543.                             memcpy(pBuf + ulFragSizeSum,
  544.                                    pFragBuffer->GetBuffer() + 4,
  545.                                    pFragBuffer->GetSize() - 4);
  546.                             ulFragSizeSum += pFragBuffer->GetSize() - 4;
  547.                         }
  548.                         HX_RELEASE(pFragBuffer);
  549.                     }
  550.                 }
  551.                 // Create the packet
  552.                 HX_RELEASE(rpPacket);
  553.                 retVal = CreatePacket(pBuf, ulAUSize, ulTime, FALSE, rpPacket);
  554.             }
  555.             HX_VECTOR_DELETE(pBuf);
  556.         }
  557.     }
  558.     return retVal;
  559. }
  560. UINT32 CVBRSimpleDepacketizer::GetAUSize(IHXPacket* pPacket, REF(UINT32) rulActualAUDataSize)
  561. {
  562.     UINT32 ulRet = 0;
  563.     if (pPacket)
  564.     {
  565.         IHXBuffer* pBuffer = pPacket->GetBuffer();
  566.         if (pBuffer)
  567.         {
  568.             ulRet = UnPackUINT16(pBuffer->GetBuffer() + 2);
  569.             rulActualAUDataSize = pBuffer->GetSize() - 4;
  570.         }
  571.         HX_RELEASE(pBuffer);
  572.     }
  573.     return ulRet;
  574. }