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