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

📄 pbc_engine.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    /* Send message to be processed by the pbc engine task */
    if (OS_MsgQSend(hPbcEngine->MsgQID, (char *)&msg, sizeof(PBCENGINE_MESSAGE), OS_NO_WAIT, OS_MSG_PRI_NORMAL) != OS_OK)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineSendMessage: Failure sending message!\n"));
        return(PLAYCTRL_FAILURE);
    }
    return(PLAYCTRL_SUCCESS);
}


/**
 * PbcEngineNavTimerCallback -- Nav timer callback handler.
 *
 * @param
 *      pvParam -- context pointer that is registered with timer
 *
 * @retval
 *      none
 */
static void PbcEngineNavTimerCallback(PVOID pvParam)
{
    PBC_HANDLE *hPBC = (PBC_HANDLE *)pvParam;

    /* Check for valid handles */
    if ( (hPbcEngine == NULL) || (hPBC == NULL) )
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineNavTimerCallback: NULL handle!\n"));
    }
    else
    {
        uint32 uiNvTimerValue;

        /* Get NV Timer register value */
        PbcRegGetPSR(PLAYCTRL_PSR_NVTIMER, &uiNvTimerValue);

        /* Pull out time from register value */
        uiNvTimerValue &= 0x0000ffff;

        /*
         * If nv timer or still timer is ticking, send msg to pbc engine task to
         * process a timer update.
         */
        if ( (uiNvTimerValue != 0) || ( (hPBC->ulStillTime != 0) && (hPBC->ulStillTime != 0xffffffff) ) )
        {
            PBCENGINE_MESSAGE   msg;

            /* Load message parameters */
            msg.tMsgType    = PBCENGINE_MSGTYPE_NVTIMER_UPDATE;
            msg.hPbc        = hPBC;
            msg.ulSemID     = 0;
            msg.pulRetVal   = NULL;

            /* Send message to be processed by the pbc engine task */
            if (OS_MsgQSend(hPbcEngine->MsgQID, (char *)&msg, sizeof(PBCENGINE_MESSAGE), OS_NO_WAIT, OS_MSG_PRI_NORMAL) != OS_OK)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineNavTimerCallback: Failure sending message!\n"));
            }
        }
    }
}

/**
 * PbcEngineTimerUpdate -- Handle updating timer values.
 *
 * @param
 *      hPBC -- pbc private data handle
 *
 * @retval
 *      PLAYCTRL_STATUS
 */
static PLAYCTRL_STATUS  PbcEngineTimerUpdate(PBC_HANDLE *hPBC)
{
    PLAYCTRL_STATUS tStatus = PLAYCTRL_SUCCESS;
    uint32          uiNvTimerValue;

    /* Take register mutex semaphore */
    OS_SemTake(hPBC->semRegisterMutex, OS_WAIT_FOREVER);

    /* Get NV Timer register value */
    PbcRegGetPSR(PLAYCTRL_PSR_NVTIMER, &uiNvTimerValue);

    /* Pull out time from register value */
    uiNvTimerValue &= 0x0000ffff;

    /* If nv timer is ticking, update the time value */
    if (uiNvTimerValue != 0)
    {
        /* Decrement nv timer */
        uiNvTimerValue--;

        /* Set NV Timer register value */
        PbcRegSetPSR(PLAYCTRL_PSR_NVTIMER, uiNvTimerValue);

        /*
         * If nv timer has expired, then inform application environment that
         * the nv timer has expired.
         */
        if (uiNvTimerValue == 0)
        {
            /* Send nvtimer expire event to registered callback */
            if (hPBC->pCallback != NULL)
            {
                hPBC->pCallback(hPBC->pvCallbackContext, PLAYCTRL_EVENT_NVTIMER_EXPIRE, NULL);
            }
        }
    }

    /* Give register mutex semaphore */
    OS_SemGive(hPBC->semRegisterMutex);

    /* If still timer is ticking, update the time value */
    if ( (hPBC->ulStillTime != 0) && (hPBC->ulStillTime != 0xffffffff) )
    {
        /* Decrement still timer */
        hPBC->ulStillTime--;

        /* If still timer has expired, then release the still */
        if (hPBC->ulStillTime == 0)
        {
            /* Check if playlist is complete after this still */
            if (hPBC->fPLCompletePending == TRUE)
            {
                /* playlist complete */
                PbcPLCtrlPlaylistComplete(hPBC, FALSE);
            }
            else
            {
                PEiStreamCtrlStillOff(hPBC->hPE);
            }
        }
    }

    return (tStatus);
}

/**
 * PbcEnginePlayButtonSound -- Play Blu-ray button sounds.
 *
 * @param hPBC     - pbc private data handle
 * @param sound_id - which button sound to play
 *
 * @retval
 *      PLAYCTRL_STATUS
 */
static PLAYCTRL_STATUS PbcEnginePlayButtonSound(PBC_HANDLE *hPBC, uint32 sound_id)
{
    SOUND_ATTRIBUTES sound_attributes;

    DBGPRINT(DBG_ON(DBG_TRACE), (">>> Button Select sound_id=%ld <<<\n", sound_id));

    /* get the sound attributes */
    if (SOUNDDBGetSoundInfo( (BYTE)(sound_id), &sound_attributes) == SOUNDDB_SUCCESS)
    {
        BYTE  *pcm;
        ULONG length;

        /* get the sound samples */
        if (SOUNDDBGetSoundData( (BYTE)(sound_id), &pcm, &length) == SOUNDDB_SUCCESS)
        {
            DBGPRINT(DBG_ON(DBG_TRACE), (">>> Play Button Selection Sound %d %d <<<\n",
                sound_attributes.channel_configuration, length));

            /* As indicated in paragraph five section 8.8.4.6.5.3.5, previous sound shall be pre-empted
             * by subsequent selection sounds. */
            if (0 != hPBC->iaudio_id)
            {
                if (PLAYCTRL_SUCCESS != PlayCtrlAMStopSound(hPBC->iaudio_id))
                {
                    DBGPRINT(DBG_ON(DBG_TRACE), ("PlayCtrlAMStopSound: ERROR\n"));
                }
            }

            /* play sound sample with correct channel config
             * NOTE: 1 = MONO, 3 = STEREO */
            if (sound_attributes.channel_configuration == 1)
            {
                if (PLAYCTRL_SUCCESS != PlayCtrlAMOpenSound(PLAYCTRL_AUDIO_STREAM_INTERACTIVE,
                    FALSE, pcm, length/2, &(hPBC->iaudio_id)))
                {
                    DBGPRINT(DBG_ON(DBG_TRACE), ("PlayCtrlAMOpenSound: ERROR\n"));
                }
                if (PLAYCTRL_SUCCESS != PlayCtrlAMPlaySound(hPBC->iaudio_id))
                {
                    DBGPRINT(DBG_ON(DBG_TRACE), ("PlayCtrlAMPlaySound: ERROR\n"));
                }
            }
            else
            {
                if (PLAYCTRL_SUCCESS != PlayCtrlAMOpenSound(PLAYCTRL_AUDIO_STREAM_INTERACTIVE,
                    TRUE, pcm, length/2, &(hPBC->iaudio_id)))
                {
                    DBGPRINT(DBG_ON(DBG_TRACE), ("PlayCtrlAMOpenSound: ERROR\n"));
                }
                if (PLAYCTRL_SUCCESS != PlayCtrlAMPlaySound(hPBC->iaudio_id))
                {
                    DBGPRINT(DBG_ON(DBG_TRACE), ("PlayCtrlAMPlaySound: ERROR\n"));
                }
            }
        }
    }

    return (PLAYCTRL_SUCCESS);
}

/**
 * PbcEngineTask -- Task that executes all pbc engine core processing.
 */
static ULONG PbcEngineTask(PVOID pvParam)
{
    PBCENGINE_MESSAGE   Msg;
    BOOLEAN             fTaskExit = FALSE;
    PLAYCTRL_STATUS     status;

    while (fTaskExit == FALSE)
    {
        /* Wait for a message */
        if (OS_MsgQReceive(hPbcEngine->MsgQID, (char *)&Msg, sizeof(PBCENGINE_MESSAGE), OS_WAIT_FOREVER) != OS_OK)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineTask: Failure receiving message!\n"));
            fTaskExit = TRUE;
        }
        else
        {
            status = PLAYCTRL_SUCCESS;

            /* Look at the message type to determine what to do */
            switch (Msg.tMsgType)
            {
            case PBCENGINE_MSGTYPE_EXIT:
                DBGPRINT(DBG_ON(DBG_TRACE), ("PbcEngineTask: PBCENGINE_MSGTYPE_EXIT!\n"));
                fTaskExit = TRUE;
                break;

            case PBCENGINE_MSGTYPE_PBC_CMD:
                DBGPRINT(DBG_ON(DBG_TRACE), ("PbcEngineTask: PBCENGINE_MSGTYPE_PBC_CMD\n"));

                /*
                 * If command type is valid, and the associated function pointer
                 * is valid, then call the playback control function.
                 */
                if (Msg.ulData0 < PLAYCTRL_INVALID_COMMAND)
                {
                    if (hPbcEngine->PbcFunc[Msg.ulData0] != NULL)
                    {
                        /* fire function pointer for associated playback control function */
                        if (hPbcEngine->PbcFunc[Msg.ulData0](Msg.hPbc, Msg.ulData1, Msg.ulData2, Msg.ulData3) != PLAYCTRL_SUCCESS)
                        {
                            status = PLAYCTRL_FAILURE;
                        }
                    }
                    else
                    {
                        status = PLAYCTRL_FAILURE;
                    }
                }
                else
                {
                    status = PLAYCTRL_FAILURE;
                }
                break;

            case PBCENGINE_MSGTYPE_BEG_STREAM:
                DBGPRINT(DBG_ON(DBG_TRACE), ("PbcEngineTask: PBCENGINE_MSGTYPE_BEG_STREAM\n"));

                /* Handle beginning of stream */
                status = PbcPLCtrlBegStream(Msg.hPbc, (PBC_PLAYITEM_CONTEXT *)Msg.ulData0, (PE_ISTREAMCTRL_INPUT)Msg.ulData1, (BOOLEAN)Msg.ulData2);

                if (status == PLAYCTRL_RETRY)
                {
                    OS_TaskDelay(OS_WAIT_1S / 50);
                    if (PLAYCTRL_FAILURE == pbcEngineSendMessage(PBCENGINE_MSGTYPE_BEG_STREAM, Msg.hPbc, Msg.ulData0, Msg.ulData1, (ULONG)TRUE, 0, 0, NULL))
                    {
                        /* @todo: handle this very bad case (though it *should* never happen) */
                        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineTask: PBCENGINE_MSGTYPE_BEG_STREAM: pbcEngineSendMessage FAILED.  FIX ME!!\n"));
                    }
                    status = PLAYCTRL_SUCCESS;
                }
                else if (status != PLAYCTRL_SUCCESS)
                {
                    status = PLAYCTRL_FAILURE;
                }
                break;

            case PBCENGINE_MSGTYPE_END_STREAM:
                DBGPRINT(DBG_ON(DBG_TRACE), ("PbcEngineTask: PBCENGINE_MSGTYPE_END_STREAM\n"));

                /* Handle end of stream */
                status = PbcPLCtrlEndStream(Msg.hPbc, (PBC_PLAYITEM_CONTEXT *)Msg.ulData0, (PE_ISTREAMCTRL_INPUT)Msg.ulData1, (BOOLEAN)Msg.ulData2);

                if (status == PLAYCTRL_RETRY)
                {
                    OS_TaskDelay(OS_WAIT_1S / 50);
                    if (PLAYCTRL_FAILURE == pbcEngineSendMessage(PBCENGINE_MSGTYPE_END_STREAM, Msg.hPbc, Msg.ulData0, Msg.ulData1, (ULONG)TRUE, 0, 0, NULL))
                    {
                        /* @todo: handle this very bad case (though it *should* never happen) */
                        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineTask: PBCENGINE_MSGTYPE_END_STREAM: pbcEngineSendMessage FAILED.  FIX ME!!\n"));
                    }
                    status = PLAYCTRL_SUCCESS;
                }
                else if (status != PLAYCTRL_SUCCESS)
                {
                    status = PLAYCTRL_FAILURE;
                }
                break;

            case PBCENGINE_MSGTYPE_DEC_DONE:
                DBGPRINT(DBG_ON(DBG_TRACE), ("PbcEngineTask: PBCENGINE_MSGTYPE_DEC_DONE\n"));
                if ( GET_BIT(Msg.hPbc->newpi.doneState, PBC_DECDONE_STATE_WAITING_BOS) )
                {
                    CLR_BIT(Msg.hPbc->newpi.doneState, PBC_DECDONE_STATE_WAITING_BOS);
                }
                else if ( GET_BIT(Msg.hPbc->newpi.doneState, PBC_DECDONE_STATE_WAITING_EOS) )
                {
                    CLR_BIT(Msg.hPbc->newpi.doneState, PBC_DECDONE_STATE_WAITING_EOS);
                }
                else if (Msg.hPbc->newpi.doneState == PBC_DECDONE_STATE_INACTIVE)
                {
                    Msg.hPbc->newpi.doneState = PBC_DECDONE_STATE_ACTIVE;
                }
                break;

            case PBCENGINE_MSGTYPE_ABORT_COMPLETE:
                DBGPRINT(DBG_ON(DBG_ALL), ("\nPbcEngineTask: PBCENGINE_MSGTYPE_ABORT_COMPLETE\n\n"));
                (Msg.hPbc)->newpi.abort = FALSE;
                (Msg.hPbc)->newpi.doneState  = PBC_DECDONE_STATE_INACTIVE;
                status = PLAYCTRL_SUCCESS;
                break;

            case PBCENGINE_MSGTYPE_NVTIMER_UPDATE:
                DBGPRINT(DBG_ON(DBG_TRACE), ("PbcEngineTask: PBCENGINE_MSGTYPE_NAVTIMER_UPDATE\n"));

                /* Update timers */
                if (PbcEngineTimerUpdate(Msg.hPbc) != PLAYCTRL_SUCCESS)
                {
                    status = PLAYCTRL_FAILURE;
                }
                break;

            case PBCENGINE_MSGTYPE_PREFILL_COMPLETE:
                DBGPRINT(DBG_ON(DBG_TRACE), ("PbcEngineTask: PBCENGINE_MSGTYPE_PREFILL_COMPLETE\n"));

                /* Handle prefill complete */
                if (PbcPLCtrlPrefillComplete(Msg.hPbc, (PE_ISTREAMCTRL_INPUT)Msg.ulData0) != PLAYCTRL_SUCCESS)
                {
                    status = PLAYCTRL_FAILURE;
                }
                break;

            case PBCENGINE_MSGTYPE_PLAY_BTN_SOUND:
                DBGPRINT(DBG_ON(DBG_TRACE), ("PbcEngineTask: PBCENGINE_MSGTYPE_PLAY_BTN_SOUND\n"));

                /* process the button sound */
                if (PbcEnginePlayButtonSound(Msg.hPbc, Msg.ulData0) != PLAYCTRL_SUCCESS)
                {
                    status = PLAYCTRL_FAILURE;
                }
                break;

            case PBCENGINE_MSGTYPE_INVALID:
            default:
                status = PLAYCTRL_FAILURE;
                break;
            }

            /* If requested return the status */
            if (Msg.pulRetVal != NULL)
            {
                *Msg.pulRetVal = status;
            }

            /* If semaphore was attached to message, give semaphore */
            if (Msg.ulSemID != 0)
            {
                OS_SemGive( (OS_SEM_ID)Msg.ulSemID );
            }
        }
    }

    /* exit task */
    OS_TaskExit();

    return (0);
}

⌨️ 快捷键说明

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