pxgifff.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,531 行 · 第 1/4 页
CPP
1,531 行
HX_VECTOR_DELETE(m_plImageStartTime);
m_plImageStartTime = new INT32 [lNumImages];
if (!m_plImageStartTime)
{
return m_pFormatResponse->StreamHeaderReady(HXR_FAIL, NULL);
}
// Initially we fill these times with the time the image has to be displayed
INT32 i;
INT32 lRunningSum = 0;
for (i = 0; i < lNumImages; i++)
{
m_plImageStartTime[i] = lRunningSum;
lRunningSum += (INT32) m_pGIFCodec->GetDelayTime(i) * 10;
}
// Now we go from last image to first, adjusting times
UINT32 ulTotalBytesToSend = 0;
INT32 lLastStartTime = m_plImageStartTime[lNumImages - 1];
for (i = m_pGIFCodec->GetNumImages() - 1; i >= 0; i--)
{
INT32 lTransmitSize = m_pGIFCodec->GetImageDataSize(i); // Actual bytes to transmit
INT32 lOverheadSize = ((lTransmitSize / 500) + 1) * 24; // This is an estimate of packet overhead
INT32 lTransmitTime = ((lTransmitSize + lOverheadSize) * 8000 / m_ulBitRate) + 1; // transmit time in milliseconds
if (lLastStartTime < m_plImageStartTime[i])
{
m_plImageStartTime[i] = lLastStartTime - lTransmitTime;
}
else
{
m_plImageStartTime[i] -= lTransmitTime;
}
lLastStartTime = m_plImageStartTime[i];
ulTotalBytesToSend += (UINT32) lTransmitSize;
}
// Now the min preroll should be the negative of the first start time
if (m_plImageStartTime[0] >= 0)
{
return m_pFormatResponse->StreamHeaderReady(HXR_FAIL, NULL);
}
UINT32 ulMinPreroll = (UINT32) -m_plImageStartTime[0];
// Resolve this with the requested preroll
if (m_ulPreroll < ulMinPreroll)
{
m_ulPreroll = ulMinPreroll;
}
// Compute predata bytes
ulPreDataBytes = m_ulBitRate * m_ulPreroll / 8000;
if (ulPreDataBytes > ulTotalBytesToSend)
{
ulPreDataBytes = ulTotalBytesToSend;
}
}
// Create an IHXValues object
IHXValues *pStreamHeader = NULL;
HX_RESULT retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXValues, (void **) &pStreamHeader);
if (retVal != HXR_OK)
{
return m_pFormatResponse->StreamHeaderReady(retVal, NULL);
}
// Set the mime type
char* pszStreamMimeType = (char*) m_pszStreamMimeType;
if (m_bParseFailed)
{
pszStreamMimeType = (char*) m_pszBadStreamMimeType;
}
// Create buffer to hold MIME type
IHXBuffer *pMimeType = NULL;
retVal = PXUtilities::CreateStringBuffer(pszStreamMimeType,
m_pContext,
pMimeType);
if (retVal != HXR_OK)
{
HX_RELEASE(pStreamHeader);
return m_pFormatResponse->StreamHeaderReady(retVal, NULL);
}
// Generate an ASM rule book
char szASMRuleBook[256]; /* Flawfinder: ignore */
if (m_bReliable)
{
sprintf(szASMRuleBook, "AverageBandwidth=%ld,Priority=10;", m_ulBitRate); /* Flawfinder: ignore */
}
else
{
sprintf(szASMRuleBook, /* Flawfinder: ignore */
"AverageBandwidth=%ld,Priority=5;AverageBandwidth=%ld,Priority=9;",
m_ulBitRate, 0);
}
// Create buffer to hold ASM rules
IHXBuffer *pASMRuleBook = NULL;
retVal = PXUtilities::CreateStringBuffer((const char*) szASMRuleBook,
m_pContext,
pASMRuleBook);
if (retVal != HXR_OK)
{
HX_RELEASE(pStreamHeader);
HX_RELEASE(pMimeType);
return m_pFormatResponse->StreamHeaderReady(retVal, NULL);
}
// Create buffer to hold intrinsic duration type string
const char* pszIntrinsicDur = NULL;
if (m_pGIFCodec->GetNumImages() == 1 &&
m_pGIFCodec->GetDelayTimeSum() == 0)
{
pszIntrinsicDur = "intrinsicDurationDiscrete";
}
else
{
pszIntrinsicDur = "intrinsicDurationContinuous";
}
IHXBuffer* pIntrinsicDur = NULL;
retVal = PXUtilities::CreateStringBuffer(pszIntrinsicDur,
m_pContext,
pIntrinsicDur);
if (retVal != HXR_OK)
{
HX_RELEASE(pStreamHeader);
HX_RELEASE(pMimeType);
HX_RELEASE(pASMRuleBook);
return m_pFormatResponse->StreamHeaderReady(retVal, NULL);
}
// Create buffer to hold opaque data
IHXBuffer *pOpaqueData = NULL;
retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, (void **) &pOpaqueData);
if (retVal != HXR_OK)
{
HX_RELEASE(pStreamHeader);
HX_RELEASE(pMimeType);
HX_RELEASE(pASMRuleBook);
HX_RELEASE(pIntrinsicDur);
return m_pFormatResponse->StreamHeaderReady(retVal, NULL);
}
// Fill in the Header with the parameters
pStreamHeader->SetPropertyULONG32("StreamNumber", 0);
pStreamHeader->SetPropertyULONG32("MaxBitRate", m_ulBitRate);
pStreamHeader->SetPropertyULONG32("AvgBitRate", m_ulBitRate);
pStreamHeader->SetPropertyULONG32("MaxPacketSize", 600);
pStreamHeader->SetPropertyULONG32("AvgPacketSize", 500);
pStreamHeader->SetPropertyULONG32("StartTime", 0);
pStreamHeader->SetPropertyULONG32("Preroll", m_ulPreroll);
pStreamHeader->SetPropertyULONG32("PreData", ulPreDataBytes);
pStreamHeader->SetPropertyULONG32("PreDataAtStart", 1);
pStreamHeader->SetPropertyULONG32("PreRollAtStart", 0);
pStreamHeader->SetPropertyULONG32("PreDataAfterSeek", 0);
pStreamHeader->SetPropertyULONG32("PreRollAfterSeek", 1);
pStreamHeader->SetPropertyULONG32("Duration", m_ulDuration);
pStreamHeader->SetPropertyULONG32("ContentVersion", m_ulContentVersion);
pStreamHeader->SetPropertyCString("MimeType", pMimeType);
pStreamHeader->SetPropertyCString("ASMRuleBook", pASMRuleBook);
pStreamHeader->SetPropertyCString("intrinsicDurationType", pIntrinsicDur);
// The mediaRepeat attribute says whether or not to strip the native
// repeat value from the media. We need support for mediaRepeat in
// the GIF renderer for this to work. Therefore, if mediaRepeat specified,
// then we also need to bump the stream version.
UINT32 ulStreamVersion = m_ulStreamVersion;
if (m_pMediaRepeatStr)
{
pStreamHeader->SetPropertyCString("mediaRepeat", m_pMediaRepeatStr);
ulStreamVersion = MEDREP_GIFSTREAM_VERSION;
}
// Now set the stream version
pStreamHeader->SetPropertyULONG32("StreamVersion", ulStreamVersion);
// Make a renderer flags property
UINT32 ulRendererFlags = 0;
if (m_bParseFailed)
{
ulRendererFlags |= GIF_RENDERER_FLAG_PARSEFAILED;
if (m_pGIFCodec)
{
pStreamHeader->SetPropertyULONG32("Width", m_pGIFCodec->GetLogicalScreenWidth());
pStreamHeader->SetPropertyULONG32("Height", m_pGIFCodec->GetLogicalScreenHeight());
}
}
pStreamHeader->SetPropertyULONG32("RendererFlags", ulRendererFlags);
// Ask the GIF Codec how big the header is
UINT32 ulLength = 0;
if (m_pGIFCodec && !m_bParseFailed)
{
retVal = m_pGIFCodec->GetPacketBufferLength(ulLength);
if (retVal != HXR_OK)
{
HX_RELEASE(pMimeType);
HX_RELEASE(pASMRuleBook);
HX_RELEASE(pOpaqueData);
HX_RELEASE(pStreamHeader);
HX_RELEASE(pIntrinsicDur);
return m_pFormatResponse->StreamHeaderReady(retVal, NULL);
}
}
// Set the opaque data buffer to this length plus a bit more
UINT32 ulExtraDataSize = 12 + (m_pURL ? m_pURL->GetLength() : 0) + 1;
retVal = pOpaqueData->SetSize(ulLength + ulExtraDataSize);
if (retVal != HXR_OK)
{
HX_RELEASE(pMimeType);
HX_RELEASE(pASMRuleBook);
HX_RELEASE(pOpaqueData);
HX_RELEASE(pStreamHeader);
HX_RELEASE(pIntrinsicDur);
return m_pFormatResponse->StreamHeaderReady(retVal, NULL);
}
// Fill in the non-image-data information
BYTE *pData = pOpaqueData->GetBuffer();
Pack8(pData, m_ucTarget);
Pack8(pData, m_ucURLType);
Pack32(pData, m_ulSeekTime);
Pack8(pData, (BYTE) ((m_ulBackgroundColor & 0x00FF0000) >> 16)); // R
Pack8(pData, (BYTE) ((m_ulBackgroundColor & 0x0000FF00) >> 8)); // G
Pack8(pData, (BYTE) (m_ulBackgroundColor & 0x000000FF) ); // B
Pack8(pData, (BYTE) ((m_ulBackgroundColor & 0xFF000000) >> 24)); // A
CHXString cTmp;
if (m_pURL)
{
cTmp = *m_pURL;
}
PackString(pData, cTmp);
if (m_pGIFCodec && !m_bParseFailed)
{
// Get the opaque data
BOOL bFirstInImage = FALSE;
retVal = m_pGIFCodec->GetPacketBuffer(pData,
pOpaqueData->GetSize() - ulExtraDataSize,
bFirstInImage);
if (retVal != HXR_OK)
{
HX_RELEASE(pMimeType);
HX_RELEASE(pASMRuleBook);
HX_RELEASE(pOpaqueData);
HX_RELEASE(pStreamHeader);
HX_RELEASE(pIntrinsicDur);
return m_pFormatResponse->StreamHeaderReady(retVal, NULL);
}
}
// Set the opaque data buffer property
pStreamHeader->SetPropertyBuffer("OpaqueData", pOpaqueData);
// Set the new state
m_ulState = kStateStreamHeaderSent;
// Initialize the current image index
m_lCurImgIndex = -1;
if (m_pGIFCodec && !m_bParseFailed)
{
// Go ahead and collect all the packets and hold them. We do
// this since if we get a Seek(), we'll need to completely
// resend all the packets. Ugh.
retVal = MakeAllPackets();
if (retVal != HXR_OK)
{
HX_RELEASE(pMimeType);
HX_RELEASE(pASMRuleBook);
HX_RELEASE(pOpaqueData);
HX_RELEASE(pStreamHeader);
HX_RELEASE(pIntrinsicDur);
return m_pFormatResponse->StreamHeaderReady(retVal, NULL);
}
}
// Now we can tell the response interface that we're done
m_pFormatResponse->StreamHeaderReady(HXR_OK, pStreamHeader);
// Release our references
HX_RELEASE(pStreamHeader);
HX_RELEASE(pMimeType);
HX_RELEASE(pASMRuleBook);
HX_RELEASE(pOpaqueData);
HX_RELEASE(pIntrinsicDur);
return HXR_OK;
}
STDMETHODIMP CGIFFileFormat::GetPacket(UINT16 usStreamNum)
{
#ifdef XXXMEH_DEBUG_LOG
DEBUG_OUTF("pxgifff.log", (s, "0x%08x::GetPacket(%u)\n", this, usStreamNum));
#endif
HX_RESULT retVal = HXR_OK;
if (m_ulState == kStateStreamHeaderSent)
{
if (usStreamNum == 0)
{
// Have we sent all the packets?
if (m_ulCurrentPacketIndex < m_ulNumPackets && !m_bParseFailed)
{
// Get the packet pointer
IHXPacket* pPacket = m_ppPacket[m_ulCurrentPacketIndex];
// Increment the packet index
m_ulCurrentPacketIndex++;
// Give the response interface the packet
m_pFormatResponse->PacketReady(HXR_OK, pPacket);
}
else
{
// Set the state
m_ulState = kStateFinished;
// Tell the response interface we're done
m_pFormatResponse->StreamDone(0);
}
}
else
{
retVal = HXR_INVALID_PARAMETER;
}
}
else
{
retVal = HXR_UNEXPECTED;
}
return retVal;
}
STDMETHODIMP CGIFFileFormat::SeekDone(HX_RESULT status)
{
return HXR_UNEXPECTED;
}
STDMETHODIMP CGIFFileFormat::Seek(UINT32 ulRequestedTime)
{
HX_RESULT retVal = HXR_OK;
// XXXMEH - no matter WHEN we get a Seek(), we have to resend all the
// packets again, since they are all timestamp 0.
//
// So all we need to do is reset the current packet index to 0.
m_ulCurrentPacketIndex = 0;
// Set the state
m_ulState = kStateStreamHeaderSent;
// Inform the response interface we're done
m_pFormatResponse->SeekDone(HXR_OK);
return retVal;
}
STDMETHODIMP CGIFFileFormat::Close()
{
if (m_ppPacket && m_ulNumPackets)
{
for (UINT32 i = 0; i < m_ulNumPackets; i++)
{
HX_RELEASE(m_ppPacket[i]);
}
m_ulNumPackets = 0;
HX_VECTOR_DELETE(m_ppPacket);
}
HX_RELEASE(m_pContext);
HX_RELEASE(m_pFileObject);
HX_RELEASE(m_pFileStat);
HX_RELEASE(m_pFormatResponse);
HX_RELEASE(m_pCommonClassFactory);
HX_RELEASE(m_pError);
HX_DELETE(m_pURL);
HX_DELETE(m_pRequestURL);
HX_RELEASE(m_pFileBuffer);
HX_RELEASE(m_pFragFileBuffer);
HX_DELETE(m_pGIFCodec);
HX_VECTOR_DELETE(m_plImageStartTime);
HX_RELEASE(m_pMediaRepeatStr);
m_ulBitRate = 0;
m_ulPreroll = 0;
m_ulDuration = 0;
m_lCurrentTime = 0;
m_ulState = kStateConstructed;
m_ulFileSize = 0;
return HXR_OK;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?