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

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
  36. #include "hxtypes.h"
  37. #include "hxwintyp.h"
  38. #include "hxcom.h"
  39. #include "hxresult.h"
  40. #include "hxcomm.h"
  41. #include "ihxpckts.h"
  42. // hxcont
  43. #include "hxslist.h"
  44. #include "hxstring.h"
  45. #include "hxmap.h"
  46. // hxmisc
  47. #include "baseobj.h"
  48. #include "unkimp.h"
  49. // pxcomlib
  50. #include "pxrect.h"
  51. #include "pxcolor.h"
  52. #include "pxeffect.h"
  53. #include "wirefmgr.h"
  54. #include "pxffmcod.h"
  55. #include "pxcmpmgr.h"
  56. #include "pxffcmgr.h"
  57. #include "pximgfil.h"
  58. // hxdebug
  59. #include "hxheap.h"
  60. #ifdef _DEBUG
  61. #undef HX_THIS_FILE
  62. static char HX_THIS_FILE[] = __FILE__;
  63. #endif
  64. PXImageFile::PXImageFile(PXWireFormatManager*      pWireFormatManager,
  65.                          PXFileFormatCodecManager* pCodecManager,
  66.                          IHXCommonClassFactory*   pCommonClassFactory)
  67. {
  68.     HX_ASSERT(pWireFormatManager);
  69.     if (pWireFormatManager)
  70.     {
  71.         m_pWireFormatManager = pWireFormatManager;
  72.         m_pWireFormatManager->AddRef();
  73.     }
  74.     HX_ASSERT(pCodecManager);
  75.     if (pCodecManager)
  76.     {
  77.         m_pCodecManager = pCodecManager;
  78.         m_pCodecManager->AddRef();
  79.     }
  80.     HX_ASSERT(pCommonClassFactory);
  81.     if (pCommonClassFactory)
  82.     {
  83.         m_pCommonClassFactory = pCommonClassFactory;
  84.         m_pCommonClassFactory->AddRef();
  85.     }
  86.     m_lRefCount     = 0;
  87.     m_ulHandle      = 0;
  88.     m_ulNumPackets  = 0;
  89.     m_ulTotalBytes  = 0;
  90.     m_ulImageWidth  = 0;
  91.     m_ulImageHeight = 0;
  92.     m_pPacketList   = NULL;
  93.     m_pCookieList   = NULL;
  94.     m_pListItr      = NULL;
  95. }
  96. PXImageFile::~PXImageFile()
  97. {
  98.     Deallocate();
  99. };
  100. void PXImageFile::Deallocate()
  101. {
  102.     HX_RELEASE(m_pWireFormatManager);
  103.     HX_RELEASE(m_pCodecManager);
  104.     HX_RELEASE(m_pCommonClassFactory);
  105.     ReleaseAllPackets();
  106.     ClearCookieList();
  107.     HX_DELETE(m_pPacketList);
  108.     HX_DELETE(m_pCookieList);
  109. }
  110. void PXImageFile::ReleaseAllPackets()
  111. {
  112.     if (m_pPacketList)
  113.     {
  114.         LISTPOSITION pos = m_pPacketList->GetHeadPosition();
  115.         while (pos)
  116.         {
  117.             IHXPacket* pPacket = (IHXPacket*) m_pPacketList->GetNext(pos);
  118.             HX_RELEASE(pPacket);
  119.         }
  120.         m_pPacketList->RemoveAll();
  121.     }
  122. }
  123. void PXImageFile::ClearCookieList()
  124. {
  125.     if (m_pCookieList)
  126.     {
  127.         LISTPOSITION pos = m_pCookieList->GetHeadPosition();
  128.         while (pos)
  129.         {
  130.             CookiePair* pPair = (CookiePair*) m_pCookieList->GetNext(pos);
  131.             if (pPair)
  132.             {
  133.                 HX_RELEASE(pPair->m_pURLStr);
  134.                 HX_RELEASE(pPair->m_pCookie);
  135.             }
  136.             HX_DELETE(pPair);
  137.         }
  138.         m_pCookieList->RemoveAll();
  139.     }
  140. }
  141. STDMETHODIMP PXImageFile::QueryInterface(REFIID riid, void** ppvObj)
  142. {
  143.     HX_RESULT retVal = HXR_OK;
  144.     if (IsEqualIID(riid, IID_IUnknown))
  145.     {
  146.         AddRef();
  147.         *ppvObj = (IUnknown *) this;
  148.     }
  149.     else
  150.     {
  151.         *ppvObj = NULL;
  152.         retVal  = HXR_NOINTERFACE;
  153.     }
  154.     return retVal;
  155. }
  156. STDMETHODIMP_(UINT32) PXImageFile::AddRef()
  157. {
  158.     return InterlockedIncrement(&m_lRefCount);
  159. }
  160. STDMETHODIMP_(UINT32) PXImageFile::Release()
  161. {
  162.     
  163.     if (InterlockedDecrement(&m_lRefCount) > 0)
  164.         return m_lRefCount;
  165.     delete this;
  166.     return 0;
  167. }
  168. HX_RESULT PXImageFile::AddCookie(IHXBuffer* pURLStr, IHXBuffer* pCookie)
  169. {
  170.     HX_RESULT retVal = HXR_OK;
  171.     if (pURLStr && pCookie)
  172.     {
  173.         if (!m_pCookieList)
  174.         {
  175.             m_pCookieList = new CHXSimpleList();
  176.             if (!m_pCookieList)
  177.             {
  178.                 retVal = HXR_OUTOFMEMORY;
  179.             }
  180.         }
  181.         if (SUCCEEDED(retVal))
  182.         {
  183.             CookiePair* pPair = new CookiePair;
  184.             if (pPair)
  185.             {
  186.                 pPair->m_pURLStr = pURLStr;
  187.                 pPair->m_pURLStr->AddRef();
  188.                 pPair->m_pCookie = pCookie;
  189.                 pPair->m_pCookie->AddRef();
  190.                 m_pCookieList->AddTail((void*) pPair);
  191.             }
  192.             else
  193.             {
  194.                 retVal = HXR_OUTOFMEMORY;
  195.             }
  196.         }
  197.     }
  198.     else
  199.     {
  200.         retVal = HXR_FAIL;
  201.     }
  202.     return retVal;
  203. }
  204. HX_RESULT PXImageFile::EnqueueCookiePacket()
  205. {
  206.     HX_RESULT retVal = HXR_OK;
  207.     // Add the cookie packet
  208.     if (m_pCookieList)
  209.     {
  210.         if (m_pCookieList->GetCount() > 0)
  211.         {
  212.             IHXBuffer** ppURL = NULL;
  213.             ppURL              = new IHXBuffer* [m_pCookieList->GetCount()];
  214.             if (ppURL)
  215.             {
  216.                 IHXBuffer** ppCookie = NULL;
  217.                 ppCookie              = new IHXBuffer* [m_pCookieList->GetCount()];
  218.                 if (ppCookie)
  219.                 {
  220.                     UINT32       i   = 0;
  221.                     LISTPOSITION pos = m_pCookieList->GetHeadPosition();
  222.                     while (pos)
  223.                     {
  224.                         CookiePair* pPair = (CookiePair*) m_pCookieList->GetNext(pos);
  225.                         if (pPair)
  226.                         {
  227.                             ppURL[i]    = pPair->m_pURLStr;
  228.                             ppCookie[i] = pPair->m_pCookie;
  229.                             i++;
  230.                         }
  231.                     }
  232.                     IHXPacket* pPacket = NULL;
  233.                     retVal              = m_pWireFormatManager->SetCookieInfo(m_pCookieList->GetCount(),
  234.                                                                               ppURL,
  235.                                                                               ppCookie,
  236.                                                                               0,
  237.                                                                               pPacket);
  238.                     if (SUCCEEDED(retVal))
  239.                     {
  240.                         // Add this to the packet list
  241.                         // FALSE makes it add at the head instead of tail
  242.                         retVal = AddPacket(pPacket, FALSE);
  243.                     }
  244.                     HX_RELEASE(pPacket);
  245.                 }
  246.                 HX_VECTOR_DELETE(ppCookie);
  247.             }
  248.             HX_VECTOR_DELETE(ppURL);
  249.             // Clear the cookie list
  250.             ClearCookieList();
  251.         }
  252.     }
  253.     return retVal;
  254. }
  255. HX_RESULT PXImageFile::EnqueueImagePackets(UINT32      ulHandle,
  256.                                            IHXBuffer* pFileBuffer)
  257. {
  258.     HX_RESULT retVal = HXR_FAIL;
  259.     if (ulHandle && pFileBuffer)
  260.     {
  261.         // Save the members
  262.         m_ulHandle = ulHandle;
  263.         // Get a codec to parse this image
  264.         IHXRealPixFileFormatCodec* pCodec = NULL;
  265.         retVal                             = m_pCodecManager->GetCodec(NULL,        // file mime type
  266.                                                                        NULL,        // file name
  267.                                                                        pFileBuffer, // file buffer
  268.                                                                        pCodec);
  269.         if (SUCCEEDED(retVal))
  270.         {
  271.             // Get the mime type for this codec
  272.             const char** ppTmp1        = NULL;
  273.             const char** ppTmp2        = NULL;
  274.             const char*  pszStreamMime = NULL;
  275.             UINT32       ulVer         = 0;
  276.             UINT32       ulMaxPerImg   = 0;
  277.             UINT32       ulMaxPerPckt  = 0;
  278.             retVal                     = pCodec->GetFileFormatCodecInfo(ppTmp1, ppTmp2, pszStreamMime,
  279.                                                                         ulVer, ulMaxPerImg, ulMaxPerPckt);
  280.             if (SUCCEEDED(retVal))
  281.             {
  282.                 IHXPacket* pImageHeaderPacket = NULL;
  283.                 retVal                         = m_pWireFormatManager->SetImageHeaderInfo(ulHandle,
  284.                                                                                           pFileBuffer->GetSize(),
  285.                                                                                           0,
  286.                                                                                           pszStreamMime,
  287.                                                                                           0,
  288.                                                                                           pImageHeaderPacket);
  289.                 if (SUCCEEDED(retVal))
  290.                 {
  291.                     // Add image header packet to list tail
  292.                     retVal = AddPacket(pImageHeaderPacket);
  293.                     if (SUCCEEDED(retVal))
  294.                     {
  295.                         // Parse the image
  296.                         UINT32      ulNumDataPackets = 0;
  297.                         IHXValues* pParam           = NULL;
  298.                         UINT32      ulSessionHandle  = 0;
  299.                         retVal                       = pCodec->ParseImage(pFileBuffer,
  300.                                                                           ulNumDataPackets,
  301.                                                                           pParam,
  302.                                                                           ulSessionHandle);
  303.                         if (SUCCEEDED(retVal))
  304.                         {
  305.                             // Get width and height
  306.                             pParam->GetPropertyULONG32("ImageWidth",  m_ulImageWidth);
  307.                             pParam->GetPropertyULONG32("ImageHeight", m_ulImageHeight);
  308.                             // Get all the image data packets
  309.                             for (UINT32 i = 0; i < ulNumDataPackets && SUCCEEDED(retVal); i++)
  310.                             {
  311.                                 IHXBuffer* pData   = NULL;
  312.                                 IHXBuffer* pOpaque = NULL;
  313.                                 BOOL        bReq    = FALSE;
  314.                                 retVal              = pCodec->GetImagePacket(ulSessionHandle, i, pData, pOpaque, bReq);
  315.                                 if (SUCCEEDED(retVal))
  316.                                 {
  317.                                     IHXPacket* pImageDataPacket = NULL;
  318.                                     retVal                       = m_pWireFormatManager->SetImageDataInfo(ulHandle, pData, pOpaque,
  319.                                                                                                           i, 0, bReq, pImageDataPacket);
  320.                                     if (SUCCEEDED(retVal))
  321.                                     {
  322.                                         // Add image data packet to tail of the list
  323.                                         retVal = AddPacket(pImageDataPacket);
  324.                                     }
  325.                                     HX_RELEASE(pImageDataPacket);
  326.                                 }
  327.                                 HX_RELEASE(pData);
  328.                                 HX_RELEASE(pOpaque);
  329.                             }
  330.                             // Now we're done with this parse session
  331.                             pCodec->ReleaseImage(ulSessionHandle);
  332.                         }
  333.                         HX_RELEASE(pParam);
  334.                     }
  335.                 }
  336.                 HX_RELEASE(pImageHeaderPacket);
  337.             }
  338.         }
  339.         HX_RELEASE(pCodec);
  340.     }
  341.     return retVal;
  342. }
  343. HX_RESULT PXImageFile::EnqueueEffectPacket(UINT32      ulEffectType,
  344.                                            UINT32      ulStart,
  345.                                            UINT32      ulDuration,
  346.                                            UINT32      ulTarget,
  347.                                            const char* pszURL,
  348.                                            UINT32      ulFillColor,
  349.                                            BOOL        bBackChannel,
  350.                                            BOOL        bLastUse,
  351.                                            BOOL        bDisplayImmediately)
  352. {
  353.     HX_RESULT retVal = HXR_OK;
  354.     // Create an effect object
  355.     PXEffect* pEffect = NULL;
  356.     retVal            = PXEffect::CreateObject(&pEffect);
  357.     if (SUCCEEDED(retVal))
  358.     {
  359.         // AddRef the effect
  360.         pEffect->AddRef();
  361.         // Set a bunch of parameters
  362.         pEffect->SetEffectType((BYTE) ulEffectType);
  363.         pEffect->SetStart(ulStart);
  364.         pEffect->SetDuration(ulDuration);
  365.         pEffect->SetTarget(ulTarget);
  366.         if (pszURL)
  367.         {
  368.             pEffect->SetURL(pszURL);
  369.         }
  370.         pEffect->SetColor(ulFillColor);
  371.         pEffect->SetPostBackChannel(bBackChannel);
  372.         pEffect->SetLastUse(bLastUse);
  373.         pEffect->SetDisplayImmediately(bDisplayImmediately);
  374.         // Get the packet
  375.         IHXPacket* pEffectPacket = NULL;
  376.         retVal                     = m_pWireFormatManager->SetEffectInfo(pEffect, 0, pEffectPacket);
  377.         if (SUCCEEDED(retVal))
  378.         {
  379.             // Add the effect packet to the tail
  380.             retVal = AddPacket(pEffectPacket);
  381.         }
  382.         HX_RELEASE(pEffectPacket);
  383.     }
  384.     HX_RELEASE(pEffect);
  385.     return retVal;
  386. }
  387. void PXImageFile::ComputeStatistics()
  388. {
  389.     m_ulNumPackets = 0;
  390.     m_ulTotalBytes = 0;
  391.     if (m_pPacketList)
  392.     {
  393.         if (m_pPacketList->GetCount() > 0)
  394.         {
  395.             // Set the number of packets
  396.             m_ulNumPackets = m_pPacketList->GetCount();
  397.             // Compute the size with overhead
  398.             m_ulTotalBytes   = 0;
  399.             LISTPOSITION pos = m_pPacketList->GetHeadPosition();
  400.             while (pos)
  401.             {
  402.                 IHXPacket* pListPacket = (IHXPacket*) m_pPacketList->GetNext(pos);
  403.                 if (pListPacket)
  404.                 {
  405.                     IHXBuffer *pListBuffer = pListPacket->GetBuffer();
  406.                     if (pListBuffer)
  407.                     {
  408.                         m_ulTotalBytes += pListBuffer->GetSize();
  409.                     }
  410.                     HX_RELEASE(pListBuffer);
  411.                 }
  412.             }
  413.         }
  414.     }
  415. }
  416. HX_RESULT PXImageFile::DequeuePacket(REF(IHXPacket*) rpPacket,
  417.                                      UINT32           ulBitrate,
  418.                                      REF(INT32)       rlCurrentTimeStamp)
  419. {
  420.     HX_RESULT retVal = HXR_FAIL;
  421.     if (ulBitrate && m_pPacketList)
  422.     {
  423.         if (m_pPacketList->GetCount() > 0)
  424.         {
  425.             IHXPacket* pPacket = (IHXPacket*) m_pPacketList->RemoveHead();
  426.             if (pPacket)
  427.             {
  428.                 UINT32      ulTimeStamp = (UINT32) (rlCurrentTimeStamp >= 0 ? rlCurrentTimeStamp : 0);
  429.                 UINT32      ulSize      = 0;
  430.                 IHXPacket* pNewPacket  = NULL;
  431.                 retVal                  = SetPacketTimeStamp(pPacket, ulTimeStamp,
  432.                                                              ulSize, pNewPacket);
  433.                 if (SUCCEEDED(retVal))
  434.                 {
  435.                     // Update the time stamp
  436.                     rlCurrentTimeStamp += (INT32) (ulSize * 8000 / ulBitrate);
  437.                     // Assign the out parameter
  438.                     HX_RELEASE(rpPacket);
  439.                     rpPacket = pNewPacket;
  440.                     rpPacket->AddRef();
  441.                 }
  442.                 HX_RELEASE(pNewPacket);
  443.             }
  444.             HX_RELEASE(pPacket);
  445.         }
  446.     }
  447.     return retVal;
  448. }
  449. HX_RESULT PXImageFile::GetFirstPacket(REF(IHXPacket*) rpPacket)
  450. {
  451.     HX_RESULT retVal = HXR_FAIL;
  452.     if (m_pPacketList)
  453.     {
  454.         LISTPOSITION pos = m_pPacketList->GetHeadPosition();
  455.         if (pos)
  456.         {
  457.             IHXPacket* pPacket = (IHXPacket*) m_pPacketList->GetNext(pos);
  458.             if (pPacket)
  459.             {
  460.                 HX_RELEASE(rpPacket);
  461.                 rpPacket = pPacket;
  462.                 rpPacket->AddRef();
  463.                 m_pListItr = pos;
  464.                 retVal     = HXR_OK;
  465.             }
  466.         }
  467.     }
  468.     return retVal;
  469. }
  470. HX_RESULT PXImageFile::GetNextPacket(REF(IHXPacket*) rpPacket)
  471. {
  472.     HX_RESULT retVal = HXR_FAIL;
  473.     if (m_pPacketList && m_pListItr)
  474.     {
  475.         IHXPacket* pPacket = (IHXPacket*) m_pPacketList->GetNext(m_pListItr);
  476.         if (pPacket)
  477.         {
  478.             HX_RELEASE(rpPacket);
  479.             rpPacket = pPacket;
  480.             rpPacket->AddRef();
  481.             retVal   = HXR_OK;
  482.         }
  483.     }
  484.     return retVal;
  485. }
  486. HX_RESULT PXImageFile::SetPacketTimeStamp(IHXPacket*      pPacket,
  487.                                           UINT32           ulTimeStamp,
  488.                                           REF(UINT32)      rulPacketSize,
  489.                                           REF(IHXPacket*) rpPacket)
  490. {
  491.     return FactorySetTimeStamp(pPacket, m_pCommonClassFactory, ulTimeStamp,
  492.                                rulPacketSize, rpPacket);
  493. }
  494. HX_RESULT PXImageFile::FactorySetTimeStamp(IHXPacket*             pPacket,
  495.                                            IHXCommonClassFactory* pFactory,
  496.                                            UINT32                  ulTimeStamp,
  497.                                            REF(UINT32)             rulPacketSize,
  498.                                            REF(IHXPacket*)        rpPacket)
  499. {
  500.     HX_RESULT retVal = HXR_OK;
  501.     if (pPacket && pFactory)
  502.     {
  503.         // Get the packet parameters
  504.         IHXBuffer* pBuffer         = NULL;
  505.         UINT32      ulTime          = 0;
  506.         UINT16      usStreamNumber  = 0;
  507.         UINT8       ucASMFlags      = 0;
  508.         UINT16      usASMRuleNumber = 0;
  509.         retVal                      = pPacket->Get(pBuffer,
  510.                                                    ulTime,
  511.                                                    usStreamNumber,
  512.                                                    ucASMFlags,
  513.                                                    usASMRuleNumber);
  514.         if (SUCCEEDED(retVal))
  515.         {
  516.             // Create a new packet
  517.             IHXPacket* pNewPacket = NULL;
  518.             retVal                 = pFactory->CreateInstance(CLSID_IHXPacket,
  519.                                                               (void**) &pNewPacket);
  520.             if (SUCCEEDED(retVal))
  521.             {
  522.                 // Set these values with the new timestamp into the new packet
  523.                 retVal = pNewPacket->Set(pBuffer,
  524.                                          ulTimeStamp,
  525.                                          usStreamNumber,
  526.                                          ucASMFlags,
  527.                                          usASMRuleNumber);
  528.                 if (SUCCEEDED(retVal))
  529.                 {
  530.                     // Assign the out parameters
  531.                     rulPacketSize = pBuffer->GetSize();
  532.                     HX_RELEASE(rpPacket);
  533.                     rpPacket = pNewPacket;
  534.                     rpPacket->AddRef();
  535.                 }
  536.             }
  537.             HX_RELEASE(pNewPacket);
  538.         }
  539.         HX_RELEASE(pBuffer);
  540.     }
  541.     else
  542.     {
  543.         retVal = HXR_INVALID_PARAMETER;
  544.     }
  545.     return retVal;
  546. }
  547. HX_RESULT PXImageFile::AddPacket(IHXPacket* pPacket, BOOL bTail)
  548. {
  549.     HX_RESULT retVal = HXR_OK;
  550.     if (pPacket)
  551.     {
  552.         // Create list if it doesn't exist
  553.         if (!m_pPacketList)
  554.         {
  555.             m_pPacketList = new CHXSimpleList();
  556.             if (!m_pPacketList)
  557.             {
  558.                 retVal = HXR_OUTOFMEMORY;
  559.             }
  560.         }
  561.         // AddRef the packet
  562.         pPacket->AddRef();
  563.         if (bTail)
  564.         {
  565.             // Add the packet at the tail
  566.             m_pPacketList->AddTail((void*) pPacket);
  567.         }
  568.         else
  569.         {
  570.             // Add the packet at the head
  571.             m_pPacketList->AddHead((void*) pPacket);
  572.         }
  573.     }
  574.     else
  575.     {
  576.         retVal = HXR_FAIL;
  577.     }
  578.     return retVal;
  579. }
  580. UINT32 PXImageFile::GetNumPacketsLeft() const
  581. {
  582.     return (m_pPacketList ? m_pPacketList->GetCount() : 0);
  583. }
  584. UINT32 PXImageFile::GetTotalSendTime(UINT32 ulBitrate) const
  585. {
  586.     UINT32 ulTime = 0;
  587.     if (ulBitrate)
  588.     {
  589.         ulTime = (m_ulTotalBytes * 8000 + (ulBitrate >> 1)) / ulBitrate;
  590.     }
  591.     return ulTime;
  592. }
  593. UINT32 PXImageFile::GetPacketSendTime(IHXPacket* pPacket, UINT32 ulBitrate)
  594. {
  595.     UINT32 ulTime = 0;
  596.     if (pPacket && ulBitrate)
  597.     {
  598.         IHXBuffer* pBuffer = pPacket->GetBuffer();
  599.         if (pBuffer)
  600.         {
  601.             ulTime = (pBuffer->GetSize() * 8000 + (ulBitrate >> 1)) / ulBitrate;
  602.         }
  603.         HX_RELEASE(pBuffer);
  604.     }
  605.     return ulTime;
  606. }