📄 pbc_pbscenario.cpp
字号:
return (PLAYCTRL_SUCCESS);
}
else
{
PbcPLCtrlInitRandomShuffle();
ubRandomShuffle = 0;
}
}
/* Get PSR for current playitem id */
PbcRegGetPSR(PLAYCTRL_PSR_PLAYITEM, &uiPlayitemID);
/* Pull out current playitem id from PSR value */
uiPlayitemID &= 0x0000ffff;
/* Get the playitem info for target playitem */
if (MPLSGetPlayItem(pPLMark->PL_mark[uiTargetPM].ref_to_PlayItem_id, &pPlayitem) != MPLS_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioPlayPLMark: Failed to get playitem info\n"));
return (PLAYCTRL_FAILURE);
}
/* Get ID of last playlist to be played */
PbcRegGetPSR(PLAYCTRL_PSR_PLAYLIST, &uiLastPlaylistID);
/* Get the PE run state */
PEiStreamCtrlGetState(hPBC->hPE, &tPEState);
/* Determine if this is a new playlist */
fNewPlaylist = (uiLastPlaylistID != uiPlaylistID) || (tPEState != PE_ISTREAMCTRL_STATE_RUN);
/*
* If this is UO and the playitem's random access flag is set, then cannot allow access into
* the playitem and must start from the beginning of the playitem.
*/
if ( (fIsUserOp == TRUE) && (pPlayitem->PlayItem_random_access_flag == 1) )
{
DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPbScenarioPlayPLMark: Playitem Random Access flag is set, so playing from beginning of playitem!\n"));
/*
* Start the playlist at the beginning of the playitem
*/
if (PbcPLCtrlStartPL(hPBC, uiPlaylistID, pPLMark->PL_mark[uiTargetPM].ref_to_PlayItem_id,
pPlayitem->IN_time, ubRandomShuffle, fNewPlaylist) != PLAYCTRL_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioPlayPLMark: pbcpbscenarioPlayPL() FAILED!\n"));
return (PLAYCTRL_FAILURE);
}
}
else
{
/*
* Start the playlist at the specified time in the playitem that
* the mark is located in.
*/
if (PbcPLCtrlStartPL(hPBC, uiPlaylistID, pPLMark->PL_mark[uiTargetPM].ref_to_PlayItem_id,
pPLMark->PL_mark[uiTargetPM].mark_time_stamp, ubRandomShuffle, fNewPlaylist) != PLAYCTRL_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioPlayPLMark: pbcpbscenarioPlayPL() FAILED!\n"));
return (PLAYCTRL_FAILURE);
}
}
/* Update Playback Control Engine State */
hPBC->tState = PLAYCTRL_STATE_PLAY;
}
else
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioPlayPLMark: specified entry mark not found!\n"));
return (PLAYCTRL_FAILURE);
}
return (PLAYCTRL_SUCCESS);
}
/**
* PbcPbScenarioLinkMark -- Change playback position to the specified playmark.
*
* @param
* hPBC -- handle to playback control engine private data
* data1 -- playmark number
* data2 -- indicates user op or navigation command
* data3 -- indicates if mark to be linked to is a repeat mark. If this flag
* is set, the first 2 parameters are ignored and the playitem and time
* in the repeat block are used as the link point.
*
* @retval
* PLAYCTRL_STATUS
*/
PLAYCTRL_STATUS PbcPbScenarioLinkMark(PBC_HANDLE *hPBC, ULONG data1, ULONG data2, ULONG data3)
{
uint32 uiPlaymarkID = data1;
BOOLEAN fIsUserOp = (BOOLEAN)(data2);
PLAYLISTMARK_TABLE *pPLMark = NULL;
APPINFOPLAYLIST_TABLE *pAppInfoPL = NULL;
BOOLEAN fMarkFound = FALSE;
uint32 uiCount = 0;
uint32 uiTargetPM = 0;
BOOLEAN fRepeatMark = (BOOLEAN)(data3);
DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPbScenarioLinkMark: playmark %lu\n", uiPlaymarkID));
/* check for valid handle */
if (hPBC == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioLinkMark: NULL handle!\n"));
return (PLAYCTRL_NULL_POINTER);
}
/* Check that playback is active */
if (hPBC->tState == PLAYCTRL_STATE_STOP)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioLinkMark: Playback is stopped!\n"));
return (PLAYCTRL_FAILURE);
}
/*
* If this is a link to a repeat mark, then link to the playitem and time
* defined in the repeat block, and return.
*/
if (fRepeatMark == TRUE)
{
/* check that repeat mode is on */
if (hPBC->RepeatBlock.repeat_mode == VDVD_INFO_REPEAT_OFF)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioLinkMark: Repeat mode is off!\n"));
return (PLAYCTRL_FAILURE);
}
/* if a is only set, force the AB point set and tell the PSL about it */
if (hPBC->RepeatBlock.repeat_mode == VDVD_INFO_REPEAT_A)
{
uint32 uiRepeatWindow;
uint32 uiPlayitemID;
TIME45k time45k_CurrPTS;
PLAYITEM *pPlayitem = NULL;
/* Get current playitem */
PbcRegGetPSR(PLAYCTRL_PSR_PLAYITEM, &uiPlayitemID);
uiPlayitemID &= 0x0000ffff;
/* Get current pts */
PbcRegGetPSR(PLAYCTRL_PSR_PRES_TIME, &time45k_CurrPTS);
/* Calculate the repeat window size */
if (uiPlayitemID == hPBC->RepeatBlock.uiPlayitemID_IN)
{
/*
* Repeat start/end points are in same playitem, so the repeat window
* is just the difference in pts's.
*/
uiRepeatWindow = (time45k_CurrPTS - hPBC->RepeatBlock.time45k_IN) / 45000;
}
else
{
/*
* Repeat start/end points are NOT in same playitem, so more detailed
* calculation needs to be done:
* Window Size = Time from starting pts to end of starting playitem +
* Total time of playitems between start/end playitems +
* Time from start of end playitem to end pts
*/
/* Get the playitem info for repeat starting playitem */
if (MPLSGetPlayItem((uint16)(hPBC->RepeatBlock.uiPlayitemID_IN), &pPlayitem) != MPLS_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioRepeeat: Failed to get playitem info\n"));
return (PLAYCTRL_FAILURE);
}
/* set repeat window to time from repeat start pts to end of the repeat start playitem */
uiRepeatWindow = (pPlayitem->OUT_time - hPBC->RepeatBlock.time45k_IN) / 45000;
/*
* Increment repeat window by playitem time of each playitem between repeat
* starting playitem and repeat ending playitem.
*/
for (uint16 i = (uint16)(hPBC->RepeatBlock.uiPlayitemID_IN + 1); i < uiPlayitemID; i++)
{
/* Get the playitem info */
if (MPLSGetPlayItem(i, &pPlayitem) != MPLS_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioRepeeat: Failed to get playitem info\n"));
return (PLAYCTRL_FAILURE);
}
uiRepeatWindow += (pPlayitem->OUT_time - pPlayitem->IN_time) / 45000;
}
/* Get the playitem info for repeat ending playitem */
if (MPLSGetPlayItem((uint16)(uiPlayitemID), &pPlayitem) != MPLS_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioRepeeat: Failed to get playitem info\n"));
return (PLAYCTRL_FAILURE);
}
/* increment repeat window by time from start of repeat end playitem to repeat end pts */
uiRepeatWindow += (time45k_CurrPTS - pPlayitem->IN_time ) / 45000;
}
/* Set repeat end point */
hPBC->RepeatBlock.uiPlayitemID_OUT = uiPlayitemID;
hPBC->RepeatBlock.time45k_OUT = time45k_CurrPTS;
/* Set repeat mode */
hPBC->RepeatBlock.repeat_mode = VDVD_INFO_REPEAT_AB;
/* send message to the PSL */
ULONG message[4] = {0};
message[0] = VDVD_STATUS_A_B;
UsrEventHandler(message);
}
/* Link to repeat start point */
if (pbcpbscenarioLink(hPBC, hPBC->RepeatBlock.uiPlayitemID_IN, hPBC->RepeatBlock.time45k_IN, 0, TRUE) != PLAYCTRL_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioLinkMark: pbcpbscenarioLink() FAILED!\n"));
return (PLAYCTRL_FAILURE);
}
return (PLAYCTRL_SUCCESS);
}
/* Get playlist info */
if (MPLSGetAppInfo(&pAppInfoPL) != MPLS_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioLinkMark: Failed to get playlist info!\n"));
return (PLAYCTRL_FAILURE);
}
/* Get playlist mark from database */
if (MPLSGetPlayMark(&pPLMark) != MPLS_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioLinkMark: MPLSGetPlayMark() FAILED!\n"));
return (PLAYCTRL_FAILURE);
}
/*
* If this is a user operation and playback type is random/shuffle, then
* the operation is invalid.
*/
if ( (pAppInfoPL->PlayList_playback_type == MPLS_SEQUENTIAL_PLAYLIST) || (fIsUserOp == FALSE) )
{
/*
* Look for appropriate entry mark.
*/
for (uint16 i = 0; i < pPLMark->number_of_PlayList_marks; i++)
{
/*
* If this mark is an entry-mark, then increase count.
*/
if (pPLMark->PL_mark[i].mark_type == ENTRY_MARK)
{
uiCount++;
}
else
{
/* if this is a navigation command and an link point, then increase count */
if ( (fIsUserOp == FALSE) && (pPLMark->PL_mark[i].mark_type == LINK_POINT) )
{
uiCount++;
}
}
/*
* If this mark is the entry mark we are looking for, then
* keep track of the mark ID, and finish search.
*/
if (fIsUserOp == TRUE)
{
if (uiCount == uiPlaymarkID)
{
fMarkFound = TRUE;
uiTargetPM = i;
break;
}
}
else if (i == uiPlaymarkID)
{
fMarkFound = TRUE;
uiTargetPM = i;
break;
}
}
}
else
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioLinkMark: Operation invalid!\n"));
return (PLAYCTRL_FAILURE);
}
/*
* If a specified mark exists, then change playback to the mark.
* Otherwise, fail this operations.
*/
if (fMarkFound == TRUE)
{
PLAYITEM *pPlayitem = NULL;
uint32 uiPlayitemID;
/* Get PSR for current playitem id */
PbcRegGetPSR(PLAYCTRL_PSR_PLAYITEM, &uiPlayitemID);
uiPlayitemID &= 0x0000ffff;
/* Get the playitem info for target playitem */
if (MPLSGetPlayItem(pPLMark->PL_mark[uiTargetPM].ref_to_PlayItem_id, &pPlayitem) != MPLS_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioLinkMark: Failed to get playitem info\n"));
return (PLAYCTRL_FAILURE);
}
/*
* If this is UO and the playitem's random access flag is set, then cannot allow access into
* the playitem and must start from the beginning of the playitem.
*/
if ( (fIsUserOp == TRUE) && (pPlayitem->PlayItem_random_access_flag == 1) )
{
DBGPRINT(DBG_ON(DBG_TRACE), ("PbcPbScenarioLinkMark: Playitem Random Access flag is set, so linking to beginning of playitem!\n"));
/*
* Link to beginning of playitem
*/
if (pbcpbscenarioLink(hPBC, pPLMark->PL_mark[uiTargetPM].ref_to_PlayItem_id, pPlayitem->IN_time, 0) != PLAYCTRL_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioLinkMark: pbcpbscenarioLink() FAILED!\n"));
return (PLAYCTRL_FAILURE);
}
}
else
{
/*
* Link to the specified time in the playitem that
* the mark is located in.
*/
if (pbcpbscenarioLink(hPBC, pPLMark->PL_mark[uiTargetPM].ref_to_PlayItem_id,
pPLMark->PL_mark[uiTargetPM].mark_time_stamp, 0) != PLAYCTRL_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcPbScenarioLinkMark: pbcpbscenarioLink() FAILED!\n"));
return (PLAYCTRL_FAILURE);
}
}
/*
* Do this after doing the link to be sure any previously playing clip is flushed out
* before resetting the mark id. There was a bug when we were setting this value before
* doing the link because we were resetting this mark id, then there was a vsync from the
* currently playing clip so we were detecting a change in playmark from the vsync, so
* incorrectly sent a playmark change event. Setting this valua fter the link will prevent
* this error from happening. There will not be a race condition here because the first
* vsync will not happen until after the beginning of stream for this new clip, and
* the beginning of stream happens in context of the pbc engine task, so we are safe.
*/
/*
* Set playmark id to an invalid value so that we will detect a change in playmark id
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -