📄 pe_istreamctrl.cpp
字号:
}
}
/* TODO-SDK - Close the decoders. */
/* free pe handle allocation */
DBGPRINT(DBG_ON(DBG_TRACE), ("PEDeleteiStreamCtrl: free pe handle allocation\n"));
OS_MemFree(iStrmCtrl);
DBGPRINT(DBG_ON(DBG_TRACE), ("PEDeleteiStreamCtrl: Finished\n"));
return (PE_SUCCESS);
}
/**
* Signals the threads to terminate. Does not return until they have.
*
* @param handle - iStrmCtrl handle.
*
* @return PE_STATUS - Error code.
*/
static PE_STATUS peiStrmKillTasks(ISTREAMCTRLHANDLE *iStrmCtrl)
{
PE_MESSAGE* pMessage = NULL;
/* verify input */
DbgAssert(iStrmCtrl);
/* request thread termination */
iStrmCtrl->fKillTasks = TRUE;
/* release possible wait states */
DBGPRINT(DBG_ON(DBG_TRACE), ("peiStrmKillTasks(): send the message to the updatetime thread\n"));
pMessage = (PE_MESSAGE *)iStrmCtrl->pCallbackMsgQ->GetMsg(OS_WAIT_FOREVER);
iStrmCtrl->pCallbackMsgQ->Write( (PVOID)pMessage );
DBGPRINT(DBG_ON(DBG_TRACE), ("peiStrmKillTasks(): send the message to the command thread\n"));
pMessage = (PE_MESSAGE *)iStrmCtrl->pMsgQ->GetMsg(OS_WAIT_FOREVER);
pMessage->ulMsgID = PE_EXIT;
iStrmCtrl->pMsgQ->Write( (PVOID)pMessage );
/* wait for threads to die */
DBGPRINT(DBG_ON(DBG_TRACE), ("peiStrmKillTasks(): Shutting down PECommand Task\n"));
OS_TaskJoin(iStrmCtrl->cmdTask);
OS_TaskDelete(iStrmCtrl->cmdTask);
OS_TaskJoin(iStrmCtrl->evntTask);
OS_TaskDelete(iStrmCtrl->evntTask);
/* Return status */
DBGPRINT(DBG_ON(DBG_TRACE), ("peiStrmKillTasks(): FINISHED\n"));
return (PE_SUCCESS);
}
/**
* Private function to receive callbacks from the PEConsumers.
*
* @param pContext - context info
* @param event - iStrmCtrl event
* @param pEventInfo - iStrmCtrl pEventInfo
*
* @return PE_STATUS.
*/
static PE_STATUS peiStrmConsumerCallback(PVOID pContext, PE_EVENT_CODE event, PVOID pEventinfo, PE_ISTREAMCTRL_INPUT input)
{
PEHANDLE *pe = (PEHANDLE *)(pContext);
#if DBG_ON(DBG_VERBOSE)
DbgPrint(("peiStrmConsumerCallback(): pContext = %08x, event = %08x, pEventinfo = %08x\n",
(ULONG)pContext, (ULONG)event, (ULONG)pEventinfo));
#endif
/* Intercept NavPacks from the main to be sent to other Consumers */
/* This method is very specialized for out-of-mux substitution streams in HD-DVD, but this may be generalized more for wider use. */
if (event == PE_EVENT_NVPCK)
{
if (input == INPUT_MAIN)
{
if (pe->iStreamCtrl->pPEConsumer[INPUT_SUBSTITUTE_AUDIO] != NULL)
{
BYTE *buf;
if (((PE_NVPCK_EVENT_INFO *)pEventinfo)->pGCIpayload != NULL)
{
buf = (BYTE *)((PE_NVPCK_EVENT_INFO *)pEventinfo)->pGCIpayload;
pe->iStreamCtrl->pPEConsumer[INPUT_SUBSTITUTE_AUDIO]->UpdateMasterNavPackPTS(MAKE_DWORD(&buf[9]));
}
}
}
}
return (peSendEvent(pe, event, pEventinfo));
}
#if BDROM_ENABLE
/**
* Private function to receive callbacks from the Interactive Graphics Decoder.
*
* @param pContext - context info
* @param event - IG event
* @param pEventInfo - Pointer to optional data to send with the event
*
* @return PE_STATUS.
*/
static IG_STATUS peiStrmIGCallback(PVOID pContext, IG_EVENT_CODE IGEventCode, PVOID pEventinfo)
{
PE_STATUS status = PE_FAILURE;
if (pContext == NULL)
{
return (IG_STATUS_ERROR);
}
switch (IGEventCode)
{
case IG_EVENT_ICS_VALID:
if (pEventinfo != NULL)
{
PE_ICS_VALID_EVENT_INFO ics_info;
/* send event to app */
status = peSendEvent(pContext, PE_EVENT_ICS_VALID, &ics_info);
/* return the PSR info to the IG decoder */
((IG_ICSVALID_EVENT_INFO *)pEventinfo)->PSR10 = ics_info.uiButtonPSR;
((IG_ICSVALID_EVENT_INFO *)pEventinfo)->PSR11 = ics_info.uiPagePSR;
}
break;
case IG_EVENT_ICS_INVALID:
status = peSendEvent(pContext, PE_EVENT_ICS_INVALID, NULL);
break;
case IG_EVENT_SELECT_PAGE:
if (pEventinfo != NULL)
{
PE_SELECT_PAGE_EVENT_INFO page_info;
if (((IG_PAGE_SELECT_EVENT_INFO *)pEventinfo)->pPage)
{
/* fill in the event info struct */
page_info.uiPageID = ((IG_PAGE_SELECT_EVENT_INFO *)pEventinfo)->pPage->PageID;
page_info.pUO_mask_table = (BYTE *)&(((IG_PAGE_SELECT_EVENT_INFO *)pEventinfo)->pPage->UO_mask_table);
}
else
{
page_info.uiPageID = 0;
page_info.pUO_mask_table = NULL;
}
/* send event to app */
status = peSendEvent(pContext, PE_EVENT_SELECT_PAGE, &page_info);
((IG_PAGE_SELECT_EVENT_INFO *)pEventinfo)->PSR10 = page_info.uiButtonPSR;
}
break;
case IG_EVENT_SELECT_BUTTON:
if (pEventinfo != NULL)
{
PE_SELECT_BUTTON_EVENT_INFO btn_info;
/* fill in the event info struct */
btn_info.uiButtonID = ((IG_BUTTON_SELECT_EVENT_INFO *)pEventinfo)->ButtonID;
btn_info.ucSelectedStateSoundID = ((IG_BUTTON_SELECT_EVENT_INFO *)pEventinfo)->SelectedStateSoundIDRef;
/* send event to app */
status = peSendEvent(pContext, PE_EVENT_SELECT_BUTTON, &btn_info);
}
else
{
/* IG sends a NULL button to indicate it wants to reset the button PSR to the default */
PE_SELECT_BUTTON_EVENT_INFO btn_info;
/* fill in the event info struct */
btn_info.uiButtonID = 0xffff;
btn_info.ucSelectedStateSoundID = 0xff;
/* send event to app */
status = peSendEvent(pContext, PE_EVENT_SELECT_BUTTON, &btn_info);
}
break;
case IG_EVENT_ACTIVATE_BUTTON:
if (pEventinfo != NULL)
{
IG_BUTTON_ACTIVATE_EVENT_INFO *pIGEventInfo = (IG_BUTTON_ACTIVATE_EVENT_INFO *)pEventinfo;
PE_ACTIVATE_BUTTON_EVENT_INFO btn_info;
/* fill in the event info struct */
btn_info.pNavCmds = (BYTE *)&(pIGEventInfo->pButton->NavCommands[0]);
btn_info.usNumNavCmds = pIGEventInfo->pButton->NumNavCommands;
btn_info.ucActivatedStateSoundID = pIGEventInfo->pButton->ActivatedStateSoundIDRef;
btn_info.pContext = pIGEventInfo->pContext;
/* send event to app */
status = peSendEvent(pContext, PE_EVENT_ACTIVATE_BUTTON, &btn_info);
}
break;
case IG_EVENT_PROCESS_BOBJ:
if (pEventinfo != NULL)
{
IG_BUTTON_ACTIVATE_EVENT_INFO *pIGEventInfo = (IG_BUTTON_ACTIVATE_EVENT_INFO *)pEventinfo;
PE_ACTIVATE_BUTTON_EVENT_INFO btn_info;
/* fill in the event info struct */
btn_info.pNavCmds = (BYTE *)&(pIGEventInfo->pButton->NavCommands[0]);
btn_info.usNumNavCmds = pIGEventInfo->pButton->NumNavCommands;
btn_info.ucActivatedStateSoundID = pIGEventInfo->pButton->ActivatedStateSoundIDRef;
btn_info.pContext = pIGEventInfo->pContext;
/* send event to app */
status = peSendEvent(pContext, PE_EVENT_PROCESS_BOBJ, &btn_info);
}
break;
default:
status = PE_FAILURE;
break;
}
if (status == PE_SUCCESS)
{
return (IG_STATUS_SUCCESS);
}
else
{
return (IG_STATUS_ERROR);
}
}
#endif
/**
* Private function to execute the PE_CONFIG command.
*
* @param iStrmCtrl - istrmctrl handle
* @param StreamType - identifies iStreamCtrls mode of operation
* @param pEventContext - context info to attach to the consumer events
* @param decodeMutex - decode mutex semaphore
*
* @return PE_STATUS.
*/
static PE_STATUS peiStrmConfig(ISTREAMCTRLHANDLE *iStrmCtrl, const PE_ISTREAMCTRL_STREAM_TYPE StreamType )
{
VDVD_ERROR error = VDVD_SUCCESS;
PE_STATUS status = PE_SUCCESS;
PEHANDLE* pe = NULL;
ICONFIGUREHANDLE* iConfigure = NULL;
int i = 0;
DbgAssert(iStrmCtrl != NULL);
DbgAssert(iStrmCtrl->pPEConsumer != NULL);
DbgAssert((iStrmCtrl->PEManager) != NULL);
pe = (PEHANDLE*)iStrmCtrl->PEManager;
iConfigure = pe->iConfigure;
DbgAssert(iConfigure != NULL);
/* Configure is only valid from UNREALIZED */
if (iStrmCtrl->SystemState != PE_ISTREAMCTRL_STATE_UNREALIZED)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("peiStrmConfig -- PE_INVALID_STATE\n"));
status = PE_INVALID_STATE;
}
else
{
status = PE_SUCCESS;
}
if (status == PE_SUCCESS)
{
PE_CONSUMER_CONFIG_INFO config_info;
#if BDROM_ENABLE
if (StreamType == STREAM_TYPE_MPEG2_BDTS)
{
/* create a PEConsumer for each of the possible inputs for BDROM */
for (i=0; i<MAX_PE_INPUTS; i++)
{
/* create a consumer for each input */
iStrmCtrl->pPEConsumer[i] = new cPEConsumer_BDROM;
if (iStrmCtrl->pPEConsumer[i] == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("peiStrmConfig -- PE_MEM_ALLOCATION\n"));
status = PE_MEM_ALLOCATION;
break;
}
/* configure the new consumer */
config_info.input = (PE_ISTREAMCTRL_INPUT)i;
config_info.fPlaybackStarted = FALSE;
if (iStrmCtrl->pPEConsumer[i]->Configure(&config_info) != PE_SUCCESS)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("peiStrmConfig -- Consumer Configure Failed!\n"));
status = PE_FAILURE;
break;
}
/* Attach callback to receive events from this PEConsumer */
iStrmCtrl->pPEConsumer[i]->AttachEvent(peiStrmConsumerCallback, iStrmCtrl->PEManager);
}
/* attach the Decode Done, PTS and Presentation Start callbacks */
iConfigure->primaryDecoder->RequestNotification( DECODE_EVENT_DECODE_DONE, DECODE_NOTIFY_ALWAYS);
iConfigure->primaryDecoder->RequestNotification( DECODE_EVENT_TIMESTAMPS, DECODE_NOTIFY_ALWAYS);
iConfigure->primaryDecoder->RequestNotification( DECODE_EVENT_PRESENTATION_START, DECODE_NOTIFY_ALWAYS);
}
else
#endif
if ( (StreamType == STREAM_TYPE_MPEG2_VOB) || (StreamType == STREAM_TYPE_MPEG2_VRO) )
{
/* here we only need the MAIN PEConsumer */
if (StreamType == STREAM_TYPE_MPEG2_VOB)
{
iStrmCtrl->pPEConsumer[INPUT_MAIN] = new cPEConsumer_DVD;
}
else if (StreamType == STREAM_TYPE_MPEG2_VRO)
{
iStrmCtrl->pPEConsumer[INPUT_MAIN] = NULL;
}
if (iStrmCtrl->pPEConsumer[INPUT_MAIN] == NULL)
{
status = PE_MEM_ALLOCATION;
}
else
{
/* Attach the decode playback */
config_info.input = INPUT_MAIN;
config_info.fPlaybackStarted = FALSE;
iStrmCtrl->pPEConsumer[INPUT_MAIN]->Configure(&config_info);
/* Attach callback to receive events from this PEConsumer */
iStrmCtrl->pPEConsumer[INPUT_MAIN]->AttachEvent(peiStrmConsumerCallback, iStrmCtrl->PEManager);
}
iConfigure->primaryDecoder->RequestNotification( DECODE_EVENT_PRESENTATION_START, DECODE_NOTIFY_ALWAYS);
}
#ifdef HDDVD_ENABLE
else if (StreamType == STREAM_TYPE_MPEG2_EVOB_STD)
{
/** Configuration for HD DVD (Standard Content) **/
/* Create a consumer for HD DVD (Standard Content) */
iStrmCtrl->pPEConsumer[INPUT_MAIN] = new cPEConsumer_HDDVD_STD;
/* Proceed only of the consumer was created successfully */
if (iStrmCtrl->pPEConsumer[INPUT_MAIN] == NULL)
{
DBGPRINT(DBG_ON(DBG_ERROR), ("peiStrmConfig(STREAM_TYPE_MPEG2_EVOB_STD) - Could not create consumer!\n"));
status = PE_MEM_ALLOCATION;
}
else
{
/* Attach the decode playback for the main input */
config_info.input = INPUT_MAIN;
config_info.fPlaybackStarted = FALSE;
iStrmCtrl->pPEConsumer[INPUT_MAIN]->Configure(&config_info);
/* Attach callback to receive events from this PEConsumer */
iStrmCtrl->pPEConsumer[INPUT_MAIN]->AttachEvent(peiStrmConsumerCallback, iStrmCtrl->PEManager);
}
/* Attach presentation start callback */
iConfigure->primaryDecoder->RequestNotification( DECODE_EVENT_PRESENTATION_START, DECODE_NOTIFY_ALWAYS);
}
else if (StreamType == STREAM_TYPE_MPEG2_EVOB_ADV)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -