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

📄 ig_render.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************
******************************************************************************
**                                                                          **
**  Copyright (c) 2005-2006 Videon Central, Inc.                            **
**  All rights reserved.                                                    **
**                                                                          **
**  The computer program contained herein contains proprietary information  **
**  which is the property of Videon Central, Inc.  The program may be used  **
**  and/or copied only with the written permission of Videon Central, Inc.  **
**  or in accordance with the terms and conditions stipulated in the        **
**  agreement/contract under which the programs have been supplied.         **
**                                                                          **
******************************************************************************
*****************************************************************************/
/**
 * @file ig_render.cpp
 *
 * $Revision: 1.7 $ 
 *
 * render functions for the IG module
 *
 */

#include "vcitypes.h"
#include "ig_defs.h"
#include "ig_parse.h"
#include "ig_util.h"
#include "ig_render.h"
#include "directfb.h"
#include "ig_graphics.h"
#include "utility.h"
#include "qa.h"  /* for qa automation */

#define DEBUG_IG_RENDER DBG_ERROR
#define DBG_ON(x)       (DEBUG_IG_RENDER >= x)

/* local prototypes */
static IG_STATUS IGWaitForPTS(ULONG PTS);
static IG_STATUS IGDoICSUpdate(INTERACTIVE_COMPOSITION_SEGMENT *ICSUpdate, int *UpdatedActivePage);
static IG_STATUS IGRenderEffectsSequence(EFFECT_SEQUENCE *Sequence);
static IG_STATUS IGUpdateOverOldPAGE(PAGE *NewPage, PAGE *OldPage);
static IG_STATUS IGICSDrawPage(PAGE *Page, int DoEffectsIn);
static IG_STATUS IGRenderEffect(EFFECT *Effect);
static IG_STATUS IGPSR10Procedure(PAGE *Page, ULONG PSR10);
static IG_STATUS IGFindButtonInBogsByID(PAGE* Page, USHORT ButtonID, BUTTON **Button, int *BogIndex);
static IG_STATUS IGFindButtonInBogsByNumber(PAGE* Page, USHORT ButtonNumber, BUTTON **Button, int *BogIndex);
static IG_STATUS IGDoButtonSelection(PAGE *Page, USHORT PSR10);
static IG_STATUS IGCopyBogs(PAGE *Dest, PAGE *Src);
static IG_STATUS IGEnableDefaultButtonsOnPage(PAGE *Page);
static IG_STATUS IGCompareButtonToDefaultValid(PAGE* Page, USHORT ButtonID, BUTTON **Button);
static IG_STATUS IGHasValidDefaultButtonID(PAGE* Page, BUTTON **Button);
static IG_STATUS IGDefaultSelectionIsButtonID(PAGE* Page, BUTTON **Button);
static IG_STATUS IGStartAnimation(PAGE *Page);
static USHORT IGGetBogIndex(PAGE *Page, USHORT ButtonID);
static void IGFreeBogs(PAGE *Page);
static void IGDisableBog(BUTTON_OVERLAP_GROUP *Bog, int NumButtons, USHORT ExceptionButtonID);
static void IGDisableAllButtonsOnPage(PAGE *Page);

/* print info */
#if DBG_ON(DBG_TRACE)
static void PrintICS(INTERACTIVE_COMPOSITION_SEGMENT *ICS);
static void PrintPages(PAGE *Pages, BYTE NumPages, int indent);
static void PrintBogs(BUTTON_OVERLAP_GROUP *Bogs, BYTE NumBogs, int indent);
static void PrintButton(BUTTON *Button, int indent);
#endif

/* calls that call the PE */
static IG_STATUS IGToPEICSValid(IG_ICSVALID_EVENT_INFO *Info);
static IG_STATUS IGToPEPageSelect(IG_PAGE_SELECT_EVENT_INFO *Info);
static IG_STATUS IGToPEButtonSelect(BUTTON *pButton);
static IG_STATUS IGToPEButtonActivate(BUTTON *pButton, PVOID pContext);

/* frame rates x 1000 for integer math */
ULONG VideoFrameRates[] = {0, 23976, 24000, 25000, 29970, 0, 50000, 59940, 0, 0, 0, 0, 0, 0, 0, 0};

/* extern'd */
extern PALETTE IGPalettes[IG_MAX_PALETTES];
extern IGINFO IGInfo;
extern int gWaitForFrame;

#define IsPopup() ((IGInfo.ICS->StreamAndUIModel & BIT6) ? 1 : 0)
#define IsOutMux() ((IGInfo.ICS->StreamAndUIModel & BIT7) ? 1 : 0)

/**
 * IGRender - The render task for the IG module
 *
 * @param PVOID pvParam - NULL
 *
 * @return IG_STATUS
 */
ULONG IGRender(PVOID pvParam)
{
    IG_RENDER_MSG *pMessage = NULL;

    /* keep on requesint pts's till we are signal'd to stop */
    while (IG_FLAGS_EXIT != IGInfo.QuitFlags)
    {
        /* Get a stream message */
        pMessage = (IG_RENDER_MSG *)IGInfo.IGRenderQ->Read(OS_WAIT_FOREVER);

        if (NULL == pMessage)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("IGRender(): Null RenderQ Message\n"));
            OS_TaskYield();
            continue;
        }

        /* pts check */
        if (NULL == pMessage->ICS)
        {
            IGInfo.IGRenderQ->ReleaseMsg(pMessage);
            pMessage = NULL;
            OS_TaskYield();
            continue;
        }

        IGWaitForPTS(pMessage->PTSRenderTime);

        /* check quit flags */
        if (IG_STATE_RUNNING != IGInfo.CurrentState)
        {
            /* free the memory */
            IGFreeICS(pMessage->ICS);

            IGInfo.IGRenderQ->ReleaseMsg(pMessage);
            pMessage = NULL;
            OS_TaskYield();
            continue;
        }

        /* render the display update */
        RenderICS(pMessage->ICS);

        /* finished with it now */
        IGInfo.IGRenderQ->ReleaseMsg(pMessage);
        pMessage = NULL;
    }

    DBGPRINT(DBG_ON(DBG_ERROR), ("IGRender(): Leaving Task\n"));

    OS_TaskExit();
    return IG_STATUS_SUCCESS;
}


/**
 * RenderICS - begin processing the Interactive Composition Segment
 *
 * @param ICS *ICS - The ICS object to render
 *
 * @return IG_STATUS
 */
