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

📄 rarender.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                                                    FALSE);
                }
            }
#endif /* #if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC) */
	    HXAudioFormat audioFmt;
	    m_pRaFormats[i]->GetAudioFormat(audioFmt);

	    if ((bMaxSampleRate  && audioFmt.ulSamplesPerSec > ulCurrentSampleRate) ||
                (!bMaxSampleRate && audioFmt.ulSamplesPerSec < ulCurrentSampleRate))
	    {
		ulCurrentSampleRate = audioFmt.ulSamplesPerSec;
		uCurrentNumChannels = audioFmt.uChannels;
		nFirstStreamToInit = i;
	    }
	    else if (audioFmt.ulSamplesPerSec == ulCurrentSampleRate &&
		     audioFmt.uChannels > uCurrentNumChannels)
	    {
		uCurrentNumChannels = audioFmt.uChannels;
		nFirstStreamToInit = i;
	    }
	}

	// mask out DECODER_NOT_FOUND so we can try all of the streams and find
	// all of the decoders that aren't installed and upgrade them all at once
	if (retVal == HXR_DEC_NOT_FOUND)
	{
#if defined(HELIX_CONFIG_SLUGGISHAUTOUPGRADE)
	    if( m_pRuleMap )
            {
                if( m_pStream && !m_pASMStream )
	        {
	            if( m_pStream->QueryInterface(IID_IHXASMStream2,
		        (void**)&m_pASMStream) == HXR_OK )
                    {
                        m_pASMStream->AddRef();
                    }
	        }

	        if( m_pASMStream )
                {
	            // Find all rules for this stream
	            for( int ii=0; ii<m_uNumOfRules; ii++ )
		    {
		        if( m_pRuleMap[ii] == i )
			{
	                    m_pASMStream->Disable( ii );
	                    numRulesToBlock++;
			}
		    }
                }
	    } // if m_pRuleMap

	    if( ( numRulesToBlock == m_uNumOfRules ) || ( numRulesToBlock == 1 && m_uNumOfRules == 0 ) )
	    {
	       bDecoderNotFound = TRUE;
	    }

	    retVal = HXR_OK;
#else
	    retVal = HXR_OK;
	    bDecoderNotFound = TRUE;
#endif
	}

	pCursor += ulBytesRead;
	ulBufferSize -= ulBytesRead;
    }

#if defined(HELIX_CONFIG_SLUGGISHAUTOUPGRADE)
    if( m_pASMStream && bDecoderNotFound == FALSE )
    {
       HX_RESULT retVal = m_pASMStream->ReCompute();
       if( retVal == HXR_FAIL )
       {
           bDecoderNotFound = TRUE;
       }
    }
#endif // (HELIX_CONFIG_SLUGGISHAUTOUPGRADE)

    // write all codecs list to registry
#if defined(HELIX_FEATURE_STATS)
    WriteCodecsToRegistry(pAllCodecs);

    // clean up char array
    HX_VECTOR_DELETE(pAllCodecs);
#endif	// HELIX_FEATURE_STATS

    // if we don't have any other errors but we are missing one or more
    // decoders, reset the result code to decoder not found so upgrade
    // gets kicked off.
    if (HXR_OK == retVal && bDecoderNotFound)
    {
	retVal = HXR_DEC_NOT_FOUND;
    }


    // This helps insure we get the audio device opened at the
    // sampling rate and # channels we want.
    if (HXR_OK == retVal)
    {
	retVal = InitAudioStream(m_pRaFormats[nFirstStreamToInit], pHeader,
	    &m_pAudioStreams[nFirstStreamToInit]);

	for (i = 0; retVal == HXR_OK &&
		i < m_uNumOfSubStreams ; i++)
	{
	    if (i != nFirstStreamToInit)
	    {
		retVal = InitAudioStream(m_pRaFormats[i], pHeader,
		     &m_pAudioStreams[i]);
	    }

	}
    }

    // add the default dry notification when we are all done
    if (HXR_OK == retVal)
    {
	AddDryNotification(DEFAULT_DRY_NOTIFICATION);
    }

#if defined(HELIX_FEATURE_SETSRCPROPS)
    // Do we have more than one substream?
    if (m_uNumOfSubStreams > 1)
    {
        // Here we need to find the highest bitrate stream
        UINT32 ulMaxBps = 0;
        for (UINT32 i = 0; i < m_uNumOfSubStreams; i++)
        {
            UINT32 ulBps = m_pRaFormats[i]->GetBitRate();
            if (ulBps > ulMaxBps)
            {
                ulMaxBps    = ulBps;
                ulSubStream = i;
            }
        }
    }
    // Save the highest bitrate substream index
    m_ulSrcPropertySubStream = ulSubStream;
#endif /* #if defined(HELIX_FEATURE_SETSRCPROPS) */

cleanup:

    if (retVal == HXR_OK && !m_pMutex)
    {
#ifdef THREADS_SUPPORTED
	HXMutex::MakeMutex(m_pMutex);
#else
	HXMutex::MakeStubMutex(m_pMutex);
#endif
    }

    HX_RELEASE(pUpgradeCollection);
    HX_RELEASE(pOpaqueData);

    return retVal;
}

CRaFormat* CRealAudioRenderer::CreateRaFormat(UINT16 uStreamNum)
{
    return new CRaFormat(m_pContext,
			 m_pCommonClassFactory,
			 m_pErrorMessages,
			 m_pRuleToFlagMap ?
			    m_pRuleToFlagMap->rule_to_flag_map : NULL,
			 uStreamNum);
}

/////////////////////////////////////////////////////////////////////////////
//  Method:
//	CRealAudioRenderer::CheckStreamVersions
HX_RESULT
CRealAudioRenderer::CheckStreamVersions(IHXValues* pHeader)
{
    // check stream and content versions so an upgrade can
    // be called if necessary...
    HX_RESULT pnr = HXR_OK;

#if defined(HELIX_FEATURE_AUTOUPGRADE)
    BOOL bVersionOK = TRUE;

    UINT32 ulStreamVersion = 0;
    UINT32 ulContentVersion = 0;

    if(HXR_OK == pHeader->GetPropertyULONG32("StreamVersion",
	ulStreamVersion))
    {
	UINT32 ulMajorVersion = HX_GET_MAJOR_VERSION(ulStreamVersion);
	UINT32 ulMinorVersion = HX_GET_MINOR_VERSION(ulStreamVersion);

	if((ulMajorVersion > STREAM_MAJOR_VERSION) ||
	   (ulMinorVersion > STREAM_MINOR_VERSION &&
		ulMajorVersion == STREAM_MAJOR_VERSION))
	{
		bVersionOK = FALSE;
	}
    }

    if(bVersionOK &&
       HXR_OK == pHeader->GetPropertyULONG32("ContentVersion",
           ulContentVersion))
    {
	UINT32 ulMajorVersion = HX_GET_MAJOR_VERSION(ulContentVersion);
	UINT32 ulMinorVersion = HX_GET_MINOR_VERSION(ulContentVersion);

	if((ulMajorVersion > CONTENT_MAJOR_VERSION) ||
	   (ulMinorVersion > CONTENT_MINOR_VERSION &&
		ulMajorVersion == CONTENT_MAJOR_VERSION))
	{
		bVersionOK = FALSE;
	}
    }

    if(!bVersionOK)
    {
	IHXUpgradeCollection* pUpColl = NULL;
	if(m_pContext &&
	   (HXR_OK == m_pContext->QueryInterface(IID_IHXUpgradeCollection,
		(void**)&pUpColl)))
	{
		CHXBuffer* pBuffer = NULL;
                m_pCommonClassFactory->CreateInstance(IID_IHXBuffer, (void**) &pBuffer);

		if (pBuffer)
		{
		    //XXXEH- in future, we may want to distinguish between
		    // "unknown content version" & "unknown stream version".
		    // For now, just treat both as "unknown content version":
		    LONG32 bufsize = strlen(zm_pStreamMimeTypes[0]) +
			    strlen(zm_pAdditionalAutoUpgradeInfo[
			    unknownRAContentVersion]) + 1;
		    pBuffer->Set((BYTE*)zm_pStreamMimeTypes[0], bufsize);
		    unsigned char* pBuf = pBuffer->GetBuffer();
		    pBuf[strlen(zm_pStreamMimeTypes[0])] = '\0';
		    SafeStrCat((char *)pBuf, zm_pAdditionalAutoUpgradeInfo[ /* Flawfinder: ignore */
			    unknownRAContentVersion], pBuffer->GetSize());
		    pUpColl->Add(eUT_Required, pBuffer, 0, 0);
		    HX_RELEASE(pBuffer);
		    HX_RELEASE(pUpColl);
		}
	}

	pnr = HXR_FAIL;
    }
#endif /* #if defined(HELIX_FEATURE_AUTOUPGRADE) */

    return pnr;
}

/////////////////////////////////////////////////////////////////////////////
//  Method:
//	CRealAudioRenderer::InitAudioStream
HX_RESULT
CRealAudioRenderer::InitAudioStream(CRaFormat* pRaFormat, IHXValues* pHeader,
    IHXAudioStream** ppAudioStream)
{
    HX_RESULT retVal;

    // init so we can HX_RELEASE on error.
    *ppAudioStream = NULL;
    pRaFormat->m_pAudioSync = NULL;

    retVal = m_pAudioPlayer->CreateAudioStream(ppAudioStream);
    if (HXR_OK == retVal)
    {
	retVal = (*ppAudioStream)->QueryInterface(IID_IHXRealAudioSync,
				(void**)&(pRaFormat->m_pAudioSync));
	if (HXR_OK == retVal)
	{
	    IHXCommonClassFactory* pCommonClassFactory;
	    if (HXR_OK == (*ppAudioStream)->QueryInterface(IID_IHXCommonClassFactory,
				(void**)&pCommonClassFactory))
	    {
		// if we can get a class factory from the ccf, it's
		// a redstone or later core
		m_bPreRedstonePlayer = FALSE;

		pRaFormat->OverrideFactory(pCommonClassFactory);
		pCommonClassFactory->Release();
	    }

	    HXAudioFormat audioFmt;
	    pRaFormat->GetAudioFormat(audioFmt);

	    /* Add default dry notification BEFORE initializing the audio
	     * stream. This is so that if we are started mid presentation
	     * and there was no audio present earlier, the timeline will
	     * change from being a fake timeline to audio timeline and
	     * the audio services will write audio for initial pushdown
	     * time. We need to get dry notifications so that we can halt
	     * the timeline, if the renderer does not have enough data.
	     */
	    retVal = (*ppAudioStream)->Init(&audioFmt, pHeader);
	}
    }

    if (HXR_OK != retVal)
    {
	HX_RELEASE((*ppAudioStream));
	HX_RELEASE(pRaFormat->m_pAudioSync);
    }

    return retVal;
}


