qtffplin.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 2,308 行 · 第 1/4 页
CPP
2,308 行
if (!m_pPacketCache[unStreamNumber].bPending)
{
m_pPacketCache[unStreamNumber].bPending = TRUE;
return HXR_OK;
}
else
{
retVal = HXR_UNEXPECTED;
}
}
else
{
retVal = m_pFFResponse->StreamDone(unStreamNumber);
}
}
else
{
// Packet Cache not primed - start priming
// To save memory, release streams not used
m_TrackManager.RemoveInactiveStreams(TRUE);
m_State = QTFF_PrimeCache;
m_pPacketCache = new
CPacketCache[m_TrackManager.GetNumStreams()];
if (m_pPacketCache)
{
m_pPacketCache[unStreamNumber].bPending = TRUE;
if (m_TrackManager.IsStreamTrackActive(0))
{
return m_TrackManager.GetStreamTrack(0)->
GetPacket(0);
}
else
{
return PacketReady(0,
HXR_STREAM_DONE,
NULL);
}
}
else
{
retVal = HXR_OUTOFMEMORY;
m_State = QTFF_Error;
}
}
break;
case QTFF_GetPacket:
case QTFF_PrimeCache:
// Delay processing packet for stream until Ready
HX_ASSERT(m_pPacketCache);
if (!m_pPacketCache[unStreamNumber].bStreamDone)
{
if (!m_pPacketCache[unStreamNumber].bPending)
{
m_pPacketCache[unStreamNumber].bPending = TRUE;
return HXR_OK;
}
else
{
retVal = HXR_UNEXPECTED;
}
}
else
{
retVal = m_pFFResponse->StreamDone(unStreamNumber);
}
break;
default:
retVal = HXR_UNEXPECTED;
break;
}
}
else
{
retVal = HXR_INVALID_PARAMETER;
}
return retVal;
}
/************************************************************************
* Seek
* Purpose:
* Called by controller to tell the file format to seek to the
* nearest packet to the requested offset. The file format should
* call IHXFileFormatResponse::SeekDone() for the IHXFileFormat-
* Session object that was passed in during initialization, when
* the seek has completed.
*/
STDMETHODIMP CQTFileFormat::Seek(ULONG32 ulOffset)
{
UINT16 uStreamNum;
HX_RESULT retVal = HXR_OK;
switch (m_State)
{
case QTFF_Ready:
for (uStreamNum = 0;
uStreamNum < m_TrackManager.GetNumStreams();
uStreamNum++)
{
if (m_TrackManager.IsStreamTrackActive(uStreamNum))
{
m_TrackManager.GetStreamTrack(uStreamNum)->Seek(ulOffset);
}
}
m_uNextPacketStreamNum = NO_STREAM_SET;
HX_VECTOR_DELETE(m_pPacketCache);
retVal = m_pFFResponse->SeekDone(HXR_OK);
break;
case QTFF_GetPacket:
case QTFF_PrimeCache:
case QTFF_SeekPending:
m_State = QTFF_SeekPending;
m_ulPendingSeekTime = ulOffset;
break;
default:
retVal = HXR_UNEXPECTED;
break;
}
return retVal;
}
/************************************************************************
* WriteDone
* Purpose:
* Notification interface provided by users of the IHXFileObject
* interface. This method is called by the IHXFileObject when the
* last write to the file is complete.
*/
STDMETHODIMP CQTFileFormat::WriteDone(HX_RESULT status)
{
return HXR_UNEXPECTED;
}
/************************************************************************
* SeekDone
* Purpose:
* Notification interface provided by users of the IHXFileObject
* interface. This method is called by the IHXFileObject when the
* last seek in the file is complete.
*/
STDMETHODIMP CQTFileFormat::SeekDone(HX_RESULT status)
{
return HXR_UNEXPECTED;
}
/************************************************************************
* Close
*/
STDMETHODIMP CQTFileFormat::Close()
{
m_State = QTFF_Error;
HX_RELEASE(m_pContext);
HX_RELEASE(m_pRequest);
HX_RELEASE(m_pFFResponse);
HX_RELEASE(m_pClassFactory);
HX_RELEASE(m_pScheduler);
HX_RELEASE(m_pErrorMessages);
if (m_pFileSwitcher)
{
m_pFileSwitcher->Close(this);
m_pFileSwitcher->Release();
m_pFileSwitcher = NULL;
}
if (m_pAtomizer)
{
m_pAtomizer->Close();
m_pAtomizer->Release();
m_pAtomizer = NULL;
}
HX_RELEASE(m_pPacketAssembler);
#ifdef QTCONFIG_BFRAG_FACTORY
HX_RELEASE(m_pBufferFragmentFactory);
#endif // QTCONFIG_BFRAG_FACTORY
HX_VECTOR_DELETE(m_pPacketCache);
m_TrackManager.CloseTracks();
return HXR_OK;
}
/************************************************************************
* IHXFileResponse
*/
/************************************************************************
* InitDone
* Purpose:
* Notification interface provided by users of the IHXFileObject
* interface. This method is called by the IHXFileObject when the
* initialization of the file is complete, and the Mime type is
* available for the request file. If the URL is not valid for the
* file system, the status HXR_FAILED should be returned,
* with a mime type of NULL. If the URL is valid but the mime type
* is unknown, then the status HXR_OK should be returned with
* a mime type of NULL.
*/
STDMETHODIMP CQTFileFormat::InitDone(HX_RESULT status)
{
HX_RESULT retVal = HXR_OK;
switch (m_State)
{
case QTFF_Init:
if (SUCCEEDED(status))
{
status = m_pAtomizer->Init((IUnknown*)(IHXFileSwitcher*) m_pFileSwitcher,
(IUnknown*)(IHXAtomizerResponse*) this,
(IUnknown*)(IHXAtomizationCommander*) this);
}
m_State = SUCCEEDED(status) ? QTFF_Ready : QTFF_Error;
retVal = m_pFFResponse->InitDone(status);
break;
default:
retVal = HXR_UNEXPECTED;
break;
}
return retVal;
}
/************************************************************************
* CloseDone
* Purpose:
* Notification interface provided by users of the IHXFileObject
* interface. This method is called by the IHXFileObject when the
* close of the file is complete.
*/
STDMETHODIMP CQTFileFormat::CloseDone(HX_RESULT status)
{
// nothing to do
return HXR_OK;
}
/************************************************************************
* ReadDone
* Purpose:
* Notification interface provided by users of the IHXFileObject
* interface. This method is called by the IHXFileObject when the
* last read from the file is complete and a buffer is available.
*/
STDMETHODIMP CQTFileFormat::ReadDone(HX_RESULT status,
IHXBuffer* pBuffer)
{
return HXR_UNEXPECTED;
}
/************************************************************************
* IHXAtomizationCommander
*/
/************************************************************************
* GetAtomCommand
*/
QTAtomizerCmd CQTFileFormat::GetAtomCommand(QTAtomType AtomType, CQTAtom* pParent)
{
QTAtomizerCmd eCmd = ATMZR_CMD_LOAD;
switch (AtomType)
{
case QT_udta:
if (pParent->GetType() == QT_HXROOT)
{
eCmd = ATMZR_CMD_SKIP;
}
break;
default:
// do nothing;
break;
}
return eCmd;
}
/************************************************************************
* IHXAtomizerResponse
*/
/************************************************************************
* AtomReady
*/
HX_RESULT CQTFileFormat::AtomReady(HX_RESULT status, CQTAtom* pRootAtom)
{
HX_RESULT retVal = HXR_UNEXPECTED;
CQTPacketizerFactory* pPacketizerFactory = NULL;
switch (m_State)
{
case QTFF_Atomize:
if (SUCCEEDED(status))
{
HX_ASSERT(pRootAtom);
pRootAtom->AddRef();
if (m_pAtomizer)
{
m_pAtomizer->Close();
m_pAtomizer->Release();
m_pAtomizer = NULL;
}
}
else
{
pRootAtom = NULL;
}
if (SUCCEEDED(status))
{
IHXClientEngine* pPlayer = NULL;
if (SUCCEEDED(m_pContext->QueryInterface(IID_IHXClientEngine,
(void**)&pPlayer)))
{
m_TrackManager.SetEType(QT_ETYPE_CLIENT);
}
else
{
m_TrackManager.SetEType(QT_ETYPE_SERVER);
}
HX_RELEASE(pPlayer);
}
if (SUCCEEDED(status))
{
status = m_TrackManager.ManageTracks(pRootAtom);
}
#ifdef QTCONFIG_PACKETIZER_FACTORY
if (SUCCEEDED(status))
{
pPacketizerFactory = BuildPacketizerFactory();
if (!pPacketizerFactory)
{
status = HXR_OUTOFMEMORY;
}
}
#endif // QTCONFIG_PACKETIZER_FACTORY
if (SUCCEEDED(status))
{
BOOL bIgnoreHintTracks = FALSE;
while (1)
{
status = m_TrackManager.ReadyTracks(bIgnoreHintTracks,
m_bViewSourceRequest);
if (SUCCEEDED(status))
{
status = m_MovieInfo.Init(pRootAtom->FindPresentChild(QT_moov),
&m_TrackManager);
}
if (SUCCEEDED(status))
{
/*
* return some error to indicate try something else
*/
status = m_TrackManager.InitTracks(this,
m_pPacketAssembler,
pPacketizerFactory);
if ((HXR_NOT_SUPPORTED == status) &&
(bIgnoreHintTracks = !bIgnoreHintTracks))
{
m_MovieInfo.Clear();
m_TrackManager.ResetTracks();
}
else
{
/*
* Until we add support for unhinted content on the server....
*
* Verify that hint tracks are present and log a warning message if
* they're missing
*/
WarnIfNotHinted(status, bIgnoreHintTracks);
/*
* XXXGo - Change warning to take into account
* hintrack and license for dynamic pktization
* e.g. force pktization yet not licensed for dynamic pktization...
*/
if (FAILED(status) && m_bViewSourceRequest)
{
// For view source, proceed attempting to return as much
// information as possible
status = HXR_OK;
}
break;
}
}
else
{
break;
}
}
}
HX_DELETE(pPacketizerFactory);
#ifdef QTCONFIG_BFRAG_FACTORY
if (SUCCEEDED(status))
{
HX_RELEASE(m_pBufferFragmentFactory);
m_pBufferFragmentFactory = new CBufferFragmentFactory(
m_TrackManager.GetNumStreams() * QTBUFFERFRAGMENT_POOL_SIZE,
m_TrackManager.GetNumStreams() * QTBUFFERFRAGMENT_INITIAL_POOL_SIZE);
retVal = HXR_OUTOFMEMORY;
if (m_pBufferFragmentFactory)
{
m_pBufferFragmentFactory->AddRef();
retVal = HXR_OK;
}
}
#endif // QTCONFIG_BFRAG_FACTORY
HX_RELEASE(pRootAtom);
m_State = SUCCEEDED(status) ? QTFF_Ready : QTFF_Error;
retVal = MakeFileHeader(status);
break;
default:
// nothing to do
break;
}
return retVal;
}
/************************************************************************
* IHXASMSource
*/
/************************************************************************
* Subscribe
*/
STDMETHODIMP CQTFileFormat::Subscribe(UINT16 uStreamNum,
UINT16 uRuleNumber)
{
return m_TrackManager.Subscribe(uStreamNum);
}
/************************************************************************
* Unsubscribe
*/
STDMETHODIMP CQTFileFormat::Unsubscribe(UINT16 uStreamNum,
UINT16 uRuleNumber)
{
return m_TrackManager.Unsubscribe(uStreamNum);
}
/************************************************************************
* Method:
* IHXPacketFormat::GetSupportedPacketFormats
* Purpose:
* Obtains a list of packet formats supported by this file format
*/
STDMETHODIMP CQTFileFormat::GetSupportedPacketFormats
(
REF(const char**) /*OUT*/ pPacketFormats
)
{
pPacketFormats = (const char**) zm_pPacketFormats;
return HXR_OK;
}
/************************************************************************
* Method:
* IHXPacketFormat::SetPacketFormat
* Purpose:
* Sets the packet type for this file format
*/
STDMETHODIMP CQTFileFormat::SetPacketFormat
(
const char* pPacketFormat
)
{
if (strcasecmp(pPacketFormat, "rtp") == 0)
{
m_ulPacketFormat = QTFF_RTP_FORMAT;
}
else
{
m_ulPacketFormat = QTFF_RDT_FORMAT;
}
return HXR_OK;
}
/************************************************************************
* Main Interface
*/
/************************************************************************
* PacketReady
*/
HX_RESULT CQTFileFormat::PacketReady(UINT16 uStreamNum,
HX_RESULT status,
IHXPacket* pPacket)
{
HX_RESULT retVal;
IHXPacket *pPacketToSend;
switch (m_State)
{
case QTFF_GetPacket:
pPacketToSend = m_pPacketCache[uStreamNum].pPacket;
HX_ASSERT(pPacketToSend);
if (status == HXR_OK)
{
HX_ASSERT(pPacket);
m_pPacketCache[uStreamNum].pPacket = pPacket;
pPacket->AddRef();
}
else
{
m_pPacketCache[uStreamNum].pPacket = NULL;
m_pPacketCache[uStreamNum].bStreamDone = TRUE;
if (status == HXR_STREAM_DONE)
{
status = HXR_OK;
}
}
AddRef(); // Make Sure we do not die as a result of PacketReady
m_pPacketCache[uStreamNum].bPending = FALSE;
retVal = m_pFFResponse->PacketReady(status, pPacketToSend);
if (pPacketToSend)
{
pPacketToSend->Release();
}
// Make sure the state did not change as result of PacketReady()
// The possible change is due to invocation of Close on PacketReady
if (m_State == QTFF_GetPacket)
{
m_State = QTFF_Ready;
// see if a pending request needs to be fullfilled
m_uNextPacketStreamNum = GetNextPacketStreamNum();
if ((m_uNextPacketStreamNum != NO_STREAM_SET) &&
m_pPacketCache[m_uNextPacketStreamNum].bPending)
{
m_State = QTFF_GetPacket;
retVal = m_TrackManager.GetStreamTrack(m_uNextPacketStreamNum)->
GetPacket(m_uNextPacketStreamNum);
}
}
Release();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?