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

📄 cdda_app.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                    /* Sending two stop commands to get a full stop state */
                    /* @todo Add a full stop command */
                    CddaCmdMsg.bCommand = CDDA_CMD_STOP;
                    uiStatus = (uint32) OS_MsgQSend(CddaAppControl.osqidQueueCdda, (char *) &CddaCmdMsg,
                        CDDA_MSG_SIZE_BYTES, OS_NO_WAIT, OS_MSG_PRI_NORMAL);
                    if (OS_OK != uiStatus)
                    {
                        DBGPRINT(DBG_ON(DBG_ERROR), ("\n%s(): ERROR (0x%lX): OS_MsgQSend.\n", __FUNCTION__, uiStatus));
                    }
                    CddaCmdMsg.bCommand = CDDA_CMD_STOP;
                    uiStatus = (uint32) OS_MsgQSend(CddaAppControl.osqidQueueCdda, (char *) &CddaCmdMsg,
                        CDDA_MSG_SIZE_BYTES, OS_WAIT_FOREVER, OS_MSG_PRI_NORMAL);
                    if (OS_OK != uiStatus)
                    {
                        DBGPRINT(DBG_ON(DBG_ERROR), ("\n%s(): ERROR (0x%lX): OS_MsgQSend.\n", __FUNCTION__, uiStatus));
                    }
                }
                break;

            case PE_EVENT_DISCONTINUITY:
                DBGPRINT(DBG_ON(DBG_TRACE), ("\n%s(): PE_EVENT_DISCONTINUITY\n", __FUNCTION__));
                break;

            case PE_EVENT_ASYNC_PREFILL:
                DBGPRINT(DBG_ON(DBG_TRACE), ("\n%s(): PE_EVENT_ASYNC_PREFILL\n", __FUNCTION__));
                PEiStreamCtrlResume(CddaAppControl.tPE);
                
                pePlayRate.direction = PE_ISTREAMCTRL_DIRECTION_FORWARD;
                pePlayRate.discontiguous = FALSE;
                pePlayRate.rate = PLAY_RATE_NORMAL;

                ulStatus = (ULONG) PEiStreamCtrlSetRate(CddaAppControl.tPE, &pePlayRate);
                if (PE_SUCCESS != ulStatus)
                {
                    DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR (0x%X): Call to PEiStreamCtrlSetRate failed.\n", __FUNCTION__, ulStatus));
                }

                ulStatus = (ULONG) PEiStreamCtrlRun(CddaAppControl.tPE);
                if (PE_SUCCESS != ulStatus)
                {
                    DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR (0x%X): Call to PEiStreamCtrlRun failed.\n", __FUNCTION__, ulStatus));
                }

                break;

            default:
                DBGPRINT(DBG_ON(DBG_ERROR), ("\n%s(): ERROR: Invalid or non-applicable PE event code (0x%X) received.\n",
                    __FUNCTION__, ulEventCode));
                status = OS_FAILURE;
                break;
        }
    }
    else
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("\n%s(): Invalid event source\n", __FUNCTION__));
        status = OS_FAILURE;
    }

    return (status);
}



/**
 * Sends message to nav_task in response to input commands.
 *
 * @param ulCommand - Received command to be processed.
 * @param ulInfo    - Additional command information passed to this command handler.
 *
 * @return OS_STATUS - Status / error code.
 */
