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

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.  *  Includes
  37.  */
  38. #include "hlxclib/stdio.h"
  39. #include "hlxclib/string.h"
  40. #include "raformat.h"
  41. #include "smppkfdr.h"
  42. #include "raparser.h"
  43. #include "raibufs.h"
  44. #include "rafactry.h"
  45. #include "hxstrutl.h"
  46. #include "hxmime.h"
  47. #include "adjtime.h"
  48. #ifdef _DEBUG
  49. #undef HX_THIS_FILE
  50. static const char HX_THIS_FILE[] = __FILE__;
  51. #endif
  52. /****************************************************************************
  53.  *  Defines
  54.  */
  55. //#define RAFORMAT_LOGING_ON
  56. #ifdef RAFORMAT_LOGING_ON
  57. #define LOG_PATH     "c:\log\rarender\raformat\"
  58. #define SPLICE_FILE     LOG_PATH##"splice.txt"
  59. #define TIMERANGE_FILE     LOG_PATH##"timerange.txt"
  60. #define PLACE_FILE     LOG_PATH##"place.txt"
  61. #define XFADE_FILE     LOG_PATH##"xfade.txt"
  62. #define DISCARDUNTIL_FILE   LOG_PATH##"discarduntil.txt"
  63. #define TREND_FILE     LOG_PATH##"trend.txt"
  64. #define TR_FILE     LOG_PATH##"timerange.txt"
  65. #define ONPACKET_FILE     LOG_PATH##"packet.txt"
  66. #define TIME_FILE     LOG_PATH##"time.txt"
  67. #define DOAUDIO_FILE     LOG_PATH##"doaudio.txt"
  68. #else
  69. #define SPLICE_FILE     0
  70. #define TIMERANGE_FILE     0
  71. #define PLACE_FILE     0
  72. #define XFADE_FILE     0
  73. #define DISCARDUNTIL_FILE   0
  74. #define TREND_FILE     0
  75. #define TR_FILE     0
  76. #define ONPACKET_FILE     0
  77. #define TIME_FILE     0
  78. #define DOAUDIO_FILE     0
  79. #endif
  80. #define MINMAX_BLOCK_GAP 1 // in ms
  81. #define MAXMAX_BLOCK_GAP 30 // in ms
  82. #define MIN_CODEC_BLOCK_DELAY 3 // in ms
  83. #define MAX_TOLERABLE_BLOCK_YIELD_DEFICIENCY 4 // in bytes
  84. #define MAX_AUDIO_DATA_ATTEMPTS 30
  85. #define DFLT_AUDIO_BUF_SIZE 32768
  86. /****************************************************************************
  87.  *  CRaFormat
  88.  */
  89. /****************************************************************************
  90.  *  Constructor & Destructor
  91.  */
  92. CRaFormat::CRaFormat (IUnknown* pContext,
  93.       IHXCommonClassFactory* pCommonClassFactory,
  94.       IHXErrorMessages* pErrorMessages,
  95.       UINT16* pRuleToFlagMap,
  96.       UINT16 uStreamNumber)
  97.     : m_IBufs(m_StreamParam, uStreamNumber)
  98.     , m_pContext(pContext)
  99.     , m_pPacketFeeder(NULL)
  100.     , m_pCodec(NULL)
  101.     , m_ulAudioBufSize(0)
  102.     , m_pUpgradeCollection(NULL)
  103.     , m_ulCrossFadeEndTime(NO_TIME_SET)
  104.     , m_ulForceDiscardUntilTime(NO_TIME_SET)
  105.     , m_ulLastPacketTime(NO_TIME_SET)
  106.     , m_ulBytesWrite(0)
  107.     , m_pAudioSync(NULL)
  108.     , m_bRegistered(FALSE)
  109.     , m_lTimeOffset(0)
  110.     , m_ulTrackStartTime(0)
  111.     , m_ulTrackEndTime(0)
  112.     , m_bForceInterleaved(FALSE)
  113.     , m_bFirstPacket(TRUE)
  114.     , m_bDeterminedAdjustment(FALSE)
  115.     , m_bForceStartTrackTime(FALSE)
  116.     , m_bForceEndTrackTime(FALSE)
  117.     , m_bAdjustTimestamps(FALSE)
  118.     , m_bEndOfPackets(FALSE)
  119.     , m_ulNextAudioTime(NO_TIME_SET)
  120.     , m_ulNextActualAudioTime(NO_TIME_SET)
  121.     , m_bSecure(FALSE)
  122.     , m_bIsVBR(FALSE)
  123.     , m_uStreamNumber(uStreamNumber)
  124.     , m_ulMaxBlockGap(MAXMAX_BLOCK_GAP)
  125.     , m_ulMinExpectedDecodedBlockSize(0)
  126.     , m_ulCodecDelay(0)
  127.     , m_fCodecDelay(0.0)
  128.     , m_bPCMStreamStart(TRUE)
  129.     , m_pRuleToFlagMap(pRuleToFlagMap)
  130.     , m_pCachingClassFactory(NULL)
  131. {
  132.     if (m_pContext)
  133.     {
  134. m_pContext->AddRef();
  135.     }
  136.     m_pCommonClassFactory = pCommonClassFactory;
  137.     if (m_pCommonClassFactory)
  138.     {
  139. m_pCommonClassFactory->AddRef();
  140.     }
  141.     if (m_pContext)
  142.     {
  143. m_pContext->QueryInterface(IID_IHXUpgradeCollection, 
  144.    (void**) &m_pUpgradeCollection);
  145.     }
  146.     if (pErrorMessages)
  147.     {
  148. m_pErrorMessages = pErrorMessages;
  149. m_pErrorMessages->AddRef();
  150.     }
  151. }
  152. CRaFormat::~CRaFormat()
  153. {
  154.     if (m_pCodec)
  155.     {
  156. m_pCodec->FreeDecoder();
  157. HX_DELETE(m_pCodec);
  158.     }
  159.     HX_DELETE(m_pPacketFeeder);
  160.     HX_RELEASE(m_pUpgradeCollection);
  161.     if( m_pCachingClassFactory )
  162.     {
  163.        HX_RELEASE(m_pCachingClassFactory);
  164.     }
  165.     HX_RELEASE(m_pCommonClassFactory);
  166.     HX_RELEASE(m_pErrorMessages);
  167.     HX_RELEASE(m_pContext);
  168. }
  169. // Read Header
  170. HX_RESULT
  171. CRaFormat::NewReadRAHeader (Byte* buffer, 
  172.     UINT32 bLength, 
  173.     BOOL bForceStartTrackTime,
  174.     BOOL bForceEndTrackTime,
  175.     UINT32 ulTrackStartTime,
  176.     UINT32 ulTrackEndTime,
  177.     UINT32* pBytesRead, 
  178.     char* pAllCodecs,
  179.                             UINT32      ulAllCodecsBufLen)
  180. {
  181.     HX_RESULT theError = HXR_INVALID_FILE;
  182.     
  183.     m_bForceStartTrackTime = bForceStartTrackTime;
  184.     m_bForceEndTrackTime = bForceEndTrackTime;
  185.     m_ulTrackStartTime = ulTrackStartTime;
  186.     m_ulTrackEndTime = ulTrackEndTime;
  187.     theError = m_StreamParam.ReadOneRAHeader(buffer, bLength, pBytesRead);
  188.     // add this codec to the AllCodecs list (if its not already in there)
  189.     if (m_StreamParam.codecID && pAllCodecs && (strstr(pAllCodecs, m_StreamParam.codecID) == 0))
  190.     {
  191. char szBuffer[64]; /* Flawfinder: ignore */
  192. if (*pAllCodecs == '')
  193. {
  194.     SafeStrCpy(szBuffer,  m_StreamParam.codecID, 64);
  195. }
  196. else
  197. {
  198.     SafeSprintf(szBuffer, 64, ", %s", m_StreamParam.codecID);
  199. }
  200. SafeStrCat(pAllCodecs, szBuffer, ulAllCodecsBufLen);
  201.     }
  202.    
  203. #if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC)
  204.     // If we are RAAC and VBRS then we need to
  205.     // tell the interleave bufs class to use the
  206.     // SamplesIn property to compute the ms per block
  207.     if ((theError == HXR_OK) &&
  208. m_StreamParam.interleaverID &&
  209.         (!strcmp(m_StreamParam.interleaverID, RA_INTERLEAVER_VBRS_ID) ||
  210.          !strcmp(m_StreamParam.interleaverID, RA_INTERLEAVER_VBRF_ID)))
  211.     {
  212. m_bIsVBR = TRUE;
  213.     }
  214. #endif /* #if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC) */
  215.     // initialize codecs
  216.     if (theError == HXR_OK)
  217.     {
  218.         theError = LoadDecoderAndInitDeInterleaver();
  219.     }
  220. #if defined(HELIX_FEATURE_AUTOUPGRADE)
  221.     else if (theError == HXR_INVALID_VERSION ||
  222.              theError == HXR_INVALID_REVISION)
  223.     {
  224.         // We parsed out an invalid RAformat version
  225.         // or revision, a condition on which we should AU.
  226.         ThrowUpgrade(REALAUDIO_MIME_TYPE);
  227.     }
  228. #endif /* #if defined(HELIX_FEATURE_AUTOUPGRADE) */
  229.     if (m_StreamParam.uInterleaveFactor == 1)
  230.     {
  231. // if the data isn't interleaved then we know 
  232. // we don't have to adjust the timestamps
  233. m_bDeterminedAdjustment = TRUE;
  234.     }
  235.     if (m_bIsVBR)
  236.     {
  237. m_IBufs.SetReliableSamplesIn(TRUE);
  238.     }
  239.     // initialize interleavers
  240.     if (theError == HXR_OK)
  241.     {
  242.         theError = m_IBufs.InitDeinterleaver();
  243.         if (theError == HXR_INVALID_INTERLEAVER)
  244.         {
  245.             // We had an unknown interleaver type, a condition
  246.             // for which we should AU.
  247.             ThrowUpgrade(REALAUDIO_MIME_TYPE);
  248.         }
  249.     }
  250.     // create superblock allocation
  251.     if (theError == HXR_OK)
  252.     {
  253. theError = m_IBufs.AllocIBufs();
  254.     }
  255.     
  256.     // create packet interleave puffer packet feeder
  257.     if (theError == HXR_OK)
  258.     {
  259. m_pPacketFeeder = CreatePacketFeeder();
  260. theError = HXR_OUTOFMEMORY;
  261. if (m_pPacketFeeder)
  262. {
  263.     theError = HXR_OK;
  264. }
  265.     }
  266.     if (theError == HXR_OK)
  267.     {
  268. if (GetMSPerBlock() >= 1.0)
  269. {
  270.     m_ulMaxBlockGap = (UINT32) (GetMSPerBlock() / 4.0 + 0.5);
  271.     // Assume max time stamp drift of 1 ms per block of superblock
  272.     if (m_ulMaxBlockGap < GetInterleaveFactor())
  273.     {
  274. m_ulMaxBlockGap = GetInterleaveFactor();
  275.     }
  276. }
  277. if (m_ulMaxBlockGap < MINMAX_BLOCK_GAP)
  278. {
  279.     m_ulMaxBlockGap = MINMAX_BLOCK_GAP;
  280. }
  281. if (m_ulMaxBlockGap > MAXMAX_BLOCK_GAP)
  282. {
  283.     m_ulMaxBlockGap = MAXMAX_BLOCK_GAP;
  284. }
  285. m_ulMinExpectedDecodedBlockSize = m_IBufs.CalcBytes(GetMSPerBlock());
  286. if (m_ulMinExpectedDecodedBlockSize > MAX_TOLERABLE_BLOCK_YIELD_DEFICIENCY)
  287. {
  288.     m_ulMinExpectedDecodedBlockSize -= MAX_TOLERABLE_BLOCK_YIELD_DEFICIENCY;
  289. }
  290.     }
  291.     DEBUG_OUTF_IDX(m_uStreamNumber, RA_FLOW_FILE, (s, "Init(%d): BlockMS=%.2f, SuperMS=%d, IBlocks=%hdn",
  292. m_uStreamNumber,
  293. GetMSPerBlock(),
  294. GetSuperBlockTime(),
  295. GetInterleaveFactor()));
  296.     return theError;
  297. }
  298. void
  299. CRaFormat::GetAudioFormat (HXAudioFormat& audioFmt)
  300. {
  301.     audioFmt.uChannels = m_StreamParam.uChannels;                
  302.     audioFmt.uBitsPerSample = m_StreamParam.uSampleSize;
  303.     audioFmt.ulSamplesPerSec = m_StreamParam.ulSampleRate;
  304.     audioFmt.uMaxBlockSize = (UINT16) m_ulAudioBufSize;
  305. }
  306. CCodec*
  307. CRaFormat::CreateDecoder(char* pCodecID)
  308. {
  309.     if (!strcmp(pCodecID, "racp"))
  310.     {
  311.         // The racp 4cc is also handled 
  312.         // by the raac codec
  313.         pCodecID = "raac";
  314.     }
  315.     return new CCodec(pCodecID, m_pContext);
  316. }
  317. CRealAudioPacketFeeder*
  318. CRaFormat::CreatePacketFeeder(void)
  319. {
  320. #if defined(HELIX_FEATURE_RAREND_ADV_PACKET_FEEDER)
  321.     // The RealAudio advanced packet feeder is distributed
  322.     // as a binary statically-linked library and therefore must
  323.     // be created from this factory class that resides in the libary.
  324.     return CRealAudioRendererFactory::CreateRealAudioAdvancedPacketFeeder(m_StreamParam, 
  325.                                                                           m_IBufs, 
  326.                                                                           m_pRuleToFlagMap,
  327.                                                                           m_uStreamNumber);
  328. #else // HELIX_FEATURE_RAREND_ADV_PACKET_FEEDER
  329.     //otherwise we just create it directly.
  330.     return new CRealAudioSimplePacketFeeder(m_StreamParam, 
  331.                                             m_IBufs,
  332.                                             m_pRuleToFlagMap,
  333.                                             m_uStreamNumber);
  334. #endif // HELIX_FEATURE_RAREND_ADV_PACKET_FEEDER
  335. }
  336. // decoding
  337. HX_RESULT
  338. CRaFormat::InitDecoder(CStreamParam& param, CCodec** hCodec)
  339. {
  340.     HX_RESULT theError = HXR_OK;
  341.     CCodec* pCodec = NULL;
  342.     CHXBuffer* pBuffer = NULL;
  343.     pCodec = CreateDecoder(param.codecID);
  344.     if (!pCodec)
  345.     {
  346. theError = HXR_OUTOFMEMORY;
  347.     }
  348.     else
  349.     {
  350. // first load with codec w/o versioning
  351. theError = pCodec->InitCodec(FALSE);
  352. if (HXR_OK != theError)
  353. {
  354.     // try to load with codec w/ versioning(xxxx3260)
  355.     theError = pCodec->InitCodec(TRUE);
  356. }
  357.     }
  358.     if (theError == HXR_OK)
  359.     {
  360. RADECODER_INIT_PARAMS   initParams;
  361. // set up initialization parameters
  362. initParams.sampleRate = param.ulSampleRate;
  363. initParams.bitsPerSample = param.uSampleSize;
  364. initParams.channels = param.uChannels;
  365. initParams.audioQuality = 100;
  366. initParams.bitsPerFrame = param.uCodecFrameSize;
  367. initParams.granularity = param.ulGranularity;
  368. initParams.opaqueDataLength = param.ulOpaqueDataSize;
  369. initParams.opaqueData = param.opaqueData;
  370. theError = pCodec->InitDecoder(&initParams, FALSE);
  371.         // Sometimes the uChannels parameter may be passed
  372.         // in with a 0, and the decoder will update the
  373.         // value. Therefore, we need to copy the decoder
  374.         // value back.
  375.         param.uChannels = initParams.channels;
  376.         // If for some reason the channels parameter is
  377.         // still 0, then we have a problem worthy of failure
  378.         if (param.uChannels == 0)
  379.         {
  380.             theError = HXR_FAIL;
  381.         }
  382.         // The param.ulSampleRate parameter may be different
  383.         // coming out of InitDecoder() than it was going in.
  384.         // This indicates that the codec has initialized itself
  385.         // at a sample rate which is different the sample rate
  386.         // in param.ulSampleRate. This can happen in the
  387.         // case of the High-Efficiency AAC profile.
  388.         param.ulSampleRate = initParams.sampleRate;
  389.         // If for some reason the sample rate is 0, then
  390.         // we have a problem
  391.         if (param.ulSampleRate == 0)
  392.         {
  393.             theError = HXR_FAIL;
  394.         }
  395. if (theError == HXR_OK)
  396.     theError = pCodec->SetFlavor(param.uFlavorIndex);
  397.     }
  398. #if defined(HELIX_FEATURE_AUTOUPGRADE)
  399.     if (HXR_DEC_NOT_FOUND == theError || HXR_INVALID_VERSION == theError)
  400.     {
  401.         ThrowUpgrade((const char*) param.codecID);
  402.     }
  403. #endif /* #if defined(HELIX_FEATURE_AUTOUPGRADE) */
  404.     if (theError == HXR_OK)
  405.     {
  406. *hCodec = pCodec;
  407.     }
  408.     else
  409.     {
  410. *hCodec = NULL;
  411. HX_DELETE(pCodec);
  412.     }
  413.     // Ask the codec for the number of samples per block, and use this to 
  414.     // figure out exactly how big our decoded data buffer needs to be.
  415.     ULONG32 * pulSamplesPerBlock;
  416.     UINT16  uPropSize = 0;
  417.     ULONG32 ulBytesPerMinute = m_StreamParam.ulBytesPerMin;
  418.     if (pCodec)
  419.     {
  420.         pulSamplesPerBlock = (ULONG32*) pCodec->GetFlavorProperty(
  421.             param.uFlavorIndex,
  422.             FLV_PROP_SAMPLES_IN,
  423.             &uPropSize);
  424.     }
  425.     if (m_bIsVBR)
  426.     {
  427. // For VBR Streams, do not use bytes per minute to compute decoder
  428. // buffer size since bytes per minute are variable
  429. ulBytesPerMinute = 0;
  430.     }
  431. #if defined(HELIX_FEATURE_MIN_HEAP)
  432.     // In case of min_heap - always use codec reported block size when avaialable
  433.     // This however does not work correctly for some non-deafult encoder setting.
  434.     // It needs to be corrected on MIN-HEAP utilizing platforms.
  435.     if (uPropSize != 0)
  436.     {
  437. ulBytesPerMinute = 0;
  438.     }
  439. #endif // HELIX_FEATURE_MIN_HEAP
  440.     if (ulBytesPerMinute != 0)
  441.     {
  442. // Resort to backup plan: this is very non-optimal for heap usage!
  443. UINT32 uMaxSecPerBlock = (m_StreamParam.uInterleaveBlockSize * 60/ulBytesPerMinute) + 1;
  444. m_ulAudioBufSize = uMaxSecPerBlock * m_StreamParam.ulSampleRate * m_StreamParam.uSampleSize / 8 * m_StreamParam.uChannels;
  445.     }
  446.     else
  447.     {
  448. if (uPropSize)
  449. {
  450.     // The original comment in here suggested that for G2 stereo content,
  451.     // param.uChannels would wrongly indicate "1" as the number of channels.
  452.     // This cannot be reproduced anymore, but to be sure, we never allocate
  453.     // memory for less than 2 channels. The downside is that
  454.     // if we're playing a mono stream we could waste as much as ~10kb. Until 
  455.     // the codec interface is changed to allow us to get the exact size of 
  456.     // the output buffer, however, this will have to suffice.
  457.     int nchannels = param.uChannels < 2 ? 2 : param.uChannels ;
  458.             // /Fixes PR 114676: also multiply by bytes-per-sample, as is done
  459.             // in the other calculation of m_ulAudioBufSize, above, to fix
  460.             // overflow of buffer in RAAC codec's Decode() when there are
  461.             // samples to conceal.  m_ulAudioBufSize should be in total bytes
  462.             // per block (total meaning for all channels):
  463.             // (samples / block)*(bytes / sample) * channels => total bytes per block. :
  464.     m_ulAudioBufSize = (*pulSamplesPerBlock) * m_StreamParam.uSampleSize / 8 * nchannels;
  465. }
  466. else
  467. {
  468.     // There is no information on how large the decode buffer should be
  469.     m_ulAudioBufSize = DFLT_AUDIO_BUF_SIZE;
  470. }
  471.     }
  472.     return theError;
  473. }
  474. BOOL
  475. CRaFormat::IsActive()
  476. {
  477.     BOOL bRetVal = FALSE;
  478.     if ((!m_IBufs.IsDSuperBlockEmpty()) || 
  479. (!m_IBufs.IsISuperBlockEmpty()))
  480.     {
  481. bRetVal = TRUE;
  482.     }
  483.     else 
  484.     {
  485.         if( m_pPacketFeeder )
  486.         {
  487.             bRetVal = m_pPacketFeeder->IsActive();
  488.         }
  489.     }
  490.     return bRetVal;
  491. }
  492. void
  493. CRaFormat::LossOccured()
  494. {
  495.     if( m_pPacketFeeder )
  496.     {
  497. m_pPacketFeeder->LossOccured();
  498.     }
  499. }
  500. HX_RESULT 
  501. CRaFormat::OnPacket(IHXPacket* pPacket, LONG32 lTimeOffset, UINT16* rule_to_flag_map)
  502. {
  503.     HX_RESULT retVal = HXR_OK;
  504.     m_lTimeOffset = lTimeOffset;
  505.     /*
  506.     DEBUG_OUTF_IDX(m_uStreamNumber, RA_FLOW_FILE, (s, "PKT: TS=%d, Rule=%d L=%sn",
  507. pPacket->GetTime() % MAX_TS_DBG_RANGE,
  508. pPacket->GetASMRuleNumber(),
  509. pPacket->IsLost() ? "YES" : "NO"));
  510. */
  511.     retVal = m_pPacketFeeder->OnPacket(pPacket, 
  512.        lTimeOffset, 
  513.        rule_to_flag_map);
  514.     // we only deinterleave data when the input buffer 
  515.     // is filled and output buffer is empty
  516.     if (m_IBufs.IsISuperBlockFilled() && m_IBufs.IsDSuperBlockEmpty())
  517.     {
  518. // deinterleave the data and fill up the interleave buffer from
  519. // the packet queue
  520. m_IBufs.DeInterleaveData();
  521.     }
  522.     return retVal;
  523. }
  524. HX_RESULT 
  525. CRaFormat::GetAudioData(HXAudioData& audioData, 
  526. UINT32& ulActualTimestamp,
  527. AUDIO_STATE audioState, 
  528. UINT32 ulSpliceToActualTime,
  529. UINT32 ulSpliceToStreamTime)
  530. {
  531.     UINT32 ulIterationCounter = 0;
  532.     HX_RESULT pnr = HXR_NO_DATA;
  533.     if (ulSpliceToActualTime != NO_TIME_SET)
  534.     {
  535. ulSpliceToActualTime = UnAdjustTimestamp(ulSpliceToActualTime, m_lTimeOffset);
  536. ulSpliceToStreamTime = UnAdjustTimestamp(ulSpliceToStreamTime, m_lTimeOffset);
  537.     }
  538.     // if we've not determined the if we need to adjust the timestamps
  539.     // the we don't have any data available.
  540.     do
  541.     {
  542. HX_RELEASE(audioData.pData);
  543. audioData.ulAudioTime = 0;
  544. // move any data from the time range queue into the IBufs
  545. m_pPacketFeeder->FillISuperBlock();
  546. switch (audioState)
  547. {
  548.     case AUDIO_CROSSFADE:
  549.     case AUDIO_DRYNOTIFICATION:
  550.     case AUDIO_END_OF_PACKETS:
  551. if (!m_IBufs.DataAvailable(audioState))
  552. {     
  553.     // this is an "emergency" state so do this even
  554.     // if the IBlock isn't quite full
  555.     m_IBufs.DeInterleaveData();
  556. }
  557. break;
  558.     default:
  559. break;
  560. }
  561. if (m_IBufs.DataAvailable(audioState))
  562. {
  563.     pnr = DecodeAudioData(audioData, 
  564.   ulActualTimestamp,
  565.   ulSpliceToActualTime,
  566.   ulSpliceToStreamTime);
  567.     if (HXR_OK == pnr)
  568.     {
  569. // if we've fulfilled the discard, reset state
  570. if (m_ulForceDiscardUntilTime != NO_TIME_SET && 
  571.     IsTimeGreater(audioData.ulAudioTime + (UINT32)GetMSPerBlock(),
  572.   m_ulForceDiscardUntilTime))
  573. {
  574.     m_ulForceDiscardUntilTime = NO_TIME_SET;
  575. }
  576. break;
  577.     }
  578.     else if (FAILED(pnr))
  579.     {
  580. DEBUG_OUTF(DOAUDIO_FILE, (s, "GetAudioDatat%lut0x%Xn", 
  581.     (UINT32)GetMSPerBlock(), pnr));
  582.                 if( pnr == HXR_OUTOFMEMORY )
  583.                 {
  584.                    return pnr;
  585.                 }
  586. break;
  587.     }
  588.     DEBUG_OUTF(DOAUDIO_FILE, (s, "DataAvailable - no decodet%lut0x%Xn", 
  589. (UINT32)GetMSPerBlock(), pnr));
  590. }
  591. else
  592. {
  593.     BOOL bTimeRangeEnded = m_pPacketFeeder->IsCurrentTimeRangeEnded();
  594.     BOOL bDataInTimeRange = !m_pPacketFeeder->IsCurrentTimeRangeEmpty();
  595.     // if the D superblock is empty and there's more data to decode
  596.     // we give it a try to move the data into the D superblock to
  597.     // decode it.
  598.     if (m_IBufs.IsDSuperBlockEmpty() &&
  599. (!m_IBufs.IsISuperBlockEmpty() || bDataInTimeRange))
  600.     {
  601. if (m_IBufs.IsISuperBlockFilled())
  602. {
  603.     m_IBufs.DeInterleaveData();
  604. }
  605. // if we don't have any data in the De-interleaved superblock
  606. // and we failed to fill the Interleaved superblock, we
  607. // must be out of data and we should break out of the while loop
  608. if (m_IBufs.IsDSuperBlockEmpty() && 
  609.     (!m_pPacketFeeder->FillISuperBlock()))
  610. {
  611.     DEBUG_OUTF(DOAUDIO_FILE, (s, "GetAudioDatat%dt%dt%dt%dt%lun", 
  612. m_IBufs.IsDSuperBlockEmpty(), m_IBufs.IsISuperBlockEmpty(), m_IBufs.IsISuperBlockFilled(), bTimeRangeEnded, (UINT32)GetMSPerBlock()));
  613.     break;
  614. }
  615.     }
  616.     else
  617.     {
  618. HX_ASSERT(!bDataInTimeRange);
  619. // we've drained the IBufs of data from the previous TR, now
  620. // we can start the next TR if there is one.
  621. if (bTimeRangeEnded)
  622. {
  623.     if (HXR_OK == DecodeAudioData(audioData, 
  624.   ulActualTimestamp, 
  625.   ulSpliceToActualTime,
  626.   ulSpliceToStreamTime,
  627.   TRUE))
  628.     {
  629. // if we've fulfilled the discard, reset state
  630. if (m_ulForceDiscardUntilTime != NO_TIME_SET && 
  631.     IsTimeGreater(audioData.ulAudioTime + (UINT32)GetMSPerBlock(), 
  632.     m_ulForceDiscardUntilTime))
  633. {
  634.     m_ulForceDiscardUntilTime = NO_TIME_SET;
  635. }
  636. pnr = HXR_OK;
  637.     }
  638.     else
  639.     {
  640. // stream done result here tells the renderer not to expect
  641. // any more data on this format for this particular time range
  642. // so it can give up on a cross fade if it is pending one here
  643. pnr = HXR_STREAM_DONE;
  644.     }
  645.     SetupForNextTimeRange();
  646. }
  647. else
  648. {
  649.     DEBUG_OUTF(DOAUDIO_FILE, (s, "GetNextAudioDataTimet%dt%dt%dt%dt%lun", 
  650. m_IBufs.IsDSuperBlockEmpty(), m_IBufs.IsISuperBlockEmpty(), m_IBufs.IsISuperBlockFilled(), bTimeRangeEnded, (UINT32)GetMSPerBlock()));
  651. }
  652. break;
  653.     }
  654. }
  655. ulIterationCounter++;
  656.     } while (ulIterationCounter < MAX_AUDIO_DATA_ATTEMPTS);
  657.     return pnr;
  658. }
  659. HX_RESULT 
  660. CRaFormat::GenerateLostAudioData (UINT32 ulForceEndTime, 
  661.   HXAudioData& audioData,     
  662.   UINT32& ulActualTimestamp,
  663.   UINT32 ulSpliceToActualTime,
  664.   UINT32 ulSpliceToStreamTime)  
  665. {
  666.     HX_RESULT theError = HXR_FAILED;
  667.     Byte* pData = new UCHAR[m_StreamParam.uInterleaveBlockSize];
  668.     UINT32 ulInSize = m_StreamParam.uInterleaveBlockSize;
  669.     UINT32 ulDataFlags = 0;
  670.     UINT32 ulOutSize;
  671.     
  672.     ulForceEndTime = UnAdjustTimestamp(ulForceEndTime, m_lTimeOffset);
  673.     if( !m_pCodec )
  674.     {
  675. theError = LoadDecoderAndInitDeInterleaver();
  676.     }
  677.     if (m_pCodec != NULL)
  678.     {
  679. theError = m_pCachingClassFactory->CreateInstance(CLSID_IHXBuffer, 
  680.     (void**) &audioData.pData);
  681. // These buffers will initially be size 0, but since we're using 
  682. // the caching class factory, they will generally be the right size
  683. // on reuse. We can't assume this, but let's not call SetSize
  684. // unnecessarily.
  685. if( audioData.pData && audioData.pData->GetSize() != m_ulAudioBufSize )
  686. {
  687.     theError = audioData.pData->SetSize( m_ulAudioBufSize  );
  688. }
  689.         if( theError != HXR_OK )
  690.         {
  691.             return theError;
  692.         }
  693. theError = m_pCodec->Decode(pData,
  694.     ulInSize,
  695.     audioData.pData->GetBuffer(), 
  696.     &ulOutSize,
  697.     ulDataFlags);
  698. // Make the buffer size smaller if necessary, since we don't always
  699. // pass the decoder the max size of encoded data. Note that this does
  700. // not alter the heap (based on current buffer implementation).
  701. if( ulOutSize < m_ulAudioBufSize )
  702. {
  703.     theError = audioData.pData->SetSize( ulOutSize  );
  704. }
  705.     }
  706.     HX_VECTOR_DELETE(pData);
  707.     
  708.     if (theError == HXR_OK && ulOutSize == 0)
  709.     {
  710. theError = HXR_NO_DATA;
  711.     }
  712.     if (theError == HXR_OK)
  713.     {
  714. audioData.ulAudioTime = ulSpliceToStreamTime;
  715. audioData.uAudioStreamType = STREAMING_AUDIO;
  716. ulActualTimestamp = ulSpliceToActualTime;
  717. // don't forget to adjust...
  718. if (!AdjustAudioData(audioData, ulActualTimestamp, ulForceEndTime))
  719. {
  720.     HX_RELEASE(audioData.pData);
  721.     audioData.ulAudioTime = 0;
  722.     theError = HXR_FAILED;
  723. }
  724.     }
  725.     else
  726.     {
  727. HX_RELEASE( audioData.pData );
  728. audioData.pData = NULL;
  729. audioData.ulAudioTime = 0;
  730.     }
  731.     return (HXR_OK == theError) ? (HXR_OK) : (HXR_NO_DATA);
  732. }
  733. HX_RESULT CRaFormat::DecodeAudioBlock(Byte* pData, 
  734.       UINT32 ulInSize, 
  735.       Byte* pAudioBuf, 
  736.       UINT32* pOutSize, 
  737.       UINT32 ulDataFlags)
  738. {
  739.     HX_RESULT retVal = HXR_OK;
  740.     retVal = m_pCodec->Decode(pData, ulInSize, 
  741.     pAudioBuf, pOutSize, 
  742.     ulDataFlags);
  743.     return retVal;
  744. }
  745. HX_RESULT 
  746. CRaFormat::DecodeAudioData (HXAudioData& audioData, 
  747.     UINT32& ulActualTimestamp,
  748.     ULONG32 ulSpliceToActualTime,
  749.     ULONG32 ulSpliceToStreamTime,
  750.     BOOL bFlushCodec)
  751. {
  752.     HX_RESULT theError = HXR_FAILED;
  753.     Byte* pData;
  754.     UINT32 ulInSize;
  755.     UINT32 ulOutSize;
  756.     UINT32 ulDataFlags;
  757.     UINT32 ulTimestamp;
  758.     // To optimize heap, we don't use the m_pAudioBuf as a 
  759.     // temporary pcm buffer; we just decode straight into the buffer
  760.     // that we're going to dump it in anyway.  
  761.     theError = m_pCachingClassFactory->CreateInstance(CLSID_IHXBuffer, 
  762.       (void**) &audioData.pData);
  763.     if( theError != HXR_OK )
  764.     {
  765. HX_RELEASE(audioData.pData);
  766. theError = HXR_OUTOFMEMORY;
  767.     }
  768.     if (theError == HXR_OK && m_pCodec != NULL)
  769.     {
  770. theError = m_IBufs.GetBlock(&pData, 
  771.     &ulInSize, 
  772.     &ulDataFlags, 
  773.     &ulTimestamp, 
  774.     &ulActualTimestamp);
  775.     }
  776.     if (theError == HXR_OK)
  777.     {
  778. // increment the IBuf for next block
  779. m_IBufs.NextBlock();
  780. if (!GetDropBlock(ulTimestamp))
  781. {
  782.     // These buffers will initially be size 0, but since we're using 
  783.     // the caching class factory, they will generally be the right 
  784.     // on reuse. We can't assume this, but let's not call SetSize
  785.     // unnecessarily.
  786.     if( audioData.pData->GetSize() != m_ulAudioBufSize )
  787.     {
  788.         theError = audioData.pData->SetSize( m_ulAudioBufSize );
  789.     }
  790.             if( theError == HXR_OUTOFMEMORY )
  791.             {
  792.                 return theError;
  793.             }
  794.     theError = DecodeAudioBlock(pData, ulInSize, audioData.pData->GetBuffer(), 
  795. &ulOutSize, ulDataFlags);
  796. }
  797. else
  798. {
  799.     DEBUG_OUTF(DOAUDIO_FILE, (s, "DropBlockt%lut%lun", 
  800. ulTimestamp, (UINT32)GetMSPerBlock()));
  801.     // assume entire block decoded?
  802.     m_IBufs.NumDecodedBytes(ConvertMsToBytes((UINT32)GetMSPerBlock()));
  803.     m_bPCMStreamStart = TRUE;
  804.     HX_RELEASE( audioData.pData );
  805.     theError = HXR_NO_DATA;
  806. }
  807.     }
  808.     else if (theError == HXR_OK && bFlushCodec && m_pCodec != NULL)
  809.     {
  810. ulOutSize = m_ulAudioBufSize;
  811. theError = m_pCodec->Flush(audioData.pData->GetBuffer(), &ulOutSize);
  812. HX_RELEASE( audioData.pData );
  813.     }
  814.     if (theError == HXR_OK && ulOutSize  == 0)
  815.     {
  816. m_fCodecDelay += GetMSPerBlock();
  817. m_ulCodecDelay = (UINT32) m_fCodecDelay;
  818. theError = HXR_NO_DATA;
  819. HX_RELEASE( audioData.pData );
  820.     }
  821.     if (theError == HXR_OK)
  822.     {
  823. // Make the buffer size smaller if necessary, since we don't always
  824. // pass the decoder the max size of encoded data. Note that this does
  825. // not alter the heap (based on current buffer implementation).
  826. if( audioData.pData->GetSize() > ulOutSize )
  827. {
  828.     theError = audioData.pData->SetSize( ulOutSize  );
  829.             if( theError == HXR_OUTOFMEMORY )
  830.             {
  831.                 return theError;
  832.             }
  833. }
  834. audioData.ulAudioTime = ulTimestamp;
  835. if (ulOutSize < m_ulMinExpectedDecodedBlockSize)
  836. {
  837.     double fCodecDelay = (GetMSPerBlock() - m_IBufs.CalcMs(ulOutSize));
  838.     if (fCodecDelay >= MIN_CODEC_BLOCK_DELAY)
  839.     {
  840. LONG32 lCodecDelay = (UINT32) fCodecDelay;
  841. audioData.ulAudioTime += lCodecDelay;
  842. m_ulCodecDelay += lCodecDelay;
  843. m_fCodecDelay += fCodecDelay;
  844.     }
  845. }
  846. audioData.ulAudioTime -= m_ulCodecDelay;
  847. m_IBufs.NumDecodedBytes(audioData.ulAudioTime, ulOutSize);
  848. SpliceAudioData(audioData, 
  849. ulActualTimestamp, 
  850. ulSpliceToActualTime, 
  851. ulSpliceToStreamTime);
  852. m_bPCMStreamStart = FALSE;
  853. if (AdjustAudioData(audioData, ulActualTimestamp))
  854. {
  855.     m_ulNextAudioTime = audioData.ulAudioTime + 
  856. (UINT32) m_IBufs.CalcMs(audioData.pData->GetSize());
  857.     m_ulNextActualAudioTime = ulActualTimestamp +
  858. (UINT32) m_IBufs.CalcMs(audioData.pData->GetSize());
  859. }
  860. else
  861. {
  862.     m_bPCMStreamStart = TRUE;
  863.     HX_RELEASE(audioData.pData);
  864.     audioData.ulAudioTime = 0;
  865.     theError = HXR_NO_DATA;
  866. }
  867.     }
  868.     else
  869.     {
  870. HX_RELEASE( audioData.pData );
  871. audioData.pData = NULL;
  872. audioData.ulAudioTime = 0;
  873.     }
  874.     return theError;
  875. }
  876. void
  877. CRaFormat::SetCrossFadeEndTime(UINT32 ulTimestamp)
  878. {
  879.     DEBUG_OUTF(XFADE_FILE, (s, "SetXFadeEndTimet%lut%lun", ulTimestamp, (UINT32)GetMSPerBlock()));
  880.     /*
  881.      * The ulTimestamp can be in one of these 5 positions.
  882.      * We start from 4 and go to 0 looking for some data that's
  883.      * less than the ulTimestamp time.
  884.      *
  885.      *     [DDD][III] {_,_,_,}  {_,_,_,_,}
  886.      * ^     ^    ^       ^ ^
  887.      * |     |    |       | |
  888.      * 0     1    2       3 4
  889.      *
  890.      */
  891.     BOOL bDone = FALSE;
  892.     ulTimestamp = UnAdjustTimestamp(ulTimestamp, m_lTimeOffset);
  893.     m_ulCrossFadeEndTime = ulTimestamp;
  894.     // see if it's at #3
  895.     bDone = m_pPacketFeeder->SetCrossFadeEndTime(ulTimestamp);
  896.     // see if it's at #2
  897.     if (!bDone)
  898.     {
  899. if (!m_IBufs.m_IBlockTimeRange.IsEmpty())
  900. {
  901.     if (m_IBufs.m_IBlockTimeRange.TimeInRange(ulTimestamp))
  902.     {
  903. DEBUG_OUTF(XFADE_FILE, (s, "SetXFadeEndTime Pos(2)t%lut%lun", ulTimestamp, (UINT32)GetMSPerBlock()));
  904. bDone = TRUE;
  905.     }
  906.     else
  907.     {
  908.         // check for the #4 position
  909. if (IsTimeGreater(ulTimestamp, m_IBufs.m_IBlockTimeRange.m_ulEnd))
  910. {
  911.     // position #4 and we're done
  912.     bDone = TRUE;
  913.     DEBUG_OUTF(XFADE_FILE, (s, "SetXFadeEndTime Pos(4 after 2)t%lut%lun", ulTimestamp, (UINT32)GetMSPerBlock()));
  914. }
  915. else
  916. {
  917.     // either 1 or 0 so flush 2
  918.     m_IBufs.FlushIBlock();
  919. }
  920.     }
  921. }
  922.     }
  923.     // see if it's #1
  924.     if (!bDone)
  925.     {
  926. if (!m_IBufs.m_DBlockTimeRange.IsEmpty())
  927. {
  928.     if (m_IBufs.m_DBlockTimeRange.TimeInRange(ulTimestamp))
  929.     {
  930. DEBUG_OUTF(XFADE_FILE, (s, "SetXFadeEndTime Pos(1)t%lut%lun", ulTimestamp, (UINT32)GetMSPerBlock()));
  931. bDone = TRUE;
  932.     }
  933.     else
  934.     {
  935.         // check for the #4 position
  936. if (IsTimeGreater(ulTimestamp, m_IBufs.m_DBlockTimeRange.m_ulEnd))
  937. {
  938.     // position #4 and we're done
  939.     DEBUG_OUTF(XFADE_FILE, (s, "SetXFadeEndTime Pos(4 after 1)t%lut%lun", ulTimestamp, (UINT32)GetMSPerBlock()));
  940.     bDone = TRUE;
  941. }
  942. else
  943. {
  944.     //it's 0, flush the I bufs now
  945.     DEBUG_OUTF(XFADE_FILE, (s, "SetXFadeEndTime Pos(0), flushing formatt%lut%lun", ulTimestamp, (UINT32)GetMSPerBlock()));
  946.     SetupForNextTimeRange();
  947. }
  948.     }
  949. }
  950. else
  951. {
  952.     //it's 0, flush the I bufs now
  953.     DEBUG_OUTF(XFADE_FILE, (s, "SetXFadeEndTime Pos(0), flushing formatt%lut%lun", ulTimestamp, (UINT32)GetMSPerBlock()));
  954.     SetupForNextTimeRange();
  955. }
  956.     }
  957. }
  958. void
  959. CRaFormat::DiscardTillEndOfCrossFade(UINT32 ulTimestamp)
  960. {
  961.     /*
  962.      * The ulTimestamp can be in one of these 5 positions.
  963.      * We start from 0 and go to 4 looking for some data that's
  964.      * greater than the ulTimestamp time.
  965.      *
  966.      *     [DDD][III] {_,_,_,_,_,_,_,}
  967.      * ^     ^    ^       ^            ^
  968.      * |     |    |       |            |
  969.      * 0     1    2       3            4
  970.      *
  971.      */
  972.     BOOL bDone = FALSE;
  973.     ulTimestamp = UnAdjustTimestamp(ulTimestamp, m_lTimeOffset);
  974.     // cannot equal NO_TIME_SET so we bump it up one
  975.     if (ulTimestamp == NO_TIME_SET)
  976.     {
  977. ulTimestamp += 1;
  978.     }
  979.     m_ulForceDiscardUntilTime = ulTimestamp;
  980.     // start looking to see if it's #0 or #1
  981.     if (!m_IBufs.m_DBlockTimeRange.IsEmpty())
  982.     {
  983. if (IsTimeGreater(m_IBufs.m_DBlockTimeRange.m_ulStart, ulTimestamp))
  984. {
  985.     DEBUG_OUTF(DISCARDUNTIL_FILE, (s, "DiscardUntil Pos(0),t%lut%lun", ulTimestamp, (UINT32)GetMSPerBlock()));
  986.     // time is in past and we're done, reset state variables
  987.     m_ulForceDiscardUntilTime = NO_TIME_SET;
  988.     bDone = TRUE;
  989. }
  990. else if (m_IBufs.m_DBlockTimeRange.TimeInRange(ulTimestamp))
  991. {
  992.     DEBUG_OUTF(DISCARDUNTIL_FILE, (s, "DiscardUntil Pos(1),t%lut%lun", ulTimestamp, (UINT32)GetMSPerBlock()));
  993.     bDone = TRUE;
  994. }
  995. else
  996. {
  997.     DEBUG_OUTF(DISCARDUNTIL_FILE, (s, "FlushDBlockt%lut%lut%lun", ulTimestamp, (UINT32)GetMSPerBlock(), m_IBufs.m_DBlockTimeRange.m_ulStart));
  998.     m_IBufs.FlushDBlock();
  999. }
  1000.     }
  1001.     
  1002.     // see if it's at #2
  1003.     if (!bDone)
  1004.     {
  1005. // fill the IBlock if we can
  1006. if (!m_IBufs.IsISuperBlockFilled())
  1007. {
  1008.     m_pPacketFeeder->FillISuperBlock();
  1009. }
  1010.     
  1011. if (!m_IBufs.m_IBlockTimeRange.IsEmpty())
  1012. {
  1013.     if (IsTimeGreater(m_IBufs.m_IBlockTimeRange.m_ulStart, ulTimestamp))
  1014.     {
  1015. DEBUG_OUTF(DISCARDUNTIL_FILE, (s, "DiscardUntil Pos(0),t%lut%lun", ulTimestamp, (UINT32)GetMSPerBlock()));
  1016. // time is in past and we're done, reset state variables
  1017. m_ulForceDiscardUntilTime = NO_TIME_SET;
  1018. bDone = TRUE;
  1019.     }
  1020.     else if (m_IBufs.m_IBlockTimeRange.TimeInRange(ulTimestamp))
  1021.     {
  1022. bDone = TRUE;
  1023. DEBUG_OUTF(DISCARDUNTIL_FILE, (s, "DiscardUntil Pos(2),t%lut%lun", ulTimestamp, (UINT32)GetMSPerBlock()));
  1024.     }
  1025.     else
  1026.     {
  1027. DEBUG_OUTF(DISCARDUNTIL_FILE, (s, "FlushIBlockt%lut%lut%lun", ulTimestamp, (UINT32)GetMSPerBlock(), m_IBufs.m_IBlockTimeRange.m_ulStart));
  1028. m_IBufs.FlushIBlock();
  1029.     }
  1030. }
  1031.     }
  1032.     bDone = m_pPacketFeeder->DiscardTillEndOfCrossFade(ulTimestamp, bDone);
  1033.     // if still not done, it's at #4, else we found it before #4
  1034.     if (!bDone)
  1035.     {
  1036. m_ulForceDiscardUntilTime = NO_TIME_SET;
  1037.     }
  1038. }
  1039. HX_RESULT
  1040. CRaFormat::GetNextAudioDataTime(UINT32& ulStart, UINT32& ulEnd)
  1041. {
  1042.     UINT32 ulIterationCounter = 0;
  1043.     HX_RESULT theError = HXR_OK;
  1044.     BOOL bSuccess = FALSE;
  1045.     
  1046.     ulStart = ulEnd = 0;
  1047.     // move any data from the time range queue into the IBufs
  1048.     m_pPacketFeeder->FillISuperBlock();
  1049.     
  1050.     if (m_bEndOfPackets)
  1051.     {
  1052. if (!m_IBufs.DataAvailable(AUDIO_END_OF_PACKETS))
  1053. {  
  1054.     // this is an "emergency" state so do this even
  1055.     // if the IBlock isn't quite full
  1056.     m_IBufs.DeInterleaveData();
  1057. }
  1058.     }
  1059.     do
  1060.     {
  1061. // move any data from the time range queue into the IBufs
  1062. m_pPacketFeeder->FillISuperBlock();
  1063. // Here we always want to know the full time range of available
  1064. // time so we always ask for the crossfade time
  1065. if (m_IBufs.DataAvailable(AUDIO_CROSSFADE))
  1066. {
  1067.     if (m_ulForceDiscardUntilTime != NO_TIME_SET)
  1068.     {
  1069. // this will be the actual start time of 
  1070. // the data returned from GetAudioData
  1071. ulStart = m_ulForceDiscardUntilTime;
  1072. DEBUG_OUTF(TIME_FILE, (s, "Force Discard Time Reportedt%lut%lun", 
  1073.     ulStart, (UINT32)GetMSPerBlock()));
  1074.     }
  1075.     else
  1076.     {
  1077. ulStart = m_IBufs.m_DBlockTimeRange.m_ulStart;
  1078. // we may have data before the track start time but we will
  1079. // not return audio data prior to the track start time
  1080. if (m_bForceStartTrackTime && IsTimeLess(ulStart, m_ulTrackStartTime))
  1081. {
  1082.     ulStart = m_ulTrackStartTime;
  1083. }
  1084. DEBUG_OUTF(TIME_FILE, (s, "DBlock start Time Reportedt%lut%lun", 
  1085.     ulStart, (UINT32)GetMSPerBlock()));
  1086. HX_ASSERT(ulStart != NO_TIME_SET);
  1087.     }
  1088.     ulEnd = ulStart + (UINT32)GetMSPerBlock();
  1089.     if (m_bForceEndTrackTime && ulEnd > m_ulTrackEndTime)
  1090.     {
  1091. ulEnd = m_ulTrackEndTime;
  1092. HX_ASSERT(ulEnd >= ulStart);
  1093.     }
  1094.             ulStart = AdjustTimestamp(ulStart, m_lTimeOffset);
  1095.             ulEnd   = AdjustTimestamp(ulEnd,   m_lTimeOffset);
  1096.     bSuccess = TRUE;
  1097.     break;
  1098. }
  1099. else 
  1100. {
  1101.     // if there is a current time range, ask it if it's 
  1102.     // ended.  We assume it's not ended.
  1103.     BOOL bTimeRangeEnded = m_pPacketFeeder->IsCurrentTimeRangeEnded();
  1104.     BOOL bDataInTimeRange = !m_pPacketFeeder->IsCurrentTimeRangeEmpty();
  1105.     // If the D superblock is empty and there's more data to decode
  1106.     // we give it a try to move the data into the D superblock to
  1107.     // decode it.
  1108.     if (m_IBufs.IsDSuperBlockEmpty() &&
  1109. (!m_IBufs.IsISuperBlockEmpty() || bDataInTimeRange))
  1110.     {
  1111. if (m_IBufs.IsISuperBlockFilled())
  1112. {
  1113.     m_IBufs.DeInterleaveData();
  1114. }
  1115. // if we don't have any data in the De-interleaved superblock
  1116. // and we failed to fill the Interleaved superblock, we
  1117. // must be out of data and we should break out of the while loop
  1118. if (m_IBufs.IsDSuperBlockEmpty() && 
  1119.     (!m_pPacketFeeder->FillISuperBlock()))
  1120. {
  1121.     DEBUG_OUTF(DOAUDIO_FILE, (s, "GetNextAudioDataTimet%dt%dt%dt%dt%lun", 
  1122. m_IBufs.IsDSuperBlockEmpty(), m_IBufs.IsISuperBlockEmpty(), m_IBufs.IsISuperBlockFilled(), bTimeRangeEnded, (UINT32)GetMSPerBlock()));
  1123.     break;
  1124. }
  1125.     }
  1126.     else
  1127.     {
  1128. // if we get here, there's no in the IBuf or the 
  1129. // current time range.
  1130. HX_ASSERT(!bDataInTimeRange);
  1131. if (bTimeRangeEnded)
  1132. {
  1133.     // the Time range has ended and the data from it is
  1134.     // gone from the IBufs so setup the next time range
  1135.     // now
  1136.     SetupForNextTimeRange();
  1137. }
  1138. else
  1139. {
  1140.     DEBUG_OUTF(DOAUDIO_FILE, (s, "GetNextAudioDataTimet%dt%dt%dt%dt%lun", 
  1141. m_IBufs.IsDSuperBlockEmpty(), m_IBufs.IsISuperBlockEmpty(), m_IBufs.IsISuperBlockFilled(), bTimeRangeEnded, (UINT32)GetMSPerBlock()));
  1142.     break;
  1143. }
  1144.     }
  1145. }
  1146.     
  1147. ulIterationCounter++;
  1148.     } while (ulIterationCounter < MAX_AUDIO_DATA_ATTEMPTS);
  1149.     if (bSuccess)
  1150.     {
  1151. return HXR_OK;
  1152.     }
  1153.     else
  1154.     {
  1155. return HXR_NO_DATA;
  1156.     }
  1157. }
  1158. UINT32
  1159. CRaFormat::GetCurrentTimeRangeEnd()
  1160. {
  1161.     UINT32 ulRet = m_pPacketFeeder->GetCurrentTimeRangeEnd();
  1162.     if (ulRet == NO_TIME_SET)
  1163.     {
  1164. if (!m_IBufs.m_IBlockTimeRange.IsEmpty())
  1165. {
  1166.     // it will be in the IBufs
  1167.     ulRet = m_IBufs.m_IBlockTimeRange.m_ulEnd;
  1168. }
  1169. else
  1170. {
  1171.     ulRet = m_IBufs.m_DBlockTimeRange.m_ulEnd;
  1172. }
  1173.     }
  1174.     DEBUG_OUTF(TREND_FILE, (s, "%lut%lun", (UINT32)GetMSPerBlock(), ulRet));
  1175.     ulRet = AdjustTimestamp(ulRet, m_lTimeOffset);
  1176.     return ulRet;
  1177. }
  1178. void CRaFormat::ThrowUpgrade(const char* pszStr)
  1179. {
  1180.     if (m_pCommonClassFactory && pszStr)
  1181.     {
  1182.         IHXBuffer* pBuffer = NULL;
  1183.         m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, (void**) &pBuffer);
  1184.         if (pBuffer)
  1185.         {
  1186.             pBuffer->Set((BYTE*) pszStr, strlen(pszStr) + 1);
  1187.             if (m_pUpgradeCollection)
  1188.             {
  1189.                 m_pUpgradeCollection->Add(eUT_Required, pBuffer, 0, 0);
  1190.             }
  1191.         }
  1192.         HX_RELEASE(pBuffer);
  1193.     }
  1194. }
  1195. HX_RESULT 
  1196. CRaFormat::OnSeek (UINT32 ulOldTime, UINT32 ulNewTime)
  1197. {
  1198.     m_IBufs.OnSeek();
  1199.     m_bFirstPacket = TRUE;
  1200.     m_bEndOfPackets = FALSE;
  1201.     m_ulCodecDelay = 0;
  1202.     m_fCodecDelay = 0.0;
  1203.     m_bPCMStreamStart = TRUE;
  1204.     
  1205.     SetupForNextTimeRange();
  1206.     m_pPacketFeeder->Reset();
  1207.     return HXR_OK;
  1208. }
  1209. BOOL
  1210. CRaFormat::IsStreamDone()
  1211. {
  1212.     if( !m_pPacketFeeder )
  1213.     {
  1214.         return TRUE;
  1215.     }
  1216.     return ((!m_pPacketFeeder->IsActive()) && m_IBufs.IsStreamDone());
  1217. }
  1218. void
  1219. CRaFormat::SetupForNextTimeRange()
  1220. {
  1221.     m_pPacketFeeder->SetupForNextTimeRange();
  1222.     if (m_pCodec != NULL)
  1223.     {
  1224.         UINT32 ulOutSize = m_ulAudioBufSize;
  1225.         IHXBuffer * pBuffer = NULL;
  1226. m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, (void**) &pBuffer);
  1227. if( pBuffer )
  1228. {
  1229.    if( pBuffer->GetSize() != m_ulAudioBufSize )
  1230.    {
  1231.               // Yikes! This can fail if heap is low: no check!
  1232.       pBuffer->SetSize( ulOutSize );
  1233.    }
  1234.         m_pCodec->Flush( pBuffer->GetBuffer(), &ulOutSize );
  1235.    HX_RELEASE( pBuffer );
  1236. }
  1237.     }
  1238.     m_ulCodecDelay = 0;
  1239.     m_fCodecDelay = 0.0;
  1240.     m_bPCMStreamStart = TRUE;
  1241.     m_ulCrossFadeEndTime = NO_TIME_SET;
  1242.     m_ulForceDiscardUntilTime = NO_TIME_SET;
  1243.     m_IBufs.SwitchOff();
  1244. }
  1245. void 
  1246. CRaFormat::OnEndofPackets(void)
  1247. {
  1248.     if( !m_pPacketFeeder )
  1249.     {
  1250.         m_bEndOfPackets = TRUE;
  1251.         return;
  1252.     }
  1253.     m_pPacketFeeder->OnEndOfPackets();
  1254.     m_bEndOfPackets = TRUE;
  1255.     
  1256.     // if we've already given all of the packets to the ibufs,
  1257.     // we can tell them we are done now, otherwise wait till
  1258.     // we do finish the packets
  1259.     if (!m_pPacketFeeder->IsActive())
  1260.     {
  1261. m_IBufs.OnEndofPackets();
  1262.     }
  1263. }
  1264. HX_RESULT
  1265. CRaFormat::UpdatePacketTimeOffset(INT32 lTimeOffset)
  1266. {
  1267.     m_lTimeOffset -= lTimeOffset;
  1268.     return HXR_OK;
  1269. }
  1270. HX_RESULT
  1271. CRaFormat::UpdatePlayTimes(IHXValues* pProps)
  1272. {
  1273.     UINT32 ulStart = 0;
  1274.     UINT32 ulEnd = 0;
  1275.     if (HXR_OK == pProps->GetPropertyULONG32("Start", ulStart))
  1276.     {
  1277. m_ulTrackStartTime = ulStart;
  1278. m_bForceStartTrackTime = TRUE;
  1279.     }
  1280.     if (HXR_OK == pProps->GetPropertyULONG32("End", ulEnd))
  1281.     {
  1282. m_ulTrackEndTime = ulEnd;
  1283. m_bForceEndTrackTime = TRUE;
  1284.     }
  1285.     return HXR_OK;
  1286. }
  1287. // statistics
  1288. #if defined(HELIX_FEATURE_STATS)
  1289. HX_RESULT CRaFormat::UpdateStatistics (IHXRegistry* pRegistry, UINT32 ulRegistryID,
  1290.        UINT32& ulCodecRegID, UINT32& ulCodecTextRegID,
  1291.        UINT32& ulCodec4CCRegID, UINT32& ulRateRegID,
  1292.        UINT32& ulChannelsRegID, UINT32& ulSurroundRegID)
  1293. {
  1294.     char     szRegistryEntry[MAX_DISPLAY_NAME] = {0}; /* Flawfinder: ignore */
  1295.     IHXBuffer*     pszRegistryName = NULL;
  1296.     IHXBuffer*     pValue = NULL;
  1297.     CStreamParam*    pParam;
  1298.     HX_RESULT retVal = HXR_OK;
  1299.     if (!pRegistry || !ulRegistryID || m_pCodec == NULL)
  1300.     {
  1301. return HXR_FAILED;
  1302.     }
  1303.     pParam = &m_StreamParam;
  1304.     if (!ulCodecRegID)
  1305.     {
  1306. // Get the current registry key name
  1307. if (!ulCodecRegID && (HXR_OK == pRegistry->GetPropName(ulRegistryID, pszRegistryName)))
  1308. {
  1309.     SafeSprintf (szRegistryEntry, MAX_DISPLAY_NAME, "%s.Codec", pszRegistryName->GetBuffer());
  1310.     if (pParam->codecID)
  1311.     {
  1312. m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, 
  1313.     (void**) &pValue);
  1314. //
  1315. UINT16 uPropSize = 0;
  1316. void* pProp = m_pCodec->GetFlavorProperty(m_StreamParam.uFlavorIndex, FLV_PROP_NAME, &uPropSize);
  1317. if (uPropSize)
  1318. {
  1319.     pValue->Set((const UCHAR*)pProp, uPropSize);
  1320.     ulCodecRegID = pRegistry->AddStr(szRegistryEntry, pValue);
  1321. }
  1322. pValue->Release();
  1323.     }
  1324.     pszRegistryName->Release();
  1325.     pszRegistryName = NULL;
  1326. }
  1327.     }
  1328.     else
  1329.     {
  1330. if (pParam->codecID)
  1331. {
  1332.     m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, 
  1333. (void**) &pValue);
  1334.     UINT16 uPropSize = 0;
  1335.     void* pProp = m_pCodec->GetFlavorProperty(m_StreamParam.uFlavorIndex, FLV_PROP_NAME, &uPropSize);
  1336.     if (uPropSize)
  1337.     {
  1338. pValue->Set((const UCHAR*)pProp, uPropSize);
  1339. pRegistry->SetStrById(ulCodecRegID, pValue);
  1340.     }
  1341.     pValue->Release();
  1342. }
  1343.     }
  1344.     if (!ulCodecTextRegID)
  1345.     {
  1346. // Get the current registry key name
  1347. if (!ulCodecTextRegID && (HXR_OK == pRegistry->GetPropName(ulRegistryID, pszRegistryName)))
  1348. {
  1349.     SafeSprintf (szRegistryEntry, MAX_DISPLAY_NAME, "%s.CodecText", pszRegistryName->GetBuffer());
  1350.     if (pParam->codecID)
  1351.     {
  1352. m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, 
  1353.     (void**) &pValue);
  1354. //
  1355. UINT16 uPropSize = 0;
  1356. void* pProp = m_pCodec->GetFlavorProperty(m_StreamParam.uFlavorIndex, FLV_PROP_STATUS_TEXT, &uPropSize);
  1357. if (uPropSize)
  1358. {
  1359.     pValue->Set((const UCHAR*)pProp, uPropSize);
  1360.     ulCodecTextRegID = pRegistry->AddStr(szRegistryEntry, pValue);
  1361. }
  1362. pValue->Release();
  1363.     }
  1364.     pszRegistryName->Release();
  1365.     pszRegistryName = NULL;
  1366. }
  1367.     }
  1368.     else
  1369.     {
  1370. if (pParam->codecID)
  1371. {
  1372.     m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, 
  1373. (void**) &pValue);
  1374.     //
  1375.     UINT16 uPropSize = 0;
  1376.     void* pProp = m_pCodec->GetFlavorProperty(m_StreamParam.uFlavorIndex, FLV_PROP_STATUS_TEXT, &uPropSize);
  1377.     if (uPropSize)
  1378.     {
  1379. pValue->Set((const UCHAR*)pProp, uPropSize);
  1380. pRegistry->SetStrById(ulCodecTextRegID, pValue);
  1381.     }
  1382.     pValue->Release();
  1383. }
  1384.     }
  1385.     if (!ulCodec4CCRegID)
  1386.     {
  1387. // Get the current registry key name
  1388. if (!ulCodec4CCRegID && (HXR_OK == pRegistry->GetPropName(ulRegistryID, pszRegistryName)))
  1389. {
  1390.     SafeSprintf (szRegistryEntry, MAX_DISPLAY_NAME, "%s.CodecFourCC", pszRegistryName->GetBuffer());
  1391.     if (pParam->codecID)
  1392.     {
  1393. m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, 
  1394.     (void**) &pValue);
  1395. pValue->Set((const UCHAR*)pParam->codecID, strlen(pParam->codecID)+1);
  1396. ulCodec4CCRegID = pRegistry->AddStr(szRegistryEntry, pValue);
  1397. pValue->Release();
  1398.     }
  1399.     pszRegistryName->Release();
  1400.     pszRegistryName = NULL;
  1401. }
  1402.     }
  1403.     else
  1404.     {
  1405. if (pParam->codecID)
  1406. {
  1407.     m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, 
  1408. (void**) &pValue);
  1409.     pValue->Set((const UCHAR*)pParam->codecID, strlen(pParam->codecID)+1);
  1410.     pRegistry->SetStrById(ulCodec4CCRegID, pValue);
  1411.     pValue->Release();
  1412. }
  1413.     }
  1414.     if (!ulRateRegID || !ulChannelsRegID)
  1415.     {
  1416. if (!ulRateRegID && (HXR_OK == pRegistry->GetPropName (ulRegistryID, pszRegistryName)))
  1417. {
  1418.     SafeSprintf (szRegistryEntry, MAX_DISPLAY_NAME, "%s.Rate", pszRegistryName->GetBuffer());
  1419.     ulRateRegID = pRegistry->AddInt (szRegistryEntry, m_IBufs.RateInBytesPerSec());
  1420.     pszRegistryName->Release();
  1421.     pszRegistryName = NULL;
  1422. }
  1423. if (!ulChannelsRegID && (HXR_OK == pRegistry->GetPropName (ulRegistryID, pszRegistryName)))
  1424. {
  1425.     SafeSprintf (szRegistryEntry, MAX_DISPLAY_NAME, "%s.Channels", pszRegistryName->GetBuffer());
  1426.     ulChannelsRegID = pRegistry->AddInt (szRegistryEntry, pParam->uChannels);
  1427.     pszRegistryName->Release();
  1428.     pszRegistryName = NULL;
  1429. }
  1430.     }
  1431.     else
  1432.     {
  1433. pRegistry->SetIntById(ulRateRegID, m_IBufs.RateInBytesPerSec());
  1434. pRegistry->SetIntById(ulChannelsRegID, pParam->uChannels);
  1435.     }
  1436.     if (pParam->ulUserData)
  1437.     {
  1438. // Get the current registry key name
  1439. if ((!ulSurroundRegID) &&
  1440.     (HXR_OK == pRegistry->GetPropName(ulRegistryID, pszRegistryName)))
  1441. {
  1442.     if ((pParam->ulUserData & USER_DATA_REALAUDIO_SURROUND) != 0)
  1443.     {
  1444. SafeSprintf (szRegistryEntry, MAX_DISPLAY_NAME, "%s.Surround", pszRegistryName->GetBuffer());
  1445. retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, 
  1446.     (void**) &pValue);
  1447. if (SUCCEEDED(retVal))
  1448. {
  1449.     retVal = pValue->Set((UINT8*) "TRUE", sizeof("TRUE"));
  1450. }
  1451. if (SUCCEEDED(retVal))
  1452. {
  1453.     if (ulSurroundRegID)
  1454.     {
  1455. pRegistry->SetStrById(ulSurroundRegID, pValue);
  1456.     }
  1457.     else
  1458.     {
  1459. ulSurroundRegID = pRegistry->AddStr(szRegistryEntry, pValue);
  1460.     }
  1461. }
  1462. HX_RELEASE(pValue);
  1463.     }
  1464.     
  1465.     HX_RELEASE(pszRegistryName);
  1466. }
  1467.     }
  1468.     return retVal;
  1469. }
  1470. #endif // HELIX_FEATURE_STATS
  1471. UINT32  
  1472. CRaFormat::ConvertMsToBytes(UINT32 ulMs)
  1473. {
  1474.     /*
  1475.      *     ms     # Channels * Sample size in Bits * # samples per second
  1476.      *    ____  * _________________________________________________________
  1477.      *
  1478.      * 1000 ms per second      8 bits per byte 
  1479.      */
  1480.     
  1481.     return  (UINT32)(((double)(ulMs * m_StreamParam.uChannels * 
  1482. m_StreamParam.uSampleSize * m_StreamParam.ulSampleRate) / 8000.0) + .5);
  1483. }
  1484. double  
  1485. CRaFormat::ConvertBytesToMs(UINT32 ulBytes)
  1486. {
  1487.     return (ulBytes * 8000.0) / 
  1488.    (m_StreamParam.uChannels * 
  1489.     m_StreamParam.uSampleSize * 
  1490.     m_StreamParam.ulSampleRate);
  1491. }
  1492. BOOL 
  1493. CRaFormat::ClipAudioBuffer(HXAudioData* pAudioData, 
  1494.    UINT32& ulActualTime, 
  1495.    UINT32 ulAudioStreamTime, 
  1496.    BOOL bFromStart)
  1497. {
  1498.     BOOL bResult = TRUE;
  1499.     UINT32 ulDuration = 0;
  1500.     UINT32 ulSize = 0;
  1501.     INT32 lExtraInMs = 0;
  1502.     UINT32 ulExtraInBytes = 0;
  1503.     IHXBuffer* pBuffer = NULL;
  1504.     ulSize = (pAudioData->pData)->GetSize();
  1505.     // caculate the worth of this data in ms
  1506.     ulDuration = (UINT32) ConvertBytesToMs(ulSize);
  1507.     
  1508.     // trim off any extra bytes
  1509.     if (bFromStart)
  1510.     {
  1511. if (IsTimeGreater(pAudioData->ulAudioTime + ulDuration, ulAudioStreamTime))
  1512. {  
  1513.     lExtraInMs = ulAudioStreamTime - pAudioData->ulAudioTime;
  1514. }
  1515.     }
  1516.     else
  1517.     {
  1518. if (IsTimeLess(pAudioData->ulAudioTime, ulAudioStreamTime))
  1519. {
  1520.     lExtraInMs = pAudioData->ulAudioTime + ulDuration - ulAudioStreamTime;     
  1521. }
  1522.     }
  1523.     if (lExtraInMs > 0)
  1524.     {
  1525. bResult = ClipAudioData(*pAudioData,
  1526. ulActualTime,
  1527. (ULONG32) lExtraInMs, 
  1528. bFromStart);
  1529.     }
  1530.     else if (lExtraInMs < 0)
  1531.     {
  1532. // Nothing to clip
  1533. bResult = TRUE;
  1534.     }
  1535.     return bResult;
  1536. }
  1537. void
  1538. CRaFormat::OverrideFactory(IHXCommonClassFactory* pCommonClassFactory)
  1539. {
  1540.     // Actually, we no longer override, we just add this one.
  1541.     m_pCachingClassFactory = pCommonClassFactory;
  1542.     m_pCachingClassFactory->AddRef();
  1543. }
  1544. BOOL
  1545. CRaFormat::GetDropBlock(UINT32 ulAudioTime)
  1546. {
  1547.     BOOL bRetVal = FALSE;
  1548.     if (m_bForceStartTrackTime && IsTimeLess(ulAudioTime, m_ulTrackStartTime) ||
  1549. m_ulForceDiscardUntilTime != NO_TIME_SET && IsTimeLess(ulAudioTime, m_ulForceDiscardUntilTime))
  1550.     {
  1551. // since the crossfade end time is going to happen in the middle of a stream
  1552. // it has "precidence" over the track start time here
  1553. UINT32 ulStartTimeToUse = (m_ulForceDiscardUntilTime != NO_TIME_SET)?(m_ulForceDiscardUntilTime):
  1554.     (m_ulTrackStartTime);
  1555. bRetVal = IsTimeLessOrEqual(ulAudioTime + (UINT32)GetMSPerBlock(), ulStartTimeToUse);
  1556.     }
  1557.     
  1558.     //XXXJEFFA add code for droping entire block clipping at end
  1559.     return bRetVal;
  1560. }
  1561. void CRaFormat::SpliceAudioData(HXAudioData &audioData, 
  1562. UINT32 &ulActualTimestamp, 
  1563. UINT32 ulSpliceToActualTime, 
  1564. UINT32 ulSpliceToStreamTime)
  1565. {
  1566.     LONG32 lActualTimeDiff = 0;
  1567.     ULONG32 ulAbsActualTimeDiff = 0;
  1568.     audioData.uAudioStreamType = TIMED_AUDIO;
  1569.     ulActualTimestamp = audioData.ulAudioTime;
  1570.     if (ulSpliceToActualTime != NO_TIME_SET)
  1571.     {
  1572. lActualTimeDiff = ulActualTimestamp - ulSpliceToActualTime;
  1573. ulAbsActualTimeDiff = (ULONG32) lActualTimeDiff;
  1574. if (lActualTimeDiff < 0)
  1575. {
  1576.     ulAbsActualTimeDiff = (ULONG32) (-lActualTimeDiff);
  1577. }
  1578. if (ulAbsActualTimeDiff <= m_ulMaxBlockGap)
  1579. {
  1580.     audioData.ulAudioTime = ulSpliceToStreamTime;
  1581.     if (!m_bPCMStreamStart)
  1582.     {
  1583. audioData.uAudioStreamType = STREAMING_AUDIO;
  1584.     }
  1585. }
  1586. else
  1587. {
  1588.     audioData.ulAudioTime = ulSpliceToStreamTime + lActualTimeDiff;
  1589. }
  1590.     }
  1591. }
  1592. BOOL    
  1593. CRaFormat::AdjustAudioData(HXAudioData& audioData, 
  1594.    UINT32& ulActualTimestamp,
  1595.    UINT32 ulTrackEndTime)
  1596. {
  1597.     BOOL bResult = TRUE;
  1598.     UINT32 ulDuration = 0;
  1599.     UINT32 ulSize = 0;
  1600.     INT32 lExtraInMs = 0;
  1601.     IHXBuffer* pBuffer = NULL;
  1602.     if (m_bForceStartTrackTime || 
  1603. m_bForceEndTrackTime || 
  1604. (m_ulForceDiscardUntilTime != NO_TIME_SET) || 
  1605. (m_ulCrossFadeEndTime != NO_TIME_SET) ||
  1606. (ulTrackEndTime != NO_TIME_SET))
  1607.     {
  1608. ulSize = (audioData.pData)->GetSize();
  1609. // caculate the worth of this data in ms
  1610. ulDuration = (UINT32) ConvertBytesToMs(ulSize);
  1611. // Trim based on start time
  1612. if (m_bForceStartTrackTime || (m_ulForceDiscardUntilTime != NO_TIME_SET))
  1613. {
  1614.     // since the crossfade end time is going to happen in the middle of a stream
  1615.     // it has "precidence" over the track start time here
  1616.     UINT32 ulStartTimeToUse = 
  1617. (m_ulForceDiscardUntilTime != NO_TIME_SET) ? m_ulForceDiscardUntilTime :
  1618.      m_ulTrackStartTime;
  1619.     lExtraInMs = ulStartTimeToUse - ulActualTimestamp;
  1620.             bResult = ClipAndAdjust(lExtraInMs, audioData, ulActualTimestamp, TRUE, ulDuration, ulSize);
  1621. }
  1622. // Trim based on track end time
  1623. if (bResult &&
  1624.     m_bForceEndTrackTime)
  1625. {
  1626.     lExtraInMs = ulActualTimestamp + ulDuration - m_ulTrackEndTime;
  1627.             bResult = ClipAndAdjust(lExtraInMs, audioData, ulActualTimestamp, FALSE, ulDuration, ulSize);
  1628.     if (lExtraInMs > 0)
  1629.     {
  1630. // if we are ending the stream here because this block goes over the forced end time
  1631. // we want to flush the IBuf etc. cause we are done.
  1632. SetupForNextTimeRange();
  1633.     }
  1634. }
  1635. // Trim based on X-fade end time
  1636. if (bResult &&
  1637.     (m_ulCrossFadeEndTime != NO_TIME_SET))
  1638. {
  1639.     lExtraInMs = ulActualTimestamp + ulDuration - m_ulCrossFadeEndTime;
  1640.             bResult = ClipAndAdjust(lExtraInMs, audioData, ulActualTimestamp, FALSE, ulDuration, ulSize);
  1641.     if (lExtraInMs > 0)
  1642.     {
  1643. SetupForNextTimeRange();
  1644.     }
  1645. }
  1646. // Trim based on forced end time
  1647. if (bResult &&
  1648.     (ulTrackEndTime != NO_TIME_SET))
  1649. {
  1650.     lExtraInMs = ulActualTimestamp + ulDuration - ulTrackEndTime;
  1651.             bResult = ClipAndAdjust(lExtraInMs, audioData, ulActualTimestamp, FALSE, ulDuration, ulSize);
  1652. }
  1653.     }
  1654.     audioData.ulAudioTime = AdjustTimestamp(audioData.ulAudioTime, m_lTimeOffset);
  1655.     ulActualTimestamp     = AdjustTimestamp(ulActualTimestamp,     m_lTimeOffset);
  1656.     return bResult;
  1657. }
  1658. BOOL    
  1659. CRaFormat::ClipAudioData(HXAudioData &audioData,
  1660.  UINT32 &ulActualTimestamp,
  1661.  UINT32 ulDurationToClip,
  1662.  BOOL bFromFront)
  1663. {   
  1664.     UINT32 ulExtraInBytes;
  1665.     UINT32 ulSize;
  1666.     BOOL bResult = FALSE;   // completely elimninated = FALSE
  1667.     // Get data size
  1668.     ulSize = audioData.pData->GetSize();
  1669.     // convert to bytes
  1670.     ulExtraInBytes = ConvertMsToBytes(ulDurationToClip);
  1671.     
  1672.     // align in sample boundary
  1673.     ulExtraInBytes -= (ulExtraInBytes % (m_StreamParam.uSampleSize * 
  1674.  m_StreamParam.uChannels / 8));
  1675.     
  1676.     if (ulExtraInBytes < ulSize)
  1677.     {
  1678. IHXBuffer* pBuffer = NULL;
  1679. m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, 
  1680.       (void**) &pBuffer);
  1681. if (pBuffer)
  1682. {
  1683.     if (bFromFront)
  1684.     {
  1685. if (SUCCEEDED(pBuffer->Set(audioData.pData->GetBuffer() + 
  1686. ulExtraInBytes, 
  1687.    ulSize - ulExtraInBytes)))
  1688. {
  1689.     audioData.pData->Release();
  1690.     audioData.pData = pBuffer;
  1691.     pBuffer = NULL;
  1692.     audioData.ulAudioTime += ulDurationToClip;
  1693.     ulActualTimestamp += ulDurationToClip;
  1694.     bResult = TRUE;
  1695. }
  1696.     }
  1697.     else
  1698.     {
  1699. if (SUCCEEDED(pBuffer->Set(audioData.pData->GetBuffer(), 
  1700.    ulSize - ulExtraInBytes)))
  1701. {
  1702.     audioData.pData->Release();
  1703.     audioData.pData = pBuffer;
  1704.     pBuffer = NULL;
  1705.     bResult = TRUE;
  1706. }
  1707.     }
  1708.     HX_RELEASE(pBuffer);
  1709. }
  1710.     }
  1711.     
  1712.     return bResult;
  1713. }
  1714. HX_RESULT
  1715. CRaFormat::LoadDecoderAndInitDeInterleaver()
  1716. {
  1717.     HX_RESULT theError = HXR_OK;
  1718.     // initialize codecs
  1719.     theError = InitDecoder (m_StreamParam, &m_pCodec);
  1720.     if (theError == HXR_OK)
  1721.     {
  1722. // Get SAMPLES_IN from codec and give it to the IBufs
  1723. UINT16 uPropSize = 0;
  1724. void* pProp = 
  1725.     m_pCodec->GetFlavorProperty(m_StreamParam.uFlavorIndex, 
  1726.     FLV_PROP_SAMPLES_IN, &uPropSize);
  1727. if (uPropSize != 0)
  1728. {
  1729.     HX_ASSERT(uPropSize == sizeof(UINT32));
  1730.     m_IBufs.SetSamplesIn(*(UINT32*)pProp);
  1731. }
  1732.     }
  1733.     return theError;
  1734. }
  1735. BOOL CRaFormat::ClipAndAdjust(INT32        lExtraInMs,
  1736.                               HXAudioData& audioData,
  1737.                               UINT32&      ulActualTimestamp,
  1738.                               BOOL         bFromFront,
  1739.                               UINT32&      ulDuration,
  1740.                               UINT32&      ulSize)
  1741. {
  1742.     BOOL bResult = TRUE;
  1743.     if (lExtraInMs > 0)
  1744.     {
  1745.         bResult = ClipAudioData(audioData,
  1746.                                 ulActualTimestamp,
  1747.                                 (ULONG32) lExtraInMs,
  1748.                                 bFromFront);
  1749.         if (bResult)
  1750.         {
  1751.             ulDuration -= lExtraInMs;
  1752.             ulSize      = audioData.pData->GetSize();
  1753.         }
  1754.         else
  1755.         {
  1756.             ulDuration = 0;
  1757.             ulSize     = 0;
  1758.         }
  1759.     }
  1760.     return bResult;
  1761. }