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

📄 ig_api.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_api.cpp
 *
 * $Revision: 1.6 $ 
 *
 * declarations of external API for IG module
 *
 */

#include <stdlib.h>
#include "vcitypes.h"
#include "osapi.h"
#include "ig_defs.h"
#include "ig_parse.h"
#include "ig_render.h"
#include "ig_graphics.h"
#include "ig_api.h"
#include "utility.h"

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

/* our one and only one status structure */
IGINFO IGInfo;
OBJECT_DEFINITION_SEGMENT IGObjList[IG_MAX_ODS];  /* our array of Objects (images) */
PALETTE IGPalettes[IG_MAX_PALETTES];
DFBRectangle IGCleanupList[IG_MAX_VISIBLE_ODS];  /* our list of objects to clean on screen */
ULONG gIGImageIndex = 0;
int gWaitForFrame = 0;
IGSTATS IGStats;

/* local prototypes */
static IG_STATUS IGScanForStartCode(BYTE *Buffer, ULONG Size, ULONG *Offset);
static IG_STATUS IGReadPESHeader(BYTE *PESStart);
static IG_STATUS IGWaitForSpaceAvail(ULONG Size);
static IG_STATUS IGAssemblePesHeader(BYTE *Buffer, ULONG Size, USHORT *ReadBytes);
static IG_STATUS IGAssembleSegmentData(BYTE *Buffer, ULONG Size, USHORT *ReadBytes);
static IG_STATUS IGAddParseMessage(ULONG BufferStart, ULONG BufferLength, ULONG DTS, ULONG PTS, ULONG Flags, BYTE MultiPES);
static void IGSendEmptyMessageToStream(cStream *Stream);
static void IGClearAddDataVars();

/**
 * IGCreate - create semaphores and threads, get everything ready for Run
 *
 * @param IG_HANDLE handle - handle to the IG module
 * @param screen_width -- width of primary surface
 * @param screen_height -- height of primary surface
 * @param dfb -- handle to directfb
 * @param disp_layer -- handle to presentation display layer
 *
 * @return IG_STATUS
 */
IG_STATUS IGCreate(IG_HANDLE *handle, int screen_width, int screen_height,
                   IDirectFB *dfb, IDirectFBDisplayLayer *disp_layer)
{
    char *   string       = getenv("player_ig_heap_size");
    uint32 ig_pool_size = 0;

    if ( (dfb == NULL) || (disp_layer == NULL) )
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGCreate(): NULL pointer\n"));
        return (IG_STATUS_ERROR_NULL_PTR);
    }

    /* our entry point, we get called here and setup our state */
    memset(&IGInfo, 0, sizeof(IGInfo));
    memset(IGPalettes, 0, sizeof(PALETTE) * IG_MAX_PALETTES);
    memset(IGObjList, 0, sizeof(OBJECT_DEFINITION_SEGMENT) * IG_MAX_ODS);
    memset(IGCleanupList, 0,  sizeof(DFBRectangle) * IG_MAX_VISIBLE_ODS);
    IGInfo.ButtonHint = NULL;  /* no button hint */

    IGInfo.CurrentState = IG_STATE_UNINITIALIZED;
    IGInfo.SyncState    = IG_DECODE_SYNC;  /* default to synchronous decoding */

    /* set dfb info */
    IGInfo.IGDFBInfo.pDFBHandle       = dfb;
    IGInfo.IGDFBInfo.DispLayer        = disp_layer;
    IGInfo.IGDFBInfo.ScreenWidth      = screen_width;
    IGInfo.IGDFBInfo.ScreenHeight     = screen_height;

    if ( getenv( "HDMV_GRFX_HALF_WIDTH" ) )
    {
        IGInfo.RLEHalfWidth = 1;
        DBGPRINT(DBG_ON(DBG_ERROR), ("(*) IG Half Width Enabled\n"));
    }
    else
    {
        IGInfo.RLEHalfWidth = 0;
    }

    if ( getenv( "HDMV_GRFX_PROFILE" ) )
    {
        IGStats.Profiling = 1;
        DBGPRINT(DBG_ON(DBG_ERROR), ("(*) IG Profiling Enabled\n"));
    }
    else
    {
        IGStats.Profiling = 0;
    }

    /* create our palettes with default colors */
    if (IG_STATUS_SUCCESS != IGGraphicsCreateAllPalettes())
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGCreate(): Failed to create all palettes\n"));
        return IG_STATUS_ERROR;
    }

    /* when ig starts it is not visible */
    if (IGInfo.IGDFBInfo.DispLayer->SetLevel(IGInfo.IGDFBInfo.DispLayer, IG_DISPLAY_NO_SHOW) != DFB_OK)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGCreate(): Failed to set the level to -1\n"));
        return IG_STATUS_ERROR;
    }

    /* popups are not on to start */
    IGInfo.fPopupEnabled = FALSE;

    /* get the primary surface for the IG diplay layer */
    if (IGInfo.IGDFBInfo.DispLayer->GetSurface(IGInfo.IGDFBInfo.DispLayer, &IGInfo.IGDFBInfo.PrimarySurface) != DFB_OK)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGCreate: Failed to get surface\n"));
        goto errout;
    }

    /* set ig preallocated surface pool size */
    if (string)
    {
        /* user defined */
        ig_pool_size = strtoul(string, NULL, 10)*1024*1024;
    }
    else
    {
        /* default to 32MB */
        ig_pool_size = 32*1024*1024;
    }

    /* Create surface manager */
    if (IGInfo.IGDFBInfo.pDFBHandle->CreateSurfaceManager(IGInfo.IGDFBInfo.pDFBHandle, ig_pool_size,
        1024, DSMT_SURFACEMANAGER_BUDDY, &IGInfo.IGDFBInfo.SurfaceManager) != DFB_OK)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGCreate: Failed to create surface manager\n"));
        goto errout;
    }

    /* allocate IGParseBuffer */
    IGInfo.IGParseBuffer = (BYTE *)OS_MemAlloc(SIZE_IG_CODED_DATA_BUFFER);
    if (IGInfo.IGParseBuffer == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGCreate(): Could not alloc IGParseBuffer\n\n"));
        goto errout;
    }

    /* ICS lock */
    IGInfo.ICSLock = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_FULL);
    if (0 == IGInfo.ICSLock)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGCreate(): Failed to create ICS lock semaphore\n"));
        goto errout;
    }

    /* Parse lock */
    IGInfo.ParseLock = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_FULL);
    if (0 == IGInfo.ParseLock)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGCreate(): Failed to create Parse lock semaphore\n"));
        goto errout;
    }

    /* Blit lock */
    IGInfo.BlitLock = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_FULL);
    if (0 == IGInfo.BlitLock)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGCreate(): Failed to create Blit lock semaphore\n"));
        goto errout;
    }

    /* State lock */
    IGInfo.StateLock = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_FULL);
    if (0 == IGInfo.StateLock)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGCreate(): Failed to create State lock semaphore\n"));
        goto errout;
    }

    /* the parse wait semaphore, NOTE created EMPTY */
    IGInfo.ParseWait.WaitSem = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_EMPTY);
    if (0 == IGInfo.ParseWait.WaitSem)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGCreate(): Failed to create Parsewait semaphore\n"));
        goto errout;
    }

    /* the render wait semaphore, NOTE created EMPTY */
    IGInfo.RenderWait.WaitSem = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_EMPTY);
    if (0 == IGInfo.RenderWait.WaitSem)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGCreate(): Failed to create Renderwait semaphore\n"));
        goto errout;
    }

    /* create ig message queue */
    IGInfo.IGParseQ = new cStream;
    IGInfo.IGParseQPool = OS_MemAlloc(sizeof(IG_PARSE_MSG) * IG_PARSE_Q_DEPTH);
    if ((NULL == IGInfo.IGParseQ) || (NULL == IGInfo.IGParseQPool))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGCreate(): Unable to create IG Parse Q!\n"));
        goto errout;
    }
    else
    {
        IGInfo.IGParseQ->Initialize(IGInfo.IGParseQPool, IG_PARSE_Q_DEPTH, sizeof(IG_PARSE_MSG), "IG_PARSE_Q");
    }

    /* create ig message queue */
    IGInfo.IGRenderQ = new cStream;
    IGInfo.IGRenderQPool = OS_MemAlloc(sizeof(IG_RENDER_MSG) * IG_RENDER_Q_DEPTH);
    if ((NULL == IGInfo.IGRenderQ) || (NULL == IGInfo.IGRenderQPool))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGCreate(): Unable to create IG Parse Q!\n"));
        goto errout;
    }
    else
    {
        IGInfo.IGRenderQ->Initialize(IGInfo.IGRenderQPool, IG_RENDER_Q_DEPTH, sizeof(IG_RENDER_MSG), "IG_RENDER_Q");
    }

    /* create the user selection timer */
    if (OS_OK != OS_TimerCreate(&IGInfo.TimerUserSelection, IGOnUserSelectionTimeout))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGCreate(): Unable to create the Timer User Selection\n"));
        goto errout;
    }

    /* create the user selection timer */
    if (OS_OK != OS_TimerCreate(&IGInfo.TimerAnimation, IGOnAnimation))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGCreate(): Unable to create the Timer Animation\n"));
        goto errout;
    }

    /* create the flip timer */
    if (OS_OK != OS_TimerCreate(&IGInfo.TimerFlip, IGGraphicsFlip))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGCreate(): Unable to create the Flip Timer\n"));
        goto errout;
    }

    /* create igparse task */
    IGInfo.IGParseTask = OS_TaskSpawnParam("IG Parse Task", IG_PARSE_PRIORITY, IG_PARSE_STACK_SIZE, IGParse, NULL, NULL);
    if (OS_FAILURE == IGInfo.IGParseTask)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGCreate(): Unable to create IG Parse thread!\n"));
        goto errout;
    }

    /* start igrender task */
    IGInfo.IGRenderTask = OS_TaskSpawnParam("IG Render Task", IG_RENDER_PRIORITY, IG_RENDER_STACK_SIZE, IGRender, NULL, NULL);
    if (OS_FAILURE == IGInfo.IGRenderTask)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("IGCreate(): Unable to create IG Render thread!\n"));
        goto errout;
    }

    /* we are now initialized */
    IGInfo.CurrentState = IG_STATE_INITIALIZED;

    /* allocate a handle here?  or just give anything back */
    *handle = (PVOID)IG_HANDLE_VALUE;

    return IG_STATUS_SUCCESS;

