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

📄 pbc_plcontrol.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    uiApplicationType = PlayCtrlGetCurrentApplicationType();

    /* Notify application of application type */
    if (hPBC->pCallback != NULL)
    {
        hPBC->pCallback(hPBC->pvCallbackContext, PLAYCTRL_EVENT_APPLICATION_TYPE, &uiApplicationType);
    }

    /* play the desired playitem */
    PbcPLCtrlPlayPlayitem(hPBC, (uint16)(uiPrevPlayitemID), playitemID, time45k_StartTime, hPBC->fReverse, hPBC->ulPlayRate,
        ubRandomShuffleIndex, fNewPlaylist, PBC_NEXT, VDVD_CONNECTION_ABORT, TRUE);

    /* Put the Decoder in the normal run state */
    PEiStreamCtrlResume(hPBC->hPE);

    return (PLAYCTRL_SUCCESS);

errout:

    /* Stop Playback */
    PbcPLCtrlStopPL(hPBC, FALSE);

    return (PLAYCTRL_FAILURE);
}

/**
 * PbcPLCtrlStopPL -- Stop playback of a playlist.
 *
 * @param
 *      hPBC -- handle to playback control engine private data
 *
 * @retval
 *      PLAYCTRL_STATUS
 */
PLAYCTRL_STATUS PbcPLCtrlStopPL(PBC_HANDLE *hPBC, BOOLEAN fHoldPicture)
{
    int i;

    DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPLCtrlStopPL: ENTER\n"));

    /* check for valid handle */
    if (hPBC == NULL)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlStopPL: NULL handle!\n"));
        return (PLAYCTRL_NULL_POINTER);
    }

    /* Stop Playback */
    DRStop(hPBC->hDR);

    /*
     * Flush the decoder.  Do not actually stop the PE so that the out-of-mux IG and
     * TextST does not get flushed.
     */
    for (i = 0; i < MAX_PE_INPUTS; i++)
    {
        PEiStreamCtrlFlush(hPBC->hPE, (PE_ISTREAMCTRL_INPUT)i);
    }

    /* If pop-up menu is on, turn it off */
    if (PEiStreamCtrlIsPopupOn(hPBC->hPE) == TRUE)
    {
        PE_ISTREAMCTRL_IG_PARAM ig_param;

        /* send pop-up off command to the PE */
        ig_param.cmd = PE_IG_POPUP_OFF;
        if (PEiStreamCtrlSendIGCmd(hPBC->hPE, &ig_param) != PE_SUCCESS)
        {
            return (PLAYCTRL_FAILURE);
        }
    }

    /* cancel any trick modes
     * fixes pause -> eject -> play */
    PEiStreamCtrlResume(hPBC->hPE);

    hPBC->ulPlayRate       = 0;
    hPBC->fReverse         = 0;
    hPBC->tState           = PLAYCTRL_STATE_STOP;
    hPBC->newpi.doneState  = PBC_DECDONE_STATE_INACTIVE;
    hPBC->newpi.playitemID = INVALID_PLAYITEM;

    hPBC->newpi.abort  = TRUE;
    if (PLAYCTRL_FAILURE == pbcEngineSendMessage(PBCENGINE_MSGTYPE_ABORT_COMPLETE, hPBC, 0, 0, 0, 0, 0, NULL))
    {
        /* @todo: handle this very bad case (though it *should* never happen) */
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcAvPres: PBCENGINE_MSGTYPE_ABORT_COMPLETE: pbcEngineSendMessage FAILED.  FIX ME!!\n"));
    }

    /* Clear repeat info */
    memset(&hPBC->RepeatBlock, 0, sizeof(hPBC->RepeatBlock));

    /* Reset flags that indicate waiting for prefills */
    for (i = 0; i < MAX_PE_INPUTS; i++)
    {
        hPBC->fWaitingPrefill[i] = FALSE;
    }

    return (PLAYCTRL_SUCCESS);
}

/**
 * PbcPLCtrlPlaylistComplete -- Playlist playback complete, stop playlist and send
 *                              callback to notify playback complete.
 *
 * @param
 *      hPBC -- handle to playback control engine private data
 *      fError -- set if playback was terminated due to an error
 *
 * @retval
 *      PLAYCTRL_STATUS
 */
void PbcPLCtrlPlaylistComplete(PBC_HANDLE *hPBC, BOOLEAN fError)
{
    PLAYCTRL_EVENT_CODE event;

    /*
     * If playlist playback is active then stop the pbc engine.
     */
    if (hPBC->tState != PLAYCTRL_STATE_STOP)
    {
        /* stop the playlist */
        if (PbcPLCtrlStopPL(hPBC, FALSE) != PLAYCTRL_SUCCESS)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlPlaylistComplete: Failed to stop playlist\n"));
        }

        /* enter the stop state */
        hPBC->tState = PLAYCTRL_STATE_STOP;
    }

    /* set event to send to callback */
    event = (fError == TRUE) ? PLAYCTRL_EVENT_ERROR_PLAYLIST_TERMINATED : PLAYCTRL_EVENT_PLAYLIST_COMPLETE;

    /*
     * Send a callback event to notify the application environment that
     * playback of a playlist is complete.
     */
    if (hPBC->pCallback != NULL)
    {
        hPBC->pCallback(hPBC->pvCallbackContext, event, NULL);
    }

    DRQueueControl(hPBC->hDR, DR_STREAM_MAIN, DR_QUEUE_CMD_DISABLE);
}

/**
 * PbcPLCtrlBegStream -- Handle the beginning of stream event from the PE.
 *
 * @param
 *      hPBC -- handle to playback control engine private data
 *      pPIContext -- pointer to playitem context of current playitem
 *      tInput -- PE Input pin that is at the beginning of stream
 *
 * @retval
 *      PLAYCTRL_STATUS
 */
PLAYCTRL_STATUS PbcPLCtrlBegStream(PBC_HANDLE *hPBC, PBC_PLAYITEM_CONTEXT *pPIContext, PE_ISTREAMCTRL_INPUT tInput, BOOLEAN fRepeatCall)
{
    PLAYCTRL_STATUS         status              = PLAYCTRL_SUCCESS;
    PLAYITEM                *pCurrentPlayItem   = NULL;
    APPINFOPLAYLIST_TABLE   *pPLAppInfo         = NULL;
    uint16                  uiNextPlayitemID;
    uint32                  uiPlaylistID;
    uint32                  uiAngleNumber;
    PE_ISTREAMCTRL_PLAYRATE OldPlayRate;

    DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPLCtrlBegStream PI %u\n",  pPIContext->uiPlayitemID));

    /* verify input */
    if ( (hPBC == NULL) || (pPIContext == NULL) )
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: NULL pointer!\n"));
        status = PLAYCTRL_NULL_POINTER;
        goto errout;
    }

    /* make sure the playlist hasn't changed */
    PbcRegGetPSR(PLAYCTRL_PSR_PLAYLIST, &uiPlaylistID);
    if (pPIContext->uiPlaylistID != uiPlaylistID)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: WRONG PLAYLIST!\n"));
        status = PLAYCTRL_FAILURE;
        goto errout;
    }

    /* Check which PE input pin hit beginning of stream */
    if (tInput == INPUT_MAIN)
    {
        TIME45k  time45k_StartTime;

        DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPLCtrlBegStream PI %u: INPUT_MAIN\n", pPIContext->uiPlayitemID));

        /* gives us a way out in the case where user changes playback before we hit the new playitem */
        if (hPBC->newpi.abort == TRUE)
        {
            DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPLCtrlBegStream PI %u: ABORTED\n", pPIContext->uiPlayitemID));
            status = PLAYCTRL_SUCCESS;
            goto out;
        }

        /* Only on first time through: */
        if (!fRepeatCall && (VDVD_CONNECTION_ABORT != pPIContext->connection) )
        {
            if (hPBC->newpi.doneState == PBC_DECDONE_STATE_ACTIVE)
            {
                hPBC->newpi.doneState = PBC_DECDONE_STATE_INACTIVE;
            }
            else
            {
                SET_BIT(hPBC->newpi.doneState, PBC_DECDONE_STATE_WAITING_BOS);
            }
        }

        /*
         * --The Wait Loop--
         * if the playitem hasn't transitioned, loop
         */
        if ( GET_BIT(hPBC->newpi.doneState, PBC_DECDONE_STATE_WAITING_BOS) &&  (VDVD_CONNECTION_ABORT != pPIContext->connection) )
        {
            DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPLCtrlBegStream PI %u: rejected.  haven't actually reached BOS\n", pPIContext->uiPlayitemID));

            TIME45k time45k_CurrPTS;
            static TIME45k time45k_PrevPTS = 0xffffffff;

            PbcRegGetPSR(PLAYCTRL_PSR_PRES_TIME, &time45k_CurrPTS);

            if ( ( (VDVD_CONNECTION_SEAMLESS_ANGLE    == pPIContext->connection) &&
                   (time45k_CurrPTS                   >= pPIContext->ptsInTime )  ) ||
                 ( (VDVD_CONNECTION_NONSEAMLESS_ANGLE == pPIContext->connection) &&
                   (time45k_CurrPTS                   == time45k_PrevPTS       )  )  )
            {
                DBGPRINT(DBG_ON(DBG_ALL), ("PbcPLCtrlBegStream PI %u: Angle Change Catch - Angle edge detected\n", pPIContext->uiPlayitemID));
                CLR_BIT(hPBC->newpi.doneState, PBC_DECDONE_STATE_WAITING_BOS);
            }
            else
            {
                time45k_PrevPTS = time45k_CurrPTS;
                OS_TaskDelayMsec(100);
                return (PLAYCTRL_RETRY);
            }
        }

        DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPLCtrlBegStream: accepted for playitem %u.  do BOS processing\n", pPIContext->uiPlayitemID));

        hPBC->fReverse      = (pPIContext->PlayRate.direction == PE_ISTREAMCTRL_DIRECTION_FORWARD) ?  0: 1;
        hPBC->ulPlayRate    = pPIContext->PlayRate.rate;

        /***                                           ***/
        /***   SET UP FOR CURRENTLY STARTING PLAYITEM  ***/
        /***                                           ***/
        /***  this section sets the playitem and angle ***/
        /***     registers to the current play and     ***/
        /***   configures the pe for the current play  ***/

        /* Get playlist info */
        if (MPLSGetAppInfo(&pPLAppInfo) != MPLS_SUCCESS)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: MPLSGetAppInfo() Failed!\n"));
            status = PLAYCTRL_FAILURE;
            goto errout;
        }

        /*
         * If playback type is random/shuffle then update the
         * random/shuffle status information.
         */
        if ( (pPLAppInfo->PlayList_playback_type == MPLS_RANDOM_PLAYLIST) ||
            (pPLAppInfo->PlayList_playback_type == MPLS_SHUFFLE_PLAYLIST) )
        {
            /* Set current playitem index */
            RandomShuffle.usCurrentIndex = pPIContext->ubRandomShuffleIndex;

            if (RandomShuffle.usCount == RandomShuffle.usCurrentIndex)
            {
                /* Add this playitem to the list of played playitems */
                RandomShuffle.usPlayedList[RandomShuffle.usCurrentIndex] = pPIContext->uiPlayitemID;

                /* Increment count of played playitems */
                RandomShuffle.usCount++;

                /* If shuffle mode, then update list of available playitems */
                if (pPLAppInfo->PlayList_playback_type == MPLS_SHUFFLE_PLAYLIST)
                {
                    /* Look for this playitem in the list */
                    for (UBYTE i = 0; i < RandomShuffle.usNumberAvailable; i++)
                    {
                        /* If playitem is found, then remove it from list of available playitems */
                        if (RandomShuffle.usAvailableList[i] == pPIContext->uiPlayitemID)
                        {
                            /* Replace this playitem with playitem from end of list and shorten list by 1 */
                            RandomShuffle.usAvailableList[i] = RandomShuffle.usAvailableList[RandomShuffle.usNumberAvailable - 1];
                            RandomShuffle.usAvailableList[RandomShuffle.usNumberAvailable - 1] = 0xff;
                            RandomShuffle.usNumberAvailable--;
                            break;
                        }
                    }
                }
            }
        }

        /* get the playitem info for this playitem */
        if (MPLSGetPlayItem(pPIContext->uiPlayitemID, &pCurrentPlayItem) != MPLS_SUCCESS)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("%s:%u - MPLSGetPlayItem: Failed to get playitem!\n", __FILE__, __LINE__));
            goto errout;
        }

        /* Get current value of the angle number register */
        PbcRegGetPSR(PLAYCTRL_PSR_ANGLE, &uiAngleNumber);
        uiAngleNumber &= 0x000000ff;

        /*
         * If the currently selected angle number is invalid, then set the angle number to 1.
         */
        if (uiAngleNumber > pCurrentPlayItem->number_of_angles)
        {
            uiAngleNumber = 1;
            if (pCurrentPlayItem->is_multi_angle == 1)
            {
                PbcRegSetPSR(PLAYCTRL_PSR_ANGLE, uiAngleNumber);

                /* Send angle change event in callback */
                if (hPBC->pCallback != NULL)

⌨️ 快捷键说明

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