IG_STATUS RenderICS(INTERACTIVE_COMPOSITION_SEGMENT *ICS)
{
    IG_ICSVALID_EVENT_INFO PSRInfo;
    IG_PAGE_SELECT_EVENT_INFO PageSelectInfo;
    int fDidICSUpdate=0;
    int UpdateActivePage=0;
    int CurrentLevel = -1;

    DBGPRINT(DBG_ON(DBG_TRACE), ("--RenderICS(): Num pages %d, state: %d\n", ICS->NumPages, ICS->CompDesc.CompositionState));

    OS_SemTake(IGInfo.ICSLock, OS_WAIT_FOREVER);

    /* check if this is an update */
    if (IGInfo.ICS)
    {
        if (COMP_STATE_EPOCH_START == ICS->CompDesc.CompositionState)
        {
            /* reset IG state related to current ICS */
            IGICSReset();
        }
        else
        {
            /* update the current ICS  */
            IGDoICSUpdate(ICS, &UpdateActivePage);

            /* we updated the current ICS */
            fDidICSUpdate = 1;
        }
    }

    /* if we didn't do an update then this a new ICS */
    if (0 == fDidICSUpdate)
    {
        /* do we already have an ICS?  free it first if so */
        if (IGInfo.ICS)
        {
            /* reset IG state related to current ICS */
            IGICSReset();
        }

        /* attach new ICS */
        IGInfo.ICS = ICS;
        IGInfo.SelectionTimedout = 0;
    }

    /* fire PE Events to get the PSR info */
    IGToPEICSValid(&PSRInfo);

    /* set the size of the display layer */
    IGInfo.IGDFBInfo.ScreenWidth  = IGInfo.ICS->VideoDesc.Width;
    IGInfo.IGDFBInfo.ScreenHeight = IGInfo.ICS->VideoDesc.Height;

    /* get level, if it's not IG_DISPLAY_LEVEL, then set it */
    IGInfo.IGDFBInfo.DispLayer->GetLevel(IGInfo.IGDFBInfo.DispLayer, &CurrentLevel);

    /* if this is a popup and popups are enabled then setlevel up */
    if ( (IsPopup() && IGInfo.fPopupEnabled) || (IsPopup() == 0))
    {
        if (CurrentLevel != IG_DISPLAY_LEVEL)
        {
            if (DFB_OK != IGInfo.IGDFBInfo.DispLayer->SetLevel(IGInfo.IGDFBInfo.DispLayer, IG_DISPLAY_LEVEL))
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("RenderICS(): Failed to set the level to IG_DISPLAY_LEVEL\n"));
            }
        }
    }
    else
    {
        if (CurrentLevel != IG_DISPLAY_NO_SHOW)
        {
            if (DFB_OK != IGInfo.IGDFBInfo.DispLayer->SetLevel(IGInfo.IGDFBInfo.DispLayer, IG_DISPLAY_NO_SHOW))
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("RenderICS(): Failed to set the level to IG_DISPLAY_NO_SHOW\n"));
            }
        }
    }

    /* if we did an update and the update changed the page currently displayed, then we need to redraw the page */
    if ((fDidICSUpdate == 1) && (UpdateActivePage == 1))
    {
        /* updateing the current active page, must clear the screen first */
        OS_SemTake(IGInfo.BlitLock, OS_WAIT_FOREVER);
        IGGraphicsClearBuffer(NULL, 1);

        /* tell the PE about this page and get PSR10 */
        PageSelectInfo.pPage = IGInfo.ActivePage;
        IGToPEPageSelect(&PageSelectInfo);

        /* enable default buttons and tell PE about the page */
        IGICSDrawPage(IGInfo.ActivePage, 1);

        /* highlight the selected button on the page */
        IGDoButtonSelection(IGInfo.ActivePage, (USHORT)(PageSelectInfo.PSR10));

        /* set the palette */
        IGGraphicsSetPalette(&IGPalettes[IGInfo.ActivePage->PaletteIDRef]);
        OS_SemGive(IGInfo.BlitLock);
    }
    else if (0 == fDidICSUpdate)
    {
        /* spec 8.8.4.7.2.2, if stream model is set to 1 and we are in a popup, we don't display anything,
        so just store the ICS, don't render it until we get a popup on */
        if (IsPopup() && IsOutMux())
        {
            /* clear the selected page and button by setting to NULL,
            we will enable these on a popup on command */

            /* no selected page */
            IGInfo.ActivePage = NULL;
            PageSelectInfo.pPage = IGInfo.ActivePage;
            IGToPEPageSelect(&PageSelectInfo);

            /* no selected button */
            IGInfo.SelectedButton = NULL;
            IGToPEButtonSelect(IGInfo.SelectedButton);
            OS_SemGive(IGInfo.ICSLock);
            return IG_STATUS_SUCCESS;
        }

        if ((IGInfo.ICS->NumPages > 0) && (NULL != &IGInfo.ICS->Pages[0]))
        {
            IGInfo.ActivePage = &IGInfo.ICS->Pages[0];
        }
        else
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("RenderICS(): There are no pages in this ICS\n"));

            /* no selected page */
            IGInfo.ActivePage = NULL;
            PageSelectInfo.pPage = IGInfo.ActivePage;
            IGToPEPageSelect(&PageSelectInfo);

            /* no selected button */
            IGInfo.SelectedButton = NULL;
            IGToPEButtonSelect(IGInfo.SelectedButton);
            OS_SemGive(IGInfo.ICSLock);

            return IG_STATUS_SUCCESS;
        }

        /* if we are supposed to be a startup menu condition then spin wait for pts's*/
        if (IGInfo.SyncState == IG_DECODE_ASYNC)
        {
            /* give lock while we wait */
            OS_SemGive(IGInfo.ICSLock);

            /* otherwise wait for first PTS to be given after the IGRun call */
            while ((gWaitForFrame > 0) && (IGInfo.CurrentState == IG_STATE_RUNNING))
            {
                OS_TaskYield();
            }

            /* take lock back */
            OS_SemTake(IGInfo.ICSLock, OS_WAIT_FOREVER);

            /* don't bother drawing the first frame */
               if ( (IGInfo.ICS == NULL) || (IGInfo.CurrentState != IG_STATE_RUNNING) )
            {
                OS_SemGive(IGInfo.ICSLock);
                return IG_STATUS_SUCCESS;
            }
        }

        /* tell the PE about this page and get PSR10 */
        PageSelectInfo.pPage = IGInfo.ActivePage;
        IGToPEPageSelect(&PageSelectInfo);

        /* draw page zero, this is the first draw of the new ICS */
        OS_SemTake(IGInfo.BlitLock, OS_WAIT_FOREVER);
        IGICSDrawPage(IGInfo.ActivePage, 1);

        /* highlight the selected button on the page */
        IGDoButtonSelection(IGInfo.ActivePage, (USHORT)(PageSelectInfo.PSR10));

        /* set the palette */
        IGGraphicsSetPalette(&IGPalettes[IGInfo.ActivePage->PaletteIDRef]);
        OS_SemGive(IGInfo.BlitLock);

        /* NOTE: the composition timeout and selection timeouts are only valid when
        the stream model is '0' (multiplexed).  If the stream is not multiplexed (preloaded)
        then consider it a menu which is always valid for doing things like chapter searches
        while watching the movie.  */
        if (0 == (IGInfo.ICS->StreamAndUIModel & BIT7))
        {
            /* composition timeout */
            DBGPRINT(DBG_ON(DBG_TRACE), ("RenderICS(): Composition Timeout 0x%x\n", IGInfo.ICS->CompositionTimeoutPTS));
            IGInfo.CompositionTimeoutPTS = IGInfo.ICS->CompositionTimeoutPTS;

            /* selection timeout */
            DBGPRINT(DBG_ON(DBG_TRACE), ("RenderICS(): Selection Timeout 0x%x\n", IGInfo.ICS->SelectionTimeoutPTS));
            IGInfo.SelectionTimeoutPTS = IGInfo.ICS->SelectionTimeoutPTS;
        }
        else
        {
            IGInfo.CompositionTimeoutPTS = 0;
            IGInfo.SelectionTimeoutPTS = 0;
        }
    }

    /* show the page */
    OS_TimerSet(IGInfo.TimerFlip, 1);
    OS_TaskYield();

    /* start any animations if any */
    IGStartAnimation(IGInfo.ActivePage);

    /* free the lock we are done */
    OS_SemGive(IGInfo.ICSLock);

    return IG_STATUS_SUCCESS;
}

/**
 * IGICSReset - clear out state info about the current ICS, this is done in IGRenderICS when we get a new ICS
 *
 * @param none
 *

⌨️ 快捷键说明

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