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

📄 pbc_engine.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
    }

    /* clear the queue */
    hPBC->newpi.abort = FALSE;
    OS_MsgQReset(hPbcEngine->MsgQID);

    return (PLAYCTRL_SUCCESS);
}

/**
 * PbcEngineMapPBCFunctions -- Map commands to PBC functions through function pointers.
 *
 * @param
 *      none
 *
 * @retval
 *      PLAYCTRL_STATUS
 */
static PLAYCTRL_STATUS  PbcEngineMapPBCFunctions(void)
{
    if (hPbcEngine == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineMapPBCFunctions: pbc engine not created!\n"));
        return (PLAYCTRL_FAILURE);
    }

    /* Set function pointers */
    hPbcEngine->PbcFunc[PLAYCTRL_PLAYPLPLAYITEM]             = PbcPbScenarioPlayPLPI;
    hPbcEngine->PbcFunc[PLAYCTRL_LINKPI]                     = PbcPbScenarioLinkPI;
    hPbcEngine->PbcFunc[PLAYCTRL_PLAYPLMARK]                 = PbcPbScenarioPlayPLMark;
    hPbcEngine->PbcFunc[PLAYCTRL_LINKMARK]                   = PbcPbScenarioLinkMark;
    hPbcEngine->PbcFunc[PLAYCTRL_PLAYPLTIME]                 = PbcPbScenarioPlayPLTime;
    hPbcEngine->PbcFunc[PLAYCTRL_LINKTIME]                   = PbcPbScenarioLinkTime;
    hPbcEngine->PbcFunc[PLAYCTRL_STOP]                       = PbcPbScenarioStop;
    hPbcEngine->PbcFunc[PLAYCTRL_SUSPEND]                    = PbcPbScenarioSuspend;
    hPbcEngine->PbcFunc[PLAYCTRL_RESUME]                     = PbcPbScenarioResume;
    hPbcEngine->PbcFunc[PLAYCTRL_SKIPTONEXTPOINT]            = PbcPbScenarioSkipNext;
    hPbcEngine->PbcFunc[PLAYCTRL_SKIPTOPREVPOINT]            = PbcPbScenarioSkipPrev;
    hPbcEngine->PbcFunc[PLAYCTRL_RESTARTPOINT]               = PbcPbScenarioRestartPoint;
    hPbcEngine->PbcFunc[PLAYCTRL_REPEAT]                     = PbcPbScenarioRepeat;
    hPbcEngine->PbcFunc[PLAYCTRL_PLAY]                       = NULL;

    hPbcEngine->PbcFunc[PLAYCTRL_PAUSEON]                    = PbcAvPresPauseOn;
    hPbcEngine->PbcFunc[PLAYCTRL_PAUSEOFF]                   = PbcAvPresPauseOff;
    hPbcEngine->PbcFunc[PLAYCTRL_STILLON]                    = PbcAvPresStillOn;
    hPbcEngine->PbcFunc[PLAYCTRL_STILLOFF]                   = PbcAvPresStillOff;
    hPbcEngine->PbcFunc[PLAYCTRL_FORWARDPLAY]                = PbcAvPresForwardPlay;
    hPbcEngine->PbcFunc[PLAYCTRL_BACKWARDPLAY]               = PbcAvPresBackwardPlay;
    hPbcEngine->PbcFunc[PLAYCTRL_AUDIOCHANGE]                = PbcAvPresAudioChange;
    hPbcEngine->PbcFunc[PLAYCTRL_SECONDARYAUDIOCHANGE]       = PbcAvPresSecondaryAudioChange;
    hPbcEngine->PbcFunc[PLAYCTRL_SUBTITLECHANGE]             = PbcAvPresSubtitleChange;
    hPbcEngine->PbcFunc[PLAYCTRL_SUBTITLEDISPLAY]            = PbcAvPresSubtitleDisplay;
    hPbcEngine->PbcFunc[PLAYCTRL_ANGLECHANGE]                = PbcAvPresAngleChange;
    hPbcEngine->PbcFunc[PLAYCTRL_IGCHANGE]                   = PbcAvPresIGChange;
    hPbcEngine->PbcFunc[PLAYCTRL_TEXTSUBTITLESTYLECHANGE]    = PbcAvPresTextSTStyleChange;
    hPbcEngine->PbcFunc[PLAYCTRL_GETNUMTEXTSUBTITLESTYLES]   = PbcAvPresGetNumTextSTStyles;

    hPbcEngine->PbcFunc[PLAYCTRL_SELECTBUTTONPAGE]           = PbcIGSelectButtonPage;
    hPbcEngine->PbcFunc[PLAYCTRL_POPUPON]                    = PbcIGPopUpOn;
    hPbcEngine->PbcFunc[PLAYCTRL_POPUPOFF]                   = PbcIGPopUpOff;
    hPbcEngine->PbcFunc[PLAYCTRL_ENABLEBUTTON]               = PbcIGEnableButton;
    hPbcEngine->PbcFunc[PLAYCTRL_DISABLEBUTTON]              = PbcIGDisableButton;
    hPbcEngine->PbcFunc[PLAYCTRL_MOVEUPSELECTEDBUTTON]       = PbcIGMoveUpSelectedButton;
    hPbcEngine->PbcFunc[PLAYCTRL_MOVEDOWNSELECTEDBUTTON]     = PbcIGMoveDownSelectedButton;
    hPbcEngine->PbcFunc[PLAYCTRL_MOVELEFTSELECTEDBUTTON]     = PbcIGMoveLeftSelectedButton;
    hPbcEngine->PbcFunc[PLAYCTRL_MOVERIGHTSELECTEDBUTTON]    = PbcIGMoveRightSelectedButton;
    hPbcEngine->PbcFunc[PLAYCTRL_SELECTBUTTON]               = PbcIGSelectButton;
    hPbcEngine->PbcFunc[PLAYCTRL_ACTIVATEBUTTON]             = PbcIGActivateButton;
    hPbcEngine->PbcFunc[PLAYCTRL_SELECTANDACTIVATEBUTTON]    = PbcIGSelectAndActivateButton;
    hPbcEngine->PbcFunc[PLAYCTRL_ACTIVATEBUTTON_COMPLETE]    = PbcIGActivateButtonComplete;
    hPbcEngine->PbcFunc[PLAYCTRL_RESET_USER_TIMEOUT]         = PbcIGResetUserTimeout;

    return (PLAYCTRL_SUCCESS);
}

/**
 * PbcEngineDRCallback -- DR Callback Event handler.
 *
 * @param
 *      pContext -- context pointer that is registered with DR
 *      event -- DR event
 *      pEventInfo -- pointer to information associated with event
 *
 * @retval
 *      DR_ERROR
 */
static DR_ERROR PbcEngineDRCallback(PVOID pContext, DR_EVENT_CODE event, PVOID pEventInfo)
{
    PBC_HANDLE          *hPBC       = (PBC_HANDLE *)pContext;
    DR_ERROR            tStatus     = DR_SUCCESS;
    PBCENGINE_MSGTYPE   tMsgType    = PBCENGINE_MSGTYPE_INVALID;
    ULONG               ulData0     = 0;
    ULONG               ulData1     = 0;
    BOOLEAN             fSendMsg    = FALSE;

    /* Check for valid context pointer */
    if (pContext == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: Invalid context pointer!\n"));
        return (DR_FAILURE);
    }

    /* Check for valid pbc engine module handle */
    if (hPbcEngine == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: Invalid pbc engine handle!\n"));
        return (DR_FAILURE);
    }

    /* Check for valid DR callback event */
    if (event >= DR_EVENT_CODE_INVALID)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: Invalid DR Event callback!\n"));
        return (DR_FAILURE);
    }

    /* Evaluate the DR callback event */
    switch (event)
    {
    case DR_EVENT_BUFFER_EMPTY:
        DBGPRINT(DBG_ON(DBG_TRACE), ("PbcEngineDRCallback: DR_EVENT_BUFFER_EMPTY\n"));
        break;

    case DR_EVENT_COMMAND_BUFFER_EMPTY:
        DBGPRINT(DBG_ON(DBG_TRACE), ("PbcEngineDRCallback: DR_EVENT_COMMAND_BUFFER_EMPTY\n"));
        break;

    case DR_EVENT_ERROR:
        switch ((ULONG)pEventInfo)
        {
        case DR_AACS_FAILURE:
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: DR_AACS_FAILURE\n"));
            /* TODO: Add code to process this failure */
            break;
        default:
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: DR_EVENT_ERROR\n"));
            break;
        }
        break;

    case DR_EVENT_COMMAND_ERROR:
        switch ((ULONG)pEventInfo)
        {
        case DR_ATTACH_LOADER:
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: DR_EVENT_COMMAND_ERROR, DR_ATTACH_LOADER\n"));
            break;
        case DR_ATTACH_STREAM:
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: DR_EVENT_COMMAND_ERROR, DR_ATTACH_STREAM\n"));
            break;
        case DR_ATTACH_EVENT:
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: DR_EVENT_COMMAND_ERROR, DR_ATTACH_EVENT\n"));
            break;
        case DR_IDENTIFY_TYPE:
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: DR_EVENT_COMMAND_ERROR, DR_IDENTIFY_TYPE\n"));
            break;
        case DR_DETACH_STREAM:
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: DR_EVENT_COMMAND_ERROR, DR_DETACH_STREAM\n"));
            break;
        case DR_PLAY_BDROM:
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: DR_EVENT_COMMAND_ERROR, DR_PLAY_BDROM\n"));
            break;
        case DR_PLAY_DVD:
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: DR_EVENT_COMMAND_ERROR, DR_PLAY_DVD\n"));
            break;
        case DR_PLAY_CD:
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: DR_EVENT_COMMAND_ERROR, DR_PLAY_CD\n"));
            break;
        case DR_STOP:
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: DR_EVENT_COMMAND_ERROR, DR_STOP\n"));
            break;
        case DR_STOP_STREAM:
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: DR_EVENT_COMMAND_ERROR, DR_STOP_STREAM\n"));
            break;
        case DR_SET_DVD_SPEED:
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: DR_EVENT_COMMAND_ERROR, DR_SET_DVD_SPEED\n"));
            break;
        case DR_SET_DVD_ANGLE:
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: DR_EVENT_COMMAND_ERROR, DR_SET_DVD_ANGLE\n"));
            break;
        case DR_SET_BDROM_ANGLE:
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: DR_EVENT_COMMAND_ERROR, DR_SET_BDROM_ANGLE\n"));
            break;
        case DR_QUEUE_CONTROL:
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: DR_EVENT_COMMAND_ERROR, DR_QUEUE_CONTROL\n"));
            break;
        case DR_RESET:
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: DR_EVENT_COMMAND_ERROR, DR_RESET\n"));
            break;
        default:
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: DR_EVENT_COMMAND_ERROR, UNSUPPORTED!!!\n"));
            tStatus = DR_FAILURE;
            break;
        }
        break;

    default:
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: Unknown DR Event callback\n"));
        tStatus = DR_FAILURE;
        break;
    }

    /*
     * If message should be sent to PBC engine task, then send message.
     *
     * NOTE: We do not take the PBC semaphore since that could lead to
     * a deadlock.
     */
    if (fSendMsg == TRUE)
    {
        PBCENGINE_MESSAGE msg;

        /* Load message parameters */
        msg.tMsgType    = tMsgType;
        msg.hPbc        = hPBC;
        msg.ulData0     = ulData0;
        msg.ulData1     = ulData1;
        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), ("PbcEngineDRCallback: Failure sending message!\n"));
            tStatus = DR_FAILURE;
        }
    }

    return (tStatus);
}

/**
 * PbcEngineCallback -- PE Event Callback handler.
 *
 * @param
 *      pContext   -- context pointer that is registered with PE
 *      event      -- PE event
 *      pEventInfo -- pointer to information associated with event
 *
 * @retval
 *      PE_STATUS
 *
 * NOTE: This is called from the context of the PE
 *       You should NEVER call PE APIs from this function as this can lead to dead lock conditions
 */
static PE_STATUS PbcEnginePECallback(PVOID pContext, PE_EVENT_CODE event, PVOID pEventInfo)
{
    PBC_HANDLE          *hPBC       = (PBC_HANDLE *)pContext;
    PE_STATUS           tStatus     = PE_SUCCESS;
    PBCENGINE_MSGTYPE   tMsgType    = PBCENGINE_MSGTYPE_INVALID;
    ULONG               ulData0     = 0;
    ULONG               ulData1     = 0;
    ULONG               ulData2     = 0;
    BOOLEAN             fSendMsg    = FALSE;

    /* Check for valid pbc engine module handle */
    if (hPbcEngine == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineDRCallback: Invalid pbc engine handle!\n"));
        return (DR_FAILURE);
    }

    /* Check for valid PE callback event */
    if (event >= PE_EVENT_CODE_INVALID)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEnginePEiStrmCtrlCallback: Invalid PE Event!\n"));
        return (PE_FAILURE);
    }

    /* Evaluate the PE callback event */
    switch (event)
    {
    case PE_EVENT_IDLE:
        DBGPRINT(DBG_ON(DBG_TRACE), ("PbcEnginePEiStrmCtrlCallback: PE_EVENT_IDLE\n"));

        /* check the input */
        if (pEventInfo == NULL)
        {
            return (PE_FAILURE);
        }
        if (((PE_IDLE_EVENT_INFO *)pEventInfo)->pContext == NULL)
        {
            return (PE_FAILURE);
        }

        /* Send beginning of stream msg to pbc msg queue. */
        fSendMsg = TRUE;
        tMsgType = PBCENGINE_MSGTYPE_BEG_STREAM;
        ulData0  = (ULONG)(((PE_IDLE_EVENT_INFO *)pEventInfo)->pContext);
        ulData1  = ((PE_IDLE_EVENT_INFO *)pEventInfo)->input;
        ulData2  = (ULONG)FALSE;
        break;

    case PE_EVENT_BEG_OF_STREAM:
        DBGPRINT(DBG_ON(DBG_TRACE), ("PbcEnginePEiStrmCtrlCallback: PE_EVENT_BEG_OF_STREAM\n"));
        PBC_PLAYITEM_CONTEXT *pPIContext;

        /* check the input */
        if (pEventInfo == NULL)
        {
            return (PE_FAILURE);
        }
        if (((PE_BEG_OF_STREAM_EVENT_INFO *)pEventInfo)->pContext == NULL)
        {
            return (PE_FAILURE);
        }

        /* set the context */
        pPIContext = (PBC_PLAYITEM_CONTEXT *)(((PE_BEG_OF_STREAM_EVENT_INFO *)pEventInfo)->pContext);

        if ( ((PE_BEG_OF_STREAM_EVENT_INFO *)pEventInfo)->input == INPUT_MAIN)
        {
            uint32                  uiLastPlayitemID;
            PE_ISTREAMCTRL_PLAYRATE CurrentPlayRate;
            uint32                  uiPlaylistID;
            PLAYITEM                *pCurrentPlayItem   = NULL;

            fSendMsg = TRUE;

            /* Get Playlist, Last Playitem, and Current play rate */
            PbcRegGetPSR(PLAYCTRL_PSR_PLAYLIST, &uiPlaylistID);
            uiLastPlayitemID = hPBC->newpi.playitemID;
            CurrentPlayRate  = ((PE_BEG_OF_STREAM_EVENT_INFO *)pEventInfo)->pe_rate;

            /*
             * a new playitem is beginning.  set the newpi informational flags.
             */
            hPBC->newpi.marker_pts = 0;

            if (uiLastPlayitemID != INVALID_PLAYITEM)
            {
                if (MPLSGetPlayItem( (uint16)(uiLastPlayitemID), &pCurrentPlayItem) == MPLS_SUCCESS)
                {
                    hPBC->newpi.marker_pts  = (!hPBC->fReverse) ? pCurrentPlayItem->OUT_time : pCurrentPlayItem->IN_time;
                }
            }
            hPBC->newpi.playitemID  = pPIContext->uiPlayitemID;
            hPBC->newpi.fReverse    = (pPIContext->PlayRate.direction == PE_ISTREAMCTRL_DIRECTION_FORWARD) ?  0: 1;

            /* check the playlist is still valid */
            if (pPIContext->uiPlaylistID == uiPlaylistID)
            {
                if ( ( pPIContext->connection             == VDVD_CONNECTION_1                 ) ||
                     ( pPIContext->connection             == VDVD_CONNECTION_NONSEAMLESS_ANGLE ) ||
                     ( pPIContext->PlayRate.discontiguous != CurrentPlayRate.discontiguous     )  )
                {
                   /*
                    * Non-Seamless Case
                    *
                    * Need to check if there is a non-seamless connection between this new playitem
                    * and the previous playitem.  If the connection is non-seamless, then this means that
                    * the pe will need re-configured.  Since the PE needs reconfigured, it will need to
                    * be idle until the re-configuration is complete.  So, we need to return an event status
                    * to the PE to tell it to stay idle until it is resumed.  It will be resumed after it
                    * had been reconfigured by the PBC Engine.
                    *
                    * We also want to wait for decode to be done on the previous before processing beginning of stream.
                    */
                    tStatus  = PE_EVNT_IDLE | PE_EVNT_WAIT_FOR_DONE;
                    fSendMsg = FALSE;
                }
                else if ( ( pPIContext->connection             == VDVD_CONNECTION_5  ) ||
                          ( pPIContext->connection             == VDVD_CONNECTION_6  )  )
                {
                   /*
                    * Seamless Case
                    *
                    * get the playitem info for the currently playing playitem (PSR and newpi.playitemID are equal at this point)
                    * we want to know it's out point so that we can wait for it to complete
                    * before we transition the PSR values to the next playitem
                    */
                   tStatus = PE_EVNT_WAIT_FOR_DONE;
                }
                else if ( pPIContext->connection             == VDVD_CONNECTION_ABORT )
                {
                   /*
                    * Abort Case
                    *
                    * This is the case where we're restarting playback.  We'll go idle, but we won't wait for done
                    *
                    */
                    tStatus  = PE_EVNT_IDLE;
                    fSendMsg = FALSE;
                }
            }
            else
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("%s:%u - Invalid Playlist!\n", __FILE__, __LINE__));

⌨️ 快捷键说明

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