📄 ig_parse.cpp
字号:
IGInfo.pICSMessage->ICS = NULL;
/* acquire ICSLock */
OS_SemTake(IGInfo.ICSLock, OS_WAIT_FOREVER);
/* if it the same ICS (ie. were looping a playitem then ignore it */
if (IGInfo.ICS != NULL)
{
if (MAKE_WORD(&SegmentIndex[SIZE_VIDEO_DESCRIPTOR]) == IGInfo.ICS->CompDesc.CompositionNumber)
{
/* give the sem back */
OS_SemGive(IGInfo.ICSLock);
/* release the message */
IGInfo.IGRenderQ->ReleaseMsg(IGInfo.pICSMessage);
IGInfo.pICSMessage = NULL;
return (IG_STATUS_SUCCESS);
}
}
/* give the sem back */
OS_SemGive(IGInfo.ICSLock);
/* malloc the ICS we are putting in the message */
IGInfo.pICSMessage->ICS = (INTERACTIVE_COMPOSITION_SEGMENT *)OS_MemAlloc(sizeof(INTERACTIVE_COMPOSITION_SEGMENT));
if (NULL == IGInfo.pICSMessage->ICS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadICS(); Unable to Get memory for ICS\n"));
IGInfo.IGRenderQ->ReleaseMsg(IGInfo.pICSMessage);
IGInfo.pICSMessage = NULL;
return IG_STATUS_ERROR;
}
/* clear out the ICS object */
memset(IGInfo.pICSMessage->ICS, 0, sizeof(INTERACTIVE_COMPOSITION_SEGMENT));
/* video descriptor */
IGInfo.pICSMessage->ICS->VideoDesc.Width = MAKE_WORD(SegmentIndex);
IGInfo.pICSMessage->ICS->VideoDesc.Height = MAKE_WORD(SegmentIndex+2);
IGInfo.pICSMessage->ICS->VideoDesc.FrameRate = ((*(SegmentIndex+4)) & 0xF0) >> 4;
SegmentIndex += SIZE_VIDEO_DESCRIPTOR;
if (IGInfo.RLEHalfWidth == 1)
{
if ((IGInfo.pICSMessage->ICS->VideoDesc.Width == 1920) && (IGInfo.pICSMessage->ICS->VideoDesc.Height == 1080))
{
IGInfo.CoordsHalfWidth = 1;
}
}
/* read in the composition descriptor */
IGInfo.pICSMessage->ICS->CompDesc.CompositionNumber = MAKE_WORD(SegmentIndex);
IGInfo.pICSMessage->ICS->CompDesc.CompositionState = ((*(SegmentIndex+2)) & 0xC0) >> 6;
SegmentIndex += SIZE_COMPOSITION_DESCRIPTOR;
/* if the stream is not acquired yet, see if we got a ACQ Point or Epoch Start */
if (0 == IGInfo.StreamAcquired)
{
if ((IGInfo.pICSMessage->ICS->CompDesc.CompositionState == COMP_STATE_ACQUISITION_POINT) ||
(IGInfo.pICSMessage->ICS->CompDesc.CompositionState == COMP_STATE_EPOCH_START) ||
(IGInfo.pICSMessage->ICS->CompDesc.CompositionState == COMP_STATE_EPOCH_CONT))
{
/* we got a valid acquisition point now */
DBGPRINT(DBG_ON(DBG_TRACE), ("IGLoadICS(): Stream Acquired state %d\n", IGInfo.pICSMessage->ICS->CompDesc.CompositionState));
IGInfo.StreamAcquired = 1;
}
else
{
/* this PCS may reference old data, do NOT keep it */
DBGPRINT(DBG_ON(DBG_TRACE), ("IGLoadICS(): Discard ICS\n"));
if (IGInfo.pICSMessage->ICS)
{
/* release the ICS */
OS_MemFree(IGInfo.pICSMessage->ICS);
IGInfo.pICSMessage->ICS = NULL;
}
IGInfo.IGRenderQ->ReleaseMsg(IGInfo.pICSMessage);
IGInfo.pICSMessage = NULL;
return IG_STATUS_SUCCESS;
}
}
/* is this a EPOCH START? */
if ((IGInfo.pICSMessage->ICS->CompDesc.CompositionState & COMP_STATE_MASK) == COMP_STATE_EPOCH_START)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("IGLoadICS(): Got epoch start in parser, clearing objects, palettes, video display\n"));
OS_SemTake(IGInfo.ICSLock, OS_WAIT_FOREVER);
/* clear screen and clear data structures */
IGGraphicsClearBuffer(NULL, 0);
OS_TimerSet(IGInfo.TimerFlip, 1);
OS_TaskYield();
IGICSReset(); /* clear the current ics, stop timers and fire ics invalid */
IGFreeObjects();
IGClearPalettes();
OS_SemGive(IGInfo.ICSLock);
}
/* skip the sequence descriptor byte */
SegmentIndex++;
/* load the composition length */
#ifdef VDVD_LITTLE_ENDIAN
IGInfo.pICSMessage->ICS->CompositionLength = ((*SegmentIndex) << 16) | ((*(SegmentIndex+1)) << 8) | (*(SegmentIndex+2));
SegmentIndex += 3;
#else
memcpy(&IGInfo.pICSMessage->ICS->CompositionLength, SegmentIndex, 3);
#endif
/* load the UI and stream model */
IGInfo.pICSMessage->ICS->StreamAndUIModel = *SegmentIndex;
SegmentIndex++;
/* if the stream model == 0 */
if (0 == (IGInfo.pICSMessage->ICS->StreamAndUIModel & BIT7))
{
/*get the upper 32 bits of the 33 here 45khz granularity */
IGInfo.pICSMessage->ICS->CompositionTimeoutPTS = ((*SegmentIndex) & BIT0) << 31;
IGInfo.pICSMessage->ICS->CompositionTimeoutPTS |= MAKE_DWORD(SegmentIndex+1) >> 1;
SegmentIndex+=5;
IGInfo.pICSMessage->ICS->SelectionTimeoutPTS = ((*SegmentIndex) & BIT0) << 31;
IGInfo.pICSMessage->ICS->SelectionTimeoutPTS = MAKE_DWORD(SegmentIndex+1) >> 1;
SegmentIndex+=5;
}
/* load user timeout duration */
#ifdef VDVD_LITTLE_ENDIAN
IGInfo.pICSMessage->ICS->UserTimeoutDuration = ((*SegmentIndex) << 16) | ((*(SegmentIndex+1)) << 8) | (*(SegmentIndex+2));
SegmentIndex += 3;
#else
memcpy(&IGInfo.pICSMessage->ICS->UserTimeoutDuration, SegmentIndex, 3);
#endif
/* load num pages */
IGInfo.pICSMessage->ICS->NumPages = *SegmentIndex;
SegmentIndex++;
/* get memory for pages */
if (IGInfo.pICSMessage->ICS->NumPages > 0)
{
IGInfo.pICSMessage->ICS->Pages = (PAGE *)OS_MemAlloc(IGInfo.pICSMessage->ICS->NumPages * sizeof(PAGE));
if (NULL == IGInfo.pICSMessage->ICS->Pages)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadICS(): No memory available for ICS Pages\n"));
goto errout;
}
/* load the pages structure */
if (IG_STATUS_SUCCESS != IGLoadICSPages(SegmentIndex, IGInfo.pICSMessage->ICS->NumPages, IGInfo.pICSMessage->ICS->Pages, &BytesMoved))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadICS(): failed call to IGLoadICSPages()\n"));
goto errout;
}
}
/* the PTS the packet came in on is it's render time, note it should be rendered by this time */
if ((PTS_ONLY == PTS_DTS_Flags) || (PTS_AND_DTS == PTS_DTS_Flags))
{
/* index our table here based on the FrameRate value */
/* 6 and 7 are interlaced so a frame is really 2 fields and thus 2x time of fps
1 = 23.976 fps
2 = 24 fps
3 = 25 fps
4 = 29.97
6 = 50 fps (interlaced)
7 = 59.94 fps (interlaced)
*/
// start render when pts shows up not done by then...
IGInfo.pICSMessage->ICS->PTS = PTS;
IGInfo.pICSMessage->PTSRenderTime = PTS - FrameTimes[IGInfo.pICSMessage->ICS->VideoDesc.FrameRate];
}
else
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadICS(): there is no PTS time given to the ICS from PES header\n"));
}
return IG_STATUS_SUCCESS;
errout:
/* free the Pages memory if alloc'd */
if (NULL != IGInfo.pICSMessage->ICS)
{
if (NULL != IGInfo.pICSMessage->ICS->Pages)
{
OS_MemFree(IGInfo.pICSMessage->ICS->Pages);
IGInfo.pICSMessage->ICS->Pages = NULL;
}
OS_MemFree(IGInfo.pICSMessage->ICS);
IGInfo.pICSMessage->ICS = NULL;
}
return IG_STATUS_ERROR;
}
/**
* IGLoadICSPages - load the pages of the ICS into the buffer given by *Pages
*
* @param BYTE *DataStart - the number of pages to load
* @param BYTE NumPages - the memory to load the PAGE structures to
* @param PAGE *Pages - The pages pointer already malloc'd to match the NumPages
* @param ULONG *MovedBytes - number of bytes we moved forward in the stream during reading
*
* @return IG_STATUS
*/
IG_STATUS IGLoadICSPages(BYTE *DataStart, BYTE NumPages, PAGE *Pages, ULONG *MovedBytes)
{
BYTE *SegmentIndex = DataStart;
ULONG MoveForward = 0;
int i=0;
/* now that we have the memory load each page as we go we will need
to call subroutines to load their pointers, let's not leak memory on
cleanup here ok? */
for (i=0; i<NumPages; i++)
{
/* get page id */
Pages[i].PageID = *SegmentIndex;
SegmentIndex++;
/* page version */
Pages[i].PageVersionNumber = *SegmentIndex;
SegmentIndex++;
/* load the UO MASK table */
#if VDVD_PLATFORM_ENDIANESS == VDVD_BIG_ENDIAN
memcpy(&(Pages[i].UO_mask_table), SegmentIndex, 8);
#else
((BYTE *)(&(Pages[i].UO_mask_table)))[0] = SegmentIndex[7];
((BYTE *)(&(Pages[i].UO_mask_table)))[1] = SegmentIndex[6];
((BYTE *)(&(Pages[i].UO_mask_table)))[2] = SegmentIndex[5];
((BYTE *)(&(Pages[i].UO_mask_table)))[3] = SegmentIndex[4];
((BYTE *)(&(Pages[i].UO_mask_table)))[4] = SegmentIndex[3];
((BYTE *)(&(Pages[i].UO_mask_table)))[5] = SegmentIndex[2];
((BYTE *)(&(Pages[i].UO_mask_table)))[6] = SegmentIndex[1];
((BYTE *)(&(Pages[i].UO_mask_table)))[7] = SegmentIndex[0];
#endif
SegmentIndex += SIZE_UO_MASK_TABLE;
/* load effect sequence in */
if (IG_STATUS_SUCCESS != IGLoadICSPageEffects(SegmentIndex, &Pages[i].InEff, &MoveForward))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadICSPages(): Couldn't load in Effects of page\n"));
goto errout;
}
SegmentIndex += MoveForward;
/* load effect sequence out */
if (IG_STATUS_SUCCESS != IGLoadICSPageEffects(SegmentIndex, &Pages[i].OutEff, &MoveForward))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadICSPages(): Couldn't load out Effects of page\n"));
goto errout;
}
SegmentIndex += MoveForward;
/* load animation frame rate code */
Pages[i].AnimationFrameRateCode = *SegmentIndex;
/* load default selected button id ref */
Pages[i].DefaultSelectedButtonIDRef = MAKE_WORD(SegmentIndex+1);
/* load default activated button id ref */
Pages[i].DefaultActivatedButtonIDRef = MAKE_WORD(SegmentIndex+3);
/* palette id reference */
Pages[i].PaletteIDRef = *(SegmentIndex+5);
/* num button overlap groups */
Pages[i].NumBogs = *(SegmentIndex+6);
SegmentIndex+=7;
/* NOTE: malloc here */
if (Pages[i].NumBogs > 0)
{
Pages[i].Bogs = (BUTTON_OVERLAP_GROUP *) OS_MemAlloc(sizeof(BUTTON_OVERLAP_GROUP) * Pages[i].NumBogs);
if (NULL == Pages[i].Bogs)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadICSPages(): Failed to allocate ics->page->bogs\n"));
goto errout;
}
/* load the button overlap groups for this page */
if (IG_STATUS_SUCCESS != IGLoadICSPageBogs(SegmentIndex, &Pages[i], &MoveForward))
{
DBGPRINT(DBG_ON(DBG_ERROR), ("IGLoadICSPages(): Failed to load the ICS Page Bogs\n"));
goto errout;
}
SegmentIndex += MoveForward;
}
}
*MovedBytes = SegmentIndex - DataStart;
return IG_STATUS_SUCCESS;
errout:
/* deallocate memory for the button overlap groups */
for (i=0; i<NumPages; i++)
{
if (Pages[i].NumBogs > 0)
{
if (NULL != Pages[i].Bogs)
{
OS_MemFree(Pages[i].Bogs);
Pages[i].Bogs = NULL;
}
}
}
return IG_STATUS_ERROR;
}
/**
* IGLoadICSPageEffects - load the pages of the ICS into the buffer given by *Pages
*
* @param BYTE *DataStart - the stream data we are processing
* @param EFFECT_SEQUENCE *Eff - the effects sequence we are filling
* @param ULONG *MovedBytes - the number of bytes we moved ahead in the stream
*
* @return IG_STATUS
*/
IG_STATUS IGLoadICSPageEffects(BYTE *DataStart, EFFECT_SEQUENCE *Eff, ULONG *MovedBytes)
{
BYTE *SegmentIndex = DataStart;
int i, CompCur;
/* how many windows? */
Eff->NumWindows = *SegmentIndex;
SegmentIndex++;
if (0 != Eff->NumWindows)
{
DBGPRINT(DBG_ON(DBG_TRACE), ("IGLoadICSPageEffects(): There are windows\n"));
/* check range on windows */
if(Eff->NumWindows > MAX_WINDOWS)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -