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 + -
显示快捷键?