⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hxflsrc.cpp

📁 linux下的一款播放器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
STDMETHODIMP	HXFileSource::PacketReady(HX_RESULT status, IHXPacket* pPacket){    HX_RESULT theErr = HXR_OK;    // We should have been initialized by now    HX_ASSERT(m_bInitialized);    if (!m_bInitialized)    {	return HXR_NOT_INITIALIZED;    }        // Report a non-HXR_OK error code only if no packet. If a packet    // accompanies the error code we assume end of stream and handle    // later on (see below).    if (!pPacket)    {        if (HXR_OK != status)        {	    mLastError = status;	    ReportError(mLastError);            return HXR_OK;        }        else        {	    // HXR_OK with a NULL packet makes no sense	    return HXR_INVALID_PARAMETER;        }    }        IHXBuffer*	    pBuffer	    = 0;    UINT32	    ulPacketTime    = 0;	    // packet time encoded    UINT32	    ulPacketFilledDuration = 0;	    // packets' time have been filled     UINT32 	    ulEventBeginTime = 0;	    // start pos of the packet(event)     INT64	    llActualPacketTime = 0;	    // packet time with timestamp rollover    INT64	    llActualEventBeginTime = 0;	    // start pos of the packet(event) with timestamp rollover    ULONG32	    ulFlags	    = 0;    UINT16	    uStreamNumber   = 0;    UINT8	    unASMFlags	    = 0;    UINT16	    unASMRuleNumber = 0;    UINT32	    streamPreRoll   = 0;    UINT32	    ulMinimumTotalPreroll = 0;    if (HXR_OK != pPacket->Get(pBuffer, ulPacketTime, uStreamNumber, unASMFlags, unASMRuleNumber))    {	theErr = HXR_FAILED;	return theErr;    }#if defined(_DEBUG) && defined(DEBUG_LOG_INFO)    HXStaticStatLog::StatPrintf("Packet: StreamNumber: %u TimeStamp: %lu\n", uStreamNumber, ulPacketTime);#endif    HX_RELEASE(pBuffer);    CHXEvent*	    theEvent	    = NULL;    STREAM_INFO*    lpStreamInfo    = NULL;    CHXEventList*  lEventList	    = NULL;    if (!mStreamInfoTable->Lookup((LONG32) uStreamNumber, (void *&) lpStreamInfo))    {	return HXR_INVALID_PARAMETER;    }    if (status != HXR_OK)    {	if (!lpStreamInfo->m_bSrcStreamDone)	{	    // if the status is not OK, it is probably the end of the stream..	    // we should mark this stream as DONE...	    lpStreamInfo->m_bPacketRequested	    = FALSE;	    lpStreamInfo->m_bSrcStreamFillingDone   = TRUE;	    lpStreamInfo->m_bSrcStreamDone	    = TRUE;	    if (m_uNumStreamsToBeFilled > 0)	    {		m_uNumStreamsToBeFilled--;	    }	    	    if (m_uActiveStreams > 0)	    {		m_uActiveStreams--;	    }	    	    if (m_uActiveStreams == 0)	    {		SetEndOfClip();	    }	}	return HXR_OK;    }    lpStreamInfo->m_ulReceived++;    if (!theErr)    {	// reset	lpStreamInfo->m_bPacketRequested    = FALSE;	lEventList = &lpStreamInfo->m_EventList;    }    /*     * Save off the initial timestamp for live streams so we can buffer     * relative to the first timstamp     */    if (m_bInitialPacket)    {	m_bInitialPacket = FALSE;	m_ulFirstPacketTime = ulPacketTime;    }    // This is the time according to the stream...    llActualPacketTime = 	lpStreamInfo->BufferingState().CreateINT64Timestamp(ulPacketTime);    llActualEventBeginTime = llActualPacketTime + m_ulDelay;    /* subtract start time from player time */    if (m_ulStartTime > 0)    {	if (m_ulStartTime < llActualPacketTime) 	{	    llActualPacketTime -= m_ulStartTime; 	}	else	{	    llActualPacketTime = 0;	}	if (m_ulStartTime < llActualEventBeginTime) 	{	    llActualEventBeginTime -= m_ulStartTime; 	}	else	{	    llActualEventBeginTime = 0;	}    }        HX_ASSERT(llActualEventBeginTime < MAX_UINT32);    HX_ASSERT(llActualPacketTime < MAX_UINT32);    ulEventBeginTime = INT64_TO_UINT32(llActualEventBeginTime);    ulPacketFilledDuration = INT64_TO_UINT32(llActualPacketTime);#if defined(HELIX_FEATURE_RECORDCONTROL)    if (m_pRecordControl)    {	m_pRecordControl->OnPacket(pPacket, m_ulStartTime - m_ulDelay);    }#endif /* HELIX_FEATURE_RECORDCONTROL */    if (!m_bPlayFromRecordControl)    {	/* 	 * force a minimum preroll of 1 second to ensure that we deliver	 * packet in time to the renderers. e.g. with delayed RealText	 * with a preroll of 0 and delay of 10 seconds, it is 	 * possible to send packets at time 0 AFTER 10 seconds if we 	 * do not ensure this minimum preroll	 * helps in fixing random "realtext not displaying" bug	 */#ifdef HELIX_FEATURE_MIN_PREROLL        streamPreRoll = max(lpStreamInfo->BufferingState().GetMinPrerollInMs(),150);#else  //HELIX_FEATURE_MIN_PREROLL        streamPreRoll = max(lpStreamInfo->BufferingState().GetMinPrerollInMs(),1000);#endif //HELIX_FEATURE_MIN_PREROLL	ulEventBeginTime = (ulEventBeginTime > streamPreRoll) ? (ulEventBeginTime - streamPreRoll) : 0;	theEvent = new CHXEvent(pPacket, ulEventBeginTime);	if(!theEvent) 	{	    theErr = HXR_OUTOFMEMORY;	}	// enqueue the event into event queue	if(!theErr) 	{    	    /* offset used by Player::ProcessCurrentEvents to send to renderer::OnPacket */    	    theEvent->SetTimeOffset(m_ulStartTime - m_ulDelay); 	    theErr = lEventList->InsertEvent(theEvent);	}	if (!theErr)	{	    m_pBufferManager->UpdateCounters(pPacket);	}    }    m_llLastFillEndTime = llActualPacketTime;    if (m_bInFillMode)    {	UINT32 ulDuration = 0;	UINT32 ulRemainToBufferInMs = 0;	UINT32 ulRemainToBuffer = 0;	m_pBufferManager->GetRemainToBuffer(ulRemainToBufferInMs,					    ulRemainToBuffer);	/* Logic:	    In FillBuffers(), we ask for a packet for a particular stream. If	    the fileformat does not return the packet immediately (i.e. we 	    go again to ask for the packet from the same stream but find out that	    we had already asked for it earlier and have not yet received it,	    the streamFilling is marked as done for that fillbuffer() iteration.	    In the meantime, we keep on asking for the packets from other streams	    In meanwhile, if the fileformat returns a packet for the stream marked 	    as done earlier, we re-activate that stream if the time of the packet	    is less than the time we fill all streams up to.	 */	if (lpStreamInfo->m_bSrcStreamFillingDone &&	    (ulRemainToBufferInMs > 0 || ulRemainToBuffer > 0) &&	    ulPacketFilledDuration <= lpStreamInfo->m_ulDuration &&	    !lpStreamInfo->m_bSrcStreamDone)	{	    lpStreamInfo->m_bSrcStreamFillingDone = FALSE;    	    m_uNumStreamsToBeFilled++;	}		if (!lpStreamInfo->m_bSrcStreamDone && 	    !lpStreamInfo->m_bSrcStreamFillingDone &&	    m_uNumStreamsToBeFilled > 0)	{            /* When playing from Record Control buffering can happen after seek to                a cached position. In this case we dont need to accelerate packet                retriaval and can stop filling the stream.             */	    if (ulPacketFilledDuration > lpStreamInfo->m_ulDuration ||		(ulRemainToBufferInMs == 0 && ulRemainToBuffer == 0) ||                (m_bPlayFromRecordControl && ulPacketFilledDuration >= m_pPlayer->GetInternalCurrentPlayTime() + ulRemainToBufferInMs))	    {		// this value also updated in PacketReady()		lpStreamInfo->m_bSrcStreamFillingDone  = TRUE;		if (m_uNumStreamsToBeFilled > 0)		{		    m_uNumStreamsToBeFilled--;		}	    }	}    }    if (!theErr)    {	m_bReceivedData	    = TRUE;    }    else if (theEvent)    {        HX_DELETE(theEvent);    }    return theErr;}STDMETHODIMP	HXFileSource::StreamDone(UINT16   uStreamNumber){    STREAM_INFO	   *lpStreamInfo    = NULL;    if (!mStreamInfoTable->Lookup((LONG32) uStreamNumber, (void *&) lpStreamInfo))    {	return HXR_INVALID_PARAMETER;    }    if (!lpStreamInfo->m_bSrcStreamDone)    {	lpStreamInfo->m_bSrcStreamDone		= TRUE;	lpStreamInfo->m_bSrcStreamFillingDone	= TRUE;	lpStreamInfo->m_bPacketRequested	= FALSE;	if (m_uNumStreamsToBeFilled > 0)	{	    m_uNumStreamsToBeFilled--;	}	if (m_uActiveStreams > 0)	{	    m_uActiveStreams--;	}    	if (m_uActiveStreams == 0)	{	    SetEndOfClip();	}    }    return HXR_OK;}STDMETHODIMP	HXFileSource::SeekDone(HX_RESULT status){    HX_RESULT lResult = HXR_OK;        if (m_nSeeking > 0)    {	m_nSeeking--;    }    _ProcessIdle(FALSE);    return lResult;}STDMETHODIMP HXFileSource::RedirectDone(IHXBuffer* pURL){    HX_RESULT	hr = HXR_NOTIMPL;    // handle redirect to diff. protocol from HTTP file system    if (m_pszURL && pURL)    {	if (strncasecmp(m_pszURL, "http://", 7) == 0 &&	    strncasecmp((const char*)pURL->GetBuffer(), "http://", 7) != 0)	{            if (m_bPartOfNextGroup)            {                m_bRedirectPending = TRUE;                HX_DELETE(m_pRedirectURL);                m_pRedirectURL = new CHXURL((const char*)pURL->GetBuffer());            }            else            { 	        hr = m_pSourceInfo->HandleRedirectRequest((char*)pURL->GetBuffer());            }	}    }        return hr;}// routine to read from the file to keep all streams filled to their preroll valueHX_RESULT    HXFileSource::FillBuffers(void){    /*      * Do not call GetPacket if we have not yet received SeekDone from     * the file format plugin.     *	    ||      * We are in a paused state and no rebuffering and no fast start      * is required.     *	    ||     * We are in force end mode such as seeking to the end of the source duration     */    if (m_nSeeking > 0 ||	(m_bPaused && !m_bFastStartInProgress && !m_bRebufferingRequired && !m_pRecordControl) ||	m_bForcedSourceEnd)    {	return HXR_OK;    }    HX_RESULT	theErr			= HXR_OK;    UINT32	ulRemainToBufferInMs	= 0;     UINT32	ulRemainToBuffer	= 0;    UINT32	lPlayPos		= m_pPlayer->GetInternalCurrentPlayTime();    UINT32	ulCurrentTime		= HX_GET_TICKCOUNT();    m_uNumStreamsToBeFilled		= 0;    m_ulMaxPreRoll			= 0;      CHXMapLongToObj::Iterator	ndxStream	= mStreamInfoTable->Begin();    STREAM_INFO*		lpStreamInfo    = NULL;    m_pBufferManager->GetMaximumPreroll(m_ulMaxPreRoll);    m_pBufferManager->GetRemainToBuffer(ulRemainToBufferInMs,					ulRemainToBuffer);    for(; ndxStream != mStreamInfoTable->End(); ++ndxStream)    {	lpStreamInfo	= (STREAM_INFO*) (*ndxStream);		if(!lpStreamInfo->m_bSrcStreamDone)	{	    m_uNumStreamsToBeFilled++;	    lpStreamInfo->m_bSrcStreamFillingDone = FALSE;	}    }    /*     * The fill end time must be offset by the intial timestamp if this     * is a live stream which is saved in the initial PacketReady     */    // we will always attempt to have m_MaxPreRoll time of data in the audio and video event queues    m_llFillEndTime = CAST_TO_INT64 (lPlayPos + 			      m_ulMaxPreRoll + m_pPlayer->m_ulMinimumAudioPreroll + 			      m_pPlayer->GetGranularity());    if (!m_pRecordControl &&	!m_bRebufferingRequired &&	ulRemainToBufferInMs == 0 &&	ulRemainToBuffer == 0 && 	m_llFillEndTime <= m_llLastFillEndTime)    {	return HXR_OK;    }#if defined(HELIX_FEATURE_RECORDCONTROL)    if (m_pRecordControl && !m_pRecordControl->CanAcceptPackets())    {	return HXR_OK;    }#endif /* HELIX_FEATURE_RECORDCONTROL */    m_bInFillMode   = TRUE;    while(!theErr && m_uNumStreamsToBeFilled > 0)    {	ndxStream = mStreamInfoTable->Begin();	for (; !theErr && ndxStream != mStreamInfoTable->End(); ++ndxStream)	{	    lpStreamInfo    = (STREAM_INFO*) (*ndxStream);	    if (!lpStreamInfo->m_bSrcStreamDone && 		!lpStreamInfo->m_bSrcStreamFillingDone && 		!lpStreamInfo->m_bPacketRequested)	    {		// this will be reset in PacketReady()		lpStreamInfo->m_bPacketRequested    = TRUE;	                HX_RESULT retVal = m_pFFObject->GetPacket((UINT16) lpStreamInfo->m_uStreamNumber);		if (HXR_OK != retVal )		{                    StreamDone(lpStreamInfo->m_uStreamNumber);                    // Don't lose OOM errors.                    if( retVal == HXR_OUTOFMEMORY )                    {                        theErr = retVal;                    }#ifdef HELIX_FEATURE_STOP_STREAM_BY_TEMP_FILE_ERROR                    if( retVal == HXR_TEMP_FILE )                    {			theErr = retVal;			m_pBufferManager->Stop();			SetEndOfClip();			mLastError = retVal;			ReportError(mLastError);                    }#endif //HELIX_FEATURE_STOP_STREAM_BY_TEMP_FILE_ERROR		}	    } 	    else if (lpStreamInfo->m_bPacketRequested)	    {		/* This logic applies to only single threaded application		 * where if we request a packet, we are either gonna get it 		 * immediately or not get it at all till a later time--		 * GetPacket() to ff->read to fs->readdone to ff->		 * packetready to fileresponse(this) 		 * In this case, m_uNumStreamsToBeFilled		 * will be adjusted in packetready depending on timestamp of stream		 * and where we wanna fill that stream upto		 * If packet requested is TRUE, it means fileformat did not response		 * immediately and thus one less stream is to be filled.		 * This however may not work in multi-threaded case where		 * fileplugin can send a response at any time.		 */		if (!lpStreamInfo->m_bSrcStreamFillingDone)		{		    lpStreamInfo->m_bSrcStreamFillingDone = TRUE;		    if (m_uNumStreamsToBeFilled > 0)	 	    {    			m_uNumStreamsToBeFilled--;		    }		}	    }	}    }    m_bInFillMode   = FALSE;    return theErr;}void		HXFileSource::SetEndOfClip(BOOL bForcedEndofClip) {    m_bForcedSourceEnd = bForcedEndofClip;    if (!m_bSourceEnd)    {	m_bSourceEnd = TRUE;				  	m_pBufferManager->Stop();	m_pPlayer->EndOfSource(this);#if defined(HELIX_FEATURE_RECORDCONTROL)	if (m_pRecordControl)	{	    m_pRecordControl->OnEndOfPackets();	}#endif /* HELIX_FEATURE_RECORDCONTROL*/    }}// IUnknown methods///////////////////////////////////////////////////////////////////////////	Method://		IUnknown::QueryInterface//	Purpose://		Implement this to export the interfaces supported by your //		object.//STDMETHODIMP HXFileSource::CMimeFinderFileResponse::QueryInterface(REFIID riid, void** ppvObj){    QInterfaceList qiList[] =        {            { GET_IIDHANDLE(IID_IHXFileMimeMapperResponse), (IHXFileMimeMapperResponse*)this },            { GET_IIDHANDLE(IID_IHXFileRecognizerResponse), (IHXFileRecognizerResponse*)this },            { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXFileMimeMapperResponse*)this },        };        return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);}///////////////////////////////////////////////////////////////////////////	Method://		IUnknown::AddRef//	Purpose://		Everyone usually implements this the same... feel free to use//		this implementation.//STDMETHODIMP_(ULONG32) HXFileSource::CMimeFinderFileResponse::AddRef(){    return Inte

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -