mp4gpyld.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,691 行 · 第 1/3 页
CPP
1,691 行
{
HX_RESULT retVal = HXR_FAIL;
if (m_pStreamHeader)
{
retVal = HXR_OK;
pHeader = m_pStreamHeader;
pHeader->AddRef();
}
return retVal;
}
STDMETHODIMP
MP4GPayloadFormat::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;
}
HX_ASSERT(m_ulSamplesPerSecond != 0);
}
else
{
m_ulRTPSamplesPerSecond = 1000; // RDT time stamp
}
m_TSConverter.SetBase(m_ulRTPSamplesPerSecond,
m_ulSamplesPerSecond);
}
if (m_bPacketize)
{
retVal = SetPacketizerPacket(pPacket);
}
else
{
retVal = SetAssemblerPacket(pPacket);
}
if (retVal == HXR_OK)
{
// Add this packet to our list of input packets
pPacket->AddRef();
m_InputQueue.AddTail(pPacket);
}
else if (retVal == HXR_NO_DATA)
{
retVal = HXR_OK;
}
return retVal;
}
HX_RESULT MP4GPayloadFormat::SetPacketizerPacket(IHXPacket* pPacket)
{
return HXR_NOTIMPL;
}
HX_RESULT MP4GPayloadFormat::SetAssemblerPacket(IHXPacket* pPacket)
{
ULONG32 ulPacketTime;
HX_RESULT retVal = HXR_NO_DATA;
if (!pPacket->IsLost())
{
ulPacketTime = GetPacketTime(pPacket);
if (m_bStartPacket)
{
m_bStartPacket = FALSE;
m_ulLastPacketTime = ulPacketTime;
}
else if (ulPacketTime != m_ulLastPacketTime)
{
m_ulFrameCount++;
m_ulLastPacketTime = ulPacketTime;
}
if (pPacket->GetASMRuleNumber() == 1)
{
m_ulFrameCount++;
m_bStartPacket = TRUE;
}
retVal = HXR_OK;
}
return retVal;
}
STDMETHODIMP
MP4GPayloadFormat::GetPacket(REF(IHXPacket*) pOutPacket)
{
HX_RESULT retVal = HXR_OK;
if (m_bPacketize)
{
retVal = GetPacketizerPacket(pOutPacket);
}
else
{
retVal = GetAssemblerPacket(pOutPacket);
}
return retVal;
}
HX_RESULT MP4GPayloadFormat::GetPacketizerPacket(IHXPacket* &pOutPacket)
{
HX_RESULT retVal = HXR_NOTIMPL;
return retVal;
}
HX_RESULT MP4GPayloadFormat::GetAssemblerPacket(IHXPacket* &pOutPacket)
{
HX_RESULT retVal = HXR_NOTIMPL;
return retVal;
}
HX_RESULT MP4GPayloadFormat::CreateMediaPacket(CMediaPacket* &pOutMediaPacket)
{
HX_RESULT retVal = HXR_OK;
CMediaPacket* pMediaPacket;
pMediaPacket = StripPacket();
if (!pMediaPacket)
{
retVal = ProducePackets();
if (retVal == HXR_OK)
{
pMediaPacket = StripPacket();
}
else if ((retVal == HXR_NO_DATA) &&
m_bFlushed)
{
retVal = HXR_STREAM_DONE;
}
}
if (retVal == HXR_OK)
{
pOutMediaPacket = pMediaPacket;
}
return retVal;
}
HX_RESULT MP4GPayloadFormat::SetSamplingRate(ULONG32 ulSamplesPerSecond)
{
HX_RESULT retVal = HXR_UNEXPECTED;
if (!m_bRTPPacketTested)
{
m_ulSamplesPerSecond = ulSamplesPerSecond;
retVal = HXR_OK;
}
return retVal;
}
ULONG32 MP4GPayloadFormat::GetTimeBase(void)
{
return m_ulSamplesPerSecond;
}
HX_RESULT MP4GPayloadFormat::SetAUDuration(ULONG32 ulAUDuration)
{
HX_RESULT retVal = HXR_OK;
if (m_Config.m_ulConstantDuration == 0)
{
CTSConverter tempConverter;
tempConverter.SetBase(m_ulSamplesPerSecond, m_ulRTPSamplesPerSecond);
m_ulAUDuration = tempConverter.ConvertVector(ulAUDuration);
}
return retVal;
}
HX_RESULT MP4GPayloadFormat::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;
}
CMediaPacket* MP4GPayloadFormat::StripPacket(void)
{
CMediaPacket* pMediaPacket = NULL;
if (!m_OutputQueue.IsEmpty())
{
pMediaPacket = (CMediaPacket*) m_OutputQueue.RemoveHead();
}
return pMediaPacket;
}
HX_RESULT MP4GPayloadFormat::ProducePackets(void)
{
BOOL bTryAgain;
HX_RESULT retVal = HXR_OK;
do
{
bTryAgain = FALSE;
retVal = CollectPacketFragments(m_pPacketFragments, // out
m_ulNumPacketFragments, // out
m_ulMaxPacketFragments);// out
if (retVal == HXR_OK)
{
retVal = ParsePacketFragments(m_pAUFragments, // out
m_ulNumAUFragments, // out
m_ulMaxAUFragments, // in/out
m_pPacketFragments, // in
m_ulNumPacketFragments); // in
if (retVal == HXR_OK)
{
retVal = AggregateAUFragments(m_pAUPackets, // out
m_ulNumAUPackets, // out
m_ulMaxAUPackets, // in/out
m_pAUFragments, // in
m_ulNumAUFragments); // in
}
bTryAgain = (retVal != HXR_OK);
if (retVal == HXR_OK)
{
retVal = DeinterleaveAUPackets(m_pAUPackets,
m_ulNumAUPackets);
}
}
} while (bTryAgain);
if (SUCCEEDED(retVal))
{
retVal = ReapMediaPacket(m_ulLastPacketTime);
}
return retVal;
}
HX_RESULT MP4GPayloadFormat::CollectPacketFragments(IHXPacket** &pPacketFragments,
ULONG32 &ulNumPacketFragments,
ULONG32 &ulMaxPacketFragments)
{
ULONG32 ulPacketTime;
IHXPacket* pPacket;
HX_RESULT retVal = HXR_NO_DATA;
FlushPacketArray(pPacketFragments, ulNumPacketFragments);
if (m_ulFrameCount != 0)
{
pPacket = (IHXPacket*) m_InputQueue.RemoveHead();
pPacketFragments[ulNumPacketFragments++] = pPacket;
if (pPacket->GetASMRuleNumber() == 0)
{
ulPacketTime = GetPacketTime(pPacket);
pPacket = (IHXPacket*) m_InputQueue.GetHead();
while (GetPacketTime(pPacket) == ulPacketTime)
{
pPacket = (IHXPacket*) m_InputQueue.RemoveHead();
pPacketFragments[ulNumPacketFragments++] = pPacket;
if (pPacket->GetASMRuleNumber() != 0)
{
// the last fragment carries the M(arker) bit, which is
// signalled by a rule != 0
break;
}
pPacket = (IHXPacket*) m_InputQueue.GetHead();
}
}
HX_ASSERT(ulNumPacketFragments <= ulMaxPacketFragments);
m_ulFrameCount--;
retVal = HXR_OK;
}
return retVal;
}
HX_RESULT MP4GPayloadFormat::ParsePacketFragments(CAUPacket** &pAUFragments,
ULONG32 &ulNumAUFragments,
ULONG32 &ulMaxAUFragments,
IHXPacket** pPacketFragments,
ULONG32& ulNumPacketFragments)
{
HX_RESULT retVal;
ULONG32 ulIdx = 0;
FlushAUArray(pAUFragments, ulNumAUFragments);
do
{
retVal = ParsePacketFragment(pAUFragments,
ulNumAUFragments,
ulMaxAUFragments,
pPacketFragments[ulIdx]);
pPacketFragments[ulIdx]->Release();
pPacketFragments[ulIdx] = NULL;
ulIdx++;
} while ((retVal == HXR_OK) && (ulIdx < ulNumPacketFragments));
if (ulIdx >= ulNumPacketFragments)
{
ulNumPacketFragments = 0;
}
return retVal;
}
HX_RESULT MP4GPayloadFormat::ParsePacketFragment(CAUPacket** &pAUFragments,
ULONG32 &ulNumAUFragments,
ULONG32 &ulMaxAUFragments,
IHXPacket* pPacketFragment)
{
ULONG32 ulFirstAUFragment = ulNumAUFragments;
ULONG32 ulStartCTS = GetPacketTime(pPacketFragment);
ULONG32 ulCTS = ulStartCTS;
ULONG32 ulDTS = ulCTS;
ULONG32 ulIdx = 0;
ULONG32 ulBaseIdx = 0;
ULONG32 ulVal = 0;
ULONG32 ulAUHdrStart = 0;
ULONG32 ulAUHdrLength = 0; // in bits
ULONG32 ulAUHdrSize = 0; // in bytes
ULONG32 ulAuxStart = 0;
ULONG32 ulAuxLength = 0; // in bits
ULONG32 ulAuxSize = 0; // in bytes
ULONG32 ulAUStart = 0;
ULONG32 ulAUSizeSum = 0;
ULONG32 ulAUSize = 0;
ULONG32 ulFixedSizeAUCount = 0;
IHXBuffer* pBuffer = NULL;
UINT8* pData = NULL;
LD bitInfo;
CAUPacket* pAUPacket = 0;
BOOL bFirstAU = TRUE;
HX_RESULT retVal = HXR_FAIL;
HX_ASSERT(pPacketFragment);
pBuffer = pPacketFragment->GetBuffer();
if (pBuffer)
{
pData = pBuffer->GetBuffer();
if (pData)
{
retVal = HXR_OK;
}
pBuffer->Release();
}
if (retVal == HXR_OK)
{
// AU-headers-length
if (m_Config.m_bHasAUHeaders)
{
ulAUHdrLength = (pData[0] << 8) + (pData[1]);
ulAUHdrSize = ulAUHdrLength / 8;
if ((ulAUHdrSize * 8) != ulAUHdrLength)
{
ulAUHdrSize++;
}
ulAUHdrStart += 2;
}
if (ulAUHdrLength > 0)
{
// AU headers are present
initbuffer(pData + ulAUHdrStart, &bitInfo);
// AU-headers
do
{
pAUPacket = new CAUPacket;
if (!pAUPacket)
{
retVal = HXR_OUTOFMEMORY;
break;
}
// Buffer
pAUPacket->m_pBuffer = pBuffer;
pBuffer->AddRef();
// Data
pAUPacket->m_pData = pData + ulAUSizeSum;
// AU - size
if (m_Config.m_ulSizeLength > 0)
{
pAUPacket->m_ulSize = getbits(m_Config.m_ulSizeLength, &bitInfo);
}
else
{
pAUPacket->m_ulSize = m_Config.m_ulConstantSize;
}
ulAUSizeSum += pAUPacket->m_ulSize;
// AU - index
if (bFirstAU)
{
bFirstAU = FALSE;
pAUPacket->m_bMinTime = FALSE;
if (m_Config.m_ulIndexLength > 0)
{
ulIdx = getbits(m_Config.m_ulIndexLength,
&bitInfo);
}
else
{
ulIdx = 0;
}
ulBaseIdx = ulIdx;
}
else
{
pAUPacket->m_bMinTime = TRUE;
if (m_Config.m_ulIndexDeltaLength > 0)
{
ulIdx += getbits(m_Config.m_ulIndexDeltaLength,
&bitInfo);
}
ulIdx++;
}
pAUPacket->m_ulIdx = ulIdx;
// CTS
ulVal = 0;
if ((m_Config.m_ulCTSDeltaLength > 0) &&
getbits1(&bitInfo))
{
ulVal = getbits(m_Config.m_ulCTSDeltaLength, &bitInfo);
ulVal = SignBitField(ulVal, m_Config.m_ulCTSDeltaLength);
ulVal = m_TSConverter.ConvertVector(ulVal);
pAUPacket->m_bMinTime = FALSE;
}
else
{
ulVal = (ulIdx - ulBaseIdx) * m_TSConverter.ConvertVector(m_ulAUDuration);
pAUPacket->m_bMinTime = (pAUPacket->m_bMinTime &&
(ulVal == 0));
}
ulCTS = ulStartCTS + ulVal;
pAUPacket->m_ulCTS = ulCTS;
// DTS
ulVal = 0;
if (m_Config.m_ulDTSDeltaLength > 0)
{
if (getbits1(&bitInfo))
{
ulVal = getbits(m_Config.m_ulDTSDeltaLength, &bitInfo);
// can be negative value
if (ulVal >> (m_Config.m_ulDTSDeltaLength - 1))
{
ulVal |= (~((1 << m_Config.m_ulDTSDeltaLength) - 1));
}
ulVal = m_TSConverter.ConvertVector(ulVal);
}
}
ulDTS = ulCTS + ulVal;
pAUPacket->m_ulDTS = ulDTS;
pAUFragments[ulNumAUFragments++] = pAUPacket;
} while (ulAUHdrLength > ((ULONG32) bitInfo.bitcnt) && ulMaxAUFragments > ulNumAUFragments);
}
}
if (retVal == HXR_OK)
{
// auxiliary data length
ulAuxStart = ulAUHdrStart + ulAUHdrSize;
ulAuxLength = m_Config.m_ulAuxDataSizeLength;
if (ulAuxLength > 0)
{
initbuffer(pData + ulAuxStart, &bitInfo);
ulAuxLength += getbits(ulAuxLength, &bitInfo);
}
ulAuxSize = ulAuxLength / 8;
if ((ulAuxSize * 8) != ulAuxLength)
{
ulAuxSize++;
}
ulAUStart = ulAuxStart + ulAuxSize;
if (ulAUHdrSize > 0)
{
// AU Headers were present and locations of AUs is
// known - just offset the AU location for inserted
// auxiliary data
for (ulIdx = ulFirstAUFragment; ulIdx < ulNumAUFragments; ulIdx++)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?