⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pe_istreamctrl.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        }
    }

    /* 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 + -