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

📄 hdmvmod.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************
******************************************************************************
**                                                                          **
**  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 + -