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 + -
显示快捷键?