mp4apyld.cpp

来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,014 行 · 第 1/2 页

CPP
1,014
字号
	{
	    retVal = HXR_OK;
	}

	if (SUCCEEDED(retVal))
	{
	    if (!m_pLATMDepack->GetCodecConfig(pCodecConfig,
					       ulConfigSize))
	    {
		pCodecConfig = NULL;
		ulConfigSize = 0;
	    }
	}

	if (SUCCEEDED(retVal))
	{
	    m_ulAudioConfigSize = ulConfigSize;

	    if (m_ulAudioConfigSize > 0)
	    {
		m_pAudioConfig = new UINT8 [m_ulAudioConfigSize];

		if (m_pAudioConfig == NULL)
		{
		    m_ulAudioConfigSize = 0;
		    retVal = HXR_OUTOFMEMORY;
		}
	    }
	}

	if (SUCCEEDED(retVal))
	{
	    if (m_ulAudioConfigSize > 0)
	    {
		memcpy(m_pAudioConfig, pCodecConfig, m_ulAudioConfigSize); /* Flawfinder: ignore */
	    }
	}
    }

    HX_RELEASE(pConfigBuffer);

    return retVal;
}

STDMETHODIMP
MP4APayloadFormat::GetStreamHeader(REF(IHXValues*) pHeader)
{
    HX_RESULT retVal = HXR_FAIL;

    if (m_pStreamHeader)
    {
	retVal = HXR_OK;
	pHeader = m_pStreamHeader;
	pHeader->AddRef();
    }

    return retVal;
}

STDMETHODIMP
MP4APayloadFormat::SetPacket(IHXPacket* pPacket)
{
    HX_RESULT retVal = HXR_OK;

    HX_ASSERT(pPacket);

    if (!m_bRTPPacketTested)
    {
	IHXRTPPacket* pRTPPacket = NULL;

	m_bUsesRTPPackets = (pPacket->QueryInterface(
				IID_IHXRTPPacket,
				(void**) &pRTPPacket)
			    == HXR_OK);

	m_bRTPPacketTested = TRUE;

	HX_RELEASE(pRTPPacket);

	if (m_bUsesRTPPackets)
	{
	    if (m_ulRTPSamplesPerSecond == 0)
	    {
		m_ulRTPSamplesPerSecond = m_ulSamplesPerSecond;
	    }
	}
	else
	{
	    m_ulRTPSamplesPerSecond = 1000; // RDT time stamp
	}

	m_TSConverter.SetBase(m_ulRTPSamplesPerSecond,
			      m_ulSamplesPerSecond);
    }

    // Add this packet to our list of input packets
    switch (m_PayloadID)
    {
    case PYID_X_HX_AAC_GENERIC:
    case PYID_X_HX_MP4_RAWAU:
	pPacket->AddRef();
	m_InputPackets.AddTail(pPacket);
	break;

    case PYID_MP4A_LATM:
	retVal = HXR_FAIL;
	if (m_pLATMDepack)
	{
	    if (pPacket->IsLost())
	    {
		if (m_pLATMDepack->OnLoss(1))
		{
		    retVal = HXR_OK;
		}
	    }
	    else
	    {
		IHXBuffer* pBuffer = pPacket->GetBuffer();

		if (pBuffer &&
		    m_pLATMDepack->OnPacket(GetPacketTime(pPacket),
					    pBuffer->GetBuffer(),
					    pBuffer->GetSize(),
					    (pPacket->GetASMRuleNumber() == 1)))
		{
		    retVal = HXR_OK;

		    pBuffer->Release();
		}
	    }
	}
	break;

    default:
	retVal = HXR_NOTIMPL;
	break;
    }

    return retVal;
}

STDMETHODIMP
MP4APayloadFormat::GetPacket(REF(IHXPacket*) pOutPacket)
{
    HX_RESULT retVal = HXR_OK;

    if (m_bPacketize)
    {
	retVal = GetPacketizerPacket(pOutPacket);
    }
    else
    {
	retVal = GetAssemblerPacket(pOutPacket);
    }

    return retVal;
}

HX_RESULT MP4APayloadFormat::GetPacketizerPacket(IHXPacket* &pOutPacket)
{
    HX_RESULT retVal = HXR_INCOMPLETE;

    if (!m_InputPackets.IsEmpty())
    {
	pOutPacket = (IHXPacket*) m_InputPackets.RemoveHead();
	retVal = HXR_OK;
    }
    else if (m_bFlushed)
    {
	retVal = HXR_STREAM_DONE;
    }

    return retVal;
}

HX_RESULT MP4APayloadFormat::GetAssemblerPacket(IHXPacket* &pOutPacket)
{
    HX_RESULT retVal = HXR_NOTIMPL;

    return retVal;
}

HX_RESULT MP4APayloadFormat::SetSamplingRate(ULONG32 ulSamplesPerSecond)
{
    HX_RESULT retVal = HXR_UNEXPECTED;

    if (!m_bRTPPacketTested)
    {
	m_ulSamplesPerSecond = ulSamplesPerSecond;
	retVal = HXR_OK;
    }

    return HXR_OK;
}

ULONG32 MP4APayloadFormat::GetTimeBase(void)
{
    return m_ulSamplesPerSecond;
}

HX_RESULT MP4APayloadFormat::SetAUDuration(ULONG32 ulAUDuration)
{
    HX_RESULT retVal = HXR_UNEXPECTED;

    if (!m_bRTPPacketTested)
    {
	switch (m_PayloadID)
	{
	case PYID_MP4A_LATM:
	    retVal = HXR_FAIL;
	    
	    if (m_pLATMDepack &&
		m_pLATMDepack->SetFrameDuration(ulAUDuration))
	    {
		retVal = HXR_OK;
	    }
	    break;
	    
	default:
	    retVal = HXR_NOTIMPL;
	    break;
	}
    }

    return retVal;
}

HX_RESULT MP4APayloadFormat::SetTimeAnchor(ULONG32 ulTimeMs)
{
    CTSConverter tempConverter;
    ULONG32 ulSamplesAnchor;
    ULONG32 ulRTPSamplesAnchor;

    tempConverter.SetBase(1000, m_ulSamplesPerSecond);
    ulSamplesAnchor = tempConverter.ConvertVector(ulTimeMs);

    tempConverter.SetBase(1000, m_ulRTPSamplesPerSecond);
    ulRTPSamplesAnchor = tempConverter.ConvertVector(ulTimeMs);

    m_TSConverter.SetAnchor(ulRTPSamplesAnchor, ulSamplesAnchor);

    return HXR_OK;
}

HX_RESULT MP4APayloadFormat::CreateMediaPacket(CMediaPacket* &pOutMediaPacket)
{
    HX_RESULT retVal = HXR_OK;

    switch (m_PayloadID)
    {
    case PYID_X_HX_AAC_GENERIC:
    case PYID_X_HX_MP4_RAWAU:
	retVal = CreateRawAUMediaPacket(pOutMediaPacket);
	break;

    case PYID_MP4A_LATM:
	if (m_OutMediaPacketQueue.IsEmpty())
	{
	    if (m_bFlushed)
	    {
		// We have used up all available input
		retVal = HXR_STREAM_DONE;
	    }
	    else
	    {
		// We don't have enough input
		// data to produce a packet
		retVal = HXR_INCOMPLETE;
	    }
	}
	else
	{
	    pOutMediaPacket = (CMediaPacket*) m_OutMediaPacketQueue.RemoveHead();
	}
	break;

    default:
	retVal = HXR_NOTIMPL;
	break;
    }

    return retVal;
}

HX_RESULT MP4APayloadFormat::OnFrame(ULONG32 ulTime,
				     const UINT8* pData,
				     ULONG32 ulSize,
				     BOOL bPreviousLoss)
{
    ULONG32 ulFlags = 0;
    CMediaPacket* pMediaPacket = NULL;
    HX_RESULT retVal = HXR_OK;

    if (pData && (ulSize != 0))
    {
	ULONG32 ulNewSize;

	if (bPreviousLoss)
	{
	    ulFlags |= MDPCKT_FOLLOWS_LOSS_FLAG;
	}

#ifdef _OVERALLOC_CODEC_DATA
	ulNewSize = ulSize + _OVERALLOC_CODEC_DATA;
#else	// _OVERALLOC_CODEC_DATA
	ulNewSize = ulSize;
#endif	// _OVERALLOC_CODEC_DATA

	UINT8* pNewData = new UINT8 [ulNewSize];

	if (pData)
	{
	    memcpy(pNewData, pData, ulSize); /* Flawfinder: ignore */

	    pMediaPacket = new CMediaPacket(pNewData,
					    pNewData,
					    ulNewSize,
					    ulSize,
					    ulTime,
					    ulFlags,
					    NULL);
	}
    }

    if (pMediaPacket)
    {
	m_OutMediaPacketQueue.AddTail(pMediaPacket);
    }

    return retVal;
}

void MP4APayloadFormat::OnFrameCallback(void* pUserData,
					ULONG32 ulTime,
					const UINT8* pData,
					ULONG32 ulSize,
					BOOL bPreviousLoss)
{
    MP4APayloadFormat* pObject = (MP4APayloadFormat*) pUserData;

    pObject->OnFrame(ulTime, pData, ulSize, bPreviousLoss);
}

HX_RESULT MP4APayloadFormat::CreateRawAUMediaPacket(CMediaPacket* &pOutMediaPacket)
{
    CMediaPacket* pMediaPacket;
    IHXPacket* pPacket = NULL;
    HX_RESULT retVal = HXR_OK;

    if (m_InputPackets.IsEmpty())
    {
	if (m_bFlushed)
	{
	    // We have used up all available input
	    retVal = HXR_STREAM_DONE;
	}
	else
	{
	    // We don't have enough input
	    // data to produce a packet
	    retVal = HXR_INCOMPLETE;
	}
    }
    else
    {
	ULONG32 ulFlags = MDPCKT_USES_IHXBUFFER_FLAG;
	IHXBuffer* pBuffer = NULL;
	pPacket = (IHXPacket*) m_InputPackets.RemoveHead();

	if (!pPacket->IsLost())
	{
	    pBuffer = pPacket->GetBuffer();

	    if (pBuffer)
	    {
		if (m_bPriorLoss)
		{
		    ulFlags |= MDPCKT_FOLLOWS_LOSS_FLAG;
		    m_bPriorLoss = FALSE;
		}

		pMediaPacket = BuildMediaPacket(pBuffer,
						GetPacketTime(pPacket),
						ulFlags);

		retVal = HXR_OUTOFMEMORY;
		if (pMediaPacket)
		{
		    pOutMediaPacket = pMediaPacket;
		    retVal = HXR_OK;
		}

		pBuffer->Release();
	    }
	    else
	    {
		m_bPriorLoss = TRUE;
		retVal = HXR_INCOMPLETE;
	    }

	    pPacket->Release();
	}
	else
	{
	    m_bPriorLoss = TRUE;
	    retVal = HXR_INCOMPLETE;
	}
    }

    return retVal;
}


CMediaPacket* MP4APayloadFormat::BuildMediaPacket(IHXBuffer* pBuffer,
						  ULONG32 ulTime,
						  ULONG32 ulFlags)
{
    CMediaPacket* pMediaPacket = NULL;
#ifdef _OVERALLOC_CODEC_DATA
    UINT8* pData = new UINT8 [pBuffer->GetSize() + _OVERALLOC_CODEC_DATA];

    if (pData)
    {
	memcpy(pData, pBuffer->GetBuffer(), pBuffer->GetSize()); /* Flawfinder: ignore */

	ulFlags &= (~MDPCKT_USES_IHXBUFFER_FLAG);
	pMediaPacket = new CMediaPacket(pData,
					pData,
					pBuffer->GetSize() + 3,
					pBuffer->GetSize(),
					ulTime,
					ulFlags,
					NULL);
    }
#else	// _OVERALLOC_CODEC_DATA
    pMediaPacket = new CMediaPacket(pBuffer,
				    pBuffer->GetBuffer(),
				    pBuffer->GetSize(),
				    pBuffer->GetSize(),
				    ulTime,
				    ulFlags,
				    NULL);

#endif	// _OVERALLOC_CODEC_DATA

    return pMediaPacket;
}

STDMETHODIMP
MP4APayloadFormat::Flush()
{
    if (m_pLATMDepack)
    {
	m_pLATMDepack->Flush();
    }

    m_bFlushed = TRUE;

    return HXR_OK;
}

void MP4APayloadFormat::FlushPackets(ULONG32 ulCount)
{
    IHXPacket* pDeadPacket;
    CMediaPacket* pDeadMediaPacket;

    while ((ulCount > 0) && (!m_InputPackets.IsEmpty()))
    {
	pDeadPacket = (IHXPacket*) m_InputPackets.RemoveHead();
	HX_RELEASE(pDeadPacket);
	if (ulCount != FLUSH_ALL_PACKETS)
	{
	    ulCount--;
	}
    }

    while ((ulCount > 0) && (!m_OutMediaPacketQueue.IsEmpty()))
    {
	pDeadMediaPacket = (CMediaPacket*) m_OutMediaPacketQueue.RemoveHead();
	HX_DELETE(pDeadMediaPacket);
	if (ulCount != FLUSH_ALL_PACKETS)
	{
	    ulCount--;
	}
    }
}

ULONG32 MP4APayloadFormat::GetPacketTime(IHXPacket* pPacket)
{
    ULONG32 ulTime;

    HX_ASSERT(pPacket);

    if (m_bUsesRTPPackets)
    {
	ulTime = ((IHXRTPPacket*) pPacket)->GetRTPTime();
    }
    else
    {
	ulTime = pPacket->GetTime();
    }

    ulTime = m_TSConverter.Convert(ulTime);

    return ulTime;
}

⌨️ 快捷键说明

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