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

📄 rarender.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:

cleanup:

    if (HXR_OK != hr)
    {
	HX_RELEASE(m_pErrorMessages);
	HX_RELEASE(m_pAudioPlayer);
	HX_RELEASE(m_pAudioPushdown2);
    }
    return hr;
}

/////////////////////////////////////////////////////////////////////////
//  Method:
//	IHXRenderer::EndStream
//  Purpose:
//	Called by client engine to inform the renderer that the stream
//	is was rendering is closed.
//
STDMETHODIMP CRealAudioRenderer::EndStream()
{
#ifdef _MACINTOSH
    if (m_pDryCallback != NULL)
    {
	m_pDryCallback->Cancel();
	HX_RELEASE(m_pDryCallback);
    }
#endif

    if ((m_usCurrentDryNotificationStream != NO_STREAM_SET) &&
	m_pAudioStreams != NULL &&
	m_pAudioStreams[m_usCurrentDryNotificationStream] != NULL)
    {
        RemoveCurrentDryNotification();
        m_usCurrentDryNotificationStream = NO_STREAM_SET;
    }

    m_PlayState = stopped;

    FlushUnregisterQueue(TRUE);

    // We're done with these...
    HX_RELEASE(m_pContext);
    HX_RELEASE(m_pCommonClassFactory);
#if defined(HELIX_FEATURE_STATS)
    HX_RELEASE(m_pRegistry);
#endif	// HELIX_FEATURE_STATS
    HX_RELEASE(m_pBufferingStats);
    HX_RELEASE(m_pStream);
#if defined(HELIX_CONFIG_SLUGGISHAUTOUPGRADE)
    HX_RELEASE(m_pASMStream);
#endif
    HX_RELEASE(m_pAudioPlayer);
    HX_RELEASE(m_pAudioPushdown2);
    HX_RELEASE(m_pErrorMessages);
#if defined(HELIX_FEATURE_SETSRCPROPS)
    HX_RELEASE(m_pValues);
#endif /* #if defined(HELIX_FEATURE_SETSRCPROPS) */

    UINT16 i = 0;

    for (i = 0; i < m_uNumOfSubStreams; i++)
    {
	if (m_pRaFormats[i])
	{
	    if (m_pRaFormats[i]->m_pAudioSync && m_pRaFormats[i]->m_bRegistered)
	    {
		m_pRaFormats[i]->m_bRegistered  = FALSE;
		m_pRaFormats[i]->m_pAudioSync->UnRegister();
		DEBUG_OUTF_IDX(i, RA_FLOW_FILE,
			       (s, "Sync Stop\n"));
	    }

	    HX_RELEASE(m_pRaFormats[i]->m_pAudioSync);
	    HX_RELEASE(m_pAudioStreams[i]);
	    HX_DELETE(m_pRaFormats[i]);
#if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC)
            HX_DELETE(m_ppVBRDepack[i]);
#endif
	}
    }

    // we might get called twice and don't want to go through
    // the above loop again.
    m_uNumOfSubStreams = 0;

    HX_VECTOR_DELETE(m_pRuleMap);
    HX_VECTOR_DELETE(m_pAudioStreams);
    HX_VECTOR_DELETE(m_pRaFormats);
#if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC)
    HX_VECTOR_DELETE(m_ppVBRDepack);
#endif

    FlushUnregisterQueue(TRUE);

    if (m_pRuleToFlagMap != NULL)
    {
	HX_VECTOR_DELETE(m_pRuleToFlagMap->rule_to_flag_map);
	HX_DELETE(m_pRuleToFlagMap);
    }

    return HXR_OK;
}

/////////////////////////////////////////////////////////////////////////
//  Method:
//	IHXRenderer::OnHeader
//  Purpose:
//	Called by client engine when a header for this renderer is
//	available. The header will arrive before any packets.
//
STDMETHODIMP CRealAudioRenderer::OnHeader(IHXValues* pHeader)
{
    IHXBuffer* pOpaqueData = NULL;
    IHXBuffer* pRuleToFlagMapValue = NULL;
    IHXUpgradeCollection* pUpgradeCollection = NULL;
    BOOL    bForceStartTrackTime = FALSE;
    BOOL    bForceEndTrackTime = FALSE;
    UINT32  ulPreroll = 0;
    UINT32  ulIsInterleaved = 0;
    UINT32  ulBytesRead = 0;
    UINT32  ulTrackStartTime = 0;
    UINT32  ulTrackEndTime = 0;
    UINT32  ulStreamNumber = 0;
    HX_RESULT	retVal = HXR_OK;
    UINT32	ulBufferSize = 0;
    UINT32	ulID = 0;
    UINT16	i = 0;
    BYTE*	pCursor = NULL;
    BYTE*	pData = NULL;
    BOOL	bDecoderNotFound = FALSE;
    char*	pAllCodecs = NULL;
    UINT32 ulSubStream = 0; // highest bitrate substream
    UINT32 ulAllCodecBufLen = 0;

    UINT16 usQuality = 4;   // highest quality is my default.
#if defined(HELIX_FEATURE_PREFERENCES)
    GetQualityPreference(usQuality);
#endif /* #if defined(HELIX_FEATURE_PREFERENCES) */
    BOOL bMaxSampleRate = (usQuality >= 2); // most of the code uses this as the turn off point
    UINT16 nFirstStreamToInit = 0;  // init first first
    UINT32 ulCurrentSampleRate = bMaxSampleRate ? 8000 : 44000; // lowest sample rate we ever want to have
    UINT16 uCurrentNumChannels = 1;

    INT32 lProtocolVersion = 0;
    BOOL bIsPNM = FALSE;
    IHXStreamSource* pSource = NULL;
    ULONG32 numRulesToBlock = 0;

#if defined(HELIX_FEATURE_AUTOUPGRADE)
    // check the stream versions
    pHeader->AddRef();
    retVal = CheckStreamVersions(pHeader);
    pHeader->Release();

    // if the stream versions didn't checkout, bail
    if (retVal != HXR_OK)
    {
	goto cleanup;
    }
#endif

    if (SUCCEEDED(pHeader->GetPropertyULONG32("StreamNumber", ulStreamNumber)))
    {
	m_usThisSourceStream = (UINT16) ulStreamNumber;
    }

    pHeader->GetPropertyBuffer ("OpaqueData",       pOpaqueData);
    pHeader->GetPropertyULONG32("Preroll",          ulPreroll);

    // XXXgfw to fix a problem with the core not handling very small
    // preroll values. This should be removed as the client audio
    // services gets reworked to properly handle small preroll values.
    if( ulPreroll < 500 )
    {
        ulPreroll = 500; //a typical value for 193kbps RA content.
        pHeader->SetPropertyULONG32("Preroll", ulPreroll);
    }
    
    pHeader->GetPropertyULONG32("IsInterleaved",    ulIsInterleaved);
    pHeader->GetPropertyULONG32("Duration",	    m_ulDuration);

    if (HXR_OK == pHeader->GetPropertyULONG32("TrackStartTime", ulTrackStartTime))
    {
	bForceStartTrackTime = TRUE;
    }

    pHeader->GetPropertyULONG32("Delay", m_ulDelay);

    if (HXR_OK == pHeader->GetPropertyULONG32("TrackEndTime", ulTrackEndTime))
    {
	bForceEndTrackTime = TRUE;
    }

    if (HXR_OK ==
	pHeader->GetPropertyBuffer(RULE_TO_FLAG_MAP_PROPERTY,
			pRuleToFlagMapValue))
    {

	m_pRuleToFlagMap = new RuleToFlagMap;
        if(!m_pRuleToFlagMap)
        {
            retVal = HXR_OUTOFMEMORY;
            goto cleanup;
        }

	m_pRuleToFlagMap->unpack(pRuleToFlagMapValue->GetBuffer(),
				pRuleToFlagMapValue->GetSize());
    }

    HX_RELEASE(pRuleToFlagMapValue);

    m_ulPreroll	= ulPreroll;


    pData = pOpaqueData->GetBuffer();
    pCursor = pData;

    ulBufferSize = pOpaqueData->GetSize();

    // format ID
    memcpy((UCHAR*)&ulID, pCursor, sizeof(UINT32)); /* Flawfinder: ignore */

    ulID = DwToHost(ulID);

    if (RM_MULTIHEADER_OBJECT == ulID)
    {
	MultiStreamHeader multiStreamHeader;

	pCursor = multiStreamHeader.unpack(pData, ulBufferSize);
	ulBufferSize -= (pCursor - pData);

	m_bStreamSwitchable = TRUE;

	m_uNumOfSubStreams = multiStreamHeader.num_headers;

	// # of rules
	m_uNumOfRules = multiStreamHeader.num_rules;


	m_pRuleMap = new UINT16[m_uNumOfRules];
        if(!m_pRuleMap)
        {
            retVal = HXR_OUTOFMEMORY;
            goto cleanup;
        }

	// retrieve the rule map
	for (i = 0; i < m_uNumOfRules; i++)
	{
	    m_pRuleMap[i] = multiStreamHeader.rule_to_header_map[i];
	}

	// must delete the rule map since PMC doesn't generate distructors
	HX_VECTOR_DELETE(multiStreamHeader.rule_to_header_map);
    }
    else if (RA_FORMAT_ID == ulID)
    {
	m_uNumOfSubStreams = 1;
    }
    else
    {
	retVal = HXR_FAILED;
	goto cleanup;
    }

    // allocate all of our per stream structures and initialize them
    m_pRaFormats = new CRaFormat*[m_uNumOfSubStreams];
    if(!m_pRaFormats)
    {
	retVal = HXR_OUTOFMEMORY;
	goto cleanup;
    }
    ::memset(m_pRaFormats, 0, sizeof(CRaFormat*) * m_uNumOfSubStreams);

    m_pAudioStreams = new IHXAudioStream*[m_uNumOfSubStreams];
    if(!m_pAudioStreams)
    {
	retVal = HXR_OUTOFMEMORY;
	goto cleanup;
    }
    ::memset(m_pAudioStreams, 0, sizeof(IHXAudioStream*) * m_uNumOfSubStreams);

#if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC)
    m_ppVBRDepack = new CVBRSimpleDepacketizer* [m_uNumOfSubStreams];
    if(!m_ppVBRDepack)
    {
	retVal = HXR_OUTOFMEMORY;
	goto cleanup;
    }
    ::memset(m_ppVBRDepack, 0, sizeof(CVBRSimpleDepacketizer*) * m_uNumOfSubStreams);
#endif /* #if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC) */

#if defined(HELIX_FEATURE_STATS)
    if (m_pRegistry)
    {
        // Check the stats to get the protocol and protocol version
        // so we can special case 3.0 and earlier servers that send
        // timestamps in tenths of a second
        if (HXR_OK == m_pStream->GetSource(pSource))
        {
	    IHXRegistryID* pSourceIRegID = NULL;

	    if (HXR_OK == pSource->QueryInterface(IID_IHXRegistryID,
	        (void**)&pSourceIRegID))
	    {
	        UINT32 ulRegistryID;

	        if (HXR_OK == pSourceIRegID->GetID(ulRegistryID))
	        {
		    char	    szRegistryEntry[MAX_DISPLAY_NAME] = {0}; /* Flawfinder: ignore */
		    IHXBuffer* pszRegistryName = NULL;

		    // Get the current registry key name
		    if (HXR_OK == m_pRegistry->GetPropName(ulRegistryID,
		        pszRegistryName))
		    {
		        SafeSprintf(szRegistryEntry, MAX_DISPLAY_NAME, "%s.ProtocolVersion",
			    pszRegistryName->GetBuffer());
		        m_pRegistry->GetIntByName(szRegistryEntry,
			    lProtocolVersion);

		        IHXBuffer* pProtocolString = NULL;
		        SafeSprintf(szRegistryEntry, MAX_DISPLAY_NAME, "%s.Protocol",
			    pszRegistryName->GetBuffer());

		        if (HXR_OK ==
			    m_pRegistry->GetStrByName(szRegistryEntry,
			    pProtocolString) && pProtocolString != NULL)
		        {
			    bIsPNM = ( 0 == strcasecmp("PNM",
			        (const char*)pProtocolString->GetBuffer()));
		        }
		        HX_RELEASE(pProtocolString);
		    }

		    HX_RELEASE(pszRegistryName);
	        }

	        HX_RELEASE(pSourceIRegID);
	    }

	    HX_RELEASE(pSource);
        }
    }
#endif	// HELIX_FEATURE_STATS

    // create codecs buffer
#if defined(HELIX_FEATURE_STATS)
    ulAllCodecBufLen = (m_uNumOfSubStreams * 6) + 1;
    pAllCodecs = new char[ulAllCodecBufLen];
    if(!pAllCodecs)
    {
        retVal = HXR_OUTOFMEMORY;
        goto cleanup;
    }
    *pAllCodecs = '\0';
#endif /* #if defined(HELIX_FEATURE_STATS) */

    // instantiate the RA format/audio stream objects for
    // each sub-stream
    for (i = 0;
	 (retVal == HXR_OK) && (i < m_uNumOfSubStreams);
	 i++)
    {
	m_pRaFormats[i] = CreateRaFormat(i);

	// initialize the Format for this header
	m_pRaFormats[i]->ForceInterleaved(ulIsInterleaved);
	m_pRaFormats[i]->SetProtocolInfo(bIsPNM, lProtocolVersion);
#if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC)
        // Determine which ASM rule specifies a keyframe for this substream
        UINT16 usKeyFrameRuleNum = 0;
        for (UINT16 q = 0; q < m_pRuleToFlagMap->num_rules; q++)
        {
            BOOL bRuleForThisSubStream = TRUE;
            if (m_bStreamSwitchable && m_pRuleMap && m_pRuleMap[q] != i)
            {
                bRuleForThisSubStream = FALSE;
            }
            if (bRuleForThisSubStream &&
                m_pRuleToFlagMap->rule_to_flag_map[q] & HX_KEYFRAME_FLAG)
            {
                // This is the keyframe rule for this substream
                usKeyFrameRuleNum = q;
                break;
            }
        }
#endif /* #if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC) */


	UINT32 ulReadRAHeaderSize = ulBufferSize;
	if (m_bStreamSwitchable)
	{
	    // adjust the header size so we only read this header
	    ulReadRAHeaderSize = getlong(pCursor);
	    pCursor += sizeof(UINT32);
	    ulBufferSize -= sizeof(UINT32);
	}

	retVal = m_pRaFormats[i]->NewReadRAHeader(pCursor, ulReadRAHeaderSize,
	    bForceStartTrackTime, bForceEndTrackTime, ulTrackStartTime,
	    ulTrackEndTime, &ulBytesRead,  pAllCodecs, ulAllCodecBufLen);

	if (HXR_OK == retVal)
	{
#if defined(HELIX_FEATURE_AUDIO_CODEC_RAAC)
            // Check if this substream is RAAC and VBRS
            char* pInterID = m_pRaFormats[i]->GetInterleaverName();
            if (pInterID &&
                (!strcmp((const char*) pInterID, RA_INTERLEAVER_VBRS_ID) ||
                 !strcmp((const char*) pInterID, RA_INTERLEAVER_VBRF_ID)))
            {
                // Create a VBR depacketizer for this sub-stream
                HX_DELETE(m_ppVBRDepack[i]);
                m_ppVBRDepack[i] = new CVBRSimpleDepacketizer();
                if (m_ppVBRDepack[i])
                {
                    // Init the depacketizer
                    retVal = m_ppVBRDepack[i]->Init(m_pContext,
                                                    m_pRaFormats[i]->GetMSPerBlock(),
                                                    m_usThisSourceStream,
                                                    usKeyFrameRuleNum,

⌨️ 快捷键说明

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