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