OS_STATUS CddaAppCommandHandler(ULONG ulCommand, ULONG ulInfo)
{
    ULONG               ulStatus;
    BOOLEAN             fIsSupported;
    CDDA_CommandMsg     CddaCmdMsg;
    ULONG               status_event[4];

    /* Map command to a nav_task command */
    fIsSupported = TRUE;
    CddaCmdMsg.sSpeed = 1;

    switch (ulCommand)
    {
        case VDVD_COMMAND_PLAY:
        case VDVD_COMMAND_PAUSE_OFF:
            DBGPRINT(DBG_ON(DBG_TRACE), ("%s(): VDVD_COMMAND_PLAY\n", __FUNCTION__));
            CddaCmdMsg.bCommand     = CDDA_CMD_PLAY;
            CddaCmdMsg.bTrackNumber = (BYTE)ulInfo;
            break;

        case VDVD_COMMAND_GOTO_CHAPTER:
            DBGPRINT(DBG_ON(DBG_TRACE), ("%s(): VDVD_COMMAND_GOTO_CHAPTER\n", __FUNCTION__));
            CddaCmdMsg.bCommand     = CDDA_CMD_GOTO_TRACK;
            CddaCmdMsg.bTrackNumber = (BYTE)ulInfo;
            break;

        case VDVD_COMMAND_RANDOM:
            CddaCmdMsg.bCommand = CDDA_CMD_RANDOM;
            break;

        case VDVD_COMMAND_STEP_FWD:
        case VDVD_COMMAND_PAUSE_ON:
            DBGPRINT(DBG_ON(DBG_TRACE), ("%s(): VDVD_COMMAND_PAUSE\n", __FUNCTION__));
            CddaCmdMsg.bCommand = CDDA_CMD_PAUSE;
            break;

        case VDVD_COMMAND_STOP:
            DBGPRINT(DBG_ON(DBG_TRACE), ("%s(): VDVD_COMMAND_STOP\n", __FUNCTION__));
            CddaCmdMsg.bCommand = CDDA_CMD_STOP;
            break;

        case VDVD_COMMAND_NEXT_CHAPTER:
            DBGPRINT(DBG_ON(DBG_TRACE), ("%s(): VDVD_COMMAND_NEXT_CHAPTER\n", __FUNCTION__));
            CddaCmdMsg.bCommand = CDDA_CMD_NEXT_TRACK;
            break;

        case VDVD_COMMAND_PREV_CHAPTER:
            DBGPRINT(DBG_ON(DBG_TRACE), ("%s(): VDVD_COMMAND_PREV_CHAPTER\n", __FUNCTION__));
            CddaCmdMsg.bCommand = CDDA_CMD_PREVIOUS_TRACK;
            break;

        case VDVD_COMMAND_FWD_PLAY:
            DBGPRINT(DBG_ON(DBG_TRACE), ("%s(): VDVD_COMMAND_FWD_PLAY\n", __FUNCTION__));
            if (ulInfo == 1000)
            {
                CddaCmdMsg.bCommand = CDDA_CMD_PLAY;
            }
            else if (ulInfo > 1000)
            {
                CddaCmdMsg.bCommand = CDDA_CMD_FAST_FWD;
            }
            CddaCmdMsg.bTrackNumber = CddaAppControl.CurrentTrack.bPoint;
            CddaCmdMsg.sSpeed = (SHORT)(ulInfo/1000);
            break;

        case VDVD_COMMAND_BWD_PLAY:
            DBGPRINT(DBG_ON(DBG_TRACE), ("%s(): VDVD_COMMAND_FWD_PLAY\n", __FUNCTION__));
            CddaCmdMsg.bCommand = CDDA_CMD_FAST_RWD;
            CddaCmdMsg.bTrackNumber = CddaAppControl.CurrentTrack.bPoint;
            CddaCmdMsg.sSpeed = (SHORT)((ulInfo/1000)*(-1));
            break;

        case VDVD_COMMAND_RESTART_CHAPTER:
            CddaCmdMsg.bCommand     = CDDA_CMD_GOTO_TRACK;
            CddaCmdMsg.bTrackNumber = CddaAppControl.CurrentTrack.bPoint;
            break;

        case VDVD_COMMAND_REPEAT:
            if ((ulInfo == VDVD_INFO_REPEAT_A) || (ulInfo == VDVD_INFO_REPEAT_AB))
            {
                CddaCmdMsg.bCommand = CDDA_CMD_REPEAT_AB;
            }
            else if (ulInfo == VDVD_INFO_REPEAT_CHAPTER)
            {
                CddaCmdMsg.bCommand = CDDA_CMD_REPEAT_TRACK;
            }
            else if ((ulInfo == VDVD_INFO_REPEAT_ALL) || (ulInfo == VDVD_INFO_REPEAT_TITLE))
            {
                CddaCmdMsg.bCommand = CDDA_CMD_REPEAT_ALL;
            }
            else if (ulInfo == VDVD_INFO_REPEAT_OFF)
            {
                CddaCmdMsg.bCommand = CDDA_CMD_REPEAT_OFF;
            }
            break;

        default:
            DBGPRINT(DBG_ON(DBG_TRACE), ("%s(): KeyCode %d NOT SUPPORTED\n", __FUNCTION__, ulCommand));
            fIsSupported = FALSE;
            break;
    }

    if (TRUE == fIsSupported)
    {
        ulStatus = (ULONG) OS_MsgQSend(CddaAppControl.osqidQueueCdda, (char *) &CddaCmdMsg, CDDA_MSG_SIZE_BYTES, OS_NO_WAIT, OS_MSG_PRI_NORMAL);
        if (OS_OK != ulStatus)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR (0x%X): OS_MsgQSend.\n", __FUNCTION__, ulStatus));
        }
    }
    else
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("%s(): Invalid command.\n", __FUNCTION__));
        status_event[0] = VDVD_STATUS_PROHIBITED;
        if (UsrEventHandler(status_event) != USR_SUCCESS)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): Failed to send status event!\n", __FUNCTION__));
        }
    }

    return (OS_OK);
}


 /**
 * Initialize the navigator, create threads, semaphores, timers, queues, etc.
 *
 * @param none
 *
 * @return none
 */
