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

📄 mpapayld.cpp

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

	// Set the 4-Byte audio header for this packet 
	// (as dictated by RFC 2250)
	putshort(pBuf, 0);
	pBuf += 2;
	putshort(pBuf, 0);
	pBuf += 2;

	// Copy the data from the input packet list 
	// into the new packet buffer
	CopyInput(pBuf, ulBufSize - 4);

	// Finalize the new packet
	pNewPacket->Set(pNewBuffer, ulNewTimestamp, 
	    (UINT16)m_ulStreamNum, HX_ASM_SWITCH_ON, 0);
	HX_RELEASE(pNewBuffer);

	pPacket = pNewPacket;
    }

    return hResult;
}

HX_RESULT
MPAPayloadFormat::CreateFragmentedPacket(REF(IHXPacket*) pPacket)
{
    HX_RESULT hResult = HXR_OK;
    UINT32 ulBufSize = 0;
    UCHAR* pBuf = NULL;
    IHXPacket* pNewPacket = NULL;
    IHXBuffer* pNewBuffer = NULL;

    // Figure out how much we want to put in this packet, based on the
    // frame size, frame offset, and max packet size
    ulBufSize = m_ulFrameSize - m_ulFrameOffset;
    if (ulBufSize > m_ulMaxPacketSize)
    {
	ulBufSize = m_ulMaxPacketSize;
    }

    if ((m_ulInputSize < ulBufSize) && 
	!m_bFlushed)
    {
	// We don't have enough input 
	// data to produce a full packet
	hResult = HXR_INCOMPLETE;
    }
    else
    {
	// Create a new packet
	m_pClassFactory->CreateInstance(CLSID_IHXPacket, 
	    (void**)&pNewPacket);

	// Create a new buffer
	m_pClassFactory->CreateInstance(CLSID_IHXBuffer, 
	    (void**)&pNewBuffer);

	// Figure out what the timestamp should be
	UINT32 ulNewTimestamp = GetNextTimestamp();

	// Set the size of the buffer appropriately
	if (m_ulInputSize < ulBufSize)
	{
	    // We must have been flushed, so fill the packet
	    // with whatever remaining data we have
	    HX_ASSERT(m_bFlushed);
	    ulBufSize = m_ulInputSize;
	}
	ulBufSize += 4;

	pNewBuffer->SetSize(ulBufSize);
	pBuf = pNewBuffer->GetBuffer();

	// Set the 4-Byte audio header for this packet 
	// (as dictated by RFC 2250)
	putshort(pBuf, 0);
	pBuf += 2;
	putshort(pBuf, (UINT16)m_ulFrameOffset);
	pBuf += 2;

	// Update the current frame offset
	m_ulFrameOffset += ulBufSize - 4;
	if (m_ulFrameOffset == m_ulFrameSize)
	{
	    // We finished a frame, so reset our offset
	    m_ulFrameOffset = 0;
	}

	// Copy the data from the input packet list 
	// into the new packet buffer
	CopyInput(pBuf, ulBufSize - 4);

	// Finalize the new packet
	pNewPacket->Set(pNewBuffer, ulNewTimestamp, 
	    (UINT16)m_ulStreamNum, HX_ASM_SWITCH_ON, 0);
	HX_RELEASE(pNewBuffer);

	pPacket = pNewPacket;
    }

    return hResult;
}

HX_RESULT
MPAPayloadFormat::UnformatRTPPacket(REF(IHXPacket*) pPacket)
{
    HX_RESULT hResult = HXR_OK;
    BOOL bDone = FALSE;

    while (!bDone)
    {
	if (m_pPartialPacket)
	{
	    // We've already unformatted part of an audio frame,
	    // so grab then next packet and add it to the end
	    hResult = UnformatNextPacket(pPacket, bDone);
	}
	else
	{
	    // We don't have any partially unformatted data,
	    // so just grab the first packet and deal with it
	    hResult = UnformatFirstPacket(pPacket, bDone);
	}
    }

    return hResult;
}

HX_RESULT
MPAPayloadFormat::UnformatFirstPacket(REF(IHXPacket*) pPacket, 
				      REF(BOOL) bDone)
{
    IHXPacket* pNextPacket = NULL;
    IHXBuffer* pNextBuffer = NULL;
    bDone = FALSE;

    // Get the next input packet
    pNextPacket = (IHXPacket*)m_pInputPackets->RemoveHead();
    HX_ASSERT(pNextPacket);

    // If this is a lost packet, give it
    // straight back to the caller
    if (pNextPacket->IsLost())
    {
	pPacket = pNextPacket;
	bDone = TRUE;
	return HXR_OK;
    }

    pNextBuffer = pNextPacket->GetBuffer();
    HX_ASSERT(pNextBuffer);

    // Create a new packet
    m_pClassFactory->CreateInstance(CLSID_IHXPacket, 
	(void**)&m_pPartialPacket);
    HX_ASSERT(m_pPartialPacket);

    // Create a new buffer
    m_pClassFactory->CreateInstance(CLSID_IHXBuffer, 
	(void**)&m_pPartialBuffer);
    HX_ASSERT(m_pPartialBuffer);

    // Add this onto the new packet
    m_pPartialBuffer->SetSize(pNextBuffer->GetSize() - 4);
    memcpy(m_pPartialBuffer->GetBuffer(), /* Flawfinder: ignore */
	   pNextBuffer->GetBuffer() + 4, 
	   pNextBuffer->GetSize() - 4);

    // Set all properties except buffer from this packet
    m_pPartialPacket->Set(m_pPartialBuffer, 
			  pNextPacket->GetTime(), 
			  pNextPacket->GetStreamNumber(), 
			  pNextPacket->GetASMFlags(), 
			  pNextPacket->GetASMRuleNumber());

    // Find out if this packet contains an integral number
    // of full frames or a fragment of a single large frame
    UINT32 ulOffset = GetFrameOffset(pNextBuffer);
    if (!ulOffset && !m_ulFrameSize)
    {
	UINT32 ulBytesSkipped = 0;

	m_ulFrameSize = GetFrameSize(pNextBuffer->GetBuffer() + 4,
	    pNextBuffer->GetSize() - 4, ulBytesSkipped);
	HX_ASSERT(m_ulFrameSize);

	if (ulBytesSkipped)
	{
	    // If we had to skip any Bytes to find the header
	    // info, discard those leading Bytes as garbage
	    m_ulInputUsed = ulBytesSkipped;
	    m_ulInputSize -= ulBytesSkipped;
	}
    }

    if (ulOffset)
    {
	// We must have lost the previous packet in this
	// frame, so toss out the rest for now
	//
	// XXXDPS - If we can actually make some use of a
	// partial audio frame, we may want to do something
	// more intelligent here...
	HX_RELEASE(m_pPartialBuffer);
	HX_RELEASE(m_pPartialPacket);

	bDone = FALSE;
    }
    else
    {
	if (m_ulFrameSize <= (pNextBuffer->GetSize() - 4))
	{
	    // The packet contains an integral number of full frames

	    // Return the packet we've constructed
	    pPacket = m_pPartialPacket;
	    pPacket->AddRef();

	    HX_RELEASE(m_pPartialBuffer);
	    HX_RELEASE(m_pPartialPacket);

	    bDone = TRUE;
	}
	else
	{
	    // The packet contains the first fragment of a large
	    // frame that spans several packets

	    // We will keep looping and adding data to this buffer
	    // until we have constructed an entire frame of audio...
	}
    }

    HX_RELEASE(pNextBuffer);
    HX_RELEASE(pNextPacket);

    return HXR_OK;
}

HX_RESULT
MPAPayloadFormat::UnformatNextPacket(REF(IHXPacket*) pPacket, 
				     REF(BOOL) bDone)
{
    HX_RESULT hResult = HXR_OK;
    IHXPacket* pNextPacket = NULL;
    IHXBuffer* pNextBuffer = NULL;
    bDone = FALSE;

    if (m_pInputPackets->IsEmpty())
    {
	if (!m_bFlushed)
	{
	    // We don't have enough input 
	    // data to produce a full packet
	    hResult = HXR_INCOMPLETE;
	}
	else
	{
	    // Return the (partial) packet we've constructed
	    pPacket = m_pPartialPacket;
	    pPacket->AddRef();

	    HX_RELEASE(m_pPartialBuffer);
	    HX_RELEASE(m_pPartialPacket);
	}
	bDone = TRUE;
    }
    else
    {
	// Get the next input packet
	pNextPacket = (IHXPacket*)m_pInputPackets->RemoveHead();
	HX_ASSERT(pNextPacket);

	if (pNextPacket->IsLost())
	{
	    // If the packet is a lost packet, discard any
	    // partial packet we may have been building and
	    // forward this lost packet back to the caller
	    pPacket = pNextPacket;
	    pPacket->AddRef();

	    HX_RELEASE(m_pPartialBuffer);
	    HX_RELEASE(m_pPartialPacket);

	    bDone = TRUE;
	}
	else
	{
	    pNextBuffer = pNextPacket->GetBuffer();
	    HX_ASSERT(pNextBuffer);

	    // Add the data from this packet onto our cumulative buffer

	    // Temporarily Release() our references on the buffer, since
	    // m_pPartialPacket has a reference on it and we can't set a
	    // buffer with 2 references. We will re-AddRef() it in a sec.
	    m_pPartialBuffer->Release();

	    UINT32 ulPrevSize = m_pPartialBuffer->GetSize();

	    m_pPartialBuffer->SetSize(ulPrevSize + 
		pNextBuffer->GetSize() - 4);

	    memcpy(m_pPartialBuffer->GetBuffer() + ulPrevSize, /* Flawfinder: ignore */
		   pNextBuffer->GetBuffer() + 4,
		   pNextBuffer->GetSize() - 4);

	    // Re-AddRef() the buffer now that we have set it
	    m_pPartialBuffer->AddRef();

	    m_pPartialPacket->Set(m_pPartialBuffer, 
				  m_pPartialPacket->GetTime(), 
				  m_pPartialPacket->GetStreamNumber(), 
				  m_pPartialPacket->GetASMFlags(), 
				  m_pPartialPacket->GetASMRuleNumber());

	    if (m_pPartialBuffer->GetSize() >= m_ulFrameSize)
	    {
		// Return the (full) packet we've constructed
		pPacket = m_pPartialPacket;
		pPacket->AddRef();

		HX_RELEASE(m_pPartialBuffer);
		HX_RELEASE(m_pPartialPacket);

		bDone = TRUE;
	    }

	    HX_RELEASE(pNextBuffer);
	}
	HX_RELEASE(pNextPacket);
    }

    return hResult;
}

HX_RESULT
MPAPayloadFormat::CreateLostPacket(IHXPacket* pOldPacket, 
				   REF(IHXPacket*) pNewPacket)
{
    // Create a new packet
    m_pClassFactory->CreateInstance(CLSID_IHXPacket, 
	(void**)&pNewPacket);
    HX_ASSERT(pNewPacket);

    // Set all properties except buffer and time from
    // the old packet
    pNewPacket->Set(NULL, 
		    0, 
		    pOldPacket->GetStreamNumber(), 
		    pOldPacket->GetASMFlags(), 
		    pOldPacket->GetASMRuleNumber());

    pNewPacket->SetAsLost();

    return HXR_OK;
}

UINT32
MPAPayloadFormat::GetNextTimestamp()
{
    if (m_pInputPackets->IsEmpty())
    {
	return 0;
    }
    else
    {
	IHXPacket* pPacket = (IHXPacket*)m_pInputPackets->GetHead();
	HX_ASSERT(pPacket);

	return pPacket->GetTime();
    }
}

void
MPAPayloadFormat::CopyInput(UCHAR* pDest, UINT32 ulSize)
{
    UINT32 ulBytesCopied = 0;

    while (ulBytesCopied < ulSize)
    {
	IHXPacket* pPacket = (IHXPacket*)m_pInputPackets->RemoveHead();
	HX_ASSERT(pPacket);

	IHXBuffer* pBuffer = pPacket->GetBuffer();
	HX_ASSERT(pBuffer);

	UCHAR* pSrc = pBuffer->GetBuffer();
	HX_ASSERT(pSrc);

	UINT32 ulSrcSize = pBuffer->GetSize();
	HX_ASSERT(ulSrcSize);

	// Offset the input buffer based on 
	// how much we have previously used
	pSrc += m_ulInputUsed;
	ulSrcSize -= m_ulInputUsed;

	if (ulSrcSize < ulSize - ulBytesCopied)
	{
	    memcpy(pDest, pSrc, ulSrcSize); /* Flawfinder: ignore */
	    pDest += ulSrcSize;
	    ulBytesCopied += ulSrcSize;

	    m_ulInputUsed = 0;
	}
	else if (ulSrcSize > ulSize - ulBytesCopied)
	{
	    // This packet is more than big enough
	    // to fill our requested size
	    UINT32 ulBytesToCopy = ulSize - ulBytesCopied;

	    memcpy(pDest, pSrc, ulBytesToCopy); /* Flawfinder: ignore */
	    pDest += ulBytesToCopy;
	    ulBytesCopied += ulBytesToCopy;

	    // Add this packet back onto the list
	    pPacket->AddRef();
	    m_pInputPackets->AddHead(pPacket);

	    // Remember how much of it we have used
	    m_ulInputUsed += ulBytesToCopy;
	}
	else
	{
	    // An exact match!
	    memcpy(pDest, pSrc, ulSrcSize); /* Flawfinder: ignore */
	    pDest += ulSrcSize;
	    ulBytesCopied += ulSrcSize;

	    m_ulInputUsed = 0;
	}

	HX_RELEASE(pBuffer);
	HX_RELEASE(pPacket);
    }

    m_ulInputSize -= ulBytesCopied;
}

⌨️ 快捷键说明

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