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

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. /****************************************************************************
  36.  *  Defines
  37.  */
  38. //#define _IGNORE_HINTS
  39. #define INV_HINT_TRACK_IDX  0xFFFFFFFF
  40. #define INV_STREAM_NUM     0xFFFF
  41. /****************************************************************************
  42.  *  Includes
  43.  */
  44. #include "qttrkmgr.h"
  45. #include "qttrack.h"
  46. /****************************************************************************
  47.  *  Class CTrackManager
  48.  */
  49. /****************************************************************************
  50.  *  Constructor/Destructor
  51.  */
  52. CQTTrackManager::CQTTrackManager(void)
  53.     : m_uNumTracks(0)
  54.     , m_uNumStreams(0)
  55.     , m_pTrackTable(NULL)
  56.     , m_pStreamToTrackMap(NULL)
  57.     , m_pTrackAtomList(new CHXSimpleList)
  58.     , m_pHintTrackIdxList(new CHXSimpleList)
  59.     , m_bSubscriptionWindowClosed(FALSE)
  60.     , m_bHintTracksActive(FALSE)
  61.     , m_bHinted(FALSE)
  62.     , m_pIodsAtom(NULL)
  63.     , m_pFtypAtom(NULL)
  64.     , m_FType(QT_FTYPE_UNKNOWN)
  65.     , m_EType(QT_ETYPE_UNKNOWN)
  66. {
  67.     HX_ASSERT(m_pTrackAtomList);
  68.     HX_ASSERT(m_pHintTrackIdxList);
  69. }
  70. CQTTrackManager::~CQTTrackManager()
  71. {
  72.     Clear();
  73. }
  74. /****************************************************************************
  75.  *  Main Interface
  76.  */
  77. /****************************************************************************
  78.  *  ManageTracks
  79.  */
  80. HX_RESULT CQTTrackManager::ManageTracks(CQTAtom *pRootAtom)
  81. {
  82.     if ((m_pTrackAtomList == NULL) ||
  83. (m_pHintTrackIdxList == NULL))
  84.     {
  85. HX_ASSERT(!"shouldn't happen");
  86. return HXR_UNEXPECTED;
  87.     }
  88.     AddTracks(pRootAtom);
  89.     if (m_FType == QT_FTYPE_UNKNOWN)
  90.     {
  91. m_FType = QT_FTYPE_QT;
  92.     }
  93.     return HXR_OK;
  94. }
  95. /****************************************************************************
  96.  *  ReadyTracks
  97.  */
  98. HX_RESULT CQTTrackManager::ReadyTracks(BOOL bIgnoreHintTracks,
  99.        BOOL bFallbackToTracks)
  100. {
  101.     HX_RESULT retVal = HXR_OK;
  102. #ifdef _IGNORE_HINTS
  103.     bIgnoreHintTracks = TRUE;
  104. #endif // _IGNORE_HINTS
  105.     if ((m_pTrackAtomList == NULL) ||
  106. (m_pHintTrackIdxList == NULL) ||
  107. (m_pTrackAtomList->GetCount() == 0))
  108.     {
  109. HX_ASSERT(!"shouldn't happen");
  110. retVal = HXR_CORRUPT_FILE;
  111.     }
  112.     if (SUCCEEDED(retVal))
  113.     {
  114. m_uNumStreams = 0;
  115. m_uNumTracks = m_pTrackAtomList->GetCount();
  116. if (!bIgnoreHintTracks)
  117. {
  118.     m_uNumStreams = m_pHintTrackIdxList->GetCount();
  119. }
  120. m_bHinted = (m_uNumStreams != 0);
  121. m_bHintTracksActive = m_bHinted;
  122. DecideHintTrackActivation(bFallbackToTracks);
  123. if (m_uNumStreams <= 0)
  124. {
  125.     retVal = HXR_FAIL; // No Streamable Tracks
  126. }
  127.     }
  128.     // Allocate Tables
  129.     if (SUCCEEDED(retVal))
  130.     {
  131. HX_ASSERT(!m_pTrackTable);
  132. HX_ASSERT(!m_pStreamToTrackMap);
  133. m_pStreamToTrackMap = new CQTStream [m_uNumStreams];
  134. m_pTrackTable = new CQTTrackTable [m_uNumTracks];
  135. if ((m_pStreamToTrackMap == NULL) ||
  136.     (m_pTrackTable == NULL))
  137. {
  138.     retVal = HXR_OUTOFMEMORY;
  139. }
  140.     }
  141.     // Fill Tables with info.
  142.     if (SUCCEEDED(retVal))
  143.     {
  144. LISTPOSITION HintTrackIdxListPosition;
  145. LISTPOSITION TrackAtomListPosition;
  146. ULONG32 ulHintTrackIdx = INV_HINT_TRACK_IDX;
  147. UINT16 uStreamTrackCount = 0;
  148. UINT16 uHintTrackCount = 0;
  149. CQTAtom* pTrackAtom;
  150. UINT16 uTrackIdx = 0;
  151. HintTrackIdxListPosition = m_pHintTrackIdxList->GetHeadPosition();
  152. TrackAtomListPosition = m_pTrackAtomList->GetHeadPosition();
  153. if (HintTrackIdxListPosition)
  154. {
  155.     ulHintTrackIdx = (UINT32) m_pHintTrackIdxList->GetNext(
  156. HintTrackIdxListPosition);
  157. }
  158. do
  159. {
  160.     pTrackAtom = (CQTAtom*) m_pTrackAtomList->GetNext(
  161. TrackAtomListPosition);
  162.     HX_ASSERT(pTrackAtom);
  163.     if (uTrackIdx == ulHintTrackIdx)
  164.     {
  165. // This is a hint track
  166. if (m_bHintTracksActive)
  167. {
  168.     retVal = CreateHintTrack(pTrackAtom,
  169.      uTrackIdx,
  170.      uStreamTrackCount);
  171.     if (retVal != HXR_OK)
  172.     {
  173. break;
  174.     }
  175. }
  176. uHintTrackCount++;
  177. if (uHintTrackCount < m_pHintTrackIdxList->GetCount())
  178. {
  179.     ulHintTrackIdx = (UINT32) m_pHintTrackIdxList->GetNext(
  180.     HintTrackIdxListPosition);
  181. }
  182.     }
  183.     else
  184.     {
  185. // This a standard track
  186. m_pTrackTable[uTrackIdx].m_pTrack = new CQTTrack(pTrackAtom);
  187. if (m_pTrackTable[uTrackIdx].m_pTrack == NULL)
  188. {
  189.     retVal = HXR_OUTOFMEMORY;
  190.     break;
  191. }
  192.      m_pTrackTable[uTrackIdx].m_pTrackAtom = pTrackAtom;
  193. pTrackAtom->AddRef();
  194. if (!m_bHintTracksActive)
  195. {
  196.     HX_ASSERT(uStreamTrackCount < m_uNumStreams);
  197.     if (uStreamTrackCount < m_uNumStreams)
  198.     {
  199. m_pStreamToTrackMap[uStreamTrackCount].m_pQTTrack =
  200.     m_pTrackTable[uTrackIdx].m_pTrack;
  201. uStreamTrackCount++;
  202.     }
  203. }
  204. // For now keep references to all "standard" tracks.
  205. // To do : reference only "standard" tracks referenced
  206. //         by hint tracks - when hint tracks are active
  207. m_pTrackTable[uTrackIdx].m_uRefCount++;
  208.     }
  209.     if (m_pTrackTable[uTrackIdx].m_pTrack)
  210.     {
  211. m_pTrackTable[uTrackIdx].m_pTrack->AddRef();
  212.     }
  213.     uTrackIdx++;
  214. } while (uTrackIdx < m_uNumTracks);
  215.     }
  216.     // Free Unreferenced Standard Tracks
  217.     if (SUCCEEDED(retVal))
  218.     {
  219. UINT16 uTrackIdx;
  220. for (uTrackIdx = 0; uTrackIdx < m_uNumTracks; uTrackIdx++)
  221. {
  222.     if (m_pTrackTable[uTrackIdx].m_uRefCount == 0)
  223.     {
  224. HX_RELEASE(m_pTrackTable[uTrackIdx].m_pTrack);
  225. HX_RELEASE(m_pTrackTable[uTrackIdx].m_pTrackAtom);
  226.     }
  227. }
  228.     }
  229.     if (FAILED(retVal))
  230.     {
  231. Clear();
  232.     }
  233.     return retVal;
  234. }
  235. /****************************************************************************
  236.  *  CloseTracks
  237.  */
  238. void CQTTrackManager::CloseTracks(void)
  239. {
  240.     UINT16 uTrackIdx;
  241.     if (m_pTrackTable)
  242.     {
  243. for (uTrackIdx = 0; uTrackIdx < m_uNumTracks; uTrackIdx++)
  244. {
  245.     if (m_pTrackTable[uTrackIdx].m_pTrack)
  246.     {
  247. m_pTrackTable[uTrackIdx].m_pTrack->Close();
  248. m_pTrackTable[uTrackIdx].m_pTrack->Release();
  249. m_pTrackTable[uTrackIdx].m_pTrack = NULL;
  250.     }
  251.     HX_RELEASE(m_pTrackTable[uTrackIdx].m_pTrackAtom);
  252. }
  253.     }
  254.     Clear();
  255. }
  256. /****************************************************************************
  257.  *  ResetTracks - reset what's done in ReadyTracks()
  258.  */
  259. void CQTTrackManager::ResetTracks(void)
  260. {
  261.     if (m_pTrackTable)
  262.     {
  263. for (UINT16 uTrackIdx = 0; uTrackIdx < m_uNumTracks; uTrackIdx++)
  264. {
  265.     if (m_pTrackTable[uTrackIdx].m_pTrack)
  266.     {
  267. m_pTrackTable[uTrackIdx].m_pTrack->Close();
  268. m_pTrackTable[uTrackIdx].m_pTrack->Release();
  269. m_pTrackTable[uTrackIdx].m_pTrack = NULL;
  270.     }
  271.     HX_RELEASE(m_pTrackTable[uTrackIdx].m_pTrackAtom);
  272. }
  273.     }
  274.     HX_VECTOR_DELETE(m_pTrackTable);
  275.     HX_VECTOR_DELETE(m_pStreamToTrackMap);
  276.     m_uNumTracks = 0;
  277.     m_uNumStreams = 0;
  278. }
  279. /****************************************************************************
  280.  *  InitTracks
  281.  */
  282. HX_RESULT CQTTrackManager::InitTracks(CQTFileFormat *pFileFormat,
  283.       CQTPacketAssembler *pPacketAssembler,
  284.       CQTPacketizerFactory* pPacketizerFactory,
  285.       const char* pProtocol)
  286. {
  287.     UINT16 uTrackIdx;
  288.     HX_RESULT retVal = HXR_OK;
  289.     if (m_pTrackTable)
  290.     {
  291. UINT16 uStreamNum;
  292. BOOL bSomeStreamsDeactivated = FALSE;
  293. for (uTrackIdx = 0;
  294.      SUCCEEDED(retVal) && (uTrackIdx < m_uNumTracks);
  295.      uTrackIdx++)
  296. {
  297.     if (m_pTrackTable[uTrackIdx].m_pTrack)
  298.     {
  299. retVal = m_pTrackTable[uTrackIdx].m_pTrack->Init(pFileFormat,
  300.  pPacketAssembler,
  301.  pPacketizerFactory,
  302.  pProtocol);
  303. uStreamNum = GetTrackStreamNum(m_pTrackTable[uTrackIdx].m_pTrack);
  304. if (uStreamNum < m_uNumStreams)
  305. {
  306.     m_pStreamToTrackMap[uStreamNum].m_bActive = (retVal == HXR_OK);
  307.     bSomeStreamsDeactivated = bSomeStreamsDeactivated ||
  308.       (!m_pStreamToTrackMap[uStreamNum].m_bActive);
  309.     if ((retVal == HXR_IGNORE) ||
  310. (retVal == HXR_NO_DATA))
  311.     {
  312. retVal = HXR_OK;
  313.     }
  314. }
  315.     }
  316. }
  317. // Some streams could have been
  318.         // disabled during initialization - remove the inactive ones
  319. if (SUCCEEDED(retVal) && bSomeStreamsDeactivated)
  320. {
  321.     retVal = RemoveInactiveStreams();
  322. #ifdef QTCONFIG_ALTERNATE_STREAMS
  323.     // Return remaining streams to inactive (unsubscribed) state
  324.     if (SUCCEEDED(retVal))
  325.     {
  326. for (uTrackIdx = 0; uTrackIdx < m_uNumStreams; uTrackIdx++)
  327. {
  328.     m_pStreamToTrackMap[uTrackIdx].m_bActive = FALSE;
  329. }
  330. m_bSubscriptionWindowClosed = FALSE;
  331.     }
  332. #endif // QTCONFIG_ALTERNATE_STREAMS
  333. }
  334. // After track initialization, release all Track Atoms from
  335. // the track manager
  336. for (uTrackIdx = 0;
  337.      uTrackIdx < m_uNumTracks;
  338.      uTrackIdx++)
  339. {
  340.     HX_RELEASE(m_pTrackTable[uTrackIdx].m_pTrackAtom);
  341. }
  342.     }
  343.     else
  344.     {
  345. retVal = HXR_UNEXPECTED;
  346.     }
  347.     if (SUCCEEDED(retVal))
  348.     {
  349.         // Release Lists
  350. DeleteTrackAtomList();
  351. HX_DELETE(m_pHintTrackIdxList);
  352.     }
  353.     return retVal;
  354. }
  355. #ifdef QTCONFIG_ALTERNATE_STREAMS
  356. /****************************************************************************
  357.  *  AddStreamToGroup
  358.  */
  359. HX_RESULT CQTTrackManager::AddStreamToGroup(UINT16 uStreamNumber,
  360.     UINT16 uGroup,
  361.     ULONG32 ulBitrate)
  362. {
  363.     HX_RESULT retVal = HXR_FAIL;
  364.     HX_ASSERT(m_pStreamToTrackMap);
  365.     HX_ASSERT(uStreamNumber < m_uNumStreams);
  366.     if (uStreamNumber < m_uNumStreams)
  367.     {
  368. m_pStreamToTrackMap[uStreamNumber].m_uGroup = uGroup;
  369. m_pStreamToTrackMap[uStreamNumber].m_ulBitrate = ulBitrate;
  370. m_pStreamToTrackMap[uStreamNumber].m_bGroupped = TRUE;
  371. retVal = HXR_OK;
  372.     }
  373.     return retVal;
  374. }
  375. /****************************************************************************
  376.  *  SubscribeDefault
  377.  */
  378. HX_RESULT CQTTrackManager::SubscribeDefault(void)
  379. {
  380.     UINT16 uStrmIdx;
  381.     HX_RESULT retVal = HXR_OUTOFMEMORY;
  382.     BOOL* pVisitedArray = new BOOL [m_uNumStreams];
  383.     HX_ASSERT(m_pStreamToTrackMap);
  384.     HX_ASSERT(pVisitedArray);
  385.     if (pVisitedArray)
  386.     {
  387. for (uStrmIdx = 0; uStrmIdx < m_uNumStreams; uStrmIdx++)
  388. {
  389.     pVisitedArray[uStrmIdx] = FALSE;
  390. }
  391. retVal = HXR_OK;
  392.     }
  393.     if (SUCCEEDED(retVal))
  394.     {
  395. for (uStrmIdx = 0; uStrmIdx < m_uNumStreams; uStrmIdx++)
  396. {
  397.     if (!pVisitedArray[uStrmIdx])
  398.     {
  399. if (m_pStreamToTrackMap[uStrmIdx].m_bGroupped)
  400. {
  401.     // Activate the highest bitrate stream in the group
  402.     UINT16 uSubIdx;
  403.     UINT16 uGroup = m_pStreamToTrackMap[uStrmIdx].m_uGroup;
  404.     ULONG32 ulHighBitrate = m_pStreamToTrackMap[uStrmIdx].m_ulBitrate;
  405.     UINT16 uHighIdx = uStrmIdx;
  406.     m_pStreamToTrackMap[uStrmIdx].m_bActive = FALSE;
  407.     for (uSubIdx = uStrmIdx + 1; uSubIdx < m_uNumStreams; uSubIdx++)
  408.     {
  409. if (m_pStreamToTrackMap[uStrmIdx].m_uGroup == uGroup)
  410. {
  411.     m_pStreamToTrackMap[uSubIdx].m_bActive = FALSE;
  412.     if (m_pStreamToTrackMap[uSubIdx].m_ulBitrate > ulHighBitrate)
  413.     {
  414. ulHighBitrate = m_pStreamToTrackMap[uSubIdx].m_ulBitrate;
  415. uHighIdx = uSubIdx;
  416.     }
  417.     pVisitedArray[uSubIdx] = TRUE;
  418. }
  419.     }
  420.     m_pStreamToTrackMap[uHighIdx].m_bActive = TRUE;
  421. }
  422. else
  423. {
  424.     m_pStreamToTrackMap[uStrmIdx].m_bActive = TRUE;
  425. }
  426. pVisitedArray[uStrmIdx] = TRUE;
  427.     }
  428. }
  429.     }
  430.     HX_VECTOR_DELETE(pVisitedArray);
  431.     return retVal;
  432. }
  433. /****************************************************************************
  434.  *  Subscribe
  435.  */
  436. HX_RESULT CQTTrackManager::Subscribe(UINT16 uStreamNum)
  437. {
  438.     HX_RESULT retVal = HXR_UNEXPECTED;
  439.     if (!m_bSubscriptionWindowClosed)
  440.     {
  441. HX_ASSERT(m_pStreamToTrackMap);
  442. HX_ASSERT(uStreamNum < m_uNumStreams);
  443. retVal = HXR_FAIL;
  444. if (uStreamNum < m_uNumStreams)
  445. {
  446.     if (m_pStreamToTrackMap[uStreamNum].m_bGroupped)
  447.     {
  448. UINT16 uStrmIdx;
  449. UINT16 uGroup = m_pStreamToTrackMap[uStreamNum].m_uGroup;
  450. // There can be only one stream subscribed in a group
  451. for (uStrmIdx = 0; uStrmIdx < m_uNumStreams; uStrmIdx++)
  452. {
  453.     if (m_pStreamToTrackMap[uStrmIdx].m_uGroup == uGroup)
  454.     {
  455. m_pStreamToTrackMap[uStrmIdx].m_bActive = FALSE;
  456.     }
  457. }
  458.     }
  459.     m_pStreamToTrackMap[uStreamNum].m_bActive = TRUE;
  460.     retVal = HXR_OK;
  461. }
  462.     }
  463.     return retVal;
  464. }
  465. /****************************************************************************
  466.  *  Unsubscribe
  467.  */
  468. HX_RESULT CQTTrackManager::Unsubscribe(UINT16 uStreamNum)
  469. {
  470.     HX_RESULT retVal = HXR_UNEXPECTED;
  471.     if (!m_bSubscriptionWindowClosed)
  472.     {
  473. HX_ASSERT(uStreamNum < m_uNumStreams);
  474. retVal = HXR_FAIL;
  475. if (uStreamNum < m_uNumStreams)
  476. {
  477.     m_pStreamToTrackMap[uStreamNum].m_bActive = FALSE;
  478.     retVal = HXR_OK;
  479. }
  480.     }
  481.     return retVal;
  482. }
  483. #else // QTCONFIG_ALTERNATE_STREAMS
  484. HX_RESULT CQTTrackManager::AddStreamToGroup(UINT16 uStreamNumber,
  485.     UINT16 uGroup,
  486.     ULONG32 ulBitrate)
  487. {
  488.     return HXR_NOTIMPL;
  489. }
  490. HX_RESULT CQTTrackManager::SubscribeDefault(void)
  491. {
  492.     return HXR_NOTIMPL;
  493. }
  494. HX_RESULT CQTTrackManager::Subscribe(UINT16 uStreamNum)
  495. {
  496.     return HXR_NOTIMPL;
  497. }
  498. HX_RESULT CQTTrackManager::Unsubscribe(UINT16 uStreamNum)
  499. {
  500.     return HXR_NOTIMPL;
  501. }
  502. #endif // QTCONFIG_ALTERNATE_STREAMS
  503. /****************************************************************************
  504.  *  RemoveInactiveStreams
  505.  */
  506. HX_RESULT CQTTrackManager::RemoveInactiveStreams(BOOL bLeaveReferences)
  507. {
  508.     HX_RESULT retVal = HXR_FAIL;
  509.     HX_ASSERT(m_pStreamToTrackMap);
  510.     UINT16 uActiveStreamCount = GetNumActiveStreams();
  511.     if (uActiveStreamCount > 0)
  512.     {
  513. CQTStream* pNewStreamToTrackMap = NULL;
  514. retVal = HXR_OK;
  515. if (!bLeaveReferences)
  516. {
  517.     pNewStreamToTrackMap = new CQTStream [uActiveStreamCount];
  518.     retVal = HXR_OUTOFMEMORY;
  519.     if (pNewStreamToTrackMap)
  520.     {
  521. retVal = HXR_OK;
  522.     }
  523. }
  524. if (SUCCEEDED(retVal))
  525. {
  526.     UINT16 uStrmIdx;
  527.     UINT16 uNewStrmIdx = 0;
  528.     for (uStrmIdx = 0; uStrmIdx < m_uNumStreams; uStrmIdx++)
  529.     {
  530. if (m_pStreamToTrackMap[uStrmIdx].m_bActive)
  531. {
  532.     if (!bLeaveReferences)
  533.     {
  534. HX_ASSERT(uNewStrmIdx < uActiveStreamCount);
  535. pNewStreamToTrackMap[uNewStrmIdx] =
  536.     m_pStreamToTrackMap[uStrmIdx];
  537. uNewStrmIdx++;
  538.     }
  539. }
  540. else
  541. {
  542.     ReleaseTrack(m_pStreamToTrackMap[uStrmIdx].m_pQTTrack);
  543. }
  544.     }
  545.     if (!bLeaveReferences)
  546.     {
  547. delete [] m_pStreamToTrackMap;
  548. m_pStreamToTrackMap = pNewStreamToTrackMap;
  549. m_uNumStreams = uActiveStreamCount;
  550.     }
  551. }
  552. m_bSubscriptionWindowClosed = TRUE;
  553.     }
  554.     return retVal;
  555. }
  556. /****************************************************************************
  557.  *  IsStreamTrack
  558.  */
  559. BOOL CQTTrackManager::IsStreamTrack(CQTTrack* pTrack)
  560. {
  561.     UINT16 uStreamCount = 0;
  562.     CQTStream* pStreamTracer = m_pStreamToTrackMap;
  563.     HX_ASSERT(pTrack);
  564.     while (uStreamCount < m_uNumStreams)
  565.     {
  566. if (pTrack == pStreamTracer->m_pQTTrack)
  567. {
  568.     return TRUE;
  569. }
  570. pStreamTracer++;
  571. uStreamCount++;
  572.     }
  573.     return FALSE;
  574. }
  575. UINT16 CQTTrackManager::GetTrackStreamNum(CQTTrack* pTrack)
  576. {
  577.     UINT16 uStreamCount = 0;
  578.     CQTStream* pStreamTracer = m_pStreamToTrackMap;
  579.     HX_ASSERT(pTrack);
  580.     while (uStreamCount < m_uNumStreams)
  581.     {
  582. if (pTrack == pStreamTracer->m_pQTTrack)
  583. {
  584.     return uStreamCount;
  585. }
  586. pStreamTracer++;
  587. uStreamCount++;
  588.     }
  589.     return INV_STREAM_NUM;
  590. }
  591. /****************************************************************************
  592.  *  GetTrackById
  593.  */
  594. CQTTrack* CQTTrackManager::GetTrackById(ULONG32 ulTrackID)
  595. {
  596.     UINT16 uTrackCount = 0;
  597.     CQTTrackTable* pTableTracer = m_pTrackTable;
  598.     while (uTrackCount < m_uNumTracks)
  599.     {
  600. if (pTableTracer->m_pTrack && (ulTrackID == pTableTracer->m_pTrack->GetID()))
  601. {
  602.     return pTableTracer->m_pTrack;
  603. }
  604. uTrackCount++;
  605. pTableTracer++;
  606.     }
  607.     return NULL;
  608. }
  609. /****************************************************************************
  610.  *  GetAtomById
  611.  */
  612. CQTAtom* CQTTrackManager::GetTrackAtomById(ULONG32 ulTrackID)
  613. {
  614.     UINT16 uTrackCount = 0;
  615.     CQTTrackTable* pTableTracer = m_pTrackTable;
  616.     while (uTrackCount < m_uNumTracks)
  617.     {
  618. if (ulTrackID == pTableTracer->m_pTrack->GetID())
  619. {
  620.     return pTableTracer->m_pTrackAtom;
  621. }
  622. uTrackCount++;
  623. pTableTracer++;
  624.     }
  625.     return NULL;
  626. }
  627. /****************************************************************************
  628.  *  GetTrackAtomHdlr
  629.  */
  630. CQT_hdlr_Atom* CQTTrackManager::GetTrackAtomHdlr(CQT_trak_Atom* pTrakAtom)
  631. {
  632.     CQT_mdia_Atom* pMdiaAtom;
  633.     CQT_hdlr_Atom* pHdlrAtom = NULL;
  634.     pMdiaAtom = (CQT_mdia_Atom*) pTrakAtom->FindPresentChild(QT_mdia);
  635.     if (pMdiaAtom)
  636.     {
  637. pHdlrAtom = (CQT_hdlr_Atom*) pMdiaAtom->FindPresentChild(QT_hdlr);
  638.     }
  639.     return pHdlrAtom;
  640. }
  641. /****************************************************************************
  642.  *  GetTrackAtomStbl
  643.  */
  644. CQT_stbl_Atom* CQTTrackManager::GetTrackAtomStbl(CQT_trak_Atom* pTrakAtom)
  645. {
  646.     CQT_mdia_Atom* pMdiaAtom;
  647.     CQT_hdlr_Atom* pMinfAtom;
  648.     CQT_stbl_Atom* pStblAtom = NULL;
  649.     pMdiaAtom = (CQT_mdia_Atom*) pTrakAtom->FindPresentChild(QT_mdia);
  650.     if (pMdiaAtom)
  651.     {
  652. pMinfAtom = (CQT_hdlr_Atom*) pMdiaAtom->FindPresentChild(QT_minf);
  653. if (pMinfAtom)
  654. {
  655.     pStblAtom = (CQT_stbl_Atom*) pMinfAtom->FindPresentChild(QT_stbl);
  656. }
  657.     }
  658.     return pStblAtom;
  659. }
  660. /****************************************************************************
  661.  *  IsHintTrackAtom
  662.  */
  663. BOOL CQTTrackManager::IsHintTrackAtom(CQT_trak_Atom* pTrakAtom)
  664. {
  665.     CQT_hdlr_Atom* pHdlrAtom = GetTrackAtomHdlr(pTrakAtom);
  666.     if (pHdlrAtom &&
  667. /*** MBO: To strict for some files
  668. (pHdlrAtom->Get_CompType() == QT_mhlr) &&
  669. ***/
  670. (pHdlrAtom->Get_CompSubtype() == QT_hint))
  671.     {
  672. return TRUE;
  673.     }
  674.     return FALSE;
  675. }
  676. /****************************************************************************
  677.  *  IsNonEmptyTrackAtom
  678.  */
  679. BOOL CQTTrackManager::IsNonEmptyTrackAtom(CQT_trak_Atom* pTrakAtom)
  680. {
  681.     CQT_SampleSize_Manager sampleSize;
  682.     CQT_stbl_Atom* pStblAtom = GetTrackAtomStbl(pTrakAtom);
  683.     if (pStblAtom)
  684.     {
  685. if (sampleSize.Init(pStblAtom) == HXR_OK)
  686. {
  687.     return TRUE;
  688. }
  689.     }
  690.     return FALSE;
  691. }
  692. /****************************************************************************
  693.  *  Private Methods
  694.  */
  695. /****************************************************************************
  696.  *  AddTracks
  697.  */
  698. void CQTTrackManager::AddTracks(CQTAtom *pRootAtom)
  699. {
  700.     UINT16 uChildCount;
  701.     if (pRootAtom->GetType() == QT_trak)
  702.     {
  703. BOOL bAdd = TRUE;
  704. if (IsHintTrackAtom((CQT_trak_Atom *) pRootAtom))
  705. {
  706.     bAdd = IsNonEmptyTrackAtom((CQT_trak_Atom*) pRootAtom);
  707.     if (bAdd)
  708.     {
  709. m_pHintTrackIdxList->AddTail(
  710.     (void *) m_pTrackAtomList->GetCount());
  711.     }
  712. }
  713. if (bAdd)
  714. {
  715.     m_pTrackAtomList->AddTail(pRootAtom);
  716.     pRootAtom->AddRef();
  717. }
  718.     }
  719.     else if (((pRootAtom->GetType() == QT_HXROOT) ||
  720.       (pRootAtom->GetType() == QT_moov)) &&
  721.      (uChildCount = pRootAtom->GetPresentChildCount()))
  722.     {
  723. CQTAtom::ChildIterator i = pRootAtom->BeginChildren();
  724. do
  725. {
  726.     AddTracks(*i);
  727.     if ((--uChildCount) == 0)
  728.     {
  729. break;
  730.     }
  731.     ++i;
  732. } while (TRUE);
  733.     }
  734.     else if (pRootAtom->GetType() == QT_iods)
  735.     {
  736. HX_ASSERT(m_pIodsAtom == NULL);
  737. if (m_pIodsAtom == NULL)
  738. {
  739.     m_pIodsAtom = (CQT_iods_Atom*) pRootAtom;
  740.     m_pIodsAtom->AddRef();
  741.     m_FType = QT_FTYPE_MP4;
  742. }
  743.     }
  744.     else if (pRootAtom->GetType() == QT_ftyp)
  745.     {
  746. HX_ASSERT(m_pFtypAtom == NULL);
  747. if (m_pFtypAtom == NULL)
  748. {
  749.     UINT32 ulBrand;
  750.     BOOL bKeepLooking;
  751.     UINT32 ulCompBrandIdx = 0;
  752.     UINT32 ulNumCompBrands = 0;
  753.     m_pFtypAtom = (CQT_ftyp_Atom*) pRootAtom;
  754.     m_pFtypAtom->AddRef();
  755.     ulBrand = m_pFtypAtom->Get_MajorBrand();
  756.     ulNumCompBrands = m_pFtypAtom->Get_NumCompatibleBrands();
  757.     do
  758.     {
  759. bKeepLooking = FALSE;
  760. switch (ulBrand)
  761. {
  762. case QT_isom:
  763. case QT_3gp4:
  764. case QT_3gp5:
  765. case QT_mp41:
  766. case QT_mp42:
  767. case QT_mmp4:
  768. case QT_m4a:
  769.     m_FType = QT_FTYPE_MP4;
  770.     break;
  771. default:
  772.     if (ulCompBrandIdx < ulNumCompBrands)
  773.     {
  774. ulBrand = m_pFtypAtom->Get_CompatibleBrand(ulCompBrandIdx);
  775.      ulCompBrandIdx++;
  776. bKeepLooking = TRUE;
  777.     }
  778.     break;
  779. }
  780.     } while (bKeepLooking);
  781. }
  782.     }
  783. }
  784. /****************************************************************************
  785.  *  DeleteTrackAtomList
  786.  */
  787. void CQTTrackManager::DeleteTrackAtomList(void)
  788. {
  789.     if (m_pTrackAtomList)
  790.     {
  791. CQTAtom *pAtom;
  792. while (!m_pTrackAtomList->IsEmpty())
  793. {
  794.     pAtom = (CQTAtom*) m_pTrackAtomList->RemoveHead();
  795.     HX_ASSERT(pAtom);
  796.     pAtom->Release();
  797. }
  798. delete m_pTrackAtomList;
  799. m_pTrackAtomList = NULL;
  800.     }
  801. }
  802. /****************************************************************************
  803.  *  Clear
  804.  */
  805. void CQTTrackManager::Clear(void)
  806. {
  807.     HX_VECTOR_DELETE(m_pTrackTable);
  808.     HX_VECTOR_DELETE(m_pStreamToTrackMap);
  809.     DeleteTrackAtomList();
  810.     HX_DELETE(m_pHintTrackIdxList);
  811.     HX_RELEASE(m_pIodsAtom);
  812.     HX_RELEASE(m_pFtypAtom);
  813.     m_uNumTracks = 0;
  814.     m_uNumStreams = 0;
  815. }
  816. /****************************************************************************
  817.  *  GetNumActiveStreams
  818.  */
  819. UINT16 CQTTrackManager::GetNumActiveStreams(void)
  820. {
  821.     UINT16 uStrmIdx;
  822.     UINT16 uActiveCount = 0;
  823.     HX_ASSERT(m_pStreamToTrackMap);
  824.     for (uStrmIdx = 0; uStrmIdx < m_uNumStreams; uStrmIdx++)
  825.     {
  826. if (m_pStreamToTrackMap[uStrmIdx].m_bActive)
  827. {
  828.     uActiveCount++;
  829. }
  830.     }
  831.     return uActiveCount;
  832. }
  833. /****************************************************************************
  834.  *  ReleaseTrack
  835.  */
  836. void CQTTrackManager::ReleaseTrack(CQTTrack* pQTTrack)
  837. {
  838.     // Remove Track from the Track Table
  839.     if (m_pTrackTable)
  840.     {
  841. UINT16 uTrackCount = 0;
  842. CQTTrackTable* pTableTracer = m_pTrackTable;
  843. while (uTrackCount < m_uNumTracks)
  844. {
  845.     if (pTableTracer->m_pTrack == pQTTrack)
  846.     {
  847. HX_RELEASE(pTableTracer->m_pTrack);
  848. HX_RELEASE(pTableTracer->m_pTrackAtom);
  849. break;
  850.     }
  851.     uTrackCount++;
  852.     pTableTracer++;
  853. }
  854.     }
  855.     // Remove The track from the Stream Map (if there)
  856.     if (m_pStreamToTrackMap)
  857.     {
  858. UINT16 uStreamCount = 0;
  859. CQTStream* pStreamTracer = m_pStreamToTrackMap;
  860. while (uStreamCount < m_uNumStreams)
  861. {
  862.     if (pStreamTracer->m_pQTTrack == pQTTrack)
  863.     {
  864. pStreamTracer->m_pQTTrack = NULL;
  865. pStreamTracer->m_bActive = FALSE;
  866. pStreamTracer->m_bGroupped = FALSE;
  867. pStreamTracer->m_uGroup = 0;
  868. pStreamTracer->m_ulBitrate = 0;
  869. break;
  870.     }
  871.     uStreamCount++;
  872.     pStreamTracer++;
  873. }
  874.     }
  875. }
  876. /****************************************************************************
  877.  *  CQTTrackManager::CQTTrackTable
  878.  */
  879. /****************************************************************************
  880.  *  Destructor
  881.  */
  882. CQTTrackManager::CQTTrackTable::~CQTTrackTable()
  883. {
  884.     if (m_pTrack)
  885.     {
  886. m_pTrack->Release();
  887.     }
  888.     if (m_pTrackAtom)
  889.     {
  890. m_pTrackAtom->Release();
  891.     }
  892. }