📄 pbc_avpres.cpp
字号:
/*
* 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 + -