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

📄 pg_api.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/*****************************************************************************
******************************************************************************
**                                                                          **
**  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 pg_api.cpp
 *
 * $Revision: 1.7 $ 
 *
 * declarations of external API for PG module
 *
 */

#include "vcitypes.h"
#include "osapi.h"
#include <stdlib.h>
#include "pg_defs.h"
#include "pg_parse.h"
#include "pg_render.h"
#include "pg_graphics.h"
#include "pg_api.h"
#include "utility.h"

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

#define PG_HANDLE_VALUE     0x21098765  /* arbitrary, but enforced */

/* structures used throughout the module */
PGINFO PGInfo;
PGSTATS PGStats;
OBJECT_DEFINITION_SEGMENT PGObjList[PG_MAX_ODS];  /* our array of Objects (images) */
PALETTE PGPalettes[PG_MAX_PALETTES];

/* local prototypes */
static PG_STATUS PGScanForStartCode(BYTE *Buffer, ULONG Size, ULONG *Offset);
static PG_STATUS PGReadPESHeader(BYTE *PESStart);
static PG_STATUS PGWaitForSpaceAvail(ULONG Size);
static PG_STATUS PGAssemblePesHeader(BYTE *Buffer, ULONG Size, USHORT *ReadBytes);
static PG_STATUS PGAssembleSegmentData(BYTE *Buffer, ULONG Size, USHORT *ReadBytes);
static PG_STATUS PGAddParseMessage(ULONG BufferStart, ULONG BufferLength, ULONG DTS, ULONG PTS, ULONG Flags, BYTE MultiPES);
static void PGSendEmptyMessageToStream(cStream *Stream);
static void PGClearAddDataVars();

/**
 * PGCreate - create semaphores and threads, get everything ready for Run
 *
 * @param PG_HANDLE handle - handle to the PG module
 * @param screen_width -- width of primary surface
 * @param screen_height -- height of primary surface
 * @param dfb -- handle to directfb
 * @param sfc -- handle to primary surface for pg/textst
 * @param disp_layer -- handle to presentation display layer
 *
 * @return PG_STATUS
 */
