qtffplin.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 2,308 行 · 第 1/4 页
CPP
2,308 行
return retVal;
case QTFF_PrimeCache:
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)
{
if (m_pPacketCache[uStreamNum].bPending)
{
AddRef(); // Make sure we do not die
m_pPacketCache[uStreamNum].bPending = FALSE;
retVal = m_pFFResponse->StreamDone(uStreamNum);
if (m_State != QTFF_PrimeCache)
{
// StreamDone must have closed us
Release();
break;
}
Release();
}
}
else
{
// Fatal failure
retVal = HandleFailure(status);
break;
}
}
uStreamNum++;
if (uStreamNum < m_TrackManager.GetNumStreams())
{
// we still have stream packets to prime
if (m_TrackManager.IsStreamTrackActive(uStreamNum))
{
retVal = m_TrackManager.GetStreamTrack(uStreamNum)->
GetPacket(uStreamNum);
}
else
{
retVal = PacketReady(uStreamNum,
HXR_STREAM_DONE,
NULL);
}
}
else
{
// we are done priming the packets
retVal = HXR_OK;
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);
}
}
break;
case QTFF_SeekPending:
HX_VECTOR_DELETE(m_pPacketCache);
m_uNextPacketStreamNum = NO_STREAM_SET;
m_State = QTFF_Ready;
retVal = Seek(m_ulPendingSeekTime);
break;
default:
retVal = HXR_UNEXPECTED;
break;
}
return retVal;
}
/************************************************************************
* Protected Methods
*/
CQTPacketizerFactory* CQTFileFormat::BuildPacketizerFactory(void)
{
#ifdef QTCONFIG_PACKETIZER_FACTORY
return new CQTPacketizerFactory();
#else // QTCONFIG_PACKETIZER_FACTORY
return NULL;
#endif // QTCONFIG_PACKETIZER_FACTORY
}
/************************************************************************
* Private Methods
*/
/************************************************************************
* GetNextPacketStreamNum
*/
inline UINT16 CQTFileFormat::GetNextPacketStreamNum(void)
{
UINT16 uStreamNum;
ULONG32 ulLowestTime = 0xFFFFFFFF;
UINT16 uNextPacketStream = NO_STREAM_SET;
HX_ASSERT(m_pPacketCache);
for (uStreamNum = 0;
uStreamNum < m_TrackManager.GetNumStreams();
uStreamNum++)
{
if (!m_pPacketCache[uStreamNum].bStreamDone)
{
HX_ASSERT(m_pPacketCache[uStreamNum].pPacket);
if (ulLowestTime >
m_pPacketCache[uStreamNum].pPacket->GetTime())
{
uNextPacketStream = uStreamNum;
ulLowestTime = m_pPacketCache[uStreamNum].
pPacket->GetTime();
}
}
}
return uNextPacketStream;
}
/************************************************************************
* HandleFailure
*/
HX_RESULT CQTFileFormat::HandleFailure(HX_RESULT status)
{
HX_RESULT retVal = HXR_OK;
HX_ASSERT(FAILED(status));
switch (m_State)
{
case QTFF_PrimeCache:
{
UINT16 uStreamNum = 0;
m_State = QTFF_Error;
AddRef();
while (m_pPacketCache &&
(uStreamNum < m_TrackManager.GetNumStreams()))
{
if (m_pPacketCache[uStreamNum].bPending)
{
m_pPacketCache[uStreamNum].bPending = FALSE;
m_pFFResponse->PacketReady(status, NULL);
}
uStreamNum++;
}
Release();
}
break;
default:
retVal = HXR_UNEXPECTED;
break;
}
return retVal;
}
/************************************************************************
* a standard way of pulling a error string out of a resource file in a
* localization friendly manner :)
*/
void
CQTFileFormat::ReportError(UINT32 ulErrorID, HX_RESULT retVal)
{
// Try to get the string from the resource manager
CHXString cErrStr;
HX_RESULT errRet = GetResourceErrorString(ulErrorID, cErrStr);
if (errRet != HXR_OK)
{
switch (ulErrorID)
{
case IDS_ERR_QT_NOTLICENSED:
cErrStr = ERRSTR_QT_NOTLICENSED;
break;
default:
cErrStr = ERRSTR_QT_GENERALERROR;
break;
}
}
if (m_pErrorMessages)
{
m_pErrorMessages->Report(HXLOG_CRIT, retVal, 0, (const char*) cErrStr, NULL);
}
}
HX_RESULT
CQTFileFormat::GetResourceErrorString(UINT32 ulErrorID, CHXString& rErrorStr)
{
IHXExternalResourceManager* pResMgr = NULL;
HX_RESULT retVal = m_pContext->QueryInterface(IID_IHXExternalResourceManager, (void**) &pResMgr);
if (retVal != HXR_OK)
{
return retVal;
}
IHXExternalResourceReader* pResRdr = NULL;
retVal = pResMgr->CreateExternalResourceReader(CORE_RESOURCE_SHORT_NAME, pResRdr);
if (retVal != HXR_OK)
{
HX_RELEASE(pResMgr);
return retVal;
}
IHXXResource* pRes = pResRdr->GetResource(HX_RT_STRING, ulErrorID);
if(!pRes)
{
HX_RELEASE(pResRdr);
HX_RELEASE(pResMgr);
return HXR_FAIL;
}
// Assign the error string to the out parameter
rErrorStr = (const char*) pRes->ResourceData();
// Release all references
HX_RELEASE(pRes);
HX_RELEASE(pResRdr);
HX_RELEASE(pResMgr);
return HXR_OK;
}
/************************************************************************
* AddMetaInfo
*/
HX_RESULT CQTFileFormat::AddMetaInfo(IHXValues* pHeader)
{
BOOL bAddAll;
ULONG32 ulPresentationWidth = 0;
ULONG32 ulPresentationHeight = 0;
HX_ASSERT(pHeader);
if ((m_TrackManager.GetEType() == QT_ETYPE_CLIENT) ||
(m_ulStreamMetaInfoMask & META_INFO_ALL) ||
(m_ulStreamMetaInfoMask & META_INFO_WIDTH) ||
(m_ulStreamMetaInfoMask & META_INFO_HEIGHT))
{
UINT16 uStreamCount;
CQTTrack* pTrack;
// Collect Meta Info
for (uStreamCount = m_TrackManager.GetNumStreams();
uStreamCount != 0;
uStreamCount--)
{
pTrack = m_TrackManager.GetStreamTrack(uStreamCount - 1);
ulPresentationWidth += pTrack->m_TrackInfo.GetTrackWidth();
ulPresentationHeight += pTrack->m_TrackInfo.GetTrackHeight();
}
}
bAddAll = ((m_TrackManager.GetEType() == QT_ETYPE_CLIENT) ||
(m_ulStreamMetaInfoMask & META_INFO_ALL));
if (bAddAll)
{
if (ulPresentationWidth > 0)
{
pHeader->SetPropertyULONG32(WIDTH_METANAME,
ulPresentationWidth);
}
if (ulPresentationHeight > 0)
{
pHeader->SetPropertyULONG32(HEIGHT_METANAME,
ulPresentationHeight);
}
}
#ifdef QTCONFIG_SERVER
else if((m_ulStreamMetaInfoMask & META_INFO_ALL) ||
(m_ulStreamMetaInfoMask & META_INFO_WIDTH) ||
(m_ulStreamMetaInfoMask & META_INFO_HEIGHT))
{
if (ulPresentationWidth > 0 &&
((m_ulStreamMetaInfoMask & META_INFO_ALL) ||
(m_ulStreamMetaInfoMask & META_INFO_WIDTH)))
{
pHeader->SetPropertyULONG32(WIDTH_METANAME,
ulPresentationWidth);
}
if (ulPresentationHeight > 0 &&
((m_ulStreamMetaInfoMask & META_INFO_ALL) ||
(m_ulStreamMetaInfoMask & META_INFO_HEIGHT)))
{
pHeader->SetPropertyULONG32(HEIGHT_METANAME,
ulPresentationHeight);
}
}
#endif // QTCONFIG_SERVER
return HXR_OK;
}
#ifdef QTCONFIG_SERVER
/************************************************************************
* CheckLicense
*/
HX_RESULT CQTFileFormat::CheckLicense(void)
{
HX_ASSERT(m_pContext);
IHXClientEngine* pPlayer = NULL;
IHXRemoteBroadcastServices* pRBServices = NULL;
if (SUCCEEDED(m_pContext->QueryInterface(IID_IHXClientEngine, (void**)&pPlayer))
|| SUCCEEDED(m_pContext->QueryInterface(IID_IHXRemoteBroadcastServices, (void**)&pRBServices)))
{
// Data types are always licensed on the Player and iqslta
m_bQTLicensed = TRUE;
m_bMP4Licensed = TRUE;
}
else
{
// On the Server, check the license section of the registry
IHXRegistry* pRegistry = NULL;
if (HXR_OK != m_pContext->QueryInterface(IID_IHXRegistry,
(void**)&pRegistry))
{
return HXR_UNEXPECTED;
}
INT32 nLicensed = 0;
if (!SUCCEEDED(pRegistry->GetIntByName(REGISTRY_QUICKTIME_ENABLED,
nLicensed)))
{
/* take default */
nLicensed = LICENSE_QUICKTIME_ENABLED;
}
m_bQTLicensed = (nLicensed) ? (TRUE) : (FALSE);
if (!SUCCEEDED(pRegistry->GetIntByName(REGISTRY_REALMP4_ENABLED,
nLicensed)))
{
/* take default */
nLicensed = LICENSE_REALMP4_ENABLED;
}
m_bMP4Licensed = (nLicensed) ? (TRUE) : (FALSE);
HX_RELEASE(pRegistry);
}
HX_RELEASE(pPlayer);
HX_RELEASE(pRBServices);
return HXR_OK;
}
/************************************************************************
* WarnIfNotHinted
*/
void CQTFileFormat::WarnIfNotHinted(HX_RESULT status, BOOL bIgnoreHintTracks)
{
/*
* log what's going on...
*/
if ((m_TrackManager.GetEType() == QT_ETYPE_SERVER) && m_pErrorMessages
&& HXR_OK == status)
{
/*
* Check the registry to see if warnings are disabled.
*/
INT32 nWarningDisabled = 0;
IHXRegistry* pRegistry = NULL;
if (m_pContext &&
(HXR_OK == m_pContext->QueryInterface(IID_IHXRegistry,
(void**)&pRegistry)))
{
pRegistry->GetIntByName("config.DisableHintingWarning",
nWarningDisabled);
}
HX_RELEASE(pRegistry);
if (nWarningDisabled)
{
return;
}
const char* pszIgnore =
"Handling HINTED content - ignoring Hint Tracks (URL: /%s)\n";
const char* pszHint =
"Handling HINTED content - using Hint Tracks (URL: /%s)\n";
const char* pszNotHinted =
"Handling UNHINTED content (URL: /%s)\n";
const char* pszMsg;
if (bIgnoreHintTracks)
{
pszMsg = pszIgnore;
}
else if (m_TrackManager.IsHinted())
{
pszMsg = pszHint;
HX_ASSERT(HXR_NOT_LICENSED != status); // can't ever be this error
}
else
{
pszMsg = pszNotHinted;
}
const char* pReqURL = NULL;
UINT32 ulMaxURLLen = 1024 * 2;
UINT32 ulBuffLen = ulMaxURLLen + strlen(pszMsg) + 1;
HX_RESULT status = HXR_OK;
if (m_pRequest)
{
status = m_pRequest->GetURL(pReqURL);
}
if (SUCCEEDED(status) && pReqURL)
{
UINT32 ulURLLen = strlen(pReqURL);
if (ulURLLen > ulMaxURLLen)
{
pReqURL += ulURLLen - ulMaxURLLen;
}
}
else
{
pReqURL = " ";
}
NEW_FAST_TEMP_STR(pszTmpStr, 4096, ulBuffLen);
snprintf(pszTmpStr, ulBuffLen, pszMsg, pReqURL);
m_pErrorMessages->Report(HXLOG_WARNING, HXR_OK, 0, pszTmpStr, NULL);
DELETE_FAST_TEMP_STR(pszTmpStr);
}
}
#else // QTCONFIG_SERVER
HX_RESULT CQTFileFormat::CheckLicense(void)
{
return HXR_OK;
}
void CQTFileFormat::WarnIfNotHinted(HX_RESULT status, BOOL bIgnoreHintTracks)
{
return;
}
#endif // QTCONFIG_SERVER
/************************************************************************
* Method:
* IHXThreadSafeMethods::IsThreadSafe
*/
STDMETHODIMP_(UINT32) CQTFileFormat::IsThreadSafe()
{
return HX_THREADSAFE_METHOD_FF_GETPACKET |
HX_THREADSAFE_METHOD_FSR_READDONE;
}
/************************************************************************
* IUnknown methods
*/
STDMETHODIMP CQTFileFormat::QueryInterface(REFIID riid, void** ppvObj)
{
QInterfaceList qiList[] =
{
{ GET_IIDHANDLE(IID_IUnknown), (IUnknown*) (IHXPlugin*) this},
{ GET_IIDHANDLE(IID_IHXPlugin), (IHXPlugin*) this},
{ GET_IIDHANDLE(IID_IHXFileFormatObject), (IHXFileFormatObject*) this},
{ GET_IIDHANDLE(IID_IHXAtomizerResponse), (IHXAtomizerResponse*) this},
{ GET_IIDHANDLE(IID_IHXAtomizationCommander), (IHXAtomizationCommander*) this},
#ifdef QTCONFIG_ALTERNATE_STREAMS
{ GET_IIDHANDLE(IID_IHXASMSource), (IHXASMSource*) this},
#endif // QTCONFIG_ALTERNATE_STREAMS
{ GET_IIDHANDLE(IID_IHXPacketFormat), (IHXPacketFormat*) this},
{ GET_IIDHANDLE(IID_IHXFileSwitcher), (IHXFileSwitcher*) m_pFileSwitcher},
{ GET_IIDHANDLE(IID_IHXCommonClassFactory), m_pClassFactory},
{ GET_IIDHANDLE(IID_IHXScheduler), m_pScheduler}
};
return QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
}
STDMETHODIMP_(ULONG32) CQTFileFormat::AddRef()
{
return InterlockedIncrement(&m_lRefCount);
}
STDMETHODIMP_(ULONG32) CQTFileFormat::Release()
{
if (InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
/************************************************************************
* GetFileHeader
* Purpose:
* Called by controller to ask the file format for the number of
* headers in the file. The file format should call the
* IHXFormatResponse::StreamCountReady() for the IHXFileFormat-
* Session object that was passed in during initialization, when the
* header count is available.
*/
STDMETHODIMP CQTFileFormat::GetFileHeader()
{
HX_RESULT retVal = HXR_UNEXPECTED;
if (m_State == QTFF_Ready)
{
if (m_pAtomizer)
{
// This must be the first call to GetFileHeader - Atomize
m_State = QTFF_Atomize;
retVal = m_pAtomizer->Atomize();
}
else
{
retVal = MakeFileHeader(HXR_OK);
}
}
return retVal;
}
/************************************************************************
* GetStreamHeader
* Purpose:
* Called by controller to ask the file format for the header for
* a particular stream in the file. The file format should call
* IHXFileFormatResponse::HeaderReady() for the IHXFileFormatResponse
* object that was passed in during initialization, when the header
* is available.
*/
STDMETHODIMP CQTFileFormat::GetStreamHeader(UINT16 unStreamNumber)
{
HX_RESULT retVal;
IHXValues* pHeader;
retVal = ObtainStreamHeader(unStreamNumber, pHeader);
if (SUCCEEDED(retVal))
{
retVal = m_pFFResponse->StreamHeaderReady(retVal, pHeader);
}
HX_RELEASE(pHeader);
return retVal;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?