static OS_STATUS cddaAppStartNav(void)
{
    ULONG               ulStatus = CDDA_SUCCESS;
    CDDA_CommandMsg     CddaCmdMsg;

    /* Create message queues */
    CddaAppControl.osqidQueueCdda = OS_MsgQCreate(CDDA_MSG_QUEUE_DEPTH, CDDA_MSG_SIZE_BYTES, OS_MSG_Q_FIFO);
    if (0 == CddaAppControl.osqidQueueCdda)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR: Message queue creation failed.\n", __FUNCTION__));
        goto err_out;
    }

    /* Create CDDA task */
    CddaAppControl.ulCddaTaskID = OS_TaskSpawnParam("CDDATask", OS_TASK_HIGH_PRIORITY, CDDA_TASK_STACKSIZE, cddaAppTask, NULL, NULL);
    if ( ((ULONG)OS_FAILURE) == CddaAppControl.ulCddaTaskID)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR: Task creation failed.\n", __FUNCTION__));
        CddaAppControl.ulCddaTaskID = 0;
        goto err_out;
    }

    /* Initialize the CDDA app control */
    CddaAppControl.fCddaAppStarted = TRUE;
    CddaAppControl.State           = CDDA_STATE_STOPPED;

    /* Send message to start first track playback */
    CddaCmdMsg.bCommand     = CDDA_CMD_PLAY;
    CddaCmdMsg.bTrackNumber = CddaAppControl.TOC.bFirstTrackNumber;
    ulStatus = (ULONG) OS_MsgQSend(CddaAppControl.osqidQueueCdda, (char *) &CddaCmdMsg, CDDA_MSG_SIZE_BYTES, OS_NO_WAIT, OS_MSG_PRI_NORMAL);
    if (OS_OK != ulStatus)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR (0x%X): OS_MsgQSend.\n", __FUNCTION__, ulStatus));
    }

    return (OS_OK);

err_out:
    return (OS_FAILURE);
}


/**
 * Kill the application threads, delete queues, events, and semaphores,
 * and release all allocations.
 *
 * @param none
 *
 * @return none
 */
static void cddaAppStopNav(void)
{
    ULONG               ulStatus;
    CDDA_CommandMsg     CddaCmdMsg;

    /* Send exit command to CDDA task */
    CddaCmdMsg.bCommand = CDDA_CMD_TASK_EXIT;
    ulStatus = (ULONG) OS_MsgQSend(CddaAppControl.osqidQueueCdda, (char *) &CddaCmdMsg, CDDA_MSG_SIZE_BYTES, OS_NO_WAIT, OS_MSG_PRI_NORMAL);
    if (OS_OK != ulStatus)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("%s(): ERROR (0x%X): OS_MsgQSend.\n", __FUNCTION__, ulStatus));
    }

    /* Wait for task to exit, then delete */
    if (0 != CddaAppControl.ulCddaTaskID)
    {
        OS_TaskJoin(CddaAppControl.ulCddaTaskID);
        OS_TaskDelete(CddaAppControl.ulCddaTaskID);
        CddaAppControl.ulCddaTaskID = 0;

    }

    /* Delete CDDA message queue */
    OS_MsgQDelete(CddaAppControl.osqidQueueCdda);

    CddaAppControl.fCddaAppStarted = FALSE;
}


/**
 * Retrieves the CDDA table of contents.
 *
 * @note This algorithm searches for the lowest numbered session that has an audio track in the first location.
 *
 * @param none
 *
 * @return ULONG status information.
 */
static ULONG cddaRetrieveCddaTOC(void)
{

    ULONG       ulStatus;
    CDDA_TOC    CddaTOC;
    CDDA_TOC    *pCddaTOC;
    int         i = 0;
    ULONG       ulIgnoreSize = 0;

    /* Initialize */
    pCddaTOC          = (CDDA_TOC *) &CddaTOC;

⌨️ 快捷键说明

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