PG_STATUS PGCreate(PG_HANDLE *handle, int screen_width, int screen_height,
                   IDirectFB *dfb, IDirectFBDisplayLayer *disp_layer)
{
    char *   string       = getenv("player_pg_heap_size");
    uint32   pg_pool_size = 0;

    DBGPRINT(DBG_ON(DBG_TRACE), ("--PGCreate\n"));

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

    /* our entry point, we get called here and setup our state */
    memset(&PGInfo, 0, sizeof(PGInfo));
    memset(PGObjList, 0, PG_MAX_ODS * sizeof(OBJECT_DEFINITION_SEGMENT));
    memset(PGPalettes, 0, PG_MAX_PALETTES * sizeof(PALETTE));
    memset(&PGStats, 0, sizeof(PGSTATS));

    PGInfo.CurrentState = PG_STATE_UNINITIALIZED;

    /* set dfb info */
    PGInfo.DFBInfo.pDFBHandle       = dfb;
    PGInfo.DFBInfo.DispLayer        = disp_layer;
    PGInfo.DFBInfo.ScreenWidth      = screen_width;
    PGInfo.DFBInfo.ScreenHeight     = screen_height;

    if ( getenv( "HDMV_GRFX_HALF_WIDTH" ) )
    {
        PGInfo.RLEHalfWidth = 1;
        DbgPrint(("(*) PG Half Width Enabled\n"));
    }
    else
    {
        PGInfo.RLEHalfWidth = 0;
    }

    if ( getenv( "HDMV_GRFX_FRAME_DROPPING" ) )
    {
        PGInfo.FrameDropping = 1;
        DbgPrint(("(*) PG Frame Dropping Enabled\n"));
    }
    else
    {
        PGInfo.FrameDropping = 0;
    }

    if ( getenv( "HDMV_GRFX_PROFILE" ) )
    {
        PGStats.Profiling = 1;
        DbgPrint(("(*) PG Profiling Enabled\n"));
    }
    else
    {
        PGStats.Profiling = 0;
    }

    /* create our palettes with default colors */
    if (PG_STATUS_SUCCESS != PGGraphicsCreateAllPalettes())
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PG: Failed to create all palettes\n"));
        return PG_STATUS_ERROR;
    }

    /* turn pg display on */
    if (PGInfo.DFBInfo.DispLayer->SetLevel(PGInfo.DFBInfo.DispLayer, PG_DISPLAY_LEVEL) != DFB_OK)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PGCreate: Failed to set the level to 1\n"));
        return PG_STATUS_ERROR;
    }

    /* get the primary surface for the PG diplay layer */
    if (PGInfo.DFBInfo.DispLayer->GetSurface(PGInfo.DFBInfo.DispLayer, &PGInfo.DFBInfo.PrimarySurface) != DFB_OK)
    {
        DbgPrint(("PGCreate: Failed to get surface\n"));
        goto errout;
    }

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

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

    /* allocate PGParseBuffer */
    PGInfo.PGParseBuffer = (BYTE *)OS_MemAlloc(SIZE_PG_CODED_DATA_BUFFER);
    if (PGInfo.PGParseBuffer == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("\n PGCreate(): Could not alloc PGParseBuffer\n\n"));
        goto errout;
    }

    /* semaphore access to the Render task */
    PGInfo.RenderLock = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_FULL);
    if (0 == PGInfo.RenderLock)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PGCreate: Failed to create RenderLock semaphore\n"));
        goto errout;
    }

    /* semaphore access to the Render task */
    PGInfo.BlitLock = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_FULL);
    if (0 == PGInfo.BlitLock)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PGCreate: Failed to create BlitLock semaphore\n"));
        goto errout;
    }

    /* semaphore access to state changes (pgrun pgstop pgadddata) */
    PGInfo.StateLock = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_FULL);
    if (0 == PGInfo.StateLock)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PGCreate: Failed to create StateLock semaphore\n"));
        goto errout;
    }

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

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

    /* create pg message queue*/
    PGInfo.PGParseQ = new cStream;
    PGInfo.PGParseQPool = OS_MemAlloc(sizeof(PG_PARSE_MSG) * PG_PARSE_Q_DEPTH);
    if ((NULL == PGInfo.PGParseQ) || (NULL == PGInfo.PGParseQPool))
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("Unable to create PG Parse Q!\n"));
        goto errout;
    }
    else
    {
        PGInfo.PGParseQ->Initialize(PGInfo.PGParseQPool, PG_PARSE_Q_DEPTH, sizeof(PG_PARSE_MSG), "PG_PARSE_Q");
    }

    /* create pgparse task */
    PGInfo.PGParseTask = OS_TaskSpawnParam("PG Parse Task", PG_PARSE_PRIORITY,
                                            PG_PARSE_STACK_SIZE, PGParse, NULL, NULL);
    if (OS_FAILURE == PGInfo.PGParseTask)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("\nUnable to create PG Parse thread!\n"));
        goto errout;
    }

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

    /* we are now initialized */
    PGInfo.CurrentState = PG_STATE_INITIALIZED;
    PGInfo.ShowGraphics = PG_HIDE_GRAPHICS;

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

    return PG_STATUS_SUCCESS;

