qttrack.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 894 行 · 第 1/2 页
CPP
894 行
/****************************************************************************
* IsThreadSafe
*/
STDMETHODIMP_(UINT32)
CQTTrack::IsThreadSafe()
{
return HX_THREADSAFE_METHOD_FF_GETPACKET | HX_THREADSAFE_METHOD_FSR_READDONE;
}
/****************************************************************************
* Protected Functions
*/
/****************************************************************************
* InitPacketizer
*/
HX_RESULT CQTTrack::InitPacketizer(IHXPayloadFormatObject* &pPacketizer,
CQTPacketizerFactory* pPacketizerFactory,
const char* pProtocol,
CQT_TrackInfo_Manager* pTrackInfo,
CQT_MovieInfo_Manager* pMovieInfo,
CQTTrackManager* pTrackManager,
CQTTrack* pTrack,
IUnknown* pContext)
{
HX_RESULT retVal = HXR_OK;
#ifdef QTCONFIG_PACKETIZER_FACTORY
if (pPacketizerFactory)
{
retVal = pPacketizerFactory->Construct(pPacketizer,
pProtocol,
pTrackInfo,
pMovieInfo,
pTrackManager,
pTrack,
pContext);
if (retVal == HXR_NO_DATA)
{
retVal = HXR_OK;
}
}
if (SUCCEEDED(retVal))
{
if (pPacketizer)
{
IHXValues* pHeader = NULL;
retVal = pPacketizer->Init(pContext, TRUE);
if (SUCCEEDED(retVal))
{
retVal = m_pFileFormat->BuildStreamHeader(pHeader,
this,
pTrackInfo,
pMovieInfo,
pTrackManager,
m_pClassFactory);
}
if (SUCCEEDED(retVal))
{
retVal = pPacketizer->SetStreamHeader(pHeader);
}
HX_RELEASE(pHeader);
if (SUCCEEDED(retVal))
{
retVal = pPacketizer->GetStreamHeader(pHeader);
}
if (SUCCEEDED(retVal))
{
pTrackInfo->SetHeader(pHeader);
}
HX_RELEASE(pHeader);
}
}
#endif // QTCONFIG_PACKETIZER_FACTORY
return retVal;
}
/****************************************************************************
* LoadData
*/
HX_RESULT CQTTrack::LoadData(IHXBuffer* pFileName,
ULONG32 ulOffset,
ULONG32 ulSize)
{
HX_RELEASE(m_pReadFileNameBuffer);
m_pReadFileName = NULL;
#ifdef _LOG_DATA_ACCESS
FILE* pf = fopen("C:\\qt_access.txt", "a");
fprintf(pf, "%d %d %d\n", m_ulTrackID, ulOffset, ulSize);
fclose(pf);
#endif // _LOG_DATA_ACCESS
#ifdef QTCONFIG_TRACK_CACHE
m_TrackCache.ReleasePage();
#endif // QTCONFIG_TRACK_CACHE
m_ulReadSize = ulSize;
m_ulReadPageSize = ulSize;
m_ulReadPageOffset = ulOffset;
if (pFileName)
{
m_pReadFileNameBuffer = pFileName;
pFileName->AddRef();
m_pReadFileName = (char *) pFileName->GetBuffer();
}
#ifdef QTCONFIG_TRACK_CACHE
else if (m_TrackCache.IsEnabled() && (ulSize < QTTRACKCACHE_PAGE_SIZE))
{
m_ulReadPageSize = QTTRACKCACHE_PAGE_SIZE;
}
#endif // QTCONFIG_TRACK_CACHE
return m_pFileSwitcher->Seek( ulOffset,
FALSE,
(IHXFileResponse*) this,
m_pReadFileName);
}
/****************************************************************************
* DataReady
*/
HX_RESULT CQTTrack::DataReady(HX_RESULT status, IHXBuffer *pBuffer)
{
#ifdef QTCONFIG_TRACK_CACHE
if (status == HXR_OK)
{
if (m_ulReadPageSize > m_ulReadSize)
{
m_TrackCache.SetPage(m_ulReadPageOffset, pBuffer);
}
}
else
{
if (m_TrackCache.IsEnabled())
{
m_TrackCache.Enable(FALSE);
return LoadData(m_pReadFileNameBuffer,
m_ulReadPageOffset,
m_ulReadSize);
}
}
#endif // QTCONFIG_TRACK_CACHE
switch (m_PendingState)
{
case QTT_SegmentRead:
m_PendingState = QTT_Offline;
if (m_pPacketAssembler)
{
return m_pPacketAssembler->SegmentReady(status, pBuffer,
0, m_ulReadSize);
}
break;
case QTT_SampleRead:
m_PendingState = QTT_Offline;
return ReturnPacket(status, pBuffer, 0, m_ulReadSize);
}
return HXR_UNEXPECTED;
}
/****************************************************************************
* ReturnPacket
*/
HX_RESULT CQTTrack::ReturnPacket(HX_RESULT status,
IHXBuffer *pBuffer)
{
return ReturnPacket(status,
pBuffer,
0,
pBuffer ? pBuffer->GetSize() : 0);
}
/****************************************************************************
* ReturnPacket
*/
HX_RESULT CQTTrack::ReturnPacket(HX_RESULT status,
IHXBuffer *pBuffer,
ULONG32 ulOffset,
ULONG32 ulSize)
{
ULONG32 ulTime = (ULONG32) (m_TrackEdit.GetRealTime() + 0.5);
ULONG32 ulRTPTime = m_TrackEdit.GetMediaTime() +
m_TimeToSample.GetCompositionOffset();
IHXPacket* pPacket = NULL;
HX_RESULT retVal = HXR_OK;
if (pBuffer)
{
#ifdef QTCONFIG_BFRAG
if ((ulOffset != 0) || (ulSize != pBuffer->GetSize()))
{
#ifdef QTCONFIG_BFRAG_FACTORY
pBuffer =
m_pFileFormat->m_pBufferFragmentFactory->WrapFragment(
pBuffer, ulOffset, ulSize);
#else // QTCONFIG_BFRAG_FACTORY
pBuffer = new CBufferFragment(pBuffer, ulOffset, ulSize);
if (pBuffer)
{
pBuffer->AddRef();
}
#endif // QTCONFIG_BFRAG_FACTORY
}
else
#else // QTCONFIG_BFRAG
HX_ASSERT((ulOffset == 0) && (ulSize == pBuffer->GetSize()));
#endif // QTCONFIG_BFRAG
{
pBuffer->AddRef();
}
}
// Form packet
if (status == HXR_OK)
{
status = m_pClassFactory->CreateInstance(CLSID_IHXRTPPacket,
(void**) &pPacket);
}
if (pBuffer)
{
if (status == HXR_OK)
{
status = ((IHXRTPPacket*) pPacket)->SetRTP(
pBuffer,
ulTime,
ulRTPTime,
m_uStreamNumber,
m_TimeToSample.IsOnSyncSample() ?
(HX_ASM_SWITCH_ON | HX_ASM_SWITCH_OFF) :
HX_ASM_SWITCH_OFF, // ASM Flags
QTASM_MARKER_ON_RULE);
}
pBuffer->Release();
pBuffer = NULL;
}
if (status == HXR_OK)
{
m_ulLastSampleDescIdx = m_SampleToChunk.GetSampleDescIdx();
m_bTrackDone = !AdvanceSample(m_TrackEdit,
m_TimeToSample,
m_SampleToChunk);
}
else
{
m_bTrackDone = TRUE;
}
if (m_pPacketizer)
{
if (status == HXR_OK)
{
m_pPacketizer->SetPacket(pPacket);
}
HX_RELEASE(pPacket);
if (m_bTrackDone)
{
m_pPacketizer->Flush();
}
status = m_pPacketizer->GetPacket(pPacket);
if (status == HXR_INCOMPLETE)
{
if (!m_bTrackDone)
{
status = GetPacket(m_uStreamNumber);
if (status == HXR_OK)
{
return status;
}
}
else
{
status = HXR_STREAM_DONE;
}
}
}
retVal = m_pFileFormat->PacketReady(m_uStreamNumber, status, pPacket);
HX_RELEASE(pPacket);
return retVal;
}
/****************************************************************************
* SequenceToTime
*/
BOOL CQTTrack::SequenceToTime(CQT_TrackEdit_Manager &TrackEdit,
CQT_TimeToSample_Manager &TimeToSample,
CQT_SampleToChunk_Manager &SampleToChunk,
BOOL bUseNonKeyFrames)
{
BOOL bOverSeek;
do
{
bOverSeek = !( bUseNonKeyFrames ?
TimeToSample.EstablishByMediaTime(
TrackEdit.GetMediaTime()) :
TimeToSample.EstablishAtKeyByMediaTime(
TrackEdit.GetMediaTime()));
} while ((!bOverSeek) &&
TrackEdit.AdvanceByMediaTime(
TimeToSample.GetLastMediaSyncTime(), bOverSeek) &&
(!bOverSeek));
if (!bOverSeek)
{
bOverSeek = !SampleToChunk.EstablishBySample(
TimeToSample.GetSampleNumber());
}
return !bOverSeek;
}
/****************************************************************************
* AdvanceSample
*/
BOOL CQTTrack::AdvanceSample(CQT_TrackEdit_Manager &TrackEdit,
CQT_TimeToSample_Manager &TimeToSample,
CQT_SampleToChunk_Manager &SampleToChunk)
{
BOOL bStreamDone;
if (TrackEdit.AdvanceByMediaTime(
TimeToSample.GetSampleDuration(),
bStreamDone))
{
// Advancement in time caused change in edit segment
if (!bStreamDone)
{
bStreamDone = !SequenceToTime(TrackEdit,
TimeToSample,
SampleToChunk,
QTTRK_USE_ANY_FRAME);
}
}
else
{
bStreamDone = ((!TimeToSample.AdvanceBySample()) ||
(!SampleToChunk.AdvanceBySample()));
}
return !bStreamDone;
}
/****************************************************************************
* IHXFileResponse methods
*/
/****************************************************************************
* ReadDone
*/
STDMETHODIMP CQTTrack::ReadDone(HX_RESULT status,
IHXBuffer* pBuffer)
{
return DataReady(status, pBuffer);
}
/****************************************************************************
* SeekDone
*/
STDMETHODIMP CQTTrack::SeekDone(HX_RESULT status)
{
if (SUCCEEDED(status))
{
return m_pFileSwitcher->Read( m_ulReadPageSize,
(IHXFileResponse*) this,
m_pReadFileName);
}
return DataReady(status, NULL);
}
/****************************************************************************
* IUnknown methods
*/
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::QueryInterface
//
STDMETHODIMP CQTTrack::QueryInterface(REFIID riid, void** ppvObj)
{
if (IsEqualIID(riid, IID_IHXThreadSafeMethods))
{
AddRef();
*ppvObj = (IHXThreadSafeMethods*) this;
return HXR_OK;
}
else if (IsEqualIID(riid, IID_IUnknown))
{
AddRef();
*ppvObj = this;
return HXR_OK;
}
*ppvObj = NULL;
return HXR_NOINTERFACE;
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::AddRef
//
STDMETHODIMP_(ULONG32) CQTTrack::AddRef()
{
return InterlockedIncrement(&m_lRefCount);
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::Release
//
STDMETHODIMP_(ULONG32) CQTTrack::Release()
{
if (InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?