📄 pbc_plcontrol.cpp
字号:
{
uint32 tmp_uiAngleNumber = uiAngleNumber;
hPBC->pCallback(hPBC->pvCallbackContext, PLAYCTRL_EVENT_ANGLECHANGE, &tmp_uiAngleNumber);
}
}
}
/* Notify UI if multi-angle is available or not */
if (1 == pCurrentPlayItem->is_multi_angle)
{
ULONG message[4];
message[0] = VDVD_STATUS_ANGLE_ON;
UsrEventHandler(message);
}
else
{
ULONG message[4];
message[0] = VDVD_STATUS_ANGLE_OFF;
UsrEventHandler(message);
}
if ( (VDVD_CONNECTION_1 == pPIContext->connection) ||
(VDVD_CONNECTION_ABORT == pPIContext->connection) ||
(VDVD_CONNECTION_NONSEAMLESS_ANGLE == pPIContext->connection) )
{
DR_STREAM stream_path;
uint32 uiTmp;
uint32 uiLastAudioStn;
uint32 uiLastSubtitleStn;
uint32 uiLastIGStn;
DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPLCtrlBegStream: non-seamless connection\n"));
PEiStreamCtrlFlush(hPBC->hPE, INPUT_MAIN);
/*
* Set PSRs
*/
/* Set Audio Stream Number (use upper bits from the current PSR) */
if (PbcRegGetPSR(PLAYCTRL_PSR_AUDIO_STN, &uiTmp) != PLAYCTRL_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: Failed to get AudioStn!\n"));
goto errout;
}
uiLastAudioStn = uiTmp & 0x000000ff;
uiTmp = (pPIContext->StreamInfo.uiPrimaryAudioStn & 0x000000ff) | (uiTmp & 0xffffff00);
if (PlayCtrlSetPSR(PLAYCTRL_PSR_AUDIO_STN, uiTmp) != PLAYCTRL_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: Failed to set audio stream number!\n"));
goto errout;
}
/* Set PG/TEXTST Stream Number (use upper bits from the current PSR) */
if (PbcRegGetPSR(PLAYCTRL_PSR_PG_AND_ST_STN, &uiTmp) != PLAYCTRL_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: Failed to get PG/TextST stream number!\n"));
goto errout;
}
uiLastSubtitleStn = uiTmp & 0x00000fff;
uiTmp = (pPIContext->StreamInfo.uiPGTextSTStn & 0x00000fff) | (uiTmp & 0xfffff000);
if (PlayCtrlSetPSR(PLAYCTRL_PSR_PG_AND_ST_STN, uiTmp) != PLAYCTRL_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: Failed to set subtitle number!\n"));
goto errout;
}
/* Set IG Stream Number (use upper bits from the current PSR) */
if (PbcRegGetPSR(PLAYCTRL_PSR_IG_STN, &uiTmp) != PLAYCTRL_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: Failed to get IG Stn!\n"));
goto errout;
}
uiLastIGStn = uiTmp & 0x000000ff;
uiTmp = (pPIContext->StreamInfo.uiIGStn & 0x000000ff) | (uiTmp & 0xffffff00);
if (PlayCtrlSetPSR(PLAYCTRL_PSR_IG_STN, uiTmp) != PLAYCTRL_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: Failed to set IG stream number!\n"));
goto errout;
}
/*
* If audio/subtitle stream PSRs have changed, then send callback events,
* notifying application of the changes.
*/
if (hPBC->pCallback != NULL)
{
if (uiLastAudioStn != pPIContext->StreamInfo.uiPrimaryAudioStn)
{
uint32 tmp_uiPrimaryAudioStn = pPIContext->StreamInfo.uiPrimaryAudioStn;
hPBC->pCallback(hPBC->pvCallbackContext, PLAYCTRL_EVENT_AUDIOCHANGE, &tmp_uiPrimaryAudioStn);
}
if (uiLastSubtitleStn != pPIContext->StreamInfo.uiPGTextSTStn)
{
uint32 tmp_uiPGTextSTStn = pPIContext->StreamInfo.uiPGTextSTStn;
hPBC->pCallback(hPBC->pvCallbackContext, PLAYCTRL_EVENT_SUBTITLECHANGE, &tmp_uiPGTextSTStn);
}
}
/*
* Configure Streams (if not discontiguous)
*/
if (pPIContext->PlayRate.discontiguous == 0)
{
uint32 uiPrevPlayitemID;
/*
* Get previous playitem ID. The PSR hasn't been set with this new playitem ID yet,
* so the value from the PSR contains the previous playitem ID.
*/
PbcRegGetPSR(PLAYCTRL_PSR_PLAYITEM, &uiPrevPlayitemID);
uiPrevPlayitemID &= 0x0000ffff;
/* get stream path that primary audio is on */
stream_path = PbcPLCtrlGetDRStreamType(hPBC, PBC_STREAM_ENTRY_PAUDIO, pPIContext->uiPlayitemID,
pPIContext->StreamInfo.uiPrimaryAudioStn);
/* Only configure primary audio if it is on the main */
if (DR_STREAM_MAIN == stream_path)
{
/* Configure Primary Audio */
if (PbcPLCtrlConfigPrimaryAudio(hPBC, uiPlaylistID, pPIContext->uiPlayitemID,
pPIContext->StreamInfo.uiPrimaryAudioStn) != PLAYCTRL_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: pbcplctrlSelectPrimaryAudio() FAILED!\n"));
}
}
else if (DR_STREAM_NONE == stream_path)
{
/* There is no audio, so remove the audio demux */
if (PbcPLCtrlConfigPrimaryAudio(hPBC, uiPlaylistID, pPIContext->uiPlayitemID, 0) != PLAYCTRL_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: pbcplctrlSelectPrimaryAudio() FAILED!\n"));
}
}
/* get stream path that secondary audio is on */
stream_path = PbcPLCtrlGetDRStreamType(hPBC, PBC_STREAM_ENTRY_SAUDIO, pPIContext->uiPlayitemID,
pPIContext->StreamInfo.uiSecondaryAudioStn);
/* Only configure secondary audio if it is on the main */
if (DR_STREAM_MAIN == stream_path)
{
/* Configure Secondary Audio */
if (pbcplctrlConfigSecondaryAudio(hPBC, uiPlaylistID, pPIContext->uiPlayitemID,
pPIContext->StreamInfo.uiSecondaryAudioStn) != PLAYCTRL_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: pbcplctrlSelectPrimaryAudio() FAILED!\n"));
}
}
/* get stream path that pg/textst is on */
stream_path = PbcPLCtrlGetDRStreamType(hPBC, PBC_STREAM_ENTRY_PGTEXTST, pPIContext->uiPlayitemID,
pPIContext->StreamInfo.uiPGTextSTStn);
/*
* Only configure PG/TextST if there is no pg/textst stream (to remove demux), or
* if the stream is on the main path.
*/
if ( (DR_STREAM_MAIN == stream_path) || (DR_STREAM_NONE == stream_path) )
{
/* Configure PG and Text ST */
if (PbcPLCtrlConfigPGandTextST(hPBC, uiPlaylistID, pPIContext->uiPlayitemID,
pPIContext->StreamInfo.uiPGTextSTStn) != PLAYCTRL_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: PbcPLCtrlConfigPGandTextST() FAILED!\n"));
}
}
else
{
/*
* Subtitle is out-of-mux TextST on a subpath. Now we need to determine if
* this TextST subpath has already been preloaded or not. If it has not already
* been preloaded, then we should preload it now. If it has been preloaded, then
* we don't need to do anything. Note that we cannot preload out-of-mux streams
* whenever we send the next playitem to the DR because that would cause the preload
* buffer to be filled with the stream for the next playitem, not the current one.
*/
/*
* Need to know if the new textst stream entry uses the same clip as the previous
* textst stream entry. If they do not use the same clip, then we need to preload
* the new textst subpath.
*/
if (FALSE == pbcPLCtrlIsSameClip(hPBC, PBC_STREAM_ENTRY_PGTEXTST, pPIContext->uiPlayitemID, (uint16)(pPIContext->StreamInfo.uiPGTextSTStn),
(uint16)(uiPrevPlayitemID), (uint16)(uiLastSubtitleStn)) )
{
/*
* Enable DR queue on TextST stream.
* Must do this before preloading the clip, because the clip is prefilled synchronously.
* If DR queue was not enabled whenever we started to prefill, we would wait forever
* because DR would never start streaming data to the PE.
*/
DRQueueControl(hPBC->hDR, DR_STREAM_BDROM_SUBPATH_TEXT_SUBTITLE, DR_QUEUE_CMD_ENABLE);
/* Preload the new TextST, and wait for prefill to complete */
if (PbcPLCtrlPlaySubPlayitem(hPBC, pPIContext->uiPlayitemID, PBC_STREAM_ENTRY_PGTEXTST, pPIContext->StreamInfo.uiPGTextSTStn, TRUE) != PLAYCTRL_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: Failed to play subplayitem!\n"));
}
}
}
/* get stream path that IG is on */
stream_path = PbcPLCtrlGetDRStreamType(hPBC, PBC_STREAM_ENTRY_IG, pPIContext->uiPlayitemID,
pPIContext->StreamInfo.uiIGStn);
/*
* Only configure IG if there is no IG stream (to remove demux), or
* if the stream is on the main path.
*/
if ( (DR_STREAM_MAIN == stream_path) || (DR_STREAM_NONE == stream_path) )
{
/* Configure IG */
if (PbcPLCtrlConfigIG(hPBC, uiPlaylistID, pPIContext->uiPlayitemID,
pPIContext->StreamInfo.uiIGStn) != PLAYCTRL_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: PbcPLCtrlConfigIG() FAILED!\n"));
}
}
else
{
/*
* IG is out-of-mux on a subpath. Now we need to determine if
* this IG subpath has already been preloaded or not. If it has not already
* been preloaded, then we should preload it now. If it has been preloaded, then
* we don't need to do anything. Note that we cannot preload out-of-mux streams
* whenever we send the next playitem to the DR because that would cause the preload
* buffer to be filled with the stream for the next playitem, not the current one.
*/
/*
* Need to know if the new IG stream entry uses the same clip as the previous
* IG stream entry. If they do not use the same clip, then we need to preload
* the new IG subpath.
*/
if (FALSE == pbcPLCtrlIsSameClip(hPBC, PBC_STREAM_ENTRY_IG, pPIContext->uiPlayitemID, (uint16)(pPIContext->StreamInfo.uiIGStn),
(uint16)(uiPrevPlayitemID), (uint16)(uiLastIGStn)) )
{
ULONG out_msg[4];
/* Notify UI that we are preloading an out of mux IG stream since this can
* take some time to prefill. */
out_msg[0] = VDVD_STATUS_LOADING;
out_msg[1] = VDVD_LOADING_TITLE;
UsrEventHandler(out_msg);
/*
* Enable DR queue on IG stream.
* Must do this before preloading the clip, because the clip is prefilled synchronously.
* If DR queue was not enabled whenever we started to prefill, we would wait forever
* because DR would never start streaming data to the PE.
*/
DRQueueControl(hPBC->hDR, DR_STREAM_BDROM_SUBPATH_INTERACTIVE_GRAPHICS, DR_QUEUE_CMD_ENABLE);
/* Preload the new IG, and wait for prefill to complete */
if (PbcPLCtrlPlaySubPlayitem(hPBC, pPIContext->uiPlayitemID, PBC_STREAM_ENTRY_IG, pPIContext->StreamInfo.uiIGStn, TRUE) != PLAYCTRL_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: Failed to play subplayitem!\n"));
}
/* Notify UI that we are done preloading the IG */
out_msg[0] = VDVD_STATUS_LOAD_COMPLETE;
out_msg[1] = VDVD_LOADING_TITLE;
UsrEventHandler(out_msg);
}
}
}
}
time45k_StartTime = (!hPBC->fReverse) ? pPIContext->ptsInTime : pPIContext->ptsOutTime;
PbcPLCtrlUpdateLocation(hPBC, time45k_StartTime, TRUE);
/* Get the Current PE PlayRate configuration */
PEiStreamCtrlGetRate(hPBC->hPE, &OldPlayRate);
/* set the new PE decode rate */
if ( (pPIContext->PlayRate.rate != OldPlayRate.rate) &&
(hPBC->tState == PLAYCTRL_STATE_PLAY ) )
{
PEiStreamCtrlSetRate(hPBC->hPE, &(pPIContext->PlayRate));
}
/*** ***/
/*** PUT NEXT PLAYITEM INTO THE PLAY QUEUE ***/
/*** ***/
/*** this section puts the next play item ***/
/*** into the play queue ***/
/* Get the next playitem id */
uiNextPlayitemID = PbcPLCtrlGetNextPlayitem(hPBC, pPIContext->uiPlayitemID);
/*
* If the the next playitem exists, then configure the DR to
* start reading the clip(s) for the next playitem.
*/
if (uiNextPlayitemID != INVALID_PLAYITEM)
{
PLAYITEM *pNextPlayItem = NULL;
UBYTE ubNextRandomShuffle = 0xff;
BOOLEAN fReverse = hPBC->fReverse;
uint32 uiPlayRate = hPBC->ulPlayRate;
VDVD_CONNECT_COND connection;
/* get the playitem info */
if (MPLSGetPlayItem(uiNextPlayitemID, &pNextPlayItem) != MPLS_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPLCtrlBegStream: Failed to get playitem!\n"));
goto errout;
}
time45k_StartTime = (!hPBC->fReverse) ? pNextPlayItem->IN_time : pNextPlayItem->OUT_time;
if ( (pPLAppInfo->PlayList_playback_type == MPLS_RANDOM_PLAYLIST) ||
(pPLAppInfo->PlayList_playback_type == MPLS_SHUFFLE_PLAYLIST) )
{
/* Get the next random/shuffle index */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -