📄 pbc_engine.cpp
字号:
/* Send message to be processed by the pbc engine task */
if (OS_MsgQSend(hPbcEngine->MsgQID, (char *)&msg, sizeof(PBCENGINE_MESSAGE), OS_NO_WAIT, OS_MSG_PRI_NORMAL) != OS_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineSendMessage: Failure sending message!\n"));
return(PLAYCTRL_FAILURE);
}
return(PLAYCTRL_SUCCESS);
}
/**
* PbcEngineNavTimerCallback -- Nav timer callback handler.
*
* @param
* pvParam -- context pointer that is registered with timer
*
* @retval
* none
*/
static void PbcEngineNavTimerCallback(PVOID pvParam)
{
PBC_HANDLE *hPBC = (PBC_HANDLE *)pvParam;
/* Check for valid handles */
if ( (hPbcEngine == NULL) || (hPBC == NULL) )
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineNavTimerCallback: NULL handle!\n"));
}
else
{
uint32 uiNvTimerValue;
/* Get NV Timer register value */
PbcRegGetPSR(PLAYCTRL_PSR_NVTIMER, &uiNvTimerValue);
/* Pull out time from register value */
uiNvTimerValue &= 0x0000ffff;
/*
* If nv timer or still timer is ticking, send msg to pbc engine task to
* process a timer update.
*/
if ( (uiNvTimerValue != 0) || ( (hPBC->ulStillTime != 0) && (hPBC->ulStillTime != 0xffffffff) ) )
{
PBCENGINE_MESSAGE msg;
/* Load message parameters */
msg.tMsgType = PBCENGINE_MSGTYPE_NVTIMER_UPDATE;
msg.hPbc = hPBC;
msg.ulSemID = 0;
msg.pulRetVal = NULL;
/* Send message to be processed by the pbc engine task */
if (OS_MsgQSend(hPbcEngine->MsgQID, (char *)&msg, sizeof(PBCENGINE_MESSAGE), OS_NO_WAIT, OS_MSG_PRI_NORMAL) != OS_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineNavTimerCallback: Failure sending message!\n"));
}
}
}
}
/**
* PbcEngineTimerUpdate -- Handle updating timer values.
*
* @param
* hPBC -- pbc private data handle
*
* @retval
* PLAYCTRL_STATUS
*/
static PLAYCTRL_STATUS PbcEngineTimerUpdate(PBC_HANDLE *hPBC)
{
PLAYCTRL_STATUS tStatus = PLAYCTRL_SUCCESS;
uint32 uiNvTimerValue;
/* Take register mutex semaphore */
OS_SemTake(hPBC->semRegisterMutex, OS_WAIT_FOREVER);
/* Get NV Timer register value */
PbcRegGetPSR(PLAYCTRL_PSR_NVTIMER, &uiNvTimerValue);
/* Pull out time from register value */
uiNvTimerValue &= 0x0000ffff;
/* If nv timer is ticking, update the time value */
if (uiNvTimerValue != 0)
{
/* Decrement nv timer */
uiNvTimerValue--;
/* Set NV Timer register value */
PbcRegSetPSR(PLAYCTRL_PSR_NVTIMER, uiNvTimerValue);
/*
* If nv timer has expired, then inform application environment that
* the nv timer has expired.
*/
if (uiNvTimerValue == 0)
{
/* Send nvtimer expire event to registered callback */
if (hPBC->pCallback != NULL)
{
hPBC->pCallback(hPBC->pvCallbackContext, PLAYCTRL_EVENT_NVTIMER_EXPIRE, NULL);
}
}
}
/* Give register mutex semaphore */
OS_SemGive(hPBC->semRegisterMutex);
/* If still timer is ticking, update the time value */
if ( (hPBC->ulStillTime != 0) && (hPBC->ulStillTime != 0xffffffff) )
{
/* Decrement still timer */
hPBC->ulStillTime--;
/* If still timer has expired, then release the still */
if (hPBC->ulStillTime == 0)
{
/* Check if playlist is complete after this still */
if (hPBC->fPLCompletePending == TRUE)
{
/* playlist complete */
PbcPLCtrlPlaylistComplete(hPBC, FALSE);
}
else
{
PEiStreamCtrlStillOff(hPBC->hPE);
}
}
}
return (tStatus);
}
/**
* PbcEnginePlayButtonSound -- Play Blu-ray button sounds.
*
* @param hPBC - pbc private data handle
* @param sound_id - which button sound to play
*
* @retval
* PLAYCTRL_STATUS
*/
static PLAYCTRL_STATUS PbcEnginePlayButtonSound(PBC_HANDLE *hPBC, uint32 sound_id)
{
SOUND_ATTRIBUTES sound_attributes;
DBGPRINT(DBG_ON(DBG_TRACE), (">>> Button Select sound_id=%ld <<<\n", sound_id));
/* get the sound attributes */
if (SOUNDDBGetSoundInfo( (BYTE)(sound_id), &sound_attributes) == SOUNDDB_SUCCESS)
{
BYTE *pcm;
ULONG length;
/* get the sound samples */
if (SOUNDDBGetSoundData( (BYTE)(sound_id), &pcm, &length) == SOUNDDB_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_TRACE), (">>> Play Button Selection Sound %d %d <<<\n",
sound_attributes.channel_configuration, length));
/* As indicated in paragraph five section 8.8.4.6.5.3.5, previous sound shall be pre-empted
* by subsequent selection sounds. */
if (0 != hPBC->iaudio_id)
{
if (PLAYCTRL_SUCCESS != PlayCtrlAMStopSound(hPBC->iaudio_id))
{
DBGPRINT(DBG_ON(DBG_TRACE), ("PlayCtrlAMStopSound: ERROR\n"));
}
}
/* play sound sample with correct channel config
* NOTE: 1 = MONO, 3 = STEREO */
if (sound_attributes.channel_configuration == 1)
{
if (PLAYCTRL_SUCCESS != PlayCtrlAMOpenSound(PLAYCTRL_AUDIO_STREAM_INTERACTIVE,
FALSE, pcm, length/2, &(hPBC->iaudio_id)))
{
DBGPRINT(DBG_ON(DBG_TRACE), ("PlayCtrlAMOpenSound: ERROR\n"));
}
if (PLAYCTRL_SUCCESS != PlayCtrlAMPlaySound(hPBC->iaudio_id))
{
DBGPRINT(DBG_ON(DBG_TRACE), ("PlayCtrlAMPlaySound: ERROR\n"));
}
}
else
{
if (PLAYCTRL_SUCCESS != PlayCtrlAMOpenSound(PLAYCTRL_AUDIO_STREAM_INTERACTIVE,
TRUE, pcm, length/2, &(hPBC->iaudio_id)))
{
DBGPRINT(DBG_ON(DBG_TRACE), ("PlayCtrlAMOpenSound: ERROR\n"));
}
if (PLAYCTRL_SUCCESS != PlayCtrlAMPlaySound(hPBC->iaudio_id))
{
DBGPRINT(DBG_ON(DBG_TRACE), ("PlayCtrlAMPlaySound: ERROR\n"));
}
}
}
}
return (PLAYCTRL_SUCCESS);
}
/**
* PbcEngineTask -- Task that executes all pbc engine core processing.
*/
static ULONG PbcEngineTask(PVOID pvParam)
{
PBCENGINE_MESSAGE Msg;
BOOLEAN fTaskExit = FALSE;
PLAYCTRL_STATUS status;
while (fTaskExit == FALSE)
{
/* Wait for a message */
if (OS_MsgQReceive(hPbcEngine->MsgQID, (char *)&Msg, sizeof(PBCENGINE_MESSAGE), OS_WAIT_FOREVER) != OS_OK)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineTask: Failure receiving message!\n"));
fTaskExit = TRUE;
}
else
{
status = PLAYCTRL_SUCCESS;
/* Look at the message type to determine what to do */
switch (Msg.tMsgType)
{
case PBCENGINE_MSGTYPE_EXIT:
DBGPRINT(DBG_ON(DBG_TRACE), ("PbcEngineTask: PBCENGINE_MSGTYPE_EXIT!\n"));
fTaskExit = TRUE;
break;
case PBCENGINE_MSGTYPE_PBC_CMD:
DBGPRINT(DBG_ON(DBG_TRACE), ("PbcEngineTask: PBCENGINE_MSGTYPE_PBC_CMD\n"));
/*
* If command type is valid, and the associated function pointer
* is valid, then call the playback control function.
*/
if (Msg.ulData0 < PLAYCTRL_INVALID_COMMAND)
{
if (hPbcEngine->PbcFunc[Msg.ulData0] != NULL)
{
/* fire function pointer for associated playback control function */
if (hPbcEngine->PbcFunc[Msg.ulData0](Msg.hPbc, Msg.ulData1, Msg.ulData2, Msg.ulData3) != PLAYCTRL_SUCCESS)
{
status = PLAYCTRL_FAILURE;
}
}
else
{
status = PLAYCTRL_FAILURE;
}
}
else
{
status = PLAYCTRL_FAILURE;
}
break;
case PBCENGINE_MSGTYPE_BEG_STREAM:
DBGPRINT(DBG_ON(DBG_TRACE), ("PbcEngineTask: PBCENGINE_MSGTYPE_BEG_STREAM\n"));
/* Handle beginning of stream */
status = PbcPLCtrlBegStream(Msg.hPbc, (PBC_PLAYITEM_CONTEXT *)Msg.ulData0, (PE_ISTREAMCTRL_INPUT)Msg.ulData1, (BOOLEAN)Msg.ulData2);
if (status == PLAYCTRL_RETRY)
{
OS_TaskDelay(OS_WAIT_1S / 50);
if (PLAYCTRL_FAILURE == pbcEngineSendMessage(PBCENGINE_MSGTYPE_BEG_STREAM, Msg.hPbc, Msg.ulData0, Msg.ulData1, (ULONG)TRUE, 0, 0, NULL))
{
/* @todo: handle this very bad case (though it *should* never happen) */
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineTask: PBCENGINE_MSGTYPE_BEG_STREAM: pbcEngineSendMessage FAILED. FIX ME!!\n"));
}
status = PLAYCTRL_SUCCESS;
}
else if (status != PLAYCTRL_SUCCESS)
{
status = PLAYCTRL_FAILURE;
}
break;
case PBCENGINE_MSGTYPE_END_STREAM:
DBGPRINT(DBG_ON(DBG_TRACE), ("PbcEngineTask: PBCENGINE_MSGTYPE_END_STREAM\n"));
/* Handle end of stream */
status = PbcPLCtrlEndStream(Msg.hPbc, (PBC_PLAYITEM_CONTEXT *)Msg.ulData0, (PE_ISTREAMCTRL_INPUT)Msg.ulData1, (BOOLEAN)Msg.ulData2);
if (status == PLAYCTRL_RETRY)
{
OS_TaskDelay(OS_WAIT_1S / 50);
if (PLAYCTRL_FAILURE == pbcEngineSendMessage(PBCENGINE_MSGTYPE_END_STREAM, Msg.hPbc, Msg.ulData0, Msg.ulData1, (ULONG)TRUE, 0, 0, NULL))
{
/* @todo: handle this very bad case (though it *should* never happen) */
DBGPRINT(DBG_ON(DBG_ERROR), ("PbcEngineTask: PBCENGINE_MSGTYPE_END_STREAM: pbcEngineSendMessage FAILED. FIX ME!!\n"));
}
status = PLAYCTRL_SUCCESS;
}
else if (status != PLAYCTRL_SUCCESS)
{
status = PLAYCTRL_FAILURE;
}
break;
case PBCENGINE_MSGTYPE_DEC_DONE:
DBGPRINT(DBG_ON(DBG_TRACE), ("PbcEngineTask: PBCENGINE_MSGTYPE_DEC_DONE\n"));
if ( GET_BIT(Msg.hPbc->newpi.doneState, PBC_DECDONE_STATE_WAITING_BOS) )
{
CLR_BIT(Msg.hPbc->newpi.doneState, PBC_DECDONE_STATE_WAITING_BOS);
}
else if ( GET_BIT(Msg.hPbc->newpi.doneState, PBC_DECDONE_STATE_WAITING_EOS) )
{
CLR_BIT(Msg.hPbc->newpi.doneState, PBC_DECDONE_STATE_WAITING_EOS);
}
else if (Msg.hPbc->newpi.doneState == PBC_DECDONE_STATE_INACTIVE)
{
Msg.hPbc->newpi.doneState = PBC_DECDONE_STATE_ACTIVE;
}
break;
case PBCENGINE_MSGTYPE_ABORT_COMPLETE:
DBGPRINT(DBG_ON(DBG_ALL), ("\nPbcEngineTask: PBCENGINE_MSGTYPE_ABORT_COMPLETE\n\n"));
(Msg.hPbc)->newpi.abort = FALSE;
(Msg.hPbc)->newpi.doneState = PBC_DECDONE_STATE_INACTIVE;
status = PLAYCTRL_SUCCESS;
break;
case PBCENGINE_MSGTYPE_NVTIMER_UPDATE:
DBGPRINT(DBG_ON(DBG_TRACE), ("PbcEngineTask: PBCENGINE_MSGTYPE_NAVTIMER_UPDATE\n"));
/* Update timers */
if (PbcEngineTimerUpdate(Msg.hPbc) != PLAYCTRL_SUCCESS)
{
status = PLAYCTRL_FAILURE;
}
break;
case PBCENGINE_MSGTYPE_PREFILL_COMPLETE:
DBGPRINT(DBG_ON(DBG_TRACE), ("PbcEngineTask: PBCENGINE_MSGTYPE_PREFILL_COMPLETE\n"));
/* Handle prefill complete */
if (PbcPLCtrlPrefillComplete(Msg.hPbc, (PE_ISTREAMCTRL_INPUT)Msg.ulData0) != PLAYCTRL_SUCCESS)
{
status = PLAYCTRL_FAILURE;
}
break;
case PBCENGINE_MSGTYPE_PLAY_BTN_SOUND:
DBGPRINT(DBG_ON(DBG_TRACE), ("PbcEngineTask: PBCENGINE_MSGTYPE_PLAY_BTN_SOUND\n"));
/* process the button sound */
if (PbcEnginePlayButtonSound(Msg.hPbc, Msg.ulData0) != PLAYCTRL_SUCCESS)
{
status = PLAYCTRL_FAILURE;
}
break;
case PBCENGINE_MSGTYPE_INVALID:
default:
status = PLAYCTRL_FAILURE;
break;
}
/* If requested return the status */
if (Msg.pulRetVal != NULL)
{
*Msg.pulRetVal = status;
}
/* If semaphore was attached to message, give semaphore */
if (Msg.ulSemID != 0)
{
OS_SemGive( (OS_SEM_ID)Msg.ulSemID );
}
}
}
/* exit task */
OS_TaskExit();
return (0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -