📄 ig_api.cpp
字号:
/*****************************************************************************
******************************************************************************
** **
** 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 + -