⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ig_parse.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    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 + -