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

📄 pbc_avpres.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                    /*
                     * Check to make sure that the playitem context returned from the DR is actually
                     * the current playitem's context, and not the next.
                     */
                    if (CurrentContext->uiPlayitemID != uiPlayItemID)
                    {
                        /*
                         * The DR is on the NEXT playitem, so need to run the stream selection
                         * algorithm for that playitem to determine the stream number to set
                         * in the context.
                         */

                        /* Get the playitem struct for what's currently playing in the DR */
                        if (MPLSGetPlayItem(CurrentContext->uiPlayitemID, &pPlayItem) != MPLS_SUCCESS)
                        {
                            DBGPRINT(DBG_ON(DBG_ERROR), ("PbcAvPresSubtitleChange: Failed to get playitem!\n"));
                            status = PLAYCTRL_FAILURE;
                            goto out;
                        }

                        /* select subtitle stream number MUST BE BASED ON NEXT PLAYITEM! */
                        PbcStnSelectPGandST( (uiSTStnNew & 0x00000fff), &pPlayItem->STN_table, &uiSTStnNext);
                        uiSTStnNext = uiSTStnNext | (uiSTStnNew & 0xfffff000);

                        /* change the stream info of what's currently playing in the DR */
                        CurrentContext->StreamInfo.uiPGTextSTStn = uiSTStnNext & 0x00000fff;
                    }
                    else
                    {
                        /* change the stream info of what's currently playing in the DR */
                        CurrentContext->StreamInfo.uiPGTextSTStn = uiSTStnNew & 0x00000fff;
                    }
                }

                PbcPLCtrlConfigPGandTextST(hPBC, uiPlaylistID, (uint16)(uiPlayItemID), (uiSTStnNew & 0x00000fff) );
            }

            /*
             *  SET THE PSR
             */
            OS_SemTake(hPBC->semRegisterMutex, OS_WAIT_FOREVER);
            PbcRegSetPSR(PLAYCTRL_PSR_PG_AND_ST_STN, uiSTStnNew);
            OS_SemGive(hPBC->semRegisterMutex);

            DBGPRINT(DBG_ON(DBG_TRACE), ("PbcAvPresSubtitleChange: PSR = 0x%lx\n", uiSTStnNew));


            /*
             *  SET UP NEXT (On the MAIN)
             */
            DRGetStatus(hPBC->hDR, DR_STREAM_MAIN, DR_STATCMD_NEXT_CONTEXT, (uint32 *)&pPIContext);

            /* if there is something in the queue, we need to update it too */
            if (pPIContext != NULL)
            {
                /* Get the playitem struct for the queued playitem */
                if (MPLSGetPlayItem(pPIContext->uiPlayitemID, &pPlayItem) != MPLS_SUCCESS)
                {
                    DBGPRINT(DBG_ON(DBG_ERROR), ("PbcAvPresSubtitleChange: Failed to get playitem!\n"));
                    status = PLAYCTRL_FAILURE;
                    goto out;
                }

                /* select subtitle stream number MUST BE BASED ON NEXT PLAYITEM! */
                PbcStnSelectPGandST( (uiSTStnNew & 0x00000fff), &pPlayItem->STN_table, &uiSTStnNext);
                uiSTStnNext = uiSTStnNext | (uiSTStnNew & 0xfffff000);

                /* modify the context */
                pPIContext->StreamInfo.uiPGTextSTStn = uiSTStnNext & 0x00000fff;
            }
        }

        /* send event to the module manager */
        if (hPBC->pCallback != NULL)
        {
            uint32 tmp_uiSTStnNew;

            uiSTStnNew &= 0x00000fff;
            tmp_uiSTStnNew = uiSTStnNew;
            hPBC->pCallback(hPBC->pvCallbackContext, PLAYCTRL_EVENT_SUBTITLECHANGE, &tmp_uiSTStnNew);
        }

out:
        DRQueueControl(hPBC->hDR, dr_stream, DR_QUEUE_CMD_ENABLE);
        DRQueueControl(hPBC->hDR, DR_STREAM_MAIN, DR_QUEUE_CMD_ENABLE);
    }

    return (PLAYCTRL_SUCCESS);
}

/**
 * PbcAvPresSubtitleDisplay -- Enable/Disable display of PG/TextST subtitles
 *
 * @param
 *      hPBC -- handle to playback control engine private data
 *      data1 -- TRUE - Enable; FALSE - Disable
 *      data2 -- not used
 *      data3 -- not used
 *
 * @retval
 *      PLAYCTRL_STATUS
 */
PLAYCTRL_STATUS PbcAvPresSubtitleDisplay(PBC_HANDLE *hPBC, ULONG data1, ULONG data2, ULONG data3)
{
    uint32 uiSTStnCurrent;

    if (data1 == FALSE)
    {
        /* Continue to decode subpics, but don't show them */
        PEiConfigureHideSubPic(hPBC->hPE);

        /* whether it passes or fails, clear the PG/ST display flag */
        OS_SemTake(hPBC->semRegisterMutex, OS_WAIT_FOREVER);
        PbcRegGetPSR(PLAYCTRL_PSR_PG_AND_ST_STN, &uiSTStnCurrent);
        PbcRegSetPSR(PLAYCTRL_PSR_PG_AND_ST_STN, (uiSTStnCurrent & 0x7fffffff));
        OS_SemGive(hPBC->semRegisterMutex);
    }
    else
    {
        /* Show the decoded subpics */
        PEiConfigureShowSubPic(hPBC->hPE);

        /* whether it passes or fails, set the PG/ST display flag */
        OS_SemTake(hPBC->semRegisterMutex, OS_WAIT_FOREVER);
        PbcRegGetPSR(PLAYCTRL_PSR_PG_AND_ST_STN, &uiSTStnCurrent);
        PbcRegSetPSR(PLAYCTRL_PSR_PG_AND_ST_STN, (uiSTStnCurrent | 0x80000000));
        OS_SemGive(hPBC->semRegisterMutex);
    }

    return (PLAYCTRL_SUCCESS);
}

/**
 * PbcAvPresAngleChange -- Change presentation to specified angle number.
 *
 * @param
 *      hPBC -- handle to playback control engine private data
 *      data1 -- angle number
 *      data2 -- not used
 *      data3 -- not used
 *
 * @retval
 *      PLAYCTRL_STATUS
 */
