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

📄 pbc_avpres.cpp

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

        return (PLAYCTRL_SUCCESS);
    }

    /* Get the current playitem id */
    PlayCtrlGetPSR(PLAYCTRL_PSR_PLAYITEM, &uiPlayItemID);
    uiPlayItemID &= 0x0000ffff;

    /* Get the playitem from the movie playlist database */
    if (MPLSGetPlayItem( (uint16)(uiPlayItemID), &pPlayItem) != MPLS_SUCCESS)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcAvPresAudioChange: Failed to get playitem!\n"));
        return (PLAYCTRL_FAILURE);
    }

    /*
     * If specified audio stream number is valid, then select
     * the audio stream number.
     */
    if ( (data1 <= pPlayItem->STN_table.number_of_primary_audio_stream_entries) || (data1 == 0xff) )
    {
        DR_STREAM dr_stream = DR_STREAM_NONE;

        OS_SemTake(hPBC->semRegisterMutex, OS_WAIT_FOREVER);

        /* Get the current audio stream number */
        PbcRegGetPSR(PLAYCTRL_PSR_AUDIO_STN, &uiAudioStnCurrent);

        /* select audio stream number */
        PbcStnSelectAudio(data1, &pPlayItem->STN_table, &uiAudioStnNew);

        /*
         * If the default stream was not requested and the requested stream number was
         * not selected, then do not change the stream.
         */
        if ( (data1 != 0xff) && (data1 != uiAudioStnNew) )
        {
            goto out;
        }

        uiAudioStnNew = uiAudioStnNew | (uiAudioStnCurrent & 0xffffff00);

        dr_stream = PbcPLCtrlGetDRStreamType(hPBC, PBC_STREAM_ENTRY_PAUDIO, (uint16)(uiPlayItemID), (uiAudioStnNew & 0x000000ff) );

        /* Halt the DR play queue so the DR status can't change */
        DRQueueControl(hPBC->hDR, DR_STREAM_MAIN, DR_QUEUE_CMD_DISABLE);
        DRQueueControl(hPBC->hDR, dr_stream, DR_QUEUE_CMD_DISABLE);

        /* If audio stream number has been changed, then switch to new audio stream */
        if ( (uiAudioStnCurrent & 0x000000ff) != (uiAudioStnNew & 0x000000ff) )
        {
            uint32                   uiPlaylistID;
            PE_ISTREAMCTRL_PLAYRATE  PlayRate;
            PBC_PLAYITEM_CONTEXT     *pPIContext = NULL;
            PBC_PLAYITEM_CONTEXT     *CurrentContext =  NULL;


            /* Configure audio */
            PbcRegGetPSR(PLAYCTRL_PSR_PLAYLIST, &uiPlaylistID);

            /*
             *  CHANGE CURRENT      (check that we're not in discrete mode)
             */
            PEiStreamCtrlGetRate(hPBC->hPE, &PlayRate);
            if (PlayRate.discontiguous == 0)
            {
                /* If desired audio is on a subpath */
                if (dr_stream != DR_STREAM_MAIN)
                {
                    /* Play the subplayitem */
                    if (PbcPLCtrlPlaySubPlayitem(hPBC, (uint16)(uiPlayItemID), PBC_STREAM_ENTRY_PAUDIO, (uiAudioStnNew & 0x000000ff), FALSE) != PLAYCTRL_SUCCESS)
                    {
                        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcAvPresAudioChange: Failed to play subplayitem!\n"));
                        status = PLAYCTRL_FAILURE;
                        goto out;
                    }
                }

                DRGetStatus(hPBC->hDR, DR_STREAM_MAIN, DR_STATCMD_CONTEXT, (uint32 *)&CurrentContext);

                if (CurrentContext != NULL)
                {
                    /*
                     * 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! */
                        PbcStnSelectAudio( (uiAudioStnNew & 0x00000fff), &pPlayItem->STN_table, &uiAudioStnNext);
                        uiAudioStnNext = uiAudioStnNext | (uiAudioStnNew & 0xffffff00);

                        /* change the stream info of what's currently playing in the DR */
                        CurrentContext->StreamInfo.uiPrimaryAudioStn = uiAudioStnNext & 0x000000ff;
                    }
                    else
                    {
                        /* change the stream info of what's currently playing in the DR */
                        CurrentContext->StreamInfo.uiPrimaryAudioStn = (uiAudioStnNew & 0x000000ff);
                    }
                }

                PbcPLCtrlConfigPrimaryAudio(hPBC, uiPlaylistID, (uint16)(uiPlayItemID), (uiAudioStnNew & 0x000000ff) );
            }

            /*
             *  SET THE PSR
             */
            PbcRegSetPSR(PLAYCTRL_PSR_AUDIO_STN, uiAudioStnNew);

            /*
             *  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), ("PbcAvPresAudioChange: Failed to get playitem!\n"));
                    status = PLAYCTRL_FAILURE;
                    goto out;
                }

                /* select audio stream number MUST BE BASED ON NEXT PLAYITEM! */
                PbcStnSelectAudio( (uiAudioStnNew & 0x00000fff), &pPlayItem->STN_table, &uiAudioStnNext);
                uiAudioStnNext = uiAudioStnNext | (uiAudioStnNew & 0xffffff00);

                /* modify the context */
                pPIContext->StreamInfo.uiPrimaryAudioStn = uiAudioStnNext & 0x000000ff;
            }
        }

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

            uiAudioStnNew &= 0x000000ff;
            tmp_uiAudioStnNew = uiAudioStnNew;
            hPBC->pCallback(hPBC->pvCallbackContext, PLAYCTRL_EVENT_AUDIOCHANGE, &tmp_uiAudioStnNew);
        }

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

    return (status);
}

