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

📄 pe_istreamctrl.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*****************************************************************************
******************************************************************************
**                                                                          **
**  Copyright (c) 2006 Videon Central, Inc.                                 **
**  All rights reserved.                                                    **
**                                                                          **
**  The computer program contained herein contains proprietary information  **
**  which is the property of Videon Central, Inc.  The program may be used  **
**  and/or copied only with the written permission of Videon Central, Inc.  **
**  or in accordance with the terms and conditions stipulated in the        **
**  agreement/contract under which the programs have been supplied.         **
**                                                                          **
******************************************************************************
*****************************************************************************/
/**
 * @file pe_istreamctrl.cpp
 *
 * $Revision: 1.29 $ 
 *
 * Presentation Engine Stream Control Interface source file.
 *
 */

#include <stdlib.h>
#include "decoder.h"
#include "vdvd_types.h"
#include "osapi.h"
#include "msg_app.h"
#include "dbgprint.h"
#include "utility.h"
#include "pe_app.h"
#include "pe_consumer.h"
#include "pe_consumer_dvd.h"
#include "pe_consumer_vcd.h"
#if BDROM_ENABLE
#include "pe_consumer_bdrom.h"
#endif
#include "pe_consumer_cdda.h"

#ifdef HDDVD_ENABLE
#include "pe_consumer_hddvd_std.h"
#include "pe_consumer_hddvd_adv.h"
#endif
#include "pe_types.h"
#include "usrapi.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif

/* THE TODO LIST
 *
 * @todo - set audio type is not implemented.
 * @todo - get state should return info about the PEConsumers
 */

#define DEBUG_ISTRMCTRL DBG_ERROR
#define DBG_ON(x)       (DEBUG_ISTRMCTRL >= x)

#define PE_STACK_SIZE    (16*1024)
#define PE_TASK_PRIORITY 130

#define PE_VSYNC_CALLBACK_DEPTH     4
#define PE_CALLBACK_DEPTH           7       /* 3 for pres start / decode end, and 4 for timestamp */

extern IDirectFB            *pDfb;
BOOLEAN                     fMainStarted;
/*
 * Private Function Prototypes
 ****************************************************************************/
static ULONG peiStrmEngine(PVOID pvParam);
static PE_STATUS peiStrmKillTasks(ISTREAMCTRLHANDLE *iStrmCtrl);
static PE_STATUS peiStrmConfigGraphics(DfbExtHandle *layer, int screen_width, int screen_height, IDirectFBDisplayLayer **disp_layer);
static PE_STATUS peiStrmResetGraphics(IDirectFBDisplayLayer **disp_layer);
static void peDecodeNotify_cb(Decoder* decoder, DECODE_EVENT_TYPE event, void *event_data, void *context);
static ULONG peiStrmDecoderEventTask(PVOID pvParam);
static PE_STATUS peiStrmSetGraphicsAspectRatio(DfbExtHandle *layer_handle, PE_ICONFIGURE_VIDEO_FORMAT VideoFormat,
    PE_ICONFIGURE_ASPECT_RATIO ScreenAspect, PE_ISTREAMCTRL_SOURCE_ASPECT_RATIO SourceAspect);

/**
 * Create the iStrmCtrl interface.
 *
 * @param PEManager - Handle to PE manager. This can be used to obtain access to the other PE interfaces.
 *
 * @return iStrmCtrl handle.
 */
ISTREAMCTRLHANDLE* PECreateiStreamCtrl(PE_HANDLE PEManager)
{
    VDVD_ERROR          error       = VDVD_SUCCESS;
    ISTREAMCTRLHANDLE*  iStrmCtrl   = NULL;
    ICONFIGUREHANDLE*   iConfigure  = NULL;
    PEHANDLE*           pe          = NULL;
    int                i;

    DbgAssert(PEManager != NULL);

    pe         = (PEHANDLE*)PEManager;
    iConfigure = pe->iConfigure;

    DbgAssert(iConfigure != NULL);

    /* allocate the iStrmCtrl handle */
    iStrmCtrl = (ISTREAMCTRLHANDLE*)OS_MemAlloc(sizeof(ISTREAMCTRLHANDLE));
    if (iStrmCtrl == NULL)
    {
        goto error_out;
    }

    /* initial conditions */
    iStrmCtrl->SystemState            = PE_ISTREAMCTRL_STATE_UNREALIZED;
    iStrmCtrl->StreamType             = STREAM_TYPE_INVALID;
    iStrmCtrl->AudioType              = AUDIO_TYPE_INVALID;
    iStrmCtrl->VideoType              = VIDEO_TYPE_INVALID;
    iStrmCtrl->fKillTasks             = FALSE;
    iStrmCtrl->pMsgQ                  = NULL;
    iStrmCtrl->pMsgQPool              = NULL;
    iStrmCtrl->pCallbackMsgQ          = NULL;
    iStrmCtrl->pCallbackMsgQPool      = NULL;
    iStrmCtrl->m_decoders.spu         = NULL;
    iStrmCtrl->semCountingVsync       = 0;
#if BDROM_ENABLE
    iStrmCtrl->m_decoders.pg_dec      = NULL;
    iStrmCtrl->m_decoders.ig_dec      = NULL;
    iStrmCtrl->m_decoders.st_dec      = NULL;
#endif
    iStrmCtrl->ig_dfb_disp_layer      = NULL;
    iStrmCtrl->pg_dfb_disp_layer      = NULL;
    iStrmCtrl->GraphicsMode           = GRAPHICS_MODE_NOT_SET;
    iStrmCtrl->sendMsgSem             = 0;
    iStrmCtrl->VideoWidth             = 0;
    iStrmCtrl->VideoHeight            = 0;
    iStrmCtrl->evntTask               = 0;
    iStrmCtrl->cmdTask                = 0;

    for (i=0; i<PE_NUM_SEMS; i++)
    {
        iStrmCtrl->msgQSem[i] = 0;
    }
    for (i=0; i<MAX_PE_INPUTS; i++)
    {
        iStrmCtrl->pPEConsumer[i]           = NULL;
    }

    /* open the decoders and decode windows
     * NOTE: the display is already opened in main because this is required earlier in the startup
     * process to enable directFB */

    error = GetDecoder(DECODER_ID_PRIMARY, &iConfigure->primaryDecoder );
    if ( VDVD_IS_ERROR(error))
    {
        goto error_out;
    }

    error = iConfigure->primaryDecoder->SetNotifyCallback(peDecodeNotify_cb,iStrmCtrl);
    if ( VDVD_IS_ERROR(error))
    {
        goto error_out;
    }


    /* PRIMARY DISPLAY:  set zorder 0 */

#ifdef SECONDARY_DISPLAY_SUPPORT
    /* SECONDARY DISPLAY:  set zorder 0, DEINTERLACE disabled */
#endif

    /* store PEManager handle */
    iStrmCtrl->PEManager = PEManager;

    /* Create the PE semaphores */
    for (i=0; i<PE_NUM_SEMS; i++)
    {
        /* create a semaphore for each command */
        iStrmCtrl->msgQSem[i] = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_EMPTY);

        /* verify */
        if (iStrmCtrl->msgQSem[i] == 0)
        {
            goto error_out;
        }
    }

    /* create mutex sem for event clients */
    iStrmCtrl->sendMsgSem = OS_SemBCreate(OS_SEM_Q_FIFO, OS_SEM_FULL);
    if (iStrmCtrl->sendMsgSem == 0)
    {
        goto error_out;
    }

    /* create counting semaphore for outstanding vsync messages in callback msgQ */
    iStrmCtrl->semCountingVsync = OS_SemCCreate(OS_SEM_Q_FIFO, PE_VSYNC_CALLBACK_DEPTH);
    if (iStrmCtrl->semCountingVsync == 0)
    {
        goto error_out;
    }

    /* Allocate and initialize the PE message queue. */
    iStrmCtrl->pMsgQ = new MESSAGEQUEUE;
    iStrmCtrl->pMsgQPool = OS_MemAlloc(sizeof(PE_MESSAGE) * PE_QUEUE_DEPTH);
    if ((iStrmCtrl->pMsgQ == NULL) || (iStrmCtrl->pMsgQPool == NULL))
    {
        goto error_out;
    }
    iStrmCtrl->pMsgQ->Initialize(iStrmCtrl->pMsgQPool, PE_QUEUE_DEPTH, sizeof(PE_MESSAGE), "PE_CMD");

    /* Allocate and initialize the Callback MsgQ */
    iStrmCtrl->pCallbackMsgQ = new MESSAGEQUEUE;
    iStrmCtrl->pCallbackMsgQPool = OS_MemAlloc(sizeof(PE_MESSAGE) * PE_CALLBACK_DEPTH);
    if ((iStrmCtrl->pCallbackMsgQ == NULL) || (iStrmCtrl->pCallbackMsgQPool == NULL))
    {
        goto error_out;
    }
    iStrmCtrl->pCallbackMsgQ->Initialize(iStrmCtrl->pCallbackMsgQPool, PE_CALLBACK_DEPTH,
        sizeof(PE_MESSAGE), "PE_CALLBACK");

    /* create the decoder callback task, this will post a message to a task to send
       times along to IG/PG/TextST and handle decode done messages */
    iStrmCtrl->evntTask = OS_TaskSpawnParam("PEDecEvnt", PE_TASK_PRIORITY,
        PE_STACK_SIZE, peiStrmDecoderEventTask, (PVOID)iStrmCtrl, NULL);
    if (iStrmCtrl->evntTask == 0)
    {
        DbgPrint(("Error Spawning PE Event Task\n"));
        goto error_out;
    }

    /* Last step is to create the iStrmCtrl task
     * don't want to create this before the message queue it needs to read from */
    iStrmCtrl->cmdTask = OS_TaskSpawnParam("PECmds", PE_TASK_PRIORITY, PE_STACK_SIZE, peiStrmEngine,
        (PVOID)iStrmCtrl, NULL);
    if (iStrmCtrl->cmdTask == 0)
    {
        DbgPrint(("Error Spawning PE Command Task\n"));
        goto error_out;
    }

    return (iStrmCtrl);

error_out:

    /* error - clean up and return NULL */
    if (iStrmCtrl->evntTask != 0)
    {
        peiStrmKillTasks(iStrmCtrl);
    }

    if (iStrmCtrl->pCallbackMsgQ != 0)
    {
        iStrmCtrl->pCallbackMsgQ->Destroy();
        delete (iStrmCtrl->pCallbackMsgQ);
    }

    if (iStrmCtrl->pCallbackMsgQPool != NULL)
    {
        OS_MemFree(iStrmCtrl->pCallbackMsgQPool);
    }

    /* release message queue */
    if (iStrmCtrl->pMsgQ != 0)
    {
        iStrmCtrl->pMsgQ->Destroy();
        delete (iStrmCtrl->pMsgQ);
    }
    if (iStrmCtrl->pMsgQPool != NULL)
    {
        OS_MemFree(iStrmCtrl->pMsgQPool);
    }

    if (iStrmCtrl->semCountingVsync != 0)
    {
        OS_SemDelete(iStrmCtrl->semCountingVsync);
        iStrmCtrl->semCountingVsync = 0;
    }

    if (iStrmCtrl->sendMsgSem != 0)
    {
        OS_SemDelete(iStrmCtrl->sendMsgSem);
        iStrmCtrl->sendMsgSem = 0;
    }

     /* TODO-SDK - Close the decoders. */

    /* release istreamctrl handle */
    if (iStrmCtrl != NULL)
    {
        OS_MemFree(iStrmCtrl);
    }

    return (NULL);
}

/**
 * Delete the iStrmCtrl interface.
 *
 * @param handle -  iStrmCtrl handle.
 *
 * @return PE_STATUS - Error code.
 */
PE_STATUS PEDeleteiStreamCtrl(ISTREAMCTRLHANDLE* iStrmCtrl)
{
    int i;

    /* verify input */
    if (NULL == iStrmCtrl)
    {
        return (PE_INVALID_HANDLE);
    }

    /* verify state
     * this insures that there all PEConsumer objects have been deleted */
    if (iStrmCtrl->SystemState != PE_ISTREAMCTRL_STATE_UNREALIZED)
    {
        return (PE_INVALID_STATE);
    }

    /* kill the pe iStrmCtrl tasks */
    DBGPRINT(DBG_ON(DBG_TRACE), ("PEDeleteiStreamCtrl: kill the pe iStrmCtrl tasks\n"));
    peiStrmKillTasks(iStrmCtrl);

    /* release message queues */
    DBGPRINT(DBG_ON(DBG_TRACE), ("PEDeleteiStreamCtrl: release message queues\n"));

    /* the updatetime queue and pool */
    if (iStrmCtrl->pCallbackMsgQ != 0)
    {
        iStrmCtrl->pCallbackMsgQ->Destroy();
        delete (iStrmCtrl->pCallbackMsgQ);
        iStrmCtrl->pCallbackMsgQ = NULL;
    }
    if (iStrmCtrl->pCallbackMsgQPool != NULL)
    {
        OS_MemFree(iStrmCtrl->pCallbackMsgQPool);
        iStrmCtrl->pCallbackMsgQPool = NULL;
    }

    /* the streamengine queue and pool */
    if (iStrmCtrl->pMsgQ != NULL)
    {
        iStrmCtrl->pMsgQ->Destroy();
        delete (iStrmCtrl->pMsgQ);
        iStrmCtrl->pMsgQ = NULL;
    }
    if (iStrmCtrl->pMsgQPool != NULL)
    {
        OS_MemFree(iStrmCtrl->pMsgQPool);
    }

    /* release semaphores */
    if (iStrmCtrl->semCountingVsync != 0)
    {
        OS_SemDelete(iStrmCtrl->semCountingVsync);
        iStrmCtrl->semCountingVsync = 0;
    }

    if (iStrmCtrl->sendMsgSem != 0)
    {
        OS_SemDelete(iStrmCtrl->sendMsgSem);
        iStrmCtrl->sendMsgSem = 0;
    }

    for (i=0; i<PE_NUM_SEMS; i++)
    {
        if (iStrmCtrl->msgQSem[i] != 0)
        {
            OS_SemDelete(iStrmCtrl->msgQSem[i]);
            iStrmCtrl->msgQSem[i] = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -