qttrack.cpp

来自「symbian 下的helix player源代码」· C++ 代码 · 共 894 行 · 第 1/2 页

CPP
894
字号
/* ***** BEGIN LICENSE BLOCK ***** 
 * Version: RCSL 1.0/RPSL 1.0 
 *  
 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
 *      
 * The contents of this file, and the files included with this file, are 
 * subject to the current version of the RealNetworks Public Source License 
 * Version 1.0 (the "RPSL") available at 
 * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 * the file under the RealNetworks Community Source License Version 1.0 
 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
 * in which case the RCSL will apply. You may also obtain the license terms 
 * directly from RealNetworks.  You may not use this file except in 
 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
 * applicable to this file, the RCSL.  Please see the applicable RPSL or 
 * RCSL for the rights, obligations and limitations governing use of the 
 * contents of the file.  
 *  
 * This file is part of the Helix DNA Technology. RealNetworks is the 
 * developer of the Original Code and owns the copyrights in the portions 
 * it created. 
 *  
 * This file, and the files included with this file, is distributed and made 
 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
 * 
 * Technology Compatibility Kit Test Suite(s) Location: 
 *    http://www.helixcommunity.org/content/tck 
 * 
 * Contributor(s): 
 *  
 * ***** END LICENSE BLOCK ***** */ 

/****************************************************************************
 *  Defines
 */
// #define _LOG_DATA_ACCESS
#define QTTRACKCACHE_PAGE_SIZE	0x0000FFFF


/****************************************************************************
 *  Includes
 */
#include "qtpktasm.h"

#include "qtffplin.h"
#include "qtpacketizerfct.h"
#include "qttrack.h"
#include "qtffrefcounter.h"


/****************************************************************************
 *  Class CQTTrack
 */
/****************************************************************************
 *  Constructor/Destructor
 */
CQTTrack::CQTTrack(CQTAtom* pTrackAtom)
    : m_pTrackAtom((CQT_trak_Atom*) pTrackAtom)
    , m_pFileFormat(NULL)
    , m_pPacketAssembler(NULL)
    , m_pReadFileNameBuffer(NULL)
    , m_pReadFileName(NULL)
    , m_pFileSwitcher(NULL)
    , m_pPacketizer(NULL)
    , m_pClassFactory(NULL)
    , m_ulTrackID(0)
    , m_bTrackDone(FALSE)
    , m_PendingState(QTT_Offline)
    , m_uStreamNumber(0)
    , m_ulReadSize(0)
    , m_ulReadPageSize(0)
    , m_ulReadPageOffset(0)
    , m_uBytesPerCBlock(0)
    , m_uSamplesPerCBlock(0)
    , m_lRefCount(0)
    , m_ulLastSampleDescIdx(0)
{
    CQT_tkhd_Atom* pTrackHeaderAtom = NULL;

    HX_ASSERT(pTrackAtom);
    pTrackAtom->AddRef();
    
    if (pTrackAtom)
    {
	pTrackHeaderAtom = (CQT_tkhd_Atom*) 
	    pTrackAtom->FindPresentChild(QT_tkhd);
    }
    
    if (pTrackHeaderAtom)
    {
	m_ulTrackID = pTrackHeaderAtom->Get_TrackID();
    }

    g_nRefCount_qtff++;
}

CQTTrack::~CQTTrack()
{
    Close();

    g_nRefCount_qtff--;
}

/****************************************************************************
 *  Main Interface
 */
/****************************************************************************
 *  Init
 */
HX_RESULT CQTTrack::Init(CQTFileFormat *pFileFormat,
			 CQTPacketAssembler *pPacketAssembler,
			 CQTPacketizerFactory* pPacketizerFactory,
			 const char* pProtocol)
{
    CQTAtom* pAtom = NULL;
    BOOL bIsStreamTrack = FALSE;
    HX_RESULT retVal = HXR_OK;

    if (!m_pTrackAtom)
    {
	retVal = HXR_UNEXPECTED;
    }

    pAtom = m_pTrackAtom;

    m_uBytesPerCBlock = 0;
    m_uSamplesPerCBlock = 0;

    if (SUCCEEDED(retVal))
    {
	HX_ASSERT(pFileFormat);

	bIsStreamTrack = pFileFormat->m_TrackManager.IsStreamTrack(this);
	
	m_pFileFormat = pFileFormat;
	pFileFormat->AddRef();

	HX_ASSERT(pPacketAssembler);

	m_pPacketAssembler = pPacketAssembler;
	pPacketAssembler->AddRef();

	retVal = pFileFormat->QueryInterface(
	    IID_IHXFileSwitcher,
	    (void**) &m_pFileSwitcher);
    }

    if (SUCCEEDED(retVal))
    {
	retVal = pFileFormat->QueryInterface(IID_IHXCommonClassFactory,
					     (void**) &m_pClassFactory);
    }

    if (SUCCEEDED(retVal))
    {
	CQT_tkhd_Atom* pTrackHeaderAtom = NULL;

	HX_ASSERT(m_pFileSwitcher);

	if (pAtom)
	{
	    pTrackHeaderAtom = (CQT_tkhd_Atom*) 
			       pAtom->FindPresentChild(QT_tkhd);
	}

	if (pTrackHeaderAtom)
	{
	    m_ulTrackID = pTrackHeaderAtom->Get_TrackID();
	}
	else
	{
	    retVal = HXR_FAIL;
	}
    }

    if (SUCCEEDED(retVal))
    {
	IHXCommonClassFactory* pClassFactory = NULL;
	CQTAtom* pChildAtom = NULL;

	if (pAtom)
	{
	    pAtom = pAtom->FindPresentChild(QT_mdia);
	}
	
	if (pAtom)
	{
	    pAtom = pAtom->FindPresentChild(QT_minf);
	}
	
	if (pAtom)
	{
	    pChildAtom = pAtom->FindPresentChild(QT_dinf);
	}
	
	retVal = pFileFormat->QueryInterface(
	    IID_IHXCommonClassFactory,
	    (void**) &pClassFactory);

	if (SUCCEEDED(retVal))
	{
	    retVal = m_DataRef.Init(pChildAtom, pClassFactory);
	}

	HX_RELEASE(pClassFactory);
    }

    if (retVal == HXR_OK)
    {
	if (pAtom)
	{
	    pAtom = pAtom->FindPresentChild(QT_stbl);
	}

	retVal = m_SampleSize.Init(pAtom);
    }

    if (retVal == HXR_OK)
    {
	retVal = m_SampleToChunk.Init(pAtom);
    }

    if (retVal == HXR_OK)
    {
	retVal = m_TimeToSample.Init(pAtom);
    }

    if (retVal == HXR_OK)
    {
	retVal = m_ChunkToOffset.Init(pAtom);
    }

    if (retVal == HXR_OK)
    {
	retVal = m_SampleDesc.Init(pAtom);
    }

    if ((retVal == HXR_OK) && bIsStreamTrack)
    {
	retVal = m_TrackInfo.Init(pFileFormat->GetContext(),
				  m_pTrackAtom,
				  &m_SampleDesc,
				  &pFileFormat->m_TrackManager,
				  &pFileFormat->m_MovieInfo);
    }

    if ((retVal == HXR_OK) && bIsStreamTrack)
    {
	retVal = InitPacketizer(m_pPacketizer,
				pPacketizerFactory,
				pProtocol,
				&m_TrackInfo,
				&pFileFormat->m_MovieInfo,
				&pFileFormat->m_TrackManager,
				this,
				pFileFormat->GetContext());
    }

    if ((retVal == HXR_OK) && bIsStreamTrack)
    {
	CQTAtom* pChildAtom = NULL;

	pChildAtom = m_pTrackAtom->FindPresentChild(QT_edts);

	retVal = m_TrackEdit.Init(
	    pChildAtom,
	    pFileFormat->m_MovieInfo.GetMovieTimeScale(),
	    m_TrackInfo.GetMediaTimeScale());
    }

    if ((retVal == HXR_OK) && bIsStreamTrack)
    {
	retVal = Seek(0);

	if (retVal == HXR_STREAM_DONE)
	{
	    retVal = HXR_OK;
	}
    }

    HX_RELEASE(m_pTrackAtom);

    return retVal;
}

/****************************************************************************
 *  Close
 */
void CQTTrack::Close(void)
{
    m_PendingState = QTT_Offline;

    HX_RELEASE(m_pTrackAtom);
    HX_RELEASE(m_pFileFormat);
    HX_RELEASE(m_pPacketAssembler);
    HX_RELEASE(m_pReadFileNameBuffer);
    HX_RELEASE(m_pFileSwitcher);
    HX_RELEASE(m_pPacketizer);
    HX_RELEASE(m_pClassFactory);
}

/****************************************************************************
 *  Seek
 */
HX_RESULT CQTTrack::Seek(ULONG32 ulTime)
{
    if (m_pPacketizer)
    {
	m_pPacketizer->Reset();
    }

    m_bTrackDone = !m_TrackEdit.EstablishByTime(ulTime);

    if (!m_bTrackDone)
    {
	m_bTrackDone = !SequenceToTime(m_TrackEdit,
				       m_TimeToSample,
				       m_SampleToChunk,
				       QTTRK_USE_KEY_FRAMES);
    }

    return m_bTrackDone ? HXR_STREAM_DONE : HXR_OK;
}

/****************************************************************************
 *  GetPacket
 */
HX_RESULT CQTTrack::GetPacket(UINT16 uStreamNum)
{
    HX_RESULT retVal = HXR_STREAM_DONE;

    m_uStreamNumber = uStreamNum;

    if (m_pPacketizer)
    {
	IHXPacket* pPacket = NULL;
	
	retVal = m_pPacketizer->GetPacket(pPacket);
	
	if (retVal != HXR_INCOMPLETE)
	{
	    m_pFileFormat->PacketReady(m_uStreamNumber, 
		retVal, 
		pPacket);
	    
	    HX_RELEASE(pPacket);
	    
	    return HXR_OK;
	}

	retVal = HXR_STREAM_DONE;
    }

    if (!m_bTrackDone)
    {
	m_PendingState = QTT_SampleRead;

	// Locate Sample
	if (m_ChunkToOffset.EstablishByChunk(
		m_SampleToChunk.GetChunkNum()) &&
	    m_SampleSize.EstablishBySample(
		m_TimeToSample.GetSampleNumber(),
		m_SampleToChunk.GetChunkSampleNum()) &&
	    m_SampleDesc.EstablishByIdx(
		m_SampleToChunk.GetSampleDescIdx()) &&
	    m_DataRef.EstablishByIdx(
		m_SampleDesc.GetDataRefIdx()))
	{
	    ULONG32 ulFileOffset = m_ChunkToOffset.GetChunkOffset() +
				   m_SampleSize.GetChunkSampleOffset();

#ifdef QTCONFIG_TRACK_CACHE
	    if (m_DataRef.GetDataRefName() == NULL)
	    {
		if (m_TrackCache.IsInPage(ulFileOffset, m_SampleSize.GetSampleSize()))
		{
		    IHXBuffer* pBuffer;
		    UINT32 ulPageOffset;
		    m_TrackCache.Get(ulFileOffset,
				     pBuffer,
				     ulPageOffset);

		    return ReturnPacket(HXR_OK,
					pBuffer,
					ulPageOffset, 
					m_SampleSize.GetSampleSize());
		}
	    }
#endif	// QTCONFIG_TRACK_CACHE

	    retVal = LoadData(
			m_DataRef.GetDataRefName(),
			ulFileOffset,
			m_SampleSize.GetSampleSize());
	}
	else
	{
	    retVal = ReturnPacket(retVal, NULL);
	}
    }
    else
    {
	retVal = ReturnPacket(retVal, NULL);
    }

    return retVal;
}

/****************************************************************************
 *  ComputeTrackSize
 */
HX_RESULT CQTTrack::ComputeTrackSize(ULONG32& ulTrackSizeOut)
{
    ULONG32 ulTrackSize = 0;
    ULONG32 ulCurrentMediaTime = m_TrackEdit.GetMediaTime();
    HX_RESULT retVal = Seek(0);

    if (SUCCEEDED(retVal))
    {
	do
	{
	    if (!m_SampleSize.EstablishBySample(
		    m_TimeToSample.GetSampleNumber(),
		    m_SampleToChunk.GetChunkSampleNum()))
	    {
		break;
	    }

	    ulTrackSize += m_SampleSize.GetSampleSize();
	} while (AdvanceSample(m_TrackEdit,
			       m_TimeToSample,
			       m_SampleToChunk));

	ulTrackSizeOut = ulTrackSize;
    }

    Seek(ulCurrentMediaTime);

    return retVal;
}

/****************************************************************************
 *  IHXThreadSafeMethods method
 */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?