3gppttrenderer.cpp

来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,765 行 · 第 1/5 页

CPP
1,765
字号
    // Keep this for later use...
    m_pHeader = pHeader;
    m_pHeader->AddRef();

    m_pHeader->GetPropertyULONG32("duration", m_ulDuration);

    HX_RESULT hxGetPropRslt = HXR_OK;

    // /Get this from numEntries of RuleToFlagMap that is "OpaqueData" buffer (below)
    if (HXR_OK == pHeader->GetPropertyBuffer(HX_3GPPTT_RULE_TO_FLAG_MAP_PROPERTY,
            pRuleToFlagMapValue))
    {
        m_pRuleToFlagMap = new RuleToFlagMap;
        if (m_pRuleToFlagMap)
        {
            m_pRuleToFlagMap->unpack(pRuleToFlagMapValue->GetBuffer(),
                    pRuleToFlagMapValue->GetSize());
        }
    }

    HX_RELEASE(pRuleToFlagMapValue);

    hxGetPropRslt = m_pHeader->GetPropertyBuffer("OpaqueData",
            m_p3GPPTextSampleEntryPackedArray);
    HX_ASSERT(HXR_OK==hxGetPropRslt  &&  m_p3GPPTextSampleEntryPackedArray);
    if (HXR_OK == hxGetPropRslt  &&  m_p3GPPTextSampleEntryPackedArray)
    {
        const UINT8* pData = m_p3GPPTextSampleEntryPackedArray->GetBuffer();
        

        // /The first byte is the 'stsd's version, the next 3 bytes are the
        // 'stsd's flags, and the next 4 bytes are the entryCount
        pData+=(1+3); // /Skip past the version and the flags.
        m_ulNumTextSampleEntries = ReadUL32(pData);
       

        HX_ASSERT(m_ulNumTextSampleEntries > 0);
        HX_ASSERT(0 == m_textSampleEntries.GetCount());

        hxrslt = m_textSampleEntries.Reset(m_ulNumTextSampleEntries);
        if(SUCCEEDED(hxrslt))
        {
            // create table of sample entries
            for (UINT32 ulSampleIndx = 0; ulSampleIndx < m_ulNumTextSampleEntries; ulSampleIndx++)
            {
                C3GPPTextSampleEntry* pEntry = new C3GPPTextSampleEntry();
                if( !pEntry )
                {
                    hxrslt = HXR_OUTOFMEMORY;
                    goto cleanup;
                }

                hxrslt = pEntry->Build(pData);
                if(FAILED(hxrslt))
                {
                    HX_DELETE(pEntry);
                    goto cleanup;
                }

                m_textSampleEntries[ulSampleIndx] = pEntry;
            }
        }
    }

    // /_______________________________________________________________
    // /
    // /Get the media's native width and height:
    m_pHeader->GetPropertyULONG32("3GPPTextTrackWidth", ulRegionWidth);

    m_pHeader->GetPropertyULONG32("3GPPTextTrackHeight", ulRegionHeight);

    // /This is the offset from the text window's origin:
    m_pHeader->GetPropertyULONG32("3GPPTextTrackTransformX", ulTransformX);
    m_pHeader->GetPropertyULONG32("3GPPTextTrackTransformY", ulTransformY);

    m_originTransformXY.x = (INT32)ulTransformX;
    m_originTransformXY.y = (INT32)ulTransformY;

    m_size.cx = (INT32)ulRegionWidth;
    m_size.cy = (INT32)ulRegionHeight;

    
    // /_______________________________________________________________
    // /
    // /Set up the offscreen draw buffer:
    hxrslt = CreateOffscreenBuffer(m_size);

    // /_______________________________________________________________
    // /
    
cleanup:
    return hxrslt;
}


/****************************************************************************
 *  IHXRenderer::OnBegin                                   ref:  hxrendr.h
 *
 *  This routine is called by the Helix core to inform the Renderer that 
 *  playback has just begun or has been resumed. The stream's time value just
 *  after resuming the playback is provided.
 */
STDMETHODIMP
C3GPPTimedTextRenderer::OnBegin(UINT32 ulTime)
{
    return HXR_OK;
}


/****************************************************************************
 *  IHXRenderer::GetDisplayType                             ref:  hxrendr.h
 *
 *  This routine returns the preferred display type of the Renderer. Any
 *  other additional information necessary for the display can also be
 *  provided. This method is called by the Helix core when the plug-in is being
 *  initialized.
 */