/////////////////////////////////////////////////////////////////////////////
//  Method:
//	CRealAudioRenderer::AddDryNotification
HX_RESULT
CRealAudioRenderer::AddDryNotification(UINT16 usStreamNumber)
{
    HX_RESULT pnr = HXR_OK;

    if (m_pAudioStreams == NULL)
    {
	pnr = HXR_FAILED;
    }

    if ((HXR_OK == pnr) &&
	(usStreamNumber != m_usCurrentDryNotificationStream))
    {
	if (m_usCurrentDryNotificationStream != NO_STREAM_SET)
	{
	    HX_ASSERT(m_pAudioStreams[m_usCurrentDryNotificationStream] != NULL);

	    QueueUnregisterSync(m_usCurrentDryNotificationStream,
				m_ulLatestActualTime);

            RemoveCurrentDryNotification();

	    DEBUG_OUT(m_pErrorMessages, DOL_REALAUDIO,
		(s, "Switching FROM: %u - Removing DryNotification",
		m_usCurrentDryNotificationStream));
	}

	IHXDryNotification* pDryNot = NULL;
	QueryInterface(IID_IHXDryNotification, (void**)&pDryNot);

	HX_ASSERT(m_pAudioStreams[usStreamNumber] != NULL);
	if (pDryNot)
	{
	    pnr = m_pAudioStreams[usStreamNumber]->AddDryNotification(pDryNot);
	}

	DEBUG_OUTF_IDX(usStreamNumber, RA_FLOW_FILE,
	    (s, "Dry-Notif. Start: %s\n", (pnr == HXR_OK) ? "OK" : "FAIL"));

	HX_ASSERT(SUCCEEDED(pnr));

        m_usCurrentDryNotificationStream = usStreamNumber;

	DEBUG_OUT(m_pErrorMessages, DOL_REALAUDIO,
		(s, "Switching TO: %u - Adding DryNotification",
		m_usCurrentDryNotificationStream));

	// fix up the granularity for this stream
	// we want to be called twice as frequently as our block size.  That
	// way we will "over write" to audio services if we have extra data.
	// This will allow build up of an audio pushdown.
	ULONG32 ulNewGranularity =
	    (UINT32) (m_pRaFormats[usStreamNumber]->GetMSPerBlock() / 2);

	if (ulNewGranularity != m_ulCurrentGranularity)
	{
	    m_ulCurrentGranularity = ulNewGranularity;
	    m_pStream->SetGranularity(m_ulCurrentGranularity);
	    DEBUG_OUTF_IDX(usStreamNumber, RA_FLOW_FILE,
			   (s, "Granularity Set: %u\n",
			    m_ulCurrentGranularity));
	}

	HX_RELEASE(pDryNot);
    }

    if (pnr == HXR_OK)
    {
	DoSyncRegister(m_usCurrentDryNotificationStream);
    }

    return pnr;
}

/////////////////////////////////////////////////////////////////////////////
//  Method:
//	CRealAudioRenderer::DoSyncRegister
void CRealAudioRenderer::DoSyncRegister(UINT16 uStreamNumber)
{
    if (m_pRaFormats &&
	m_pRaFormats[uStreamNumber]->m_pAudioSync &&
	(!m_pRaFormats[uStreamNumber]->m_bRegistered))
    {
	DEBUG_OUTF_IDX(uStreamNumber, RA_FLOW_FILE,
		       (s, "Sync Start\n"));
	m_pRaFormats[uStreamNumber]->m_bRegistered = TRUE;
	m_pRaFormats[uStreamNumber]->m_pAudioSync->Register();
    }
}

void CRealAudioRenderer::UnregisterTimeSyncs(UINT32 ulCurrentTime)
{
    UINT16 uCurrentStream = m_uSyncUnregisterStream;

    if (uCurrentStream != NO_STREAM_SET)
    {
	BOOL bStreamDone = m_pRaFormats[uCurrentStream]->IsStreamDone();

	if ((m_bAllStreamsToBeUnregistered &&
	     (IsTimeGreaterOrEqual(ulCurrentTime, m_ulDuration) ||
	      bStreamDone)) ||
	    ((m_ulSyncUnregisterTime == NO_TIME_SET) &&
	     IsTimeGreaterOrEqual(ulCurrentTime,
				  m_ulSyncUnregisterTime)))
	{
	    CRealAudioRenderer::QueueUnregisterSync(uCurrentStream,
						    NO_TIME_SET);
	}
    }
}

/////////////////////////////////////////////////////////////////////////////
//  Method:
//	CRealAudioRenderer::QueueUnregisterSync

⌨️ 快捷键说明

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