PLAYCTRL_STATUS PbcAvPresAngleChange(PBC_HANDLE *hPBC, ULONG data1, ULONG data2, ULONG data3)
{
    PLAYCTRL_STATUS         status                   = PLAYCTRL_SUCCESS;
    uint32                  uiPlaylistID;
    uint32                  uiPlayitemID;
    PLAYITEM                *pPlayItem               = NULL;
    uint32                  uiCurAngle;
    uint32                  uiNewAngle               = 1;
    PBC_PLAYITEM_CONTEXT    *pPIContext              = NULL;
    ULONG                   ptsValue;
    DR_ERROR                retCode;
    UBYTE                   ubNextRandomShuffleIndex = 0xff;
    BOOLEAN                 fGiveSem                 = FALSE;
    BOOLEAN                 fSendNotification        = TRUE;

    DBGPRINT(DBG_ON(DBG_TRACE), ("PbcAvPresAngleChange: angle number = %d\n", data1));

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

    /* if we're currently stopped then just update the PSR */
    if (hPBC->tState == PLAYCTRL_STATE_STOP)
    {
        DBGPRINT(DBG_ON(DBG_TRACE), ("PbcAvPresAngleChange: JUST UPDATE PSR\n"));

        /* update the current angle selection */
        OS_SemTake(hPBC->semRegisterMutex, OS_WAIT_FOREVER);
        PbcRegGetPSR(PLAYCTRL_PSR_ANGLE, &uiCurAngle);
        uiCurAngle &= 0xffffff00;
        uiCurAngle |= (data1 & 0x000000ff);
        PbcRegSetPSR(PLAYCTRL_PSR_ANGLE, uiCurAngle);
        OS_SemGive(hPBC->semRegisterMutex);

        DBGPRINT(DBG_ON(DBG_TRACE), ("PbcAvPresAngleChange: PSR = 0x%lx\n", uiCurAngle));

        /* send event, notifying application of subtitle change */
        if (hPBC->pCallback != NULL)
        {
            uint32 tmp_data1 = data1;
            hPBC->pCallback(hPBC->pvCallbackContext, PLAYCTRL_EVENT_ANGLECHANGE, &tmp_data1);
        }

        return (PLAYCTRL_SUCCESS);
    }

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

    /* Halt the DR play queue */
    DRQueueControl(hPBC->hDR, DR_STREAM_MAIN, DR_QUEUE_CMD_DISABLE);

    /* find out context of the dr's current play */
    DRGetStatus(hPBC->hDR, DR_STREAM_MAIN, DR_STATCMD_CONTEXT, (uint32 *)&pPIContext);

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

    /* find the Decoder's current location */
    PbcRegGetPSR(PLAYCTRL_PSR_PLAYITEM, &uiPlayitemID);

    DBGPRINT(DBG_ON(DBG_VERBOSE), ("play item id number: %lu\n", uiPlayitemID));

    /* Get pointer to the playitem from the movie playlist database */
    if (MPLSGetPlayItem( (uint16)(uiPlayitemID), &pPlayItem) != MPLS_SUCCESS)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcAvPresAngleChange: Failed to get playitem!\n"));
        status = PLAYCTRL_FAILURE;
        fGiveSem = TRUE;
        goto out;
    }

    /*
     * Is the playitem that the decoder is in multi-angle?
     * If so, set the angle PSR accordingly.
     * If it is not multi-angle, the spec says to just set the angle PSR to the specified value.
     */
    if (1 == pPlayItem->is_multi_angle)
    {
        /* Get the current angle number */
        PbcRegGetPSR(PLAYCTRL_PSR_ANGLE, &uiCurAngle);
        uiCurAngle &= 0x000000ff;

        DBGPRINT(DBG_ON(DBG_VERBOSE), ("is multi angle\n"));
        /*  Is the desired angle valid? */
        if (data1 <= pPlayItem->number_of_angles)
        {
            DBGPRINT(DBG_ON(DBG_VERBOSE), ("is being set to angle\n"));
            /* If so, then set the angle number register */
            uiNewAngle = data1;
            PbcRegSetPSR(PLAYCTRL_PSR_ANGLE, uiNewAngle);
        }
        else
        {
            uiNewAngle = uiCurAngle;

            /* this angle change request is rejected, so don't send notification of angle change */
            fSendNotification = FALSE;
        }
    }
    else
    {
        /* Just update the PSR */
        uiNewAngle = data1;
        PbcRegSetPSR(PLAYCTRL_PSR_ANGLE, uiNewAngle);
        status = PLAYCTRL_SUCCESS;
        fGiveSem = TRUE;
        goto out;
    }

    OS_SemGive(hPBC->semRegisterMutex);


    /* Get pointer to the playitem from the movie playlist database */
    if (MPLSGetPlayItem(pPIContext->uiPlayitemID, &pPlayItem) != MPLS_SUCCESS)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcAvPresAngleChange: Failed to get playitem!\n"));
        status = PLAYCTRL_FAILURE;
        goto out;
    }

    DBGPRINT(DBG_ON(DBG_TRACE), ("curangle:  %lu  ---   newangle: %lu\n", uiCurAngle, uiNewAngle));

    if ( (uiCurAngle != uiNewAngle) && (1 == pPlayItem->is_multi_angle) )        /* if angle number has changed (and DR's still in that block), switch dr to new angle*/
    {
        uint16                uiNextPlayitemID;
        APPINFOPLAYLIST_TABLE *pPLAppInfo = NULL;
        PBC_WHICH_CONTEXT     pwContext;
        VDVD_CONNECT_COND     connection  = VDVD_CONNECTION_UNDEF;

        DBGPRINT(DBG_ON(DBG_TRACE), ("angle is changing\n"));

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

        /* angle changed: clear the old playitems out of the queue
         *   if something was removed, re-use that context */
        if (DR_SUCCESS == DRQueueControl(hPBC->hDR, DR_STREAM_MAIN, DR_QUEUE_CMD_CLEAR))
        {
            pwContext = PBC_CURRENT;
        }
        else
        {
            pwContext = PBC_NEXT;
        }

        retCode = DRBDROMStopAtPoint(hPBC->hDR, TRUE, &ptsValue, (PVOID *)&pPIContext);

        if (DR_FAILURE != retCode)
        {
            /* if we successfully found an angle point in the current playitem,
             * RE-SEND THE CURRENT playitem with the new angle, and starting at the angle point
             */
            DBGPRINT(DBG_ON(DBG_TRACE), ("PbcAvPresAngleChange: found angle change point\n"));
            uiNextPlayitemID = pPIContext->uiPlayitemID;

            if (hPBC->ulPlayRate == 1000)
            {
                if (pPlayItem->is_seamless_angle_change)
                {
                    connection = VDVD_CONNECTION_SEAMLESS_ANGLE;
                }
                else
                {
                    connection = VDVD_CONNECTION_NONSEAMLESS_ANGLE;
                }
            }
            else
            {
                if (pPlayItem->is_seamless_angle_change)
                {
                    connection = VDVD_CONNECTION_5;
                }
                else
                {
                    connection = VDVD_CONNECTION_1;
                }
            }

            /*
             * If playlist is random/shuffle, then set the random/shuffle index
             * of the playitem to be played.
             */
            if ( (pPLAppInfo->PlayList_playback_type == MPLS_RANDOM_PLAYLIST) ||
                (pPLAppInfo->PlayList_playback_type == MPLS_SHUFFLE_PLAYLIST) )

⌨️ 快捷键说明

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