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

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 "hlxclib/stdio.h"
  36. #include "hlxclib/string.h"
  37. #include "netbyte.h"
  38. #include "hxtypes.h"
  39. #include "hxresult.h"
  40. #include "hxcom.h"
  41. #include "hxcomm.h"
  42. #include "hxbuffer.h"
  43. #include "hxausvc.h"
  44. #include "ihxpckts.h"
  45. #include "hxcodec.h"
  46. #include "raparser.h"
  47. #include "hxengin.h"
  48. #include "cinterl.h"
  49. #include "codec.h"
  50. #include "hxcore.h"
  51. #include "hxupgrd.h"
  52. #include "hxslist.h"
  53. #include "raformat.h"
  54. #include "rmfftype.h"
  55. #include "hxassert.h"
  56. #include "errdbg.h"
  57. #include "hxtick.h"
  58. #include "hxheap.h"
  59. #ifdef _DEBUG
  60. #undef HX_THIS_FILE
  61. static const char HX_THIS_FILE[] = __FILE__;
  62. #endif
  63. #include "hxstat.h"
  64. #define LOG_INFO 0
  65. // Add this back and make it work if you turn on LOG_VIDEO_INFO
  66. //#define RAIBUFS_LOGING_ON
  67. #ifdef RAIBUFS_LOGING_ON
  68. #define LOG_PATH     "D:\Temp\"
  69. #define SPLICE_FILE     LOG_PATH##"splice.txt"
  70. #define XFADEREADY_FILE     LOG_PATH##"xfadeready.txt"
  71. #define TIMERANGE_FILE     LOG_PATH##"timerange.txt"
  72. #define GETBLOCK_FILE     LOG_PATH##"getblock.txt"
  73. #else
  74. #define SPLICE_FILE     0
  75. #define XFADEREADY_FILE     0
  76. #define TIMERANGE_FILE     0
  77. #define GETBLOCK_FILE     0
  78. #endif
  79. // this value is the approximate maximum overlap of superblocks caused by math
  80. // error when calculating block times.  If the error is .5 ms and the superblock
  81. // had 20 blocks it could be as much as 10 ms off.  Currently the max superblock
  82. // size is 14 blocks so we have some room to grow.
  83. #define SUPERBLOCK_OVERLAP_FUDGE    10
  84. #define SUPERBLOCK_VALUE_FACTOR     2
  85. // Constructors & Destructors
  86. CInterleaveBufs::CInterleaveBufs (CStreamParam& param, UINT16 uStreamNumber)
  87.     : m_Param(param)
  88.     , m_uStreamNumber(uStreamNumber)
  89.     , m_Interleaver(NULL)
  90.     , m_ulSuperBlockSize(0)
  91.     , m_fmsPerBlock(0.0)
  92.     , m_pIDataBuf(NULL)
  93.     , m_pDDataBuf(NULL)
  94.     , m_pIPresent(NULL)
  95.     , m_pDPresent(NULL)
  96.     , m_pIActualTimestamps(NULL)
  97.     , m_pDActualTimestamps(NULL)
  98.     , m_bISuperBlockEmpty(TRUE)
  99.     , m_bISuperBlockDone(FALSE)
  100.     , m_uNumIBlocks(0)
  101.     , m_ulFirstSequenceNum(0)
  102.     , m_fActualTimestamp(0.0)
  103.     , m_bFirstPacketReceived(FALSE)
  104.     , m_bDSuperBlockEmpty(TRUE)
  105.     , m_uBlockToDecode(0)
  106.     , m_bEndOfPackets(FALSE)
  107.     , m_fMsPerByte((double) 0.)
  108.     , m_bTimeStampsInTenths(FALSE)
  109.     , m_ulSamplesIn(0)
  110.     , m_fLastDecodedTime(0.0)
  111.     , m_bLastDecodedTimeSet(FALSE)
  112.     , m_bDeinterleaveInPlace(FALSE)
  113.     , m_bReliableSamplesIn(FALSE)
  114.     , m_bIsVBRS(FALSE)
  115.     , m_ulVBRSMaxBufSize(INITIAL_VBR_MAXBUFSIZE)
  116.     , m_ulVBRSDBufBytes(0)
  117. {
  118.     DEBUG_OUTF(SPLICE_FILE, (s, "Start Streamt%pt*******n", this));
  119. }
  120. CInterleaveBufs::~CInterleaveBufs()
  121. {
  122.     DeallocIBufs();
  123.     HX_DELETE(m_Interleaver);
  124. }
  125. // de-interleaving
  126. HX_RESULT 
  127. CInterleaveBufs::InitDeinterleaver (void)
  128. {
  129.     HX_RESULT theError = HXR_OK;
  130.     if (strcmp(m_Param.interleaverID, RA_NO_INTERLEAVER) != 0)
  131.     {
  132. m_Interleaver = CInterleave::Construct(m_Param.interleaverID, &theError, (void*) &m_Param.uFlavorIndex);
  133. if ((m_Interleaver == NULL) && (SUCCEEDED(theError)))
  134. {
  135.     theError = HXR_OUTOFMEMORY;
  136. }
  137.         else if (m_Interleaver)
  138.         {
  139.             ULONG32 bitProperties = m_Interleaver->GetProperties();
  140.             if( bitProperties && INTERPROP_INPLACE )
  141.             {
  142.                 m_bDeinterleaveInPlace = TRUE;
  143.             }
  144.         }
  145.     }
  146. #if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC)
  147.     if (m_Param.interleaverID &&
  148.         (!strcmp(m_Param.interleaverID, RA_INTERLEAVER_VBRS_ID) ||
  149.          !strcmp(m_Param.interleaverID, RA_INTERLEAVER_VBRF_ID)))
  150.     {
  151.         m_bIsVBRS = TRUE;
  152.     }
  153. #endif /* #if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC) */
  154.     if (theError == HXR_OK)
  155.     {
  156. if (m_Interleaver) 
  157. {
  158.     theError = m_Interleaver->Init(&m_Param.uCodecFrameSize,
  159.    &m_Param.uInterleaveBlockSize,
  160.    &m_Param.uInterleaveFactor,
  161.    m_Param.interleavePattern);
  162. }
  163. m_ulSuperBlockSize = m_Param.uInterleaveBlockSize * m_Param.uInterleaveFactor;
  164. if (theError == HXR_OK)
  165. {
  166.     m_fMsPerByte = (double) (1./(m_Param.uChannels * 
  167. (m_Param.uSampleSize/8) * 
  168. (double) m_Param.ulSampleRate/1000.));
  169.     // Compute the less accurate msPerBlock - but more reliable
  170.     if (m_Param.ulBytesPerMin != 0.0)
  171.     {
  172. m_fmsPerBlock = 
  173.     ((double)(m_Param.uInterleaveBlockSize * 60000)) / m_Param.ulBytesPerMin;
  174.     }
  175.     if (m_ulSamplesIn != 0)
  176.     {
  177. /* Compute more accurate msPerBlock - 
  178.    however some codecs report samplesIn incorrectly 
  179.    (by an integer factor).  Thus, apply the more accurate
  180.    computation only if it is in the ballpark of the
  181.    less accurate one to filter out any rogue reports. */
  182. double fRatio = 1.0;
  183. double fmsPerBlock = ((double) (1000 * m_ulSamplesIn)) /
  184.      ((double) (m_Param.ulSampleRate * m_Param.uChannels));
  185.                 if (m_bReliableSamplesIn)
  186.                 {
  187.                     // If the m_bReliableSamplesIn flag is set to TRUE,
  188.                     // then this indicates that the fmsPerBlock value computed
  189.                     // from the codec's SamplesIn property should be
  190.                     // used in computing the fmsPerBlock UNCONDITIONALLY
  191.                     m_fmsPerBlock = fmsPerBlock;
  192.                 }
  193.                 else
  194.                 {
  195.     if (m_fmsPerBlock != 0.0)
  196.     {
  197.         fRatio = fmsPerBlock / m_fmsPerBlock;
  198.     }
  199.     if ((fRatio > 0.94) && (fRatio < 1.06))
  200.     {
  201.         m_fmsPerBlock = fmsPerBlock;
  202.     }
  203.                 }
  204.     }
  205. }
  206. HX_ASSERT(m_fmsPerBlock != 0.0);
  207.     }
  208.     return theError;
  209. }
  210. HX_RESULT
  211. CInterleaveBufs::AllocIBufs (void)
  212. {
  213.     DeallocIBufs();
  214.     UINT32 ulAllocSize = m_ulSuperBlockSize;
  215. #if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC)
  216.     if (m_bIsVBRS)
  217.     {
  218.         ulAllocSize = m_ulVBRSMaxBufSize;
  219.     }
  220. #endif /* #if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC) */
  221.     m_pIDataBuf = new Byte[ulAllocSize];
  222.     if( m_bDeinterleaveInPlace == TRUE )
  223.     {
  224.        m_pDDataBuf = m_pIDataBuf;
  225.     }
  226.     else
  227.     {
  228.        m_pDDataBuf = new Byte [ulAllocSize];
  229.     }
  230.     m_pIPresent = new UINT32[m_Param.uInterleaveFactor];
  231.     // set the present flags for the interleaved buffer
  232.     memset(m_pIPresent, 0, m_Param.uInterleaveFactor * sizeof(UINT32));
  233.     m_pDPresent = new UINT32[m_Param.uInterleaveFactor];
  234.     m_pIActualTimestamps = new double[m_Param.uInterleaveFactor];
  235.     m_pDActualTimestamps = new double[m_Param.uInterleaveFactor];
  236.     
  237.     if (!m_pIDataBuf || !m_pDDataBuf || 
  238. !m_pIPresent || !m_pDPresent || 
  239. !m_pIActualTimestamps || !m_pDActualTimestamps)
  240.     {
  241. DeallocIBufs();
  242. return HXR_OUTOFMEMORY;
  243.     }
  244.     return HXR_OK;
  245. }
  246. void
  247. CInterleaveBufs::DeallocIBufs (void)
  248. {
  249.     HX_VECTOR_DELETE(m_pIDataBuf);
  250.     if( m_bDeinterleaveInPlace == FALSE )
  251.     {
  252.        HX_VECTOR_DELETE(m_pDDataBuf);
  253.     }
  254.     HX_VECTOR_DELETE(m_pIPresent);
  255.     HX_VECTOR_DELETE(m_pDPresent);
  256.     HX_VECTOR_DELETE(m_pIActualTimestamps);
  257.     HX_VECTOR_DELETE(m_pDActualTimestamps);
  258. }
  259. HX_RESULT 
  260. CInterleaveBufs::DeInterleaveData()
  261. {
  262.     // if the interleave buffer isn't full, we cannot deinterleave
  263.     if (!m_bISuperBlockDone)
  264. return HXR_NO_DATA;
  265.     // XXXJEFFA this assert was commented out, why?
  266.     // Why do we need this if statement?  If we aren't
  267.     // paying attention to the state flag, why have it?
  268.     HX_ASSERT (m_bDSuperBlockEmpty);
  269.     m_bDSuperBlockEmpty = TRUE;
  270.     if (m_Interleaver)
  271.     {
  272. HX_RESULT   theError;
  273. UINT16     outSize;
  274. theError = m_Interleaver->ErrorCorrection2(m_pIDataBuf, 
  275.    (UINT16) m_ulSuperBlockSize, 
  276.    m_pDDataBuf, 
  277.    &outSize, 
  278.    m_pIPresent, 
  279.    m_Param.ulGranularity);
  280. if (theError != HXR_OK)
  281. {
  282.    goto cleanup;
  283. }
  284. #if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC)
  285.         if (m_bIsVBRS)
  286.         {
  287.             m_ulVBRSDBufBytes = outSize;
  288.         }
  289.         else
  290. #endif /* #if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC) */
  291.         {
  292.             HX_ASSERT (outSize == m_ulSuperBlockSize);
  293.         }
  294.     }
  295.     else
  296.     {
  297. // XXXJEFFA we should just swap pointers here instead
  298. // of memcpying
  299. memcpy(m_pDDataBuf, m_pIDataBuf, m_ulSuperBlockSize); /* Flawfinder: ignore */
  300.     }
  301.     /* This should happen ONLY if we have received endofpackets() */
  302.     HX_ASSERT(m_bEndOfPackets || m_uNumIBlocks >= m_Param.uInterleaveFactor);
  303.     // if the number of interleave blocks recieved is less than the interleave
  304.     // factor then we assume we didn't fill in the whole superblock because
  305.     // we were either stopped during playback or the encoding didn't fill
  306.     // up the entire superblock.  We fill in the remaining timestamp vector
  307.     // values for the rest of the blocks in the superblock for book keeping
  308.     // purposes
  309.     if (m_uNumIBlocks < m_Param.uInterleaveFactor)
  310.     {
  311. /* Fill in the right timestamps for the missing packets */
  312. for (UINT16 i=m_uNumIBlocks; i < m_Param.uInterleaveFactor; i++)
  313. {
  314.     m_pIActualTimestamps[i]   = m_fActualTimestamp;
  315.     INCREMENT_FLOAT_TS(m_fActualTimestamp, m_fmsPerBlock);
  316. }
  317.     }
  318.     // XXXJEFFA we could swap pointers here instead of memcpying
  319.     //
  320.     // we've moved the data, now move the present flags and timestamps from the
  321.     // interleave blocks to the de-interleave blocks
  322.     memcpy(m_pDPresent, m_pIPresent, m_Param.uInterleaveFactor * sizeof(UINT32)); /* Flawfinder: ignore */
  323.     memcpy(m_pDActualTimestamps, m_pIActualTimestamps, m_Param.uInterleaveFactor * sizeof(double)); /* Flawfinder: ignore */
  324.     // reset the present flags for the interleaved buffer
  325.     memset(m_pIPresent, 0, m_Param.uInterleaveFactor * sizeof(UINT32));
  326.     // if we go here we have a full deinterleaved super block
  327.     m_bDSuperBlockEmpty = FALSE;
  328. cleanup:
  329.     if( m_bDeinterleaveInPlace == FALSE )
  330.     {
  331.        m_bISuperBlockEmpty = TRUE;
  332.        m_bISuperBlockDone = FALSE;
  333.        m_uNumIBlocks = 0;
  334.        m_uBlockToDecode = 0;
  335.     }
  336.     // fix up the time ranges
  337.     if (!m_bDSuperBlockEmpty)
  338.     {
  339. double fEndTS = m_pDActualTimestamps[m_Param.uInterleaveFactor - 1];
  340. INCREMENT_FLOAT_TS(fEndTS, m_fmsPerBlock);
  341. if (m_DBlockTimeRange.m_ulStart == NO_TIME_SET)
  342. {
  343.     if (m_bLastDecodedTimeSet)
  344.     {
  345. m_DBlockTimeRange.m_ulStart = (UINT32) m_fLastDecodedTime;
  346.     }
  347.     else
  348.     {
  349. m_fLastDecodedTime = m_pDActualTimestamps[0];
  350. m_DBlockTimeRange.m_ulStart = (UINT32) m_fLastDecodedTime;
  351. m_bLastDecodedTimeSet = TRUE;
  352.     }
  353. }
  354. m_DBlockTimeRange.m_ulEnd = (UINT32)(fEndTS);
  355. DEBUG_OUTF_IDX(m_uStreamNumber, RA_FLOW_FILE, 
  356.     (s, "DBufDone: Start=%d, End=%dn",
  357.      m_DBlockTimeRange.m_ulStart % MAX_TS_DBG_RANGE,
  358.      m_DBlockTimeRange.m_ulEnd % MAX_TS_DBG_RANGE));
  359.     }
  360.     else
  361.     {
  362.         m_DBlockTimeRange.m_ulStart = NO_TIME_SET;
  363. m_DBlockTimeRange.m_ulEnd = NO_TIME_SET;
  364.     }
  365.     m_IBlockTimeRange.m_ulStart = NO_TIME_SET;
  366.     m_IBlockTimeRange.m_ulEnd = NO_TIME_SET;
  367.     return HXR_OK;
  368. }
  369. BOOL
  370. CInterleaveBufs::IsISuperBlockFilled(void)
  371. {
  372.     return m_bISuperBlockDone;
  373. }
  374. BOOL
  375. CInterleaveBufs::IsDSuperBlockEmpty(void)
  376. {
  377.     return m_bDSuperBlockEmpty;
  378. }
  379. BOOL
  380. CInterleaveBufs::IsStreamDone(void)
  381. {
  382.     return (m_bEndOfPackets && 
  383.     m_bDSuperBlockEmpty && 
  384.     m_bISuperBlockEmpty);
  385. }
  386. HX_RESULT 
  387. CInterleaveBufs::OnPacket(Byte* pData, UINT32 ulSize, UINT32 ulSequence, 
  388.      UINT32 ulTimestamp, BOOL bLost, UINT16 usFlag)
  389. {
  390.     HX_RESULT theError = HXR_OK;
  391.     INT16 i = 0;
  392.     UINT16 j = 0;
  393.     UINT16 uBlockNum = 0;
  394.     // we got off superblock alignment here so throw away any data we
  395.     // have in the interleave buffer and start again with this packet
  396.     if ((usFlag & HX_KEYFRAME_FLAG) &&
  397. (!m_bISuperBlockEmpty))
  398.     {
  399. m_bISuperBlockEmpty = TRUE;
  400. m_bISuperBlockDone = FALSE;
  401. m_uNumIBlocks = 0;
  402. m_bFirstPacketReceived = FALSE;
  403.     }
  404.     m_bEndOfPackets = FALSE;
  405.     if (m_bISuperBlockEmpty)
  406.     {
  407. m_ulFirstSequenceNum = ulSequence;
  408. m_bISuperBlockEmpty = FALSE;
  409.     }
  410.     // Calculate block location
  411.     uBlockNum = (UINT16) (ulSequence - m_ulFirstSequenceNum);
  412.     
  413.     // Se if this block is in range
  414.     if (uBlockNum >= m_Param.uInterleaveFactor)
  415.     {
  416. // We have received block from next superblock
  417. HX_ASSERT(uBlockNum < m_Param.uInterleaveFactor);
  418. if (!bLost)
  419. {
  420.     // We need to make a choice to either flush the superblock data
  421.     // we have at this point or treat this packet as lost and finish
  422.     // off the current super-block.
  423.     UINT16 ulDataBlocksInSuperBlock = 0;
  424.     // Se how far away the new block is
  425.     UINT16 uNewBlockNum = (UINT16) (ulSequence - 
  426.     (m_ulFirstSequenceNum + 
  427.      m_Param.uInterleaveFactor));
  428.     // See how valuable the current data is
  429.     for (j = 0; j < uBlockNum; j++)
  430.     {
  431. if (m_pIPresent[i])
  432. {
  433.     ulDataBlocksInSuperBlock++;
  434. }
  435.     }
  436.     // Decide whtether to keep current super-block or loose packet
  437.     if ((ulDataBlocksInSuperBlock == 0) ||
  438. (((m_Param.uInterleaveFactor / ulDataBlocksInSuperBlock) > 
  439.   SUPERBLOCK_VALUE_FACTOR) &&
  440.  (uNewBlockNum < m_Param.uInterleaveFactor)))
  441.     {
  442. // Current superblock data is not valuable enough - flush it
  443. uBlockNum = uNewBlockNum % m_Param.uInterleaveFactor;
  444. m_ulFirstSequenceNum = ulSequence - uBlockNum;
  445. // reset the present flags for the interleaved buffer
  446. memset(m_pIPresent, 0, m_Param.uInterleaveFactor * sizeof(UINT32));
  447. m_bISuperBlockDone = FALSE;
  448.     }
  449.     else
  450.     {
  451. // Current superblock data is valuable enough, loose the packet
  452. bLost = TRUE;
  453. uBlockNum = m_Param.uInterleaveFactor - 1;
  454. theError = HXR_BUFFER_NOT_AVAILABLE;
  455.     }
  456. }
  457. else
  458. {
  459.     // Finish of the current superblock
  460.     uBlockNum = m_Param.uInterleaveFactor - 1;
  461. }
  462.     }
  463.     HX_ASSERT(uBlockNum < m_Param.uInterleaveFactor);
  464.     m_uNumIBlocks = uBlockNum + 1;
  465.     // Copy block into place
  466.     if (!bLost)
  467.     {
  468. #if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC)
  469.         // If we are VBRS, then our sizes won't
  470.         // necessarily match up every time to the
  471.         // interleave block size, since the interleave
  472.         // block size is just an average
  473.         if (m_bIsVBRS)
  474.         {
  475.             // XXXMEH TODO: Make sanity check here for < m_ulVBRSMaxBufSize
  476.     memcpy(m_pIDataBuf, /* Flawfinder: ignore */
  477.            pData, 
  478.            ulSize);
  479.             /* Since this is VBR, superblock size is 
  480.        variable and changes from packet to packet */
  481.             m_ulSuperBlockSize = ulSize;
  482.         }
  483.         else
  484. #endif /* #if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC) */
  485.         {
  486.     if (ulSize != m_Param.uInterleaveBlockSize)
  487.     {
  488.         return HXR_BAD_FORMAT;
  489.     }
  490.     memcpy(m_pIDataBuf + (uBlockNum * m_Param.uInterleaveBlockSize), /* Flawfinder: ignore */
  491.            pData, 
  492.            ulSize);
  493.         }
  494. m_pIPresent[uBlockNum] = 0xffffffff;
  495. // Timestamps:
  496. // we are calculating the timestamps for the blocks of the superblock here
  497. // since old non-switchable content doesn't have unique timestamps for each
  498. // block of a superblock, we resync the timestamps at superblock boundaries
  499. if ((uBlockNum == 0) || (!m_bFirstPacketReceived))
  500. {
  501.     /* If this is the first non-lost packet, initialize the 
  502.      * current timestamp counter, m_bFirstpacketRecieved tells us
  503.      * if we've recieved a whole packet for this superblock or the
  504.      * initial packets were lost
  505.     */ 
  506.     m_fActualTimestamp  = UINT32_TO_DOUBLE(ulTimestamp);
  507. }
  508.     }
  509.     m_pIActualTimestamps[uBlockNum] = m_fActualTimestamp;
  510.     INCREMENT_FLOAT_TS(m_fActualTimestamp, m_fmsPerBlock);
  511.     // Check if superblock is done
  512.     if (uBlockNum == (m_Param.uInterleaveFactor - 1))
  513.     {
  514. i = uBlockNum;
  515. while ((i > 0) && (m_pIPresent[i] == 0))
  516. {
  517.     i--;
  518. }
  519. // if all of the present flags are set to 0 then we lost 
  520. // the entire superblock, resync on the next block
  521. if ((m_pIPresent[i] == 0) && (m_Param.uInterleaveFactor > 1))
  522. {
  523.     DEBUG_OUTF(SPLICE_FILE, (s, "Lost entire superblockt%lun", ulTimestamp));
  524.     m_bISuperBlockEmpty = TRUE;
  525.     m_bISuperBlockDone = FALSE;
  526.     m_uNumIBlocks = 0;
  527.     m_bFirstPacketReceived = FALSE;
  528. }
  529. else
  530. {
  531.     m_bISuperBlockDone = TRUE;
  532.          m_ulFirstSequenceNum += m_Param.uInterleaveFactor;
  533. }
  534.     }
  535.     else
  536.     {
  537. HX_ASSERT(m_uNumIBlocks < m_Param.uInterleaveFactor);
  538.     }
  539.     // if we haven't recieved an actual packet for this superblock yet
  540.     // (i.e. the previous packets were lost) we now go back and
  541.     // give the lost blocks timestamps based on the timestamp for this
  542.     // packet
  543.     if (!m_bFirstPacketReceived)
  544.     {
  545. if (bLost && (m_Param.uInterleaveFactor == 1))
  546. {
  547.     // This logic prevents:
  548.     // If interleave factor is one and we seek backwards and lose 
  549.     // the very first (few) packet(s), we do not know the time of 
  550.     // these packets to report.
  551.     m_bISuperBlockDone = FALSE;
  552. }
  553. else if (!bLost)
  554. {
  555.     // we only have to fixup the previous lost packets for this
  556.     // superblock, if this is the first block (uBlockNum == 0),
  557.     // we don't have any fixup to do.
  558.     if (uBlockNum != 0)
  559.     {
  560. double ts;
  561. i = uBlockNum - 1;
  562. for (j = 2; i >= 0; i--, j++)
  563. {
  564.     ts = m_fActualTimestamp - m_fmsPerBlock * j;
  565.     if (ts < 0.0)
  566.     {
  567. ts = 0.0;
  568.     }
  569.     /* Mark the actual timestamps as our own computed ts */
  570.     m_pIActualTimestamps[i] = ts;
  571. }
  572.     }
  573.     m_bFirstPacketReceived = TRUE;
  574. }
  575.     }
  576.     // update the IBlock Time stamp range
  577.     m_IBlockTimeRange.m_ulStart = (UINT32) m_pIActualTimestamps[0];
  578.     m_IBlockTimeRange.m_ulEnd = (UINT32) 
  579. (m_pIActualTimestamps[uBlockNum] + m_fmsPerBlock);
  580.     return theError;
  581. }
  582. BOOL 
  583. CInterleaveBufs::DataAvailable(AUDIO_STATE audioState)
  584. {
  585.     // We normally keep both superblocks buffered but if we are done
  586.     // or switching we only require there to be data in the 
  587.     // de-interleaved superblock.
  588.     switch (audioState)
  589.     {
  590. case AUDIO_CROSSFADE:
  591. case AUDIO_DRYNOTIFICATION:
  592. case AUDIO_END_OF_PACKETS:
  593.     return !m_bDSuperBlockEmpty;
  594.     break;
  595. default:
  596.     return !m_bDSuperBlockEmpty && !m_bISuperBlockEmpty;
  597.     break;
  598.     }
  599. }
  600. HX_RESULT 
  601. CInterleaveBufs::NextBlock(void)
  602. {
  603.     if (m_bDSuperBlockEmpty)
  604.     {
  605. return HXR_NO_DATA;
  606.     }
  607.     HX_ASSERT(m_uBlockToDecode < m_Param.uInterleaveFactor);
  608.     m_uBlockToDecode++;
  609.     if (m_uBlockToDecode == m_Param.uInterleaveFactor)
  610.     {
  611. m_bDSuperBlockEmpty = TRUE;
  612.         m_DBlockTimeRange.m_ulStart = NO_TIME_SET;
  613. m_DBlockTimeRange.m_ulEnd = NO_TIME_SET;
  614.         if( m_bDeinterleaveInPlace == TRUE )
  615.         {
  616.            m_bISuperBlockEmpty = TRUE;
  617.            m_bISuperBlockDone = FALSE;
  618.            m_uNumIBlocks = 0;
  619.            m_uBlockToDecode = 0;
  620.         }
  621.     }
  622.     return HXR_OK;
  623. }
  624. HX_RESULT 
  625. CInterleaveBufs::GetBlock(Byte** hData, 
  626.      UINT32* pDataSize, 
  627.      UINT32* pDataFlags, 
  628.      UINT32* pTimestamp,
  629.      UINT32* pActualTimestamp)
  630. {
  631.     if (m_bDSuperBlockEmpty)
  632.     {
  633. return HXR_NO_DATA;
  634.     }
  635.     HX_ASSERT(m_uBlockToDecode < m_Param.uInterleaveFactor);
  636. #if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC)
  637.     if (m_bIsVBRS)
  638.     {
  639.         *hData     = m_pDDataBuf;
  640.         *pDataSize = m_ulVBRSDBufBytes;
  641.     }
  642.     else
  643. #endif /* #if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC) */
  644.     {
  645.         *hData     = m_pDDataBuf + (m_uBlockToDecode * m_Param.uInterleaveBlockSize);
  646.         *pDataSize = m_Param.uInterleaveBlockSize;
  647.     }
  648.     *pDataFlags = m_pDPresent[m_uBlockToDecode];
  649.     *pTimestamp = (ULONG32) m_pDActualTimestamps[m_uBlockToDecode];
  650.     return HXR_OK;
  651. }
  652. void     
  653. CInterleaveBufs::NumDecodedBytes(UINT32 ulNumDecodedBytes)
  654. {
  655.     if (m_bLastDecodedTimeSet)
  656.     {
  657. INCREMENT_FLOAT_TS(m_fLastDecodedTime, CalcMs(ulNumDecodedBytes));
  658. m_DBlockTimeRange.m_ulStart = (UINT32) m_fLastDecodedTime;
  659.     }
  660. }
  661. void     
  662. CInterleaveBufs::NumDecodedBytes(UINT32 ulEndingTS, UINT32 ulNumDecodedBytes)
  663. {
  664.     m_fLastDecodedTime = UINT32_TO_DOUBLE(ulEndingTS);
  665.     m_bLastDecodedTimeSet = TRUE;
  666.     NumDecodedBytes(ulNumDecodedBytes);
  667. }
  668. double
  669. CInterleaveBufs::CalcMs(UINT32 ulNumBytes)
  670. {
  671.     return ulNumBytes * m_fMsPerByte;
  672. }
  673. UINT32
  674. CInterleaveBufs::CalcBytes(double fMs)
  675. {
  676.     return ((UINT32) (fMs / m_fMsPerByte + 0.5));
  677. }
  678. void 
  679. CInterleaveBufs::SwitchOff(void)
  680. {
  681.     m_bISuperBlockEmpty = TRUE;
  682.     m_bISuperBlockDone = FALSE;
  683.     m_bFirstPacketReceived = FALSE;
  684.     m_bDSuperBlockEmpty = TRUE;
  685.     m_uNumIBlocks = 0;
  686.     m_bLastDecodedTimeSet = FALSE;
  687.     m_fLastDecodedTime = 0.0;
  688.     m_DBlockTimeRange.m_ulStart = NO_TIME_SET;
  689.     m_DBlockTimeRange.m_ulEnd = NO_TIME_SET;
  690.     m_IBlockTimeRange.m_ulStart = NO_TIME_SET;
  691.     m_IBlockTimeRange.m_ulEnd = NO_TIME_SET;
  692. }
  693. HX_RESULT
  694. CInterleaveBufs::OnSeek(void)
  695. {
  696.     DEBUG_OUTF(SPLICE_FILE, (s, "Seekt%pt*******n", this));
  697.     SwitchOff();
  698.     return HXR_OK;
  699. }
  700. void 
  701. CInterleaveBufs::OnEndofPackets(void)
  702. {
  703.     m_bEndOfPackets = TRUE;
  704.     if ((m_Param.uInterleaveFactor > 1) && (!m_bISuperBlockEmpty))
  705.     {
  706. m_bISuperBlockDone = TRUE;
  707.     }
  708. }