📄 hdmvmod.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 hdmvmod.cpp
*
* API to the BD-ROM Navigator's HDMV Module.
* The HDMV Module is responsible for processing Movie Objects
* and Button Objects in HDMV mode.
*
* $Id: hdmvmod.cpp,v 1.20 2006/10/25 23:38:48 rbehe Exp $
*/
#include "vdvd_types.h"
#include "osapi.h"
#include "../mvobjdb.h"
#include "../playctrl/playctrl.h"
#include "hdmvmod.h"
#include "cmdproc.h"
#include "dbgprint.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif
/* Debug macros */
#define DBG_HDMVMOD DBG_ERROR
#define DBG_ON(x) (DBG_HDMVMOD >= x)
/* Local constants */
#define HDMVMOD_MSG_QUEUE_DEPTH 5
/**
* HDMV Module Message types
*/
typedef enum tagHDMVMOD_MSG_TYPE
{
HDMVMOD_MSG_EXIT = 0,
HDMVMOD_MSG_PROCESS_MOBJ,
HDMVMOD_MSG_TERMINATE_MOBJ,
HDMVMOD_MSG_SUSPEND_MOBJ,
HDMVMOD_MSG_RESUME_MOBJ,
HDMVMOD_MSG_LOAD_MOBJ,
HDMVMOD_MSG_PROCESS_BOBJ,
HDMVMOD_MSG_PLAYBACK_COMPLETE,
HDMVMOD_MSG_NVTIMER_EXPIRE,
HDMVMOD_MSG_REPEAT,
/* All new message types above this line */
HDMVMOD_MSG_INVALID
} HDMVMOD_MSG_TYPE;
/**
* HDMV Module Message
*/
typedef struct tagHDMVMOD_MESSAGE
{
HDMVMOD_MSG_TYPE tMsgType;
ULONG ulData0;
ULONG ulData1;
PVOID pvBuffer;
ULONG ulBufferLength;
ULONG ulSemID;
ULONG* pulRetVal;
} HDMVMOD_MESSAGE;
/**
* HDMV Module local handle
*/
typedef struct tagHDMVMOD_HANDLE
{
HDMV_CALLBACK callback;
PVOID pvCallbackContext;
HDMVMOD_STATE tState;
ULONG ulTaskId;
OS_MSG_Q_ID MsgQID;
OS_SEM_ID sem_sync;
PVOID pvMemPoolBuf;
OS_MEMPOOL_ID mempoolBtnCmds;
} HDMVMOD_HANDLE;
/**
* Local variables
*/
HDMVMOD_HANDLE *hHdmvMod = NULL;
/**
* Local functions
*/
static ULONG HdmvModTask(PVOID pvParam);
static void HdmvModEvaluateStatus(CMDPROC_STATUS tStatus, ULONG ulStatusParam);
/**
* HdmvModInitialize -- Initialize the HDMV Module
*
* @param
* callback -- callback function to receive HDMV events
* pvContext -- callback context
*
* @retval
* HDMVMOD_SUCCESS if successful
* HDMVMOD_FAILURE if not successful
* HDMVMOD_NULL_PTR if callback is NULL
*/
HDMVMOD_STATUS HdmvModInitialize(HDMV_CALLBACK callback, PVOID pvContext)
{
ULONG ulSizeOfMemPool;
if (hHdmvMod != NULL)
{
DbgPrint(( "HdmvModInitialize: Already created!\n"));
return (HDMVMOD_FAILURE);
}
if (callback == NULL)
{
DbgPrint(( "HdmvModInitialize: Must supply a valid callback!\n"));
return (HDMVMOD_NULL_PTR);
}
/* Create the local handle */
hHdmvMod = (HDMVMOD_HANDLE *)OS_MemAlloc(sizeof(HDMVMOD_HANDLE) );
if (hHdmvMod == NULL)
{
DbgPrint(( "HdmvModInitialize: Failure creating local handle!\n"));
goto errout;
}
/* Initialize state */
hHdmvMod->tState = HDMVMOD_STATE_TERMINATED;
hHdmvMod->sem_sync = 0;
hHdmvMod->MsgQID = 0;
hHdmvMod->ulTaskId = 0;
hHdmvMod->callback = callback;
hHdmvMod->pvCallbackContext = pvContext;
/* create a memory pool for receiving Button Navigation Commands */
ulSizeOfMemPool = sizeof(MVOBJ_NAV_COMMAND) * 510; /* enough for 2 max sized button programs */
hHdmvMod->pvMemPoolBuf = OS_MemAlloc(ulSizeOfMemPool);
hHdmvMod->mempoolBtnCmds = OS_CreateMemPool(hHdmvMod->pvMemPoolBuf, ulSizeOfMemPool, sizeof(MVOBJ_NAV_COMMAND));
if (hHdmvMod->mempoolBtnCmds == NULL)
{
DbgPrint(( "HdmvModInitialize: memPool creation failed!\n"));
goto errout;
}
/* Create semaphore used for synchronous message processing */
hHdmvMod->sem_sync = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_EMPTY);
if (hHdmvMod->sem_sync == 0)
{
DbgPrint(( "HdmvModInitialize: Failure creating semaphore!\n"));
goto errout;
}
/* Create the message queue */
hHdmvMod->MsgQID = OS_MsgQCreate(HDMVMOD_MSG_QUEUE_DEPTH, sizeof(HDMVMOD_MESSAGE), OS_MSG_Q_FIFO);
if (hHdmvMod->MsgQID == 0)
{
DbgPrint(( "HdmvModInitialize: Failure creating msg queue!\n"));
goto errout;
}
/* Create a task to receive and process messages */
hHdmvMod->ulTaskId = OS_TaskSpawnParam("HdmvModTask", OS_TASK_HIGH_PRIORITY, 4096, HdmvModTask, NULL, NULL);
if (hHdmvMod->ulTaskId == (ULONG)OS_FAILURE)
{
hHdmvMod->ulTaskId = 0;
DbgPrint(( "HdmvModInitialize: Failure spawning task!\n"));
goto errout;
}
/* Initialize the command processor */
if (CmdProcInitialize() != CMDPROC_SUCCESS)
{
DbgPrint(( "HdmvModInitialize: Failure initializing command processor!\n"));
goto errout;
}
return (HDMVMOD_SUCCESS);
errout:
/* Perform un-initialization routines */
HdmvModUninitialize();
return (HDMVMOD_FAILURE);
}
/**
* HdmvModUninitialize -- Uninitialize the HDMV Module
*
* @param
* none
*
* @retval
* HDMVMOD_SUCCESS if successful
* HDMVMOD_FAILURE if not successful
*/
HDMVMOD_STATUS HdmvModUninitialize(void)
{
if (hHdmvMod != NULL)
{
if (hHdmvMod->ulTaskId != 0)
{
HDMVMOD_MESSAGE msg;
/* Send an exit message to the HDMV Module task */
msg.tMsgType = HDMVMOD_MSG_EXIT;
msg.ulData0 = 0;
msg.ulData1 = 0;
msg.ulSemID = 0;
OS_MsgQSend(hHdmvMod->MsgQID, (char *)&msg, sizeof(HDMVMOD_MESSAGE), OS_NO_WAIT, OS_MSG_PRI_NORMAL);
/* Wait for task to exit then delete the task */
OS_TaskJoin(hHdmvMod->ulTaskId);
OS_TaskDelete(hHdmvMod->ulTaskId);
hHdmvMod->ulTaskId = 0;
}
/* Uninit command processor */
CmdProcUninitialize();
if (hHdmvMod->MsgQID != 0)
{
/* Delete the msg queue */
OS_MsgQDelete(hHdmvMod->MsgQID);
hHdmvMod->MsgQID = 0;
}
if (0 != hHdmvMod->sem_sync)
{
OS_SemDelete(hHdmvMod->sem_sync);
hHdmvMod->sem_sync = 0;
}
/* free memory pool */
if (hHdmvMod->pvMemPoolBuf != NULL)
{
OS_MemFree(hHdmvMod->pvMemPoolBuf);
}
if (hHdmvMod->mempoolBtnCmds != NULL)
{
OS_DeleteMemPool(hHdmvMod->mempoolBtnCmds);
}
/* Delete local handle */
OS_MemFree(hHdmvMod);
hHdmvMod = NULL;
}
else
{
DBGPRINT(DBG_ON(DBG_ERROR), ("HdmvModUninitialize: Not created!\n"));
return (HDMVMOD_FAILURE);
}
return (HDMVMOD_SUCCESS);
}
/**
* HdmvModGetState -- Get the current state of the HDMV Module.
*
* @param
* none.
*
* @retval
* HDMVMOD_STATE
*/
HDMVMOD_STATE HdmvModGetState(void)
{
if (hHdmvMod == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("HdmvModGetState: HDMV Module not created!\n"));
return (HDMVMOD_STATE_INVALID);
}
return (hHdmvMod->tState);
}
/**
* HdmvModProcessMobj -- Process the specified movie object
*
* @param
* ulMobjID -- ID of movie object to be processed
*
* @retval
* HDMVMOD_SUCCESS if successful
* HDMVMOD_FAILURE if not successful
*/
HDMVMOD_STATUS HdmvModProcessMobj(ULONG ulMobjID)
{
HDMVMOD_MESSAGE msg;
if (hHdmvMod == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("HdmvModProcessMobj: HDMV Module not created!\n"));
return (HDMVMOD_FAILURE);
}
/* Check that message queue is created */
if (hHdmvMod->MsgQID == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("HdmvModProcessMobj: Msg queue not created!\n"));
return (HDMVMOD_FAILURE);
}
/* Send message to the task */
msg.tMsgType = HDMVMOD_MSG_PROCESS_MOBJ;
msg.ulData0 = ulMobjID;
msg.ulData1 = 0;
msg.ulSemID = 0;
if (OS_MsgQSend(hHdmvMod->MsgQID, (char *)&msg, sizeof(HDMVMOD_MESSAGE), OS_NO_WAIT, OS_MSG_PRI_NORMAL) != OS_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("HdmvModProcessMobj: Failure sending message!\n"));
return (HDMVMOD_FAILURE);
}
return (HDMVMOD_SUCCESS);
}
/**
* HdmvModTerminateMobj -- Terminate processing of current movie object
*
* @param
* none
*
* @retval
* HDMVMOD_SUCCESS if successful
* HDMVMOD_FAILURE if not successful
*/
HDMVMOD_STATUS HdmvModTerminateMobj(void)
{
HDMVMOD_MESSAGE msg;
ULONG ulStatus;
if (hHdmvMod == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("HdmvModTerminateMobj: HDMV Module not created!\n"));
return (HDMVMOD_FAILURE);
}
/* Check that message queue is created */
if (hHdmvMod->MsgQID == 0)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("HdmvModTerminateMobj: Msg queue not created!\n"));
return (HDMVMOD_FAILURE);
}
/* Reset sem_sync */
OS_SemTake(hHdmvMod->sem_sync, OS_NO_WAIT);
/* Send message to the task. Send semaphore to make it synchronous. */
msg.tMsgType = HDMVMOD_MSG_TERMINATE_MOBJ;
msg.ulData0 = 0;
msg.ulData1 = 0;
msg.ulSemID = hHdmvMod->sem_sync;
msg.pulRetVal = &ulStatus;
if (OS_MsgQSend(hHdmvMod->MsgQID, (char *)&msg, sizeof(HDMVMOD_MESSAGE), OS_NO_WAIT, OS_MSG_PRI_NORMAL) != OS_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("HdmvModTerminateMobj: Failure sending message!\n"));
return (HDMVMOD_FAILURE);
}
else
{
/* Wait for message processing to complete */
OS_SemTake(hHdmvMod->sem_sync, OS_WAIT_FOREVER);
}
return ( (HDMVMOD_STATUS)ulStatus);
}
/**
* HdmvModSuspendMobj -- Suspend processing of current movie object
*
* @param
* pulCmdID -- pointer to command ID that gets set to suspended position in
* the Movie Object command program
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -