📄 hxflsrc.cpp
字号:
}
HX_RELEASE(pValue);
}
HX_RELEASE(pResponseHeaders);
if (!pMimeType)
{
if (HXXFile::IsPlusURL(pszURL))
{
pMimeType = "application/x-pn-plusurl";
}
else
{
// separate options from the URL
pszTemp = (char*) ::HXFindChar(pszURL, '?');
if (pszTemp)
{
*pszTemp = '\0';
}
}
}
FinishSetup(HXR_OK, pMimeType);
theErr = mLastError;
}
return theErr;
}
void
HXFileSource::FinishSetup(HX_RESULT status, const char* pMimeType)
{
#if !defined(HELIX_FEATURE_META)
m_bValidateMetaDone = TRUE;
m_bIsMeta = FALSE;
#endif /* HELIX_FEATURE_META */
if (status == HXR_OK)
{
if (pMimeType)
{
HX_VECTOR_DELETE(m_pMimeType);
m_pMimeType = ::new_string(pMimeType);
}
// detect if this is a valid meta file if we haven't done so
if (!m_bValidateMetaDone)
{
AttempToLoadFilePlugin(RAM_MIMETYPE);
}
#if defined(HELIX_FEATURE_SDPLITE)
// retrieve the whole SDP file without SDP fileformat/renderer which
// requires basic group&track
else if (m_pMimeType && 0 == strcasecmp(m_pMimeType, "application/sdp"))
{
if (!m_pFileReader)
{
m_pFileReader = new CFileReader(this);
HX_ADDREF(m_pFileReader);
}
if (m_pFileReader)
{
m_pFileReader->GetFile(m_pFileObject);
}
return;
}
#endif /* HELIX_FEATURE_SDPLITE */
// we have already validated the file and know whether
// it is a meta or not
else
{
if (m_bIsMeta)
{
AttempToLoadFilePlugin(RAM_MIMETYPE);
}
else
{
// Call recognizer here if we do not have a definite
// mimetype from the filesytem
if ((!m_pMimeType || m_pMimeType == "*") && !m_pFileRecognizer)
{
m_pFileRecognizer = new CHXFileRecognizer;
if (m_pFileRecognizer)
{
m_pFileRecognizer->AddRef();
if (!m_pMimeFinderResponse)
{
m_pMimeFinderResponse = new CMimeFinderFileResponse(this);
HX_ADDREF(m_pMimeFinderResponse);
}
if (m_pMimeFinderResponse)
{
m_pFileRecognizer->GetMimeType(m_pFileObject,
(IHXFileRecognizerResponse*)m_pMimeFinderResponse);
return;
}
else
{
HX_DELETE(m_pFileRecognizer);
}
}
}
AttempToLoadFilePlugin(m_pMimeType);
}
}
}
else if (!mLastError)
{
mLastError = status;
ReportError(mLastError);
}
}
void
HXFileSource::AttempToLoadFilePlugin(const char* pMimeType)
{
char* pExtension = NULL;
char* pszTemp = NULL;
char* pszURL = NULL;
HX_RESULT theErr = HXR_OK;
IUnknown* pUnknown = NULL;
if (!m_bValidateMetaDone)
{
pExtension = "ram";
}
else
{
// This will fix up any redirected
GetURL();
// make a copy of the URL
pszURL = new char[strlen(m_pszURL)+1];
memset(pszURL, 0, strlen(m_pszURL)+1);
strcpy(pszURL, m_pszURL); /* Flawfinder: ignore */
// separate fragment from the URL
pszTemp = (char*) ::HXFindChar(pszURL, '#');
if (pszTemp)
{
*pszTemp = '\0';
}
// separate options from the URL
pszTemp = (char*) ::HXFindChar(pszURL, '?');
if (pszTemp)
{
*pszTemp = '\0';
}
// load plugin
pExtension = strrchr(pszURL, '.');
if (pExtension)
{
/* get past . */
pExtension++;
}
if (pExtension)
{
HX_VECTOR_DELETE(m_pExtension);
m_pExtension = ::new_string(pExtension);
}
}
if (!m_pCurrentFileFormatUnk)
{
IHXPluginHandler3* pPlugin2Handler3 = NULL;
HX_VERIFY(HXR_OK ==
m_pPlayer->m_pPlugin2Handler->QueryInterface(IID_IHXPluginHandler3, (void**) &pPlugin2Handler3));
if (pMimeType)
{
pPlugin2Handler3->FindGroupOfPluginsUsingStrings(PLUGIN_CLASS, PLUGIN_FILEFORMAT_TYPE,
PLUGIN_FILEMIMETYPES, (char*)pMimeType, 0, 0, m_pFileFormatEnumerator);
}
if (!m_pFileFormatEnumerator)
{
pPlugin2Handler3->FindGroupOfPluginsUsingStrings(PLUGIN_CLASS, PLUGIN_FILEFORMAT_TYPE,
PLUGIN_FILEEXTENSIONS, pExtension, 0 ,0, m_pFileFormatEnumerator);
}
HX_RELEASE(pPlugin2Handler3);
if (m_pFileFormatEnumerator)
{
m_pFileFormatEnumerator->GetNextPlugin(m_pCurrentFileFormatUnk, NULL);
HX_ASSERT(m_pCurrentFileFormatUnk != NULL);
}
}
if (!m_pCurrentFileFormatUnk)
{
if (!m_bDefaultAltURL)
{
theErr = HXR_NO_FILEFORMAT;
#if defined(HELIX_FEATURE_AUTOUPGRADE)
IHXUpgradeCollection* pUpgradeCollection = NULL;
if(m_pPlayer)
m_pPlayer->QueryInterface(IID_IHXUpgradeCollection, (void**)&pUpgradeCollection);
if(pUpgradeCollection)
{
IHXBuffer* pPluginID = (IHXBuffer*) new CHXBuffer;
pPluginID->AddRef();
if (pMimeType && !(*pMimeType == '*'))
{
pPluginID->Set((const UINT8*)pMimeType, strlen(pMimeType) + 1);
}
else if (pExtension)
{
// return file extension if mimeType is unknown
pPluginID->Set((const UINT8*)pExtension, strlen(pExtension) + 1);
}
else
{
pPluginID->Set((const UINT8*)"Unknown FileFormat", strlen("Unknown FileFormat") + 1);
}
pUpgradeCollection->Add(eUT_Required, pPluginID, 0, 0);
pPluginID->Release();
pUpgradeCollection->Release();
}
#endif /* HELIX_FEATURE_AUTOUPGRADE */
}
else
{
theErr = HXR_INVALID_FILE;
}
}
// initialize fileformat plugins...
if (!theErr)
{
theErr = InitializeFileFormat();
}
HX_VECTOR_DELETE(pszURL);
// if there is an error, make sure there is no m_pCurrentFileFormatUnk...
// if m_pCurrentFileFormatUnk is not NULL, it means we need to try
// the next plugin that supports this mimetype.
// ignore error in this case.
if (theErr && !m_pCurrentFileFormatUnk)
{
mLastError = theErr;
CheckForDefaultUpgrade(theErr);
// merge any upgrade requests for this source to the player
MergeUpgradeRequest(m_bAddDefaultUpgrade, m_pDefaultUpgradeString);
#if defined(HELIX_FEATURE_AUTOUPGRADE)
if (theErr != HXR_NO_FILEFORMAT)
#endif
{
ReportError(theErr);
DoCleanup();
}
}
}
HX_RESULT
HXFileSource::InitializeFileFormat()
{
HX_RESULT theErr = HXR_OK;
HX_RESULT resultInitFF = HXR_OK;
IHXRequest* pRequest = NULL;
IHXPlugin* pPlugin = NULL;
HX_ASSERT(m_pCurrentFileFormatUnk != NULL);
if (m_pCurrentFileFormatUnk)
{
HX_VERIFY(HXR_OK ==
m_pCurrentFileFormatUnk->QueryInterface(IID_IHXFileFormatObject, (void**) &m_pFFObject));
}
HX_RELEASE(m_pCurrentFileFormatUnk);
m_bCurrentFileFormatUnkInUse = FALSE;
HX_ASSERT(m_pFFObject != NULL);
if (!m_pFFObject)
{
return HXR_INVALID_FILE; //??
}
// we keep RAM FF object around by AddRef()
// to avoid self-destruct in ::InitDone when it's not a RAM
// It will be released in ::FinishSetup().
if (!m_bValidateMetaDone)
{
HX_ASSERT(!m_pRAMFFObject);
m_pRAMFFObject = m_pFFObject;
m_pRAMFFObject->AddRef();
}
if (HXR_OK != m_pFFObject->QueryInterface(IID_IHXPlugin,(void**)&pPlugin))
{
theErr = HXR_NOT_INITIALIZED;
goto exit;
}
if (HXR_OK != pPlugin->InitPlugin((IUnknown*) (IHXStreamSource*)this))
{
theErr = HXR_NOT_INITIALIZED;
goto exit;
}
if (m_pRequestHandler->GetRequest(pRequest) != HXR_OK)
{
theErr = HXR_NOT_INITIALIZED;
goto exit;
}
if (HXR_OK != (resultInitFF=m_pFFObject->InitFileFormat(pRequest,
this,
m_pFileObject)) )
{
if(HXR_UNSUPPORTED_VIDEO == resultInitFF ||
HXR_UNSUPPORTED_AUDIO == resultInitFF ||
HXR_DOC_MISSING == resultInitFF)
{
theErr = resultInitFF;
}
else
{
theErr = HXR_INVALID_FILE; //HXR_NOT_INITIALIZED;
}
goto exit;
}
exit:
HX_RELEASE(pRequest);
HX_RELEASE(pPlugin);
if (theErr)
{
/* do we need to try the next one! */
if (!m_pCurrentFileFormatUnk && m_pFileFormatEnumerator)
{
m_pFileFormatEnumerator->GetNextPlugin(m_pCurrentFileFormatUnk, NULL);
if (m_pCurrentFileFormatUnk && m_pSourceInfo)
{
m_pSourceInfo->ScheduleProcessCallback();
}
}
}
return theErr;
}
HX_RESULT
HXFileSource::DoCleanup(EndCode endCode)
{
/* UnRegister any previously registered source */
if (m_pSourceInfo)
{
m_pSourceInfo->UnRegister();
}
CleanupFileObjects();
HX_RELEASE(m_pCurrentFileFormatUnk);
m_bCurrentFileFormatUnkInUse = FALSE;
HX_RELEASE(m_pFileFormatEnumerator);
#if defined(HELIX_FEATURE_ASM)
HX_RELEASE(m_pSimulatedSourceBandwidth);
#endif /* HELIX_FEATURE_ASM */
HX_VECTOR_DELETE(m_pMimeType);
HX_VECTOR_DELETE(m_pExtension);
HX_VECTOR_DELETE(m_pDefaultUpgradeString);
m_bAddDefaultUpgrade = FALSE;
HX_RELEASE(m_pFileRecognizer);
#if defined(HELIX_FEATURE_STATS) && defined(HELIX_FEATURE_REGISTRY)
/* Reason to add this code is because in FileSource
* we create/delete it while in NetSource
* case, Protocol creates/deletes it
*/
for (CHXMapLongToObj::Iterator i = mStreamInfoTable->Begin();
i != mStreamInfoTable->End(); ++i)
{
STREAM_INFO* sInfo = (STREAM_INFO*) (*i);
if (sInfo)
{
HX_DELETE (sInfo->m_pStats);
}
}
#endif /* HELIX_FEATURE_STATS && HELIX_FEATURE_REGISTRY*/
HXSource::DoCleanup();
return HXR_OK;
}
void
HXFileSource::ReportError(HX_RESULT theErr)
{
CHXString DecodedURL;
CHXURL::decodeURL(m_pURL->GetURL(), DecodedURL);
m_pPlayer->ReportError( this, theErr, DecodedURL );
}
void
HXFileSource::CleanupFileObjects()
{
HX_RELEASE (m_pFSObject);
if (m_pFFObject)
{
m_pFFObject->Close();
HX_RELEASE (m_pFFObject);
}
HX_RELEASE (m_pFileResponse);
if (m_pFileObject)
{
m_pFileObject->Close();
HX_RELEASE (m_pFileObject);
}
HX_RELEASE (m_pRequestHandler);
HX_RELEASE (m_pMimeFinderResponse);
}
HX_RESULT
HXFileSource::DoSeek(ULONG32 seekTime)
{
/* Add any start time to seek time */
if (seekTime >= m_ulDelay)
{
seekTime -= m_ulDelay;
m_bDelayed = FALSE;
}
else
{
seekTime = 0;
/* This source has not been even started yet...
* Do not attempt to seek it if the start time = 0
*/
if (m_bDelayed && m_ulStartTime == 0 && !m_bSourceEnd)
{
// will start pre-fetch again in TryResume()
if (!m_bIsPreBufferingDone)
{
m_bIsPreBufferingStarted = FALSE;
// will be registered again in DoResume() or TryResume()
if (m_pSourceInfo)
{
m_pSourceInfo->UnRegister();
}
}
return HXR_OK;
}
m_bDelayed = TRUE;
}
seekTime += m_ulStartTime;
/* Are we seeking past the last expected packet time?
* If so, don't bother... and mark this source as done
*/
HX_ASSERT(m_llLastExpectedPacketTime < MAX_UINT32);
// XXX HP make sure the source has been initialized otherwise
// m_llLastExpectedPacketTime could be 0 and we could falsely
// mark the source ended
if (m_bInitialized && !mLiveStream && seekTime >= INT64_TO_UINT32(m_llLastExpectedPacketTime))
{
if (m_pSourceInfo && m_pSourceInfo->m_bSeekToLastFrame)
{
seekTime = INT64_TO_UINT32(m_llLastExpectedPacketTime);
}
else
{
m_bSourceEnd = TRUE;
m_bForcedSourceEnd = TRUE;
AdjustClipBandwidthStats(FALSE);
goto cleanup;
}
}
m_bInitialBuffering = TRUE;
m_bForcedSourceEnd = FALSE;
m_uActiveStreams = m_uNumStreams;
m_bIsPreBufferingStarted = FALSE;
m_bIsPreBufferingDone = FALSE;
if (m_nSeeking == 0)
{
m_nSeeking++;
}
#if defined(HELIX_FEATURE_RECORDCONTROL)
if (m_pRecordControl && m_pRecordControl->Seek(seekTime) == HXR_OK &&
m_bPlayFromRecordControl)
{
m_pBufferManager->DoSeek(seekTime, TRUE);
SeekDone(HXR_OK);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -