amrff.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 914 行 · 第 1/3 页
CPP
914 行
}
// Set some properties
pHdr->SetPropertyULONG32("StreamNumber", 0);
pHdr->SetPropertyULONG32("MaxBitRate", ulAvgBitRate);
pHdr->SetPropertyULONG32("AvgBitRate", ulAvgBitRate);
pHdr->SetPropertyULONG32("MaxPacketSize", AMR_IDEAL_PACKET_SIZE);
pHdr->SetPropertyULONG32("AvgPacketSize", AMR_IDEAL_PACKET_SIZE);
pHdr->SetPropertyULONG32("MinPacketSize", AMR_IDEAL_PACKET_SIZE);
pHdr->SetPropertyULONG32("StartTime", 0);
pHdr->SetPropertyULONG32("Duration", ulDur);
// Pass this stream header into the payload format object
retVal = m_pPayloadFormat->SetStreamHeader(pHdr);
if (SUCCEEDED(retVal))
{
// Create a raw file packet
IHXPacket* pPacket = NULL;
retVal = MakeRawFilePacket(pBuffer, m_ulNextTimeStamp, pPacket);
if (SUCCEEDED(retVal))
{
// Add this packet to the payload object
retVal = m_pPayloadFormat->SetPacket(pPacket);
if (SUCCEEDED(retVal))
{
// Update the next file offset
m_ulNextFileOffset += m_pPayloadFormat->GetPacketBytesConsumed();
// Update the next time stamp
m_ulNextTimeStamp += m_pPayloadFormat->GetDurationConsumed();
// Set the state
m_eState = StateReady;
// Send the stream header
retVal = m_pFormatResponse->StreamHeaderReady(HXR_OK, pHdr);
}
}
HX_RELEASE(pPacket);
}
}
HX_RELEASE(pHdr);
}
}
}
if (FAILED(retVal))
{
// Return to StateReady
m_eState = StateReady;
// Fail out to response interface
retVal = m_pFormatResponse->StreamHeaderReady(retVal, NULL);
}
}
else if (m_eState == StateGetPacketReadDonePending)
{
retVal = status;
if (SUCCEEDED(retVal))
{
// Do we need to scan this buffer for a frame begin?
IHXBuffer* pNewBuffer = NULL;
UINT32 ulNewBufferOffset = 0;
if (m_bScanForFrameBegin)
{
#ifdef DEBUG_TEST_FRAME_SCAN
// Force the first fifth of the buffer to be invalid
memset(pBuffer->GetBuffer(), 0x83, pBuffer->GetSize() / 5);
#endif
// Scan the buffer
UINT32 ulOffset = 0;
BYTE bRet = CAMRFrameInfo::FindFrameBegin((m_bWideBand ? WideBand : NarrowBand),
pBuffer->GetBuffer(),
pBuffer->GetSize(),
AMR_MIN_CONSEC_FRAMES,
ulOffset);
if (bRet)
{
// If the offset is at the beginning
// of the buffer, then we don't have to
// do anything. If the offset is NOT at the
// beginning, then we need to create a new
// buffer and copy the old one into it.
if (ulOffset > 0 && ulOffset < pBuffer->GetSize())
{
// We have a valid offset
retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer,
(void**) &pNewBuffer);
if (SUCCEEDED(retVal))
{
retVal = pNewBuffer->Set(pBuffer->GetBuffer() + ulOffset,
pBuffer->GetSize() - ulOffset);
if (SUCCEEDED(retVal))
{
ulNewBufferOffset = ulOffset;
}
}
}
else if (ulOffset != 0)
{
// Huh? the offset was outside the buffer? Surrender!
retVal = HXR_FAIL;
}
}
else
{
// Yikes! We didn't find a frame in this
// buffer at all? We surrender!
retVal = HXR_FAIL;
}
// Clear the flag
m_bScanForFrameBegin = FALSE;
}
if (SUCCEEDED(retVal))
{
// Create a raw file packet
IHXPacket* pRawPacket = NULL;
retVal = MakeRawFilePacket((pNewBuffer ? pNewBuffer : pBuffer),
m_ulNextTimeStamp, pRawPacket);
if (SUCCEEDED(retVal))
{
// If the buffer was less than we read, then we are
// probably at the end of the file. Therefore, we want
// to process ALL of this buffer, regardless of the
// minimum packet size. So we need to tell the payload
// format object to Flush().
if (pBuffer->GetSize() < AMR_READ_SIZE)
{
m_pPayloadFormat->Flush();
}
// Add this packet to the payload object
retVal = m_pPayloadFormat->SetPacket(pRawPacket);
if (SUCCEEDED(retVal))
{
// Update the next file offset
m_ulNextFileOffset += m_pPayloadFormat->GetPacketBytesConsumed() + ulNewBufferOffset;
// Update the next time stamp
m_ulNextTimeStamp += m_pPayloadFormat->GetDurationConsumed();
// Did we get here from a GetPacket() or a seek
// Now try and get a packet from the payload format object
IHXPacket* pPacket = NULL;
retVal = m_pPayloadFormat->GetPacket(pPacket);
if (SUCCEEDED(retVal))
{
// Set the state
m_eState = StateReady;
// We have a packet to give, so give it
retVal = m_pFormatResponse->PacketReady(retVal, pPacket);
}
HX_RELEASE(pPacket);
}
}
HX_RELEASE(pRawPacket);
}
HX_RELEASE(pNewBuffer);
}
if (FAILED(retVal))
{
// We either got here because of something bad, or because
// we simply got to the end of the file and couldn't read
// any more. Either way, we issue a StreamDone().
//
// Go back to ready
m_eState = StateReady;
// Issue a StreamDone
retVal = m_pFormatResponse->StreamDone(0);
}
}
else
{
retVal = HXR_UNEXPECTED;
}
return retVal;
}
STDMETHODIMP CAMRFileFormat::WriteDone(HX_RESULT status)
{
HX_RESULT retVal = HXR_OK;
return retVal;
}
STDMETHODIMP CAMRFileFormat::CloseDone(HX_RESULT status)
{
HX_RESULT retVal = HXR_OK;
return retVal;
}
STDMETHODIMP CAMRFileFormat::StatDone(HX_RESULT status, UINT32 ulSize, UINT32 ulCreationTime,
UINT32 ulAccessTime, UINT32 ulModificationTime, UINT32 ulMode)
{
HX_RESULT retVal = HXR_UNEXPECTED;
if (m_eState == StateInitFileFormatStatDonePending)
{
// Did we succeed?
if (SUCCEEDED(status))
{
// Save the file size
m_ulFileSize = ulSize;
// Now we are done with the stat interface
HX_RELEASE(m_pFileStat);
}
// Set the state
m_eState = StateReady;
// Call back to response
retVal = m_pFormatResponse->InitDone(status);
}
return retVal;
}
HX_RESULT STDAPICALLTYPE CAMRFileFormat::HXCreateInstance(IUnknown** ppIUnknown)
{
HX_RESULT retVal = HXR_FAIL;
if (ppIUnknown)
{
// Set default
*ppIUnknown = NULL;
// Create the object
CAMRFileFormat *pObj = new CAMRFileFormat();
if (pObj)
{
// QI for IUnknown
retVal = pObj->QueryInterface(IID_IUnknown, (void**) ppIUnknown);
}
if (FAILED(retVal))
{
HX_DELETE(pObj);
}
}
return retVal;
}
HX_RESULT STDAPICALLTYPE CAMRFileFormat::CanUnload2(void)
{
return ((CHXBaseCountingObject::ObjectsActive() > 0) ? HXR_FAIL : HXR_OK);
}
HX_RESULT CAMRFileFormat::GetStreamInfo(IHXBuffer* pBuffer,
UINT32 ulOffset,
REF(UINT32) rulAvgBitRate,
REF(UINT32) rulBytesPerFrame)
{
HX_RESULT retVal = HXR_OK;
if (pBuffer && ulOffset < pBuffer->GetSize())
{
BYTE* pBuf = pBuffer->GetBuffer() + ulOffset;
BYTE* pBufLimit = pBuffer->GetBuffer() + pBuffer->GetSize();
UINT32 ulByteSum = 0;
UINT32 ulMSSum = 0;
UINT32 ulNumFr = 0;
CAMRFrameHdr cHdr((m_bWideBand ? WideBand : NarrowBand));
while (1)
{
if (pBuf + cHdr.HdrBytes() >= pBufLimit)
{
break;
}
cHdr.Unpack(pBuf);
if(pBuf + cHdr.DataBytes() >= pBufLimit)
{
break;
}
pBuf += cHdr.DataBytes();
ulByteSum += cHdr.DataBytes() + cHdr.HdrBytes();
ulMSSum += CAMRFrameInfo::FrameDuration();
ulNumFr++;
}
if (ulNumFr) rulBytesPerFrame = ulByteSum / ulNumFr;
if (ulMSSum) rulAvgBitRate = ulByteSum * 8000 / ulMSSum;
}
else
{
retVal = HXR_FAIL;
}
return retVal;
}
HX_RESULT CAMRFileFormat::MakeRawFilePacket(IHXBuffer* pBuffer, UINT32 ulTimeStamp,
REF(IHXPacket*) rpPacket)
{
HX_RESULT retVal = HXR_FAIL;
if (pBuffer && m_pCommonClassFactory)
{
IHXPacket* pPacket = NULL;
retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXPacket, (void**) &pPacket);
if (SUCCEEDED(retVal))
{
retVal = pPacket->Set(pBuffer, ulTimeStamp, 0, HX_ASM_SWITCH_ON, 0);
if (SUCCEEDED(retVal))
{
HX_RELEASE(rpPacket);
rpPacket = pPacket;
rpPacket->AddRef();
}
}
HX_RELEASE(pPacket);
}
return retVal;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?