STDMETHODIMP
C3GPPTimedTextRenderer::GetDisplayType
(
    REF(HX_DISPLAY_TYPE)   ulFlags,
    REF(IHXBuffer*)         pBuffer
)
{
    ulFlags = HX_DISPLAY_WINDOW;

    return HXR_OK;
}


/****************************************************************************
 *  IHXRenderer::OnPacket                                   ref:  hxrendr.h
 *
 *  This routine is passed the packet object streamed by the associated
 *  file format plug-in. It is called by the Helix core when a packet is due
 *  to be delivered. In most cases, the actual rendering of the packet is
 *  done in this method. The stream's time offset with respect to the master
 *  timeline is provided.
 */
STDMETHODIMP
C3GPPTimedTextRenderer::OnPacket
(
    IHXPacket* pPacket,
    INT32 lTimeOffset
)
{
#if defined(XXXEH_DEBUGOUT_DRAW_3GPPTT)
pFile = fopen("c:\\3gppttdrawPos.txt", ulCount?"a+":"w");
if (pFile)
{
    fprintf(pFile, "[OnPacket] at %ld\tlTimeOffset=%ld\tpktContentTime=%ld\tpktTime=%ld\t%s\t%s\n",
            HX_GET_BETTERTICKCOUNT(), lTimeOffset,
            pPacket? GetPacketContentTime(pPacket):0xFFFFFFFF,
            pPacket?pPacket->GetTime():0xFFFFFFFF,
            m_bInSeekMode?"Skipped: m_bInSeekMode=TRUE":"",
            m_bGotAllPacketsAlready?"Skipped: m_bGotAllPacketsAlready=TRUE":"");
    fclose(pFile);
}
ulCount++;
#endif // /XXXEH_DEBUGOUT_DRAW_3GPPTT.

    HX_RESULT hxrslt = HXR_OK;

    /* Ignore pre-seek packets. Some renderers may want to use them though */
    if (m_bInSeekMode)
    {
        return hxrslt;
    }

    // /If we have all packets already, then we're receiving resends after a
    // seek and we don't need the data resent because we store it all:
    if (m_bGotAllPacketsAlready)
    {
        return hxrslt;
    }

    // Release the last packet if we had one...
    if (m_pLatestPacket)
    {
        HX_RELEASE(m_pLatestPacket);
    }

    // Keep this one for later use...
    m_pLatestPacket = pPacket;

    BOOL bFirstPkt = FALSE;

    if (m_pLatestPacket)
    {
        m_pLatestPacket->AddRef();

        if (!m_pTextContainerList)
        {
            bFirstPkt = TRUE;
            m_pTextContainerList = new CHXSimpleList();
            if (!m_pTextContainerList)
            {
                hxrslt = HXR_OUTOFMEMORY;
            }
        }

        if (HXR_OK == hxrslt)
        {
            LISTPOSITION plistPosOfFirstTxtCntnr = NULL;

            HandleNewText(m_pLatestPacket, plistPosOfFirstTxtCntnr);

            if (bFirstPkt)
            {
                m_pTextContainerListFutureTimePos =
                        m_pTextContainerList->GetHeadPosition();
            }
            else
            {
                // /Not first packet, but it points past end of list,
                // so point it to last in list:
                if (!m_pTextContainerListFutureTimePos)
                {
                    HX_ASSERT(plistPosOfFirstTxtCntnr);

                    // /Use first of HandleNewText()'s TC's, not last:
                    m_pTextContainerListFutureTimePos = plistPosOfFirstTxtCntnr;
                    if (NULL == m_pTextContainerListFutureTimePos)
                    {
                        // /Use tail if no T.C. was created from this new pkt:
                        m_pTextContainerListFutureTimePos =
                                m_pTextContainerList->GetTailPosition();
                    }
                }

                // /Now go through prior packet's T.C.'s and establish their
                // end times (which == m_pLatestPacket->GetRTPTime() ):
                SetPriorPacketTCsEndTimes();
            }
        }

// /#define DUMP_3GPPTEXT_PACKET_CONTENTS
#if defined(DUMP_3GPPTEXT_PACKET_CONTENTS)
#if !defined(_DEBUG)
#pragma message("====##### ***RELEASE BUILD: THIS TEST CODE SHOULD BE #####====")
#pragma message("====#####    ifdef'd OUT BEFORE BEING CHECKED IN     #####====")
#endif
{
    static UINT32 ulPktNum = 0;
    FILE* pFile = fopen("c:\\3gppttdump.txt", ulPktNum?"a+":"w");
    if (pFile)
    {
        IHXBuffer* pBuff = pPacket->GetBuffer();
        char* pText = pBuff? (char*)pBuff->GetBuffer() : "[NULL]";
        fprintf(pFile, "packet  \t%lu\npkt time\t%lu\npacket content time\t"
            "%lu\ncur time%lu\nsize    \t%d\ncontents\t{{{[len=%u]%s}}}\n\n",
                ulPktNum, pPacket->GetTime(), GetPacketContentTime(
                m_pLatestPacket), m_ulTimeOfLastTimeSync,
                pPacket->GetBuffer()->GetSize(),
                ((*pText)<< 8)|(*(pText+1)), &pText[2]);
        fclose(pFile);
    }
    ulPktNum++;
}
#endif
    }

    // NOTE: If this stream has been offset in time due to start, end, or
    // groupstart properties on the stream, packets will need to be adjusted
    // before comparing against the time line.   The following code determines
    // the offset of this packet's delivery time in the real timeline.
    UINT32 ulPacketContentTime = GetPacketContentTime(pPacket);
    UINT32 ulRealContentTime;
 
    if ((UINT32)lTimeOffset > ulPacketContentTime)
    {
        ulRealContentTime = 0;
    }
    else
    {
        ulRealContentTime = ulPacketContentTime - lTimeOffset;
    }

    m_ulLastPacketTime = ulPacketContentTime;
    m_ulLastRealPacketTime = ulRealContentTime;

    return hxrslt;
}


/****************************************************************************
 *  IHXRenderer::OnTimeSync                                 ref:  hxrendr.h
 *
 *  This routine is called by the Helix core periodically passing the current
 *  playback time. The Renderer should use this time value to synchronize the
 *  playback of various streams.
 */
STDMETHODIMP
C3GPPTimedTextRenderer::OnTimeSync(UINT32 ulTime)
{
    // Here's a good time to actually render the data!

    // Remember the time we are!
    m_ulTimeOfLastTimeSync = ulTime;

    BOOL bForceDraw = FALSE;

    C3GPPTextContainer* pTextContainer = NULL;
    // /Find out if any begin time was hit:
    if (m_pTextContainerList  &&  m_pTextContainerListFutureTimePos)
    {
        pTextContainer = (C3GPPTextContainer*)
                m_pTextContainerList->GetAt(m_pTextContainerListFutureTimePos);

#if defined(XXXEH_DEBUGOUT_DRAW_3GPPTT)
pFile = fopen("c:\\3gppttdrawPos.txt", ulCount?"a+":"w");
if (pFile)
{
    fprintf(pFile, "[OnTimeSync - 1] T.C. = %p, begin time=%lu, at time %lu, "
        "m_pTextContainerListFutureTimePos=%x\n", pTextContainer,
        pTextContainer->GetBeginTime(), ulTime, m_pTextContainerListFutureTimePos);
    fclose(pFile);
}
ulCount++;
#endif // /XXXEH_DEBUGOUT_DRAW_3GPPTT.

        if (pTextContainer  &&
                // /XXXEH- handle possible time-offset!:
                pTextContainer->GetBeginTime() <= ulTime  &&
                pTextContainer->GetEndTime() > ulTime)
        {
            bForceDraw = TRUE;
        }
    }

    // /No new ones need drawing? Then see if any current ones need redrawing
    // due to scrolling or blinking:
    if (!bForceDraw  &&  m_pTextContainerRedrawList  &&
                m_pTextContainerRedrawList->GetCount())
    {
        pTextContainer = (C3GPPTextContainer*)
                m_pTextContainerRedrawList->GetHead();

#if defined(XXXEH_DEBUGOUT_DRAW_3GPPTT)
pFile = fopen("c:\\3gppttdrawPos.txt", ulCount?"a+":"w");
if (pFile)
{
    fprintf(pFile, "[OnTimeSync - 2] T.C. = %p (begin=%lu,\tend=%lu,\t"
        "nextActive=%lu)\tat time %lu\tm_pTextContainerListFutureTimePos=%p\n",
        pTextContainer, pTextContainer->GetBeginTime(),
        pTextContainer->GetEndTime(), pTextContainer->GetNextActivityTime(),
        m_ulTimeOfLastTimeSync, m_pTextContainerListFutureTimePos);
    fclose(pFile);
}
ulCount++;
#endif // /XXXEH_DEBUGOUT_DRAW_3GPPTT.

        if (pTextContainer  &&

⌨️ 快捷键说明

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