/**
 * PbcAvPresSecondaryAudioChange -- Change presentation of secondary audio to
 *                                 specified secondary audio stream
 *
 * @param
 *      hPBC -- handle to playback control engine private data
 *      data1 -- audio stream number
 *      data2 -- not used
 *      data3 -- not used
 *
 * @retval
 *      PLAYCTRL_STATUS
 */
PLAYCTRL_STATUS PbcAvPresSecondaryAudioChange(PBC_HANDLE *hPBC, ULONG data1, ULONG data2, ULONG data3)
{
    DBGPRINT(DBG_ON(DBG_ERROR), ("PbcAvPresSecondaryAudioChange: stubbed\n"));
    return (PLAYCTRL_NOT_IMPLEMENTED);
}

/**
 * PbcAvPresSubtitleChange -- Change presentation of subtitle to specified subtitle stream
 *
 * @param
 *      hPBC -- handle to playback control engine private data
 *      data1 -- subtitle stream number
 *      data2 -- not used
 *      data3 -- not used
 *
 * @retval
 *      PLAYCTRL_STATUS
 */
PLAYCTRL_STATUS PbcAvPresSubtitleChange(PBC_HANDLE *hPBC, ULONG data1, ULONG data2, ULONG data3)
{
    uint32          uiPlayItemID    = 0;
    PLAYITEM        *pPlayItem      = NULL;
    uint32          uiSTStnCurrent;
    uint32          uiSTStnNew;
    uint32          uiSTStnNext;
    PLAYCTRL_STATUS status          = PLAYCTRL_SUCCESS;

    DBGPRINT(DBG_ON(DBG_TRACE), ("PbcAvPresSubtitleChange: subtitle stream = %d\n", data1));

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

    /* zero is not a valid option */
    if (data1 == 0)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcAvPresSubtitleChange: Invalid Param!\n"));
        return (PLAYCTRL_FAILURE);
    }

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

        /* update the current stream selection */
        OS_SemTake(hPBC->semRegisterMutex, OS_WAIT_FOREVER);
        PbcRegGetPSR(PLAYCTRL_PSR_PG_AND_ST_STN, &uiSTStnCurrent);

        /* check if the requested subtitle stream is different than the current subtitle stream */
        if (data1 != (uiSTStnCurrent & 0x00000fff) )
        {
            /*
             * Set flag to indicate that subtitle stream change needs to happen when a
             * playlist is started again.
             */
            hPBC->fSubtitleChangePending = TRUE;
        }

        /* Set the PSR to the requested stream number */
        uiSTStnCurrent &= 0xfffff000;
        uiSTStnCurrent |= (data1 & 0x00000fff);
        PbcRegSetPSR(PLAYCTRL_PSR_PG_AND_ST_STN, uiSTStnCurrent);
        OS_SemGive(hPBC->semRegisterMutex);

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

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

        return (PLAYCTRL_SUCCESS);
    }

    /* Get the current playitem id */
    PlayCtrlGetPSR(PLAYCTRL_PSR_PLAYITEM, &uiPlayItemID);
    uiPlayItemID &= 0x0000ffff;

    /* Get the playitem from the movie playlist database */
    if (MPLSGetPlayItem( (uint16)(uiPlayItemID), &pPlayItem) != MPLS_SUCCESS)
    {
        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcAvPresSubtitleChange: Failed to get playitem!\n"));
        return (PLAYCTRL_FAILURE);
    }

    /*
     * If specified subtitle stream number is valid, then select
     * the subtitle stream number.
     */
    if ( (data1 <= pPlayItem->STN_table.number_of_PG_textST_stream_entries) || (data1 == 0x0fff) )
    {
        DR_STREAM dr_stream = DR_STREAM_NONE;

        /* Get the current subtitle stream number */
        PbcRegGetPSR(PLAYCTRL_PSR_PG_AND_ST_STN, &uiSTStnCurrent);

        /* select subtitle stream number */
        PbcStnSelectPGandST(data1, &pPlayItem->STN_table, &uiSTStnNew);

        /*
         * If the default stream was not requested and the requested stream number was
         * not selected, then do not change the stream.
         */
        if ( (data1 != 0x0fff) && (data1 != uiSTStnNew) )
        {
            goto out;
        }

        uiSTStnNew = uiSTStnNew | (uiSTStnCurrent & 0xfffff000);

        dr_stream = PbcPLCtrlGetDRStreamType(hPBC, PBC_STREAM_ENTRY_PGTEXTST, (uint16)(uiPlayItemID), (uiSTStnNew & 0x00000fff) );

        /* Halt the DR play queue so the DR status can't change */
        DRQueueControl(hPBC->hDR, DR_STREAM_MAIN, DR_QUEUE_CMD_DISABLE);
        DRQueueControl(hPBC->hDR, dr_stream, DR_QUEUE_CMD_DISABLE);

        /* If subtitle stream number has been changed, then switch to new subtitle stream */
        if ( (uiSTStnCurrent & 0x00000fff) != (uiSTStnNew & 0x00000fff) )
        {
            uint32                   uiPlaylistID;
            PE_ISTREAMCTRL_PLAYRATE  PlayRate;
            PBC_PLAYITEM_CONTEXT     *pPIContext = NULL;
            PBC_PLAYITEM_CONTEXT     *CurrentContext = NULL;

            /* Configure PG, Text Subtitles */
            PbcRegGetPSR(PLAYCTRL_PSR_PLAYLIST, &uiPlaylistID);

            /*
             *  CHANGE CURRENT      (check that we're not in discrete mode)
             */
            PEiStreamCtrlGetRate(hPBC->hPE, &PlayRate);
            if (PlayRate.discontiguous == 0)
            {
                /* If desired subtitle is on a subpath */
                if (dr_stream != DR_STREAM_MAIN)
                {
                    /*
                     * Note: Do not remove the current demux now, because the new demux will get added
                     * when we process the subplayitem in PbcPLCtrlPlaySubPlayitem().  This is a
                     * change that occured with prefilling the TextST subpath synchronously.  Previously
                     * the new demux was not added until the beginning of stream processing, so we
                     * needed to remove the old demux here.
                     */

                    /* Play the subplayitem */
                    if (PbcPLCtrlPlaySubPlayitem(hPBC, (uint16)(uiPlayItemID), PBC_STREAM_ENTRY_PGTEXTST, (uiSTStnNew & 0x00000fff), FALSE) != PLAYCTRL_SUCCESS)
                    {
                        DBGPRINT(DBG_ON(DBG_ERROR), ("PbcAvPresSubtitleChange: Failed to play subplayitem!\n"));
                        status = PLAYCTRL_FAILURE;
                        goto out;
                    }
                }

                DRGetStatus(hPBC->hDR, DR_STREAM_MAIN, DR_STATCMD_CONTEXT, (uint32 *)&CurrentContext);

                if (CurrentContext != NULL)
                {

⌨️ 快捷键说明

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