errout:

    /* free everything and return an error */
    if (PGInfo.PGFlipTimer != 0)
    {
        OS_TimerDelete(PGInfo.PGFlipTimer);
        PGInfo.PGFlipTimer = 0;
    }

    if (PGInfo.PGParseTask)
    {
        OS_TaskDelete(PGInfo.PGParseTask);
        PGInfo.PGParseTask = 0;
    }

    if (PGInfo.PGParseQ)
    {
        delete PGInfo.PGParseQ;
        PGInfo.PGParseQ = NULL;
    }

    if (PGInfo.PGParseQPool)
    {
        OS_MemFree(PGInfo.PGParseQPool);
        PGInfo.PGParseQPool = NULL;
    }

    if (PGInfo.RenderLock)
    {
        OS_SemDelete(PGInfo.RenderLock);
        PGInfo.RenderLock = 0;
    }

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

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

    if (PGInfo.ParseWait.WaitSem)
    {
        OS_SemDelete(PGInfo.ParseWait.WaitSem);
        PGInfo.ParseWait.WaitSem = 0;
    }

    if (PGInfo.RenderWait.WaitSem)
    {
        OS_SemDelete(PGInfo.RenderWait.WaitSem);
        PGInfo.RenderWait.WaitSem = 0;
    }

    if (PGInfo.PGParseBuffer != NULL)
    {
        OS_MemFree(PGInfo.PGParseBuffer);
        PGInfo.PGParseBuffer = NULL;
    }

    /* release dfb surface */
    if (PGInfo.DFBInfo.PrimarySurface != NULL)
    {
        PGInfo.DFBInfo.PrimarySurface->Release(PGInfo.DFBInfo.PrimarySurface);
    }

    /* release surface manager */
    if (PGInfo.DFBInfo.SurfaceManager != NULL)
    {
        PGInfo.DFBInfo.SurfaceManager->Release(PGInfo.DFBInfo.SurfaceManager);
    }

    return PG_STATUS_ERROR;
}

/**
 * PGDelete - stop threads and free all memory
 *
 * @param PG_HANDLE handle - handle to the PG module
 *
 * @return PG_STATUS
 */
PG_STATUS PGDelete(PG_HANDLE handle)
{
    if (handle != (PVOID)PG_HANDLE_VALUE)
    {
        return PG_STATUS_INVALID_HANDLE;
    }

    DBGPRINT(DBG_ON(DBG_TRACE), ("--PGDelete()\n"));

    /* must be in the stopped or initialized state to shutdown */
    if ((PG_STATE_STOPPED == PGInfo.CurrentState) || (PG_STATE_INITIALIZED == PGInfo.CurrentState))
    {
        /* set the exit flag for the parser and renderer */
        PGInfo.QuitFlags = PG_FLAGS_EXIT;

        /* que an empty message to render and parse */
        PGSendEmptyMessageToStream(PGInfo.PGParseQ);

        /* wait for tasks to quit */
        OS_TaskJoin(PGInfo.PGParseTask);

        /* turn pg display off */
        PGGraphicsDeleteAllPalettes();
        PGGraphicsClearBuffer(NULL, 0);
        PGInfo.DFBInfo.DispLayer->SetLevel(PGInfo.DFBInfo.DispLayer, -1);
        PGGraphicsFlip();

        /* destroy all threads and cleanup memory */
        if (PGInfo.PGParseTask)
        {
            OS_TaskDelete(PGInfo.PGParseTask);
            PGInfo.PGParseTask = 0;
        }

        if (PGInfo.PGParseQ)
        {
            PGInfo.PGParseQ->Destroy();
            delete PGInfo.PGParseQ;
            PGInfo.PGParseQ = NULL;
        }

        if (PGInfo.PGParseQPool)
        {
            OS_MemFree(PGInfo.PGParseQPool);
            PGInfo.PGParseQPool = NULL;
        }

        if (PGInfo.RenderLock)
        {
            OS_SemDelete(PGInfo.RenderLock);
            PGInfo.RenderLock = 0;
        }

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

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

        if (PGInfo.ParseWait.WaitSem)
        {
            OS_SemDelete(PGInfo.ParseWait.WaitSem);
            PGInfo.ParseWait.WaitSem = 0;
        }

        if (PGInfo.RenderWait.WaitSem)
        {
            OS_SemDelete(PGInfo.RenderWait.WaitSem);
            PGInfo.RenderWait.WaitSem = 0;
        }

        if (PGInfo.PGParseBuffer != NULL)
        {
            OS_MemFree(PGInfo.PGParseBuffer);
            PGInfo.PGParseBuffer = NULL;
        }

        if (PGInfo.PGFlipTimer != 0)

⌨️ 快捷键说明

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