pxgifrnd.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,936 行 · 第 1/5 页
CPP
1,936 行
rulVersionNumber = TARVER_ULONG32_VERSION;
return HXR_OK;
}
STDMETHODIMP CGIFRenderer::InitPlugin(IUnknown* pContext)
{
HX_RESULT retVal = HXR_FAIL;
if (pContext)
{
// Save a copy of the calling context
HX_RELEASE(m_pContext);
m_pContext = pContext;
m_pContext->AddRef();
// Get a IHXCommonClassFactory interface
HX_RELEASE(m_pCommonClassFactory);
retVal = m_pContext->QueryInterface(IID_IHXCommonClassFactory,
(void**) &m_pCommonClassFactory);
if (SUCCEEDED(retVal))
{
#if defined(HELIX_FEATURE_HYPER_NAVIGATE)
// Get an IHXHyperNavigate interface
HX_RELEASE(m_pHyperNavigate);
m_pContext->QueryInterface(IID_IHXHyperNavigate,
(void**) &m_pHyperNavigate);
#endif /* #if defined(HELIX_FEATURE_HYPER_NAVIGATE) */
// Get the IHXStatusMessage interface - it's OK if TLC doesn't support
// this, so we won't check error return.
HX_RELEASE(m_pStatusMessage);
m_pContext->QueryInterface(IID_IHXStatusMessage,
(void**) &m_pStatusMessage);
// Get an IHXScheduler interface
HX_RELEASE(m_pScheduler);
retVal = m_pContext->QueryInterface(IID_IHXScheduler,
(void**) &m_pScheduler);
if (SUCCEEDED(retVal))
{
// Get the IHXErrorMessages interface - OK if
// TLC doesn't support it
HX_RELEASE(m_pErrorMessages);
m_pContext->QueryInterface(IID_IHXErrorMessages,
(void**) &m_pErrorMessages);
// Create a PXCallback object
HX_RELEASE(m_pCallback);
m_pCallback = new PXCallback();
if (m_pCallback)
{
// AddRef the object
m_pCallback->AddRef();
// Init the callback object
retVal = m_pCallback->Init(m_pContext, this);
if (SUCCEEDED(retVal))
{
// Create the IHXValues object
HX_RELEASE(m_pValues);
m_pCommonClassFactory->CreateInstance(CLSID_IHXValues,
(void**) &m_pValues);
}
}
else
{
retVal = HXR_OUTOFMEMORY;
}
}
}
}
return retVal;
}
STDMETHODIMP CGIFRenderer::GetRendererInfo(REF(const char **) rppszStreamMimeType,
REF(UINT32) rulInitialGranularity)
{
rppszStreamMimeType = (const char**) m_ppszStreamMimeType;
rulInitialGranularity = 1000;
return HXR_OK;
}
STDMETHODIMP CGIFRenderer::StartStream(IHXStream* pStream, IHXPlayer* pPlayer)
{
HX_RESULT retVal = HXR_OK;
if (pStream && pPlayer)
{
// Save a copy of the stream
HX_RELEASE(m_pStream);
m_pStream = pStream;
m_pStream->AddRef();
// Create a PXClientAdviseSink object
HX_RELEASE(m_pClientAdviseSink);
m_pClientAdviseSink = new PXClientAdviseSink();
if (m_pClientAdviseSink)
{
// AddRef the object
m_pClientAdviseSink->AddRef();
// Init the object - this registers this renderer
// as a client advise sink
retVal = m_pClientAdviseSink->Init(pPlayer,
(PXClientAdviseSinkResponse*) this);
}
else
{
retVal = HXR_OUTOFMEMORY;
}
#if defined(HELIX_FEATURE_MISU)
if (SUCCEEDED(retVal))
{
// Create a IHXMultiInstanceSiteUserSupplier interface
HX_RELEASE(m_pMISUS);
retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXMultiInstanceSiteUserSupplier,
(void**) &m_pMISUS);
if (SUCCEEDED(retVal))
{
// Register ourselves as a site user
retVal = m_pMISUS->SetSingleSiteUser((IUnknown*) (IHXSiteUser*) this);
}
}
#endif
}
else
{
retVal = HXR_FAIL;
}
return retVal;
}
STDMETHODIMP CGIFRenderer::OnHeader(IHXValues *pStreamHeaderObj)
{
// Check for input error
if (pStreamHeaderObj == NULL)
{
return HXR_FAIL;
}
// Get content version from header
UINT32 ulIncomingContentVersion;
HX_RESULT retVal = pStreamHeaderObj->GetPropertyULONG32("ContentVersion", ulIncomingContentVersion);
if (retVal != HXR_OK)
{
return HXR_FAIL;
}
// Get stream version from header
UINT32 ulIncomingStreamVersion;
retVal = pStreamHeaderObj->GetPropertyULONG32("StreamVersion", ulIncomingStreamVersion);
if (retVal != HXR_OK)
{
return HXR_FAIL;
}
// Check the versions
if (ulIncomingContentVersion > m_ulHighestSupportedContentVersion ||
ulIncomingStreamVersion > m_ulHighestSupportedStreamVersion)
{
// Add to AU collection
AddToAutoUpgradeCollection(m_ppszStreamMimeType[2], m_pContext);
// Now we return an error, any error actually
return HXR_NO_RENDERER;
}
// Get the opaque data from the stream header
IHXBuffer *pBuffer = NULL;
retVal = pStreamHeaderObj->GetPropertyBuffer("OpaqueData", pBuffer);
if (retVal != HXR_OK)
{
return retVal;
}
// Unpack some info
BYTE *pData = pBuffer->GetBuffer();
UnPack8(pData, m_ucTarget);
// These are no longer used by the renderer they are parsed in the new hypernavigate object in the core so all renderer
// commands are consistent and parsed in one place. We do have to skip over them since the file format still puts them in.
// UnPack8(pData, m_ucURLType);
// UnPack32(pData, m_ulSeekTime);
pData += 5; // Even though the 2 above members were removed we still need to increment the data pointer
// Note that we don't get the alpha from the background color
// in the opaque part of the stream header - we get that from
// the "bgOpacity" CString property in the stream header
BYTE ucBgRed = pData[0];
BYTE ucBgGreen = pData[1];
BYTE ucBgBlue = pData[2];
m_ulBackgroundColor = (ucBgRed << 16) | (ucBgGreen << 8) | ucBgBlue;
pData += 4;
UnPackString(pData, m_cURL);
// Get the current URL
IHXStreamSource* pStreamSource = NULL;
retVal = m_pStream->GetSource(pStreamSource);
if (retVal != HXR_OK || !pStreamSource)
{
HX_RELEASE(pBuffer);
return HXR_FAIL;
}
const char* pszURL = pStreamSource->GetURL();
if (!pszURL)
{
HX_RELEASE(pBuffer);
HX_RELEASE(pStreamSource);
return HXR_FAIL;
}
CHXString cOriginalURL = pszURL;
HX_RELEASE(pStreamSource);
// Check the URL to see if it's relative
if (m_cURL.length() > 0)
{
if (m_ucTarget == kTargetPlayer)
{
if (IsURLRelative(m_cURL.c_str()) &&
!strstr(m_cURL.c_str(), "command:"))
{
CHXString cRelURL(m_cURL.c_str());
CHXString cAbsURL;
retVal = MakeAbsoluteURL(cOriginalURL, cRelURL, cAbsURL);
if (retVal == HXR_OK)
{
m_cURL = (const char *) cAbsURL;
}
}
}
}
// Get the renderer flags property
m_ulRendererFlags = 0;
pStreamHeaderObj->GetPropertyULONG32("RendererFlags", m_ulRendererFlags);
// Check bit 0 to see if parsing failed
m_ulWidth = 0;
m_ulHeight = 0;
UINT32 ulBytesUsed = 0;
if (m_ulRendererFlags & GIF_RENDERER_FLAG_PARSEFAILED)
{
// Get the width and height from the stream header
pStreamHeaderObj->GetPropertyULONG32("Width", m_ulWidth);
pStreamHeaderObj->GetPropertyULONG32("Height", m_ulHeight);
if (!m_ulWidth || !m_ulHeight)
{
m_ulWidth = 48;
m_ulHeight = 48;
m_bNoNativeSize = TRUE;
}
}
else
{
// Create a CGIFCodec
HX_DELETE(m_pGIFCodec);
m_pGIFCodec = new CGIFCodec();
if (!m_pGIFCodec)
{
HX_RELEASE(pBuffer);
return HXR_OUTOFMEMORY;
}
// Initialize the CGIFCodec for decompression
ulBytesUsed = pData - pBuffer->GetBuffer();
retVal = m_pGIFCodec->InitDecompress(pData, pBuffer->GetSize() - ulBytesUsed);
if (retVal != HXR_OK)
{
HX_RELEASE(pBuffer);
HX_DELETE(m_pGIFCodec);
return retVal;
}
// Set the width and height
m_ulWidth = m_pGIFCodec->GetLogicalScreenWidth();
m_ulHeight = m_pGIFCodec->GetLogicalScreenHeight();
}
// Get the mediaRepeat string
IHXBuffer* pMediaRepeatStr = NULL;
pStreamHeaderObj->GetPropertyCString("mediaRepeat",
pMediaRepeatStr);
if (pMediaRepeatStr)
{
if (!strcmp((const char*) pMediaRepeatStr->GetBuffer(), "strip"))
{
m_bPreserveMediaRepeat = FALSE;
}
}
HX_RELEASE(pMediaRepeatStr);
// Save the stream header's opaque buffer
HX_RELEASE(m_pStreamHeaderBuffer);
m_pStreamHeaderBuffer = pBuffer;
m_pStreamHeaderBuffer->AddRef();
// Init the stream header buffer offset
m_ulStreamHeaderOffset = ulBytesUsed;
// Now we can release the IHXBuffer
HX_RELEASE(pBuffer);
// Create an output buffer
HX_RELEASE(m_pOutputBuffer);
retVal = m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, (void **) &m_pOutputBuffer);
if (retVal != HXR_OK)
{
HX_DELETE(m_pGIFCodec);
return retVal;
}
// Compute the size of the output buffer
m_ulDataWidth = m_ulWidth * m_ulBytesPerPixel;
m_ulPadWidth = (m_ulDataWidth + 3) & ~3; // This rounds up to nearest multiple of 4
UINT32 ulNumBytes = m_ulPadWidth * m_ulHeight;
// Set the size of the output buffer
retVal = m_pOutputBuffer->SetSize(ulNumBytes);
if (retVal != HXR_OK)
{
HX_DELETE(m_pGIFCodec);
HX_RELEASE(m_pOutputBuffer);
return retVal;
}
// Initially draw the background color into the display buffer
DrawBackgroundColor();
// Initialize the rendering members
m_ulCurImg = 0;
m_ulCurImgRenderTime = 0;
m_ulCurDelayTime = 0;
m_lLastImg = -1;
// Initialize the loop done count
m_ulLoopsDone = 0;
// Clear the ignore packets flag
m_bIgnorePackets = FALSE;
// Set the first time sync flag
m_bFirstTimeSync = TRUE;
// If the parsing failed, then fill in the image with a bomb image
if (m_ulRendererFlags & GIF_RENDERER_FLAG_PARSEFAILED)
{
CopyBombImage();
}
else
{
// Send some debug info
MLOG_MISC(m_pErrorMessages,
"0x%08x::OnHeader() w=%lu h=%lu loopcount=%lu\n",
this, m_pGIFCodec->GetLogicalScreenWidth(),
m_pGIFCodec->GetLogicalScreenHeight(), m_pGIFCodec->GetLoopCount());
}
// Get the duration
pStreamHeaderObj->GetPropertyULONG32("Duration", m_ulEndTime);
return HXR_OK;
}
STDMETHODIMP CGIFRenderer::OnBegin(UINT32 ulTimeAfterBegin)
{
MLOG_MISC(m_pErrorMessages,
"%lu OnBegin(%lu) this=0x%08x\n",
HX_GET_BETTERTICKCOUNT(), ulTimeAfterBegin, this);
return HXR_OK;
}
STDMETHODIMP CGIFRenderer::GetDisplayType(REF(HX_DISPLAY_TYPE) rDisplayType,
REF(IHXBuffer *) rpDisplayInfo)
{
rDisplayType = HX_DISPLAY_WINDOW |
HX_DISPLAY_SUPPORTS_RESIZE |
HX_DISPLAY_SUPPORTS_FULLSCREEN;
return HXR_OK;
}
STDMETHODIMP CGIFRenderer::OnPacket(IHXPacket *pPacket, INT32 lTimeOffset)
{
MLOG_MISC(m_pErrorMessages,
"%lu OnPacket(,%ld) this=0x%08x\n",
HX_GET_BETTERTICKCOUNT(), lTimeOffset, this);
// Check for input error
if (pPacket == NULL)
{
return HXR_INVALID_PARAMETER;
}
// Save the time offset
m_lTimeOffset = lTimeOffset;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?