qtffplin.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 2,308 行 · 第 1/4 页
CPP
2,308 行
ulGroupBitrate = 0;
}
status = m_TrackManager.AddStreamToGroup(
uStrmIdx,
(UINT16) ulGroupID,
ulGroupBitrate);
}
HX_RELEASE(pGroupInfo);
if (FAILED(status))
{
break;
}
}
}
}
// Make Default subscriptions
if (SUCCEEDED(status))
{
status = m_TrackManager.SubscribeDefault();
}
// If we are running in player, eliminate inactive stream tracks
if (SUCCEEDED(status))
{
IHXClientEngine *pPlayer = NULL;
if (SUCCEEDED(m_pContext->QueryInterface(IID_IHXClientEngine,
(void**) &pPlayer)))
{
// Running in player
status = m_TrackManager.RemoveInactiveStreams();
}
HX_RELEASE(pPlayer);
}
#endif // QTCONFIG_ALTERNATE_STREAMS
// Set General properties, Stream Count and duration
if (SUCCEEDED(status))
{
pHeader->SetPropertyULONG32("IsRealDataType", 0);
pHeader->SetPropertyULONG32("StreamCount",
m_TrackManager.GetNumStreams());
pHeader->SetPropertyULONG32("Duration",
(ULONG32) ((1000.0 * ((double) m_MovieInfo.GetMovieDuration())) /
m_MovieInfo.GetMovieTimeScale()));
}
// Set the licensing information: Basically this information is used by the
// Broadcast Receiver plug-in to check and see if the RealServer is actually
// licensed to receive this content
#ifdef QTCONFIG_SERVER
if(SUCCEEDED(status) && (!m_bViewSourceRequest))
{
switch(m_TrackManager.GetFType())
{
case QT_FTYPE_QT:
case QT_FTYPE_UNKNOWN:
{
IHXBuffer* pFileTypeBuf = NULL;
IHXBuffer* pLicenseKeyBuf = NULL;
m_pClassFactory->CreateInstance(CLSID_IHXBuffer, (void**)&pFileTypeBuf);
m_pClassFactory->CreateInstance(CLSID_IHXBuffer, (void**)&pLicenseKeyBuf);
pFileTypeBuf->Set((const BYTE*)"QuickTime", strlen("QuickTime") + 1);
pLicenseKeyBuf->Set((const BYTE*)REGISTRY_QUICKTIME_ENABLED, strlen(REGISTRY_QUICKTIME_ENABLED) + 1);
pHeader->SetPropertyCString("FileType", pFileTypeBuf);
pHeader->SetPropertyCString("LicenseKey", pLicenseKeyBuf);
pHeader->SetPropertyULONG32("DefaultLicenseValue", LICENSE_QUICKTIME_ENABLED);
HX_RELEASE(pFileTypeBuf);
HX_RELEASE(pLicenseKeyBuf);
break;
}
case QT_FTYPE_MP4:
{
IHXBuffer* pFileTypeBuf = NULL;
IHXBuffer* pLicenseKeyBuf = NULL;
m_pClassFactory->CreateInstance(CLSID_IHXBuffer, (void**)&pFileTypeBuf);
m_pClassFactory->CreateInstance(CLSID_IHXBuffer, (void**)&pLicenseKeyBuf);
pFileTypeBuf->Set((const BYTE*)"MPEG4", strlen("MPEG4") + 1);
pLicenseKeyBuf->Set((const BYTE*)REGISTRY_REALMP4_ENABLED, strlen(REGISTRY_REALMP4_ENABLED) + 1);
pHeader->SetPropertyCString("FileType", pFileTypeBuf);
pHeader->SetPropertyCString("LicenseKey", pLicenseKeyBuf);
pHeader->SetPropertyULONG32("DefaultLicenseValue", LICENSE_REALMP4_ENABLED);
HX_RELEASE(pFileTypeBuf);
HX_RELEASE(pLicenseKeyBuf);
break;
}
}
}
#endif // QTCONFIG_SERVER
// Set Requested Meta Information
if (SUCCEEDED(status))
{
IHXValues* pHeaders = NULL;
IHXBuffer* pBuffer = NULL;
if (m_pRequest &&
(m_pRequest->GetRequestHeaders(pHeaders) == HXR_OK) &&
pHeaders)
{
pHeaders->Release();
}
status = AddMetaInfo(pHeader);
// We no longer need the request so release it
HX_RELEASE(m_pRequest);
}
// Set View Source specific information
#ifdef HELIX_FEATURE_VIEWSOURCE
if (SUCCEEDED(status) && m_bViewSourceRequest)
{
IHXBuffer* pCStringBuffer = NULL;
status = m_pClassFactory->CreateInstance(CLSID_IHXBuffer,
(void**) &pCStringBuffer);
if (SUCCEEDED(status))
{
const char* pString = "Not Hinted";
if (m_TrackManager.IsHinted())
{
pString = "Hinted";
}
status = pCStringBuffer->Set((UINT8*) pString, strlen(pString) + 1);
}
if (SUCCEEDED(status))
{
status = pHeader->SetPropertyCString("Characteristic", pCStringBuffer);
}
HX_RELEASE(pCStringBuffer);
if (SUCCEEDED(status))
{
status = pHeader->SetPropertyULONG32("ViewSourceInfoHeaders", 1);
}
}
#endif // HELIX_FEATURE_VIEWSOURCE
if (FAILED(status))
{
HX_RELEASE(pHeader);
}
retVal = m_pFFResponse->FileHeaderReady(status, pHeader);
HX_RELEASE(pHeader);
return retVal;
}
HX_RESULT CQTFileFormat::ObtainStreamHeader(UINT16 unStreamNumber,
IHXValues* &pHeader)
{
HX_RESULT retVal = HXR_OK;
CQTTrack* pTrack = NULL;
pHeader = NULL;
// Check Entry requirements
if (m_State != QTFF_Ready)
{
retVal = HXR_UNEXPECTED;
}
if (SUCCEEDED(retVal))
{
retVal = HXR_INVALID_PARAMETER;
if (unStreamNumber < m_TrackManager.GetNumStreams())
{
retVal = HXR_OK;
}
}
// See if made header is already available
if (SUCCEEDED(retVal))
{
pTrack = m_TrackManager.GetStreamTrack(unStreamNumber);
if (pTrack->m_TrackInfo.GetHeader(pHeader) != HXR_OK)
{
retVal = BuildStreamHeader(pHeader,
pTrack,
&pTrack->m_TrackInfo,
&m_MovieInfo,
&m_TrackManager,
m_pClassFactory);
}
}
if (SUCCEEDED(retVal))
{
HX_ASSERT(pHeader);
pHeader->SetPropertyULONG32("StreamNumber", unStreamNumber);
}
return retVal;
}
HX_RESULT CQTFileFormat::BuildStreamHeader(IHXValues* &pHeader,
CQTTrack* pTrack,
CQT_TrackInfo_Manager* pTrackInfo,
CQT_MovieInfo_Manager* pMovieInfo,
CQTTrackManager* pTrackManager,
IHXCommonClassFactory* pClassFactory)
{
IHXBuffer* pName = NULL;
IHXBuffer* pASMRuleBook = NULL;
IHXBuffer* pMimeType = NULL;
ULONG32 ulPayloadType = QT_BAD_PAYLOAD;
ULONG32 ulAvgBitRate = 0;
ULONG32 ulMaxBitRate = 0;
ULONG32 ulPreroll = 0;
ULONG32 ulPredata = 0;
ULONG32 ulWidth = 0;
ULONG32 ulHeight = 0;
ULONG32 ulChannels = 0;
HX_RESULT retVal = HXR_OK;
// Create needed buffers
if (!pHeader)
{
retVal = pClassFactory->CreateInstance(CLSID_IHXValues,
(void**) &pHeader);
}
if (SUCCEEDED(retVal))
{
retVal = pClassFactory->CreateInstance(CLSID_IHXBuffer,
(void**) &pName);
}
if (SUCCEEDED(retVal))
{
retVal = pClassFactory->CreateInstance(CLSID_IHXBuffer,
(void**) &pASMRuleBook);
}
// Set Stream Name
if (SUCCEEDED(retVal) && (pTrackInfo->GetNameLength() > 0))
{
UCHAR* pNameMem;
ULONG32 ulNameMemLength = 0;
retVal = pName->SetSize(pTrackInfo->GetNameLength() + 1);
if (SUCCEEDED(retVal))
{
pName->Get(pNameMem, ulNameMemLength);
memcpy(pNameMem, pTrackInfo->GetName(), /* Flawfinder: ignore */
ulNameMemLength - 1);
pNameMem[ulNameMemLength - 1] = '\0';
pHeader->SetPropertyCString("StreamName", pName);
}
}
HX_RELEASE(pName);
// Set Opaque Data - if any
if (SUCCEEDED(retVal) && (pTrackInfo->GetOpaqueDataLength() > 0))
{
IHXBuffer* pOpaqueData = NULL;
retVal = pClassFactory->CreateInstance(CLSID_IHXBuffer,
(void**) &pOpaqueData);
if (SUCCEEDED(retVal))
{
UCHAR* pOpaqueDataMem;
ULONG32 ulOpaqueDataLength = 0;
retVal = pOpaqueData->SetSize(pTrackInfo->GetOpaqueDataLength());
if (SUCCEEDED(retVal))
{
pOpaqueData->Get(pOpaqueDataMem, ulOpaqueDataLength);
memcpy(pOpaqueDataMem, /* Flawfinder: ignore */
pTrackInfo->GetOpaqueData(),
ulOpaqueDataLength);
pHeader->SetPropertyBuffer("OpaqueData", pOpaqueData);
}
}
HX_RELEASE(pOpaqueData);
}
if (SUCCEEDED(retVal))
{
retVal = GetPayloadIdentity(pHeader, pTrack, pTrackInfo);
}
// Set Duration, AvgBitRate and Preroll
if (SUCCEEDED(retVal))
{
ULONG32 ulDuration;
ulDuration = (ULONG32) ((pTrackInfo->GetTrackDuration()
* 1000.0)
/ pMovieInfo->GetMovieTimeScale());
ulAvgBitRate = pTrackInfo->GetAvgBitrate();
ulMaxBitRate = pTrackInfo->GetMaxBitrate();
ulPreroll = pTrackInfo->GetPreroll();
ulPredata = pTrackInfo->GetPredata();
ulWidth = pTrackInfo->GetTrackWidth();
ulHeight= pTrackInfo->GetTrackHeight();
if ((ulAvgBitRate == 0) && (ulDuration > 0))
{
ULONG32 ulTrackSize = pTrackInfo->GetTrackSize();
if (ulTrackSize == 0)
{
pTrack->ComputeTrackSize(ulTrackSize);
}
ulAvgBitRate = (ULONG32) ((((double) ulTrackSize) * 8000.0)
/ ulDuration + 0.5);
}
if (ulAvgBitRate == 0)
{
ulAvgBitRate = SDPMapPayloadToBitrate(ulPayloadType);
}
pHeader->SetPropertyULONG32("Duration", ulDuration);
if (ulAvgBitRate != 0)
{
pHeader->SetPropertyULONG32("AvgBitRate", ulAvgBitRate);
}
if (ulMaxBitRate != 0)
{
pHeader->SetPropertyULONG32("MaxBitRate", ulMaxBitRate);
}
if (ulPreroll != 0)
{
pHeader->SetPropertyULONG32("Preroll", ulPreroll);
}
if (ulPredata != 0)
{
pHeader->SetPropertyULONG32("Predata", ulPredata);
}
if(ulWidth != 0)
{
pHeader->SetPropertyULONG32(WIDTH_METANAME, ulWidth);
}
if(ulHeight != 0)
{
pHeader->SetPropertyULONG32(HEIGHT_METANAME, ulHeight);
}
}
if (SUCCEEDED(retVal))
{
// .mp4 and .mov files may produce streams with out-of-order time stamps
// Client core does not normally expect this in RDT protocol so set this
// property to alert client core of this fact.
pHeader->SetPropertyULONG32("HasOutOfOrderTS", 1);
}
// Set ASM Rule Book
if (SUCCEEDED(retVal))
{
char pRuleBook[128]; /* Flawfinder: ignore */
#ifdef QTCONFIG_SERVER
pHeader->GetPropertyULONG32("RTPPayloadType", ulPayloadType);
if (pTrackManager->GetEType() != QT_ETYPE_CLIENT)
{
// Server Side
retVal = HXR_FAIL;
if (ulPayloadType != QT_BAD_PAYLOAD)
{
retVal = HXR_OK;
}
if (SUCCEEDED(retVal))
{
BOOL bSupportedPayload = SDPIsKnownPayload(ulPayloadType);
pHeader->GetPropertyCString("MimeType", pMimeType);
// This is not a standard payload -
// but maybe the encoding is standard
if (!bSupportedPayload && pMimeType)
{
bSupportedPayload = (SDPMapMimeToPayload(pMimeType,
ulPayloadType)
== HXR_OK);
}
// Set the ASM rule book
if ((ulAvgBitRate > 0)
#ifndef QTFORCE_AVG_BITRATE_DELIVERY
&& bSupportedPayload
&& SDPIsFixedRatePayload(ulPayloadType)
#endif // QTFORCE_AVG_BITRATE_DELIVERY
)
{
// divide avg bitrate
UINT32 ulAvgBandwidth = ulAvgBitRate / 2;
SafeSprintf(pRuleBook, 128,
"Marker=%d,AverageBandwidth=%d;"
"Marker=%d,AverageBandwidth=%d;",
(QTASM_MARKER_ON_RULE == 0) ? 1 : 0,
ulAvgBitRate - ulAvgBandwidth,
(QTASM_MARKER_ON_RULE == 0) ? 0 : 1,
ulAvgBandwidth);
}
else
{
if (ulAvgBitRate > 0)
{
SafeSprintf(pRuleBook, 128, "Marker=%d,AverageBandwidth=%d,TimeStampDelivery=TRUE;"
"Marker=%d,AverageBandwidth=0,TimeStampDelivery=TRUE;",
(QTASM_MARKER_ON_RULE == 0) ? 1 : 0,
ulAvgBitRate,
(QTASM_MARKER_ON_RULE == 0) ? 0 : 1);
}
else
{
SafeSprintf(pRuleBook, 128, "Marker=%d,TimeStampDelivery=TRUE;"
"Marker=%d,TimeStampDelivery=TRUE;",
(QTASM_MARKER_ON_RULE == 0) ? 1 : 0,
(QTASM_MARKER_ON_RULE == 0) ? 0 : 1);
}
}
}
}
else
#endif // QTCONFIG_SERVER
{
// Player Side
SafeSprintf(pRuleBook, 128, "Marker=%d;Marker=%d;",
(QTASM_MARKER_ON_RULE == 0) ? 1 : 0,
(QTASM_MARKER_ON_RULE == 0) ? 0 : 1);
}
if (SUCCEEDED(retVal))
{
retVal = pASMRuleBook->Set((UCHAR*) pRuleBook, strlen(pRuleBook) + 1);
}
if (SUCCEEDED(retVal))
{
pHeader->SetPropertyCString("ASMRuleBook", pASMRuleBook);
}
}
HX_RELEASE(pASMRuleBook);
HX_RELEASE(pMimeType);
return retVal;
}
HX_RESULT CQTFileFormat::GetSessionIdentity(IHXValues* pHeader,
CQT_MovieInfo_Manager* pMovieInfo)
{
return HXR_OK;
}
HX_RESULT CQTFileFormat::GetPayloadIdentity(IHXValues* pHeader,
CQTTrack* pTrack,
CQT_TrackInfo_Manager* pTrackInfo)
{
HX_RESULT retVal = HXR_OK;
if (SUCCEEDED(retVal))
{
const char* pMimeType = pTrackInfo->GetMimeType();
retVal = HXR_FAIL;
if (pMimeType)
{
IHXBuffer* pMimeTypeBuffer = NULL;
UINT32 ulMimeTypeLength = strlen(pMimeType);
retVal = m_pClassFactory->CreateInstance(CLSID_IHXBuffer,
(void**) &pMimeTypeBuffer);
if (SUCCEEDED(retVal))
{
retVal = pMimeTypeBuffer->SetSize(ulMimeTypeLength + 1);
}
if (SUCCEEDED(retVal))
{
memcpy(pMimeTypeBuffer->GetBuffer(), /* Flawfinder: ignore */
pMimeType,
ulMimeTypeLength + 1);
retVal = pHeader->SetPropertyCString("MimeType", pMimeTypeBuffer);
}
HX_RELEASE(pMimeTypeBuffer);
}
}
if (SUCCEEDED(retVal))
{
ULONG32 ulTimeScale = pTrackInfo->GetMediaTimeScale();
retVal = HXR_FAIL;
if (ulTimeScale != 0)
{
retVal = pHeader->SetPropertyULONG32("SamplesPerSecond", ulTimeScale);
}
}
if (SUCCEEDED(retVal))
{
ULONG32 ulPayloadType = pTrackInfo->GetPayloadType();
retVal = HXR_FAIL;
if (ulPayloadType != QT_BAD_PAYLOAD)
{
retVal = pHeader->SetPropertyULONG32("RTPPayloadType", ulPayloadType);
}
}
return retVal;
}
/************************************************************************
* GetPacket
* Method:
* IHXFileFormatObject::GetPacket
* Purpose:
* Called by controller to ask the file format for the next packet
* for a particular stream in the file. The file format should call
* IHXFileFormatResponse::Data*() for the IHXFileFormatResponse
* object that was passed in during initialization, when the packet
* is available.
*/
STDMETHODIMP CQTFileFormat::GetPacket(UINT16 unStreamNumber)
{
HX_RESULT retVal;
if (unStreamNumber < m_TrackManager.GetNumStreams())
{
switch (m_State)
{
case QTFF_Ready:
if (unStreamNumber == m_uNextPacketStreamNum)
{
// Process this packet request
// - but replace stream's cache first
HX_ASSERT(m_pPacketCache);
m_State = QTFF_GetPacket;
return m_TrackManager.GetStreamTrack(unStreamNumber)->
GetPacket(unStreamNumber);
}
else if (m_pPacketCache)
{
// Delay processing packet for stream until its turn
if (!m_pPacketCache[unStreamNumber].bStreamDone)
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?