errout:

    /* set the exit flag for the parser and renderer */
    IGInfo.QuitFlags = IG_FLAGS_EXIT;

    /* free everything and return an error */
    if (IGInfo.IGParseTask)
    {
        OS_TaskJoin(IGInfo.IGParseTask);
        OS_TaskDelete(IGInfo.IGParseTask);
        IGInfo.IGParseTask = 0;
    }

    if (IGInfo.IGRenderTask)
    {
        OS_TaskJoin(IGInfo.IGRenderTask);
        OS_TaskDelete(IGInfo.IGRenderTask);
        IGInfo.IGRenderTask = 0;
    }

    if (IGInfo.TimerUserSelection)
    {
        OS_TimerDelete(IGInfo.TimerUserSelection);
        IGInfo.TimerUserSelection = 0;
    }

    if (IGInfo.TimerFlip)
    {
        OS_TimerDelete(IGInfo.TimerFlip);
        IGInfo.TimerFlip = 0;
    }

    if (IGInfo.TimerAnimation)
    {
        OS_TimerDelete(IGInfo.TimerAnimation);
        IGInfo.TimerAnimation = 0;
    }

    if (IGInfo.IGParseQ)
    {
        delete IGInfo.IGParseQ;
        IGInfo.IGParseQ = NULL;
    }

    if (IGInfo.IGParseQPool)
    {
        OS_MemFree(IGInfo.IGParseQPool);
        IGInfo.IGParseQPool = NULL;
    }

    if (IGInfo.IGRenderQ)
    {
        delete IGInfo.IGRenderQ;
        IGInfo.IGRenderQ = NULL;
    }

    if (IGInfo.IGRenderQPool)
    {
        OS_MemFree(IGInfo.IGRenderQPool);
        IGInfo.IGRenderQPool = NULL;
    }

    if (IGInfo.StateLock)
    {
        OS_SemDelete(IGInfo.StateLock);
        IGInfo.StateLock = 0;
    }

    if (IGInfo.BlitLock)
    {
        OS_SemDelete(IGInfo.BlitLock);
        IGInfo.BlitLock = 0;
    }

    if (IGInfo.ICSLock)
    {

⌨️ 快捷键说明

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