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