📄 modmgr.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 modmgr.cpp
*
* API to the BD-ROM Navigator's Module Manager.
* The Module Manager is responsible for managing Title playback
* in the BD-ROM Navigator.
*
* $Id: modmgr.cpp,v 1.95 2007/01/26 23:35:48 jared Exp $
*/
#include <stdio.h>
#include <stdlib.h>
#include "vdvd_types.h"
#include "osapi.h"
#ifdef VDVD_ENABLE_BDJ
# include "../bdjobjdb.h"
#endif
#include "../modmgr.h"
#include "modmgr_private.h"
#include "eventmgr.h"
#include "../indexdb.h"
#include "../mvobjdb.h"
#include "../sounddb.h"
#include "../hdmvmod/hdmvmod.h"
#include "../playctrl/playctrl.h"
#include "clpinfodb.h"
#ifdef VDVD_ENABLE_BDJ
# include "BDJModuleAPI.h"
extern IDirectFB* pDfb;
#endif
#include "dr_app.h"
#include "pe_app.h"
#include "utility.h"
#include "usrapi.h"
#include "dbgprint.h"
/* Debug macros */
#define DBG_MODMGR DBG_ERROR
#define DBG_ON(x) (DBG_MODMGR >= x)
/* Local constants */
#define MODMGR_MSG_QUEUE_DEPTH 5
#define BDJ_MOD_THREAD_PRIORITY_LEVEL 2 // Normal priority
/* UOP Masks */
const uint64 MODMGR_UOMASK_STOP = ((uint64)1 << 56);
const uint64 MODMGR_UOMASK_RESUME = ((uint64)1 << 50);
/**
* Module Manager Message types
*/
typedef enum tagMODMGR_MSG_TYPE
{
MODMGR_MSG_EXIT = 0,
MODMGR_MSG_PROCESS_USER_EVENT,
MODMGR_MSG_PROCESS_HDMV_EVENT,
MODMGR_MSG_PROCESS_BDJ_EVENT,
MODMGR_MSG_DISC_INSERT,
/* All new message types above this line */
MODMGR_MSG_INVALID
} MODMGR_MSG_TYPE;
/**
* Module Manager Message
*/
typedef struct tagMODMGR_MESSAGE
{
MODMGR_MSG_TYPE tMsgType;
MODMGR_COMMAND cmd;
int data;
OS_SEM_ID sem;
} MODMGR_MESSAGE;
/**
* Module Manager Object
*/
typedef struct tagMODMGR_BDJ_OBJECT
{
BOOLEAN fValid;
MODMGR_TITLE tTitleType;
INDEX_OBJ_ID ObjID;
ULONG ulSuspendedCmdID;
} MODMGR_OBJECT;
/**
* Module Manager Playback Location
*/
typedef struct tagMODMGR_PLAY_LOCATION
{
uint32 uiSize;
MODMGR_OBJECT MovieObject;
uint32 PSR[PSR_TOTAL_NUMBER];
uint32 GPR[GPR_TOTAL_NUMBER];
uint32 uiTimeInSeconds;
} MODMGR_PLAY_LOCATION;
/**
* Module Manager local handle
*/
typedef struct tagMODMGR_HANDLE
{
MODMGR_STATE_INFO StateInfo;
ULONG ulTaskId;
OS_MSG_Q_ID MsgQID;
MODMGR_OBJECT ActiveObj;
MODMGR_OBJECT SuspendedObj;
BOOLEAN fBDJTitleRepeat;
PE_HANDLE hPE;
} MODMGR_HANDLE;
/**
* Local variables
*/
static MODMGR_HANDLE *hModMgr = NULL;
#ifdef VDVD_ENABLE_BDJ
BDJ_Module_Handle bdj_handle;
UInt32 key_interest_table = 0;
int disc_unbound_app = 0;
bool menu_call_mask;
bool title_search_mask;
#endif
/*
** TODO: get rid of this. this is defined in BDJModuleTypes.h
** and we need these types defined even if BDJ is not active.
*/
#ifndef __CommonTypes_h__
typedef unsigned long UInt32;
typedef signed long SInt32;
typedef SInt32 SonicError;
#endif
/**
* Module Manager private functions
*/
static MODMGR_STATUS ModMgrResume(void);
static MODMGR_STATUS ModMgrJumpObj(int mobj_id);
static MODMGR_STATUS ModMgrCallObj(int mobj_id);
static MODMGR_STATUS ModMgrJumpTitle(int title_number);
static MODMGR_STATUS ModMgrCallTitle(int title_number);
static MODMGR_STATUS ModMgrHdmvTerminated(void);
static void ModMgrHdmvCallback(PVOID pvContext, HDMV_EVENT_CODE event, ULONG ulParam);
static void ModMgrPlayctrlCallback(PVOID pvContext, PLAYCTRL_EVENT_CODE event, PVOID pvParam);
static void ModMgrSplashScreenShow(void);
static void ModMgrSplashScreenHide(void);
static ULONG ModMgrTask(PVOID pvParam);
#ifdef VDVD_ENABLE_BDJ
static SInt32 ModMgrBdjCallback(UInt32 type, UInt32 param );
#endif
/**
* ModMgrCreate -- Create and Initialize Module Manager. Also, initialize
* all other components of the BD-ROM navigator.
*
* @param
* hDR -- handle to the DR
* hPE -- handle to the PE
*
* @retval
* MODMGR_SUCCESS if successful
* MODMGR_FAILURE if not successful
*/
MODMGR_STATUS ModMgrCreate(DR_HANDLE hDR, PE_HANDLE hPE)
{
if (hModMgr != NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ModMgrCreate: Already created!\n"));
return (MODMGR_FAILURE);
}
/* Create the local handle */
hModMgr = (MODMGR_HANDLE *)OS_MemAlloc(sizeof(MODMGR_HANDLE) );
if (hModMgr == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ModMgrCreate: Failure creating local handle!\n"));
goto errout;
}
/* Initialize state information */
hModMgr->StateInfo.tState = MODMGR_STATE_TERMINATED_FIRSTPLAY;
hModMgr->StateInfo.tActiveTitle = MODMGR_TITLE_NONE;
/* Initialize object references */
hModMgr->ActiveObj.fValid = FALSE;
hModMgr->SuspendedObj.fValid = FALSE;
hModMgr->fBDJTitleRepeat = FALSE;
/* Set PE handle */
hModMgr->hPE = hPE;
/* Create the message queue */
hModMgr->MsgQID = OS_MsgQCreate(MODMGR_MSG_QUEUE_DEPTH, sizeof(MODMGR_MESSAGE), OS_MSG_Q_FIFO);
if (hModMgr->MsgQID == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ModMgrCreate: Failure creating msg queue!\n"));
goto errout;
}
/* Create the Module Manager task */
hModMgr->ulTaskId = OS_TaskSpawnParam("ModMgrTask", OS_TASK_HIGH_PRIORITY, 4096, ModMgrTask, NULL, NULL);
if (hModMgr->ulTaskId == (ULONG)OS_FAILURE)
{
hModMgr->ulTaskId = 0;
DBGPRINT(DBG_ON(DBG_ERROR), ("ModMgrCreate: Failure spawning task!\n"));
goto errout;
}
/* Load the index table database */
if (IndexLoad() != INDEX_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ModMgrCreate: Failed to load index database\n"));
goto errout;
}
/* Load the movie object database */
if (MvObjLoad() != MVOBJ_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ModMgrCreate: Failed to load mobj database\n"));
goto errout;
}
/* Load the movie object database */
if (SOUNDDBLoad() != SOUNDDB_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ModMgrCreate: Failed to load sound database\n"));
/* if sounds fail, don't die completely */
}
/* Create the playback control engine */
if (PlayCtrlCreate(hDR, hPE, ModMgrPlayctrlCallback, NULL) != PLAYCTRL_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ModMgrCreate: Failure creating playback control engine!\n"));
goto errout;
}
/* Initialize the HDMV Module */
if (HdmvModInitialize(ModMgrHdmvCallback, NULL) != PLAYCTRL_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ModMgrCreate: Failure initializing hdmv module!\n"));
goto errout;
}
#ifdef VDVD_ENABLE_BDJ
BDJ_OpenBDJModule( bdj_handle, BDJ_MOD_THREAD_PRIORITY_LEVEL, pDfb );
BDJ_SetBDJCallback( bdj_handle, ModMgrBdjCallback );
#endif
return (MODMGR_SUCCESS);
errout:
/* Perform un-initialization routines */
ModMgrDelete();
return (MODMGR_FAILURE);
}
/**
* ModMgrDelete -- Delete and Uninitialize Module Manager. Also, uninitialize
* all other components of the BD-ROM navigator.
*
* @param
* none
*
* @retval
* MODMGR_SUCCESS if successful
* MODMGR_FAILURE if not successful
*/
MODMGR_STATUS ModMgrDelete(void)
{
if (hModMgr != NULL)
{
if (hModMgr->ulTaskId != 0)
{
MODMGR_MESSAGE msg;
/* Send an exit message to the Module Manager task */
msg.tMsgType = MODMGR_MSG_EXIT;
OS_MsgQSend(hModMgr->MsgQID, (char *)&msg, sizeof(MODMGR_MESSAGE), OS_NO_WAIT, OS_MSG_PRI_NORMAL);
/* Wait for task to exit then delete the task */
OS_TaskJoin(hModMgr->ulTaskId);
OS_TaskDelete(hModMgr->ulTaskId);
hModMgr->ulTaskId = 0;
}
if (hModMgr->MsgQID != 0)
{
/* Delete the msg queue */
OS_MsgQDelete(hModMgr->MsgQID);
hModMgr->MsgQID = 0;
}
/* Delete local handle */
OS_MemFree(hModMgr);
hModMgr = NULL;
}
else
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ModMgrDelete: Not created!\n"));
return (MODMGR_FAILURE);
}
return (MODMGR_SUCCESS);
}
/**
* ModMgrGetState -- Get the current state of the Module Manager
*
* @param
* none
*
* @retval
* MODMGR_STATE
*/
MODMGR_STATE ModMgrGetState(void)
{
if (hModMgr == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ModMgrGetState: Module Manager not created!\n"));
return (MODMGR_STATE_TERMINATED);
}
return (hModMgr->StateInfo.tState);
}
/**
* ModMgrAddUserEvent -- Send a User Event to the Module Manager task for processing.
*
* @param
* cmd -- specifies the command to execute
* data -- optional parameter passed with command
*
* @retval
* MODMGR_SUCCESS if successful
* MODMGR_FAILURE if not successful
*/
MODMGR_STATUS ModMgrAddUserEvent(MODMGR_COMMAND cmd, int data)
{
MODMGR_MESSAGE msg;
BOOLEAN PreFillIG = FALSE;
if (hModMgr == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ModMgrAddUserEvent: Module Manager not created!\n"));
return (MODMGR_FAILURE);
}
/* Check that message queue is created */
if (hModMgr->MsgQID == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ModMgrAddUserEvent: Msg queue not created!\n"));
return (MODMGR_FAILURE);
}
/* see if ig is prefilling, if so drop this user event */
PlayCtrlGetPrefillIGFlag(&PreFillIG);
if (PreFillIG == TRUE)
{
return (MODMGR_SUCCESS);
}
/* Any user events that change playrate should be processed sync. */
switch (cmd)
{
case MODMGR_FORWARDPLAY:
case MODMGR_BACKWARDPLAY:
case MODMGR_PAUSEON:
case MODMGR_PAUSEOFF:
case MODMGR_PLAY:
/* Create semaphore */
msg.sem = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_EMPTY);
if (msg.sem == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ModMgrAddUserEvent: Failure creating semaphore!\n"));
}
break;
default:
msg.sem = 0;
break;
}
/* Send message to the task */
msg.tMsgType = MODMGR_MSG_PROCESS_USER_EVENT;
msg.cmd = cmd;
msg.data = data;
if (OS_MsgQSend(hModMgr->MsgQID, (char *)&msg, sizeof(MODMGR_MESSAGE), OS_NO_WAIT, OS_MSG_PRI_NORMAL) != OS_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ModMgrAddUserEvent: Failure sending message!\n"));
return (MODMGR_FAILURE);
}
/* If this user event should be processed sync, then wait for it */
if (msg.sem != 0)
{
/* take semaphore, wait forever */
OS_SemTake(msg.sem, OS_WAIT_FOREVER);
/* delete semaphore */
OS_SemDelete(msg.sem);
}
return (MODMGR_SUCCESS);
}
/**
* ModMgrAddHDMVEvent -- Send a HDMV Event to the Module Manager task for processing.
*
* @param
* cmd -- specifies the command to execute
* data -- optional parameter passed with command
*
* @retval
* MODMGR_SUCCESS if successful
* MODMGR_FAILURE if not successful
*/
MODMGR_STATUS ModMgrAddHDMVEvent(MODMGR_COMMAND cmd, int data)
{
MODMGR_MESSAGE msg;
if (hModMgr == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("ModMgrAddHDMVEvent: Module Manager not created!\n"));
return (MODMGR_FAILURE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -