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

📄 pe_isplashscreen.cpp

📁 这是DVD中伺服部分的核心代码
💻 CPP
字号:

/*****************************************************************************
******************************************************************************
**                                                                          **
**  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_isplashscreen.cpp
 *
 * $Revision: 1.12 $ 
 *
 * DVD Presentation Engine API for displaying splash screens.
 *
 */

#include "decoder.h"
#include "vdvd_types.h"
#include "osapi.h"

#include "pe_app.h"
#include "pe_consumer.h"
#include "pe_types.h"
#include "dbgprint.h"
#ifdef DMALLOC
#include "dmalloc.h"
#endif

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

extern IDirectFB*     pDfb;
IDirectFBDisplayLayer *disp_layer = NULL;

/* TODO-SDK - Supply splashscreen file. */
const char* filename = NULL;

/* Set to an invalid format to force a first render of the splashscreen. */
PE_ICONFIGURE_VIDEO_FORMAT old_frmt = VIDEO_FORMAT_INVALID;

/**
 * Create the iSplashScreen interface.
 *
 * @param PEManager - Handle to PE manager. This can be used to obtain access to the other PE interfaces.
 *
 * @return iSplashScreen handle.
 */
ISPLASHSCREENHANDLE* PECreateiSplashScreen(PE_HANDLE PEManager)
{
    ISPLASHSCREENHANDLE* iSplashScreen;
    DbgAssert(PEManager != NULL);

    iSplashScreen = (ISPLASHSCREENHANDLE*)OS_MemAlloc(sizeof(ISPLASHSCREENHANDLE));
    if (iSplashScreen != NULL)
    {
        DfbExtLayerSettingsType settings;

        /* Store PEManager handle */
        iSplashScreen->PEManager         = PEManager;
        iSplashScreen->SplashScreenId    = PE_ISPLASHCREEN_ID_INVALID;
        iSplashScreen->pDFBImageProvider = NULL;

        /* get the current layer settings so we can configure the pixed format, size, etc */
        if (DfbExtLayerGet(((PEHANDLE *)PEManager)->dfb_background_layer, &settings) != 0)
        {
            DbgPrint(("PECreateiSplashScreen: Failed call to DfbExtLayerGet\n"));
            goto error_out;
        }

        /* get the directfb display layer for specified graphics layer */
        if (pDfb->GetDisplayLayer(pDfb, settings.id, &disp_layer) != DFB_OK)
        {
            DbgPrint(("PECreateiSplashScreen: Failed to set GetDisplayLayer\n"));
            goto error_out;
        }

        /* set display layer coop. level */
        if (disp_layer->SetCooperativeLevel(disp_layer, DLSCL_ADMINISTRATIVE) != DFB_OK)
        {
            DbgPrint(("PECreateiSplashScreen: Failed to set coop level\n"));
            goto error_out;
        }

        /* Maybe this should default to black. 
         * DirectFB defaults to blue for bg, so setting to transparent black. */
        if (disp_layer->SetBackgroundColor(disp_layer, 0, 0, 0, 0) != DFB_OK)
        {
            DbgPrint(("PECreateiSplashScreen: Failed to SetBackgroundColor!\n"));
            goto error_out;
        }

        if (pDfb->CreateImageProvider(pDfb, filename, &iSplashScreen->pDFBImageProvider) != DFB_OK)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PECreateiSplashScreen: Failed to CreateImageProvider bitmap object!\n"));
            goto error_out;
        }
    }

    return (iSplashScreen);

error_out:
    if (iSplashScreen != NULL)
    {
        OS_MemFree(iSplashScreen);
    }

    return (NULL);
}

/**
 * Delete the iSplashScreen interface.
 *
 * @param handle - Handle for the iSplashScreen interface to be deleted.
 *
 * @return PE_STATUS - PE Error Code defined in pe_app.h
 */
PE_STATUS PEDeleteiSplashScreen(ISPLASHSCREENHANDLE* iSplashScreen)
{
    if (iSplashScreen == NULL)
    {
        return (PE_INVALID_HANDLE);
    }

    /* release directFB objects */
    if (iSplashScreen->pDFBImageProvider != NULL)
    {
        iSplashScreen->pDFBImageProvider->Release(iSplashScreen->pDFBImageProvider);
    }

    /* release the display layer */
    if (disp_layer != NULL)
    {
        disp_layer->Release( disp_layer );
        disp_layer = NULL;
    }

    /* release resources */
    OS_MemFree(iSplashScreen);

    /* return success */
    return (PE_SUCCESS);
}

/**
 * Displays a splash screen.
 *
 * @param handle - iSplashScreen handle.
 * @param id - which splash screen to draw.
 *
 * @return PE_STATUS - PE Error code.
 *
 * @notes NONE
 */
PE_STATUS PEiSplashScreenDisplay(PE_HANDLE handle, PE_ISPLASHSCREEN_ID id)
{
    ISPLASHSCREENHANDLE*          iSplashScreen = ((PEHANDLE*)handle)->iSplashScreen;
    DFBDisplayLayerConfig         LayerConfig;
    int                           screen_width;
    int                           screen_height;
    DFBSurfaceDescription         desc;
    PE_STATUS                     status;
    PE_ICONFIGURE_VIDEO_FORMAT    new_frmt;
    IDirectFBSurface              *sfc = NULL;

    /* validate input */
    if (NULL == iSplashScreen)
    {
        return (PE_INVALID_HANDLE);
    }


    /* all splash screens are currently the same
     * if desired a different splashscreen could be drawn for each unique id */
    switch (id)
    {
    case PE_SPLASHSCREEN_ID_1:
    case PE_SPLASHSCREEN_ID_2:
    case PE_SPLASHSCREEN_ID_3:
    case PE_SPLASHSCREEN_ID_4:
    case PE_SPLASHSCREEN_ID_5:
    default:
        /* make the splashscreen visible
         * NOTE: using the IG layer for splashscreen */

        new_frmt = ((PEHANDLE *)handle)->iConfigure->VideoFormat;

        /* Update if the output settings changed */
        if (new_frmt != old_frmt)
        {
            if (disp_layer->GetConfiguration(disp_layer, &LayerConfig) != DFB_OK)
            {
                DBGPRINT(DBG_ON(DBG_ERROR), ("PEiSplashScreenDisplay: Failed to GetConfiguration!\n"));
                status = PE_FAILURE;
                break;
            }

            if (LayerConfig.buffermode != DLBM_BACKVIDEO)
            {
                switch (new_frmt)
                {
                case VIDEO_FORMAT_1080I_29_97:
                case VIDEO_FORMAT_1080I_25:
                case VIDEO_FORMAT_1080P_24:
                case VIDEO_FORMAT_1080P_23_976:
                    screen_width  = 1920;
                    screen_height = 1080;
                    break;

                case VIDEO_FORMAT_720P_59_94:
                case VIDEO_FORMAT_720P_50:
                case VIDEO_FORMAT_720P_24:
                case VIDEO_FORMAT_720P_23_976:
                    screen_width  = 1280;
                    screen_height = 720;
                    break;

                case VIDEO_FORMAT_PAL:
                case VIDEO_FORMAT_576P:
                    screen_width  = 720;
                    screen_height = 576;
                    break;

                case VIDEO_FORMAT_480P:
                case VIDEO_FORMAT_NTSC:
                default:
                    screen_width  = 720;
                    screen_height = 480;
                    break;
                }

                if (iSplashScreen->pDFBImageProvider->GetSurfaceDescription(iSplashScreen->pDFBImageProvider, &desc) != DFB_OK)
                {
                    DBGPRINT(DBG_ON(DBG_ERROR), ("PEiSplashScreenDisplay: Failed to GetSurfaceDescription!\n"));
                    status = PE_FAILURE;
                    break;
                }

                /* setup output surface based on display resolution */
                LayerConfig.flags       = (DFBDisplayLayerConfigFlags)(DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT);
                LayerConfig.width       = screen_width;
                LayerConfig.height      = screen_height;
                LayerConfig.pixelformat = desc.pixelformat;

                /* setup the graphics plane */
                if (disp_layer->SetConfiguration(disp_layer, &LayerConfig) != DFB_OK)
                {
                    DbgPrint(("PEiSplashScreenDisplay: Failed to SetConfiguration\n"));
                    status = PE_FAILURE;
                    break;
                }

                /* get the primary surface for this display layer */
                if (disp_layer->GetSurface(disp_layer, &sfc) != DFB_OK)
                {
                    DbgPrint(("PEiSplashScreenDisplay: Failed to get surface\n"));
                    status = PE_FAILURE;
                    break;
                }

                if (iSplashScreen->pDFBImageProvider->RenderTo(iSplashScreen->pDFBImageProvider, sfc, NULL) != DFB_OK)
                {
                    DBGPRINT(DBG_ON(DBG_ERROR), ("PEiSplashScreenDisplay: Failed to RenderTo bitmap object!\n"));
                    status = PE_FAILURE;
                    break;
                }
            }
            else if (old_frmt == VIDEO_FORMAT_INVALID)
            {
                /* We only need to render once, and the display layer will be the format specified by the
                 * image description */
                if (iSplashScreen->pDFBImageProvider->GetSurfaceDescription(iSplashScreen->pDFBImageProvider, &desc) != DFB_OK)
                {
                    DBGPRINT(DBG_ON(DBG_ERROR), ("PEiSplashScreenDisplay: Failed to GetSurfaceDescription!\n"));
                    status = PE_FAILURE;
                    break;
                }

                /* setup output surface based on image description */
                LayerConfig.flags       = (DFBDisplayLayerConfigFlags)(DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT);
                LayerConfig.width       = desc.width;
                LayerConfig.height      = desc.height;
                LayerConfig.pixelformat = desc.pixelformat;

                /* setup the graphics plane */
                if (disp_layer->SetConfiguration(disp_layer, &LayerConfig) != DFB_OK)
                {
                    DbgPrint(("PEiSplashScreenDisplay: Failed to SetConfiguration\n"));
                    status = PE_FAILURE;
                    break;
                }

                /* get the primary surface for this display layer */
                if (disp_layer->GetSurface(disp_layer, &sfc) != DFB_OK)
                {
                    DbgPrint(("PEiSplashScreenDisplay: Failed to get surface\n"));
                    status = PE_FAILURE;
                    break;
                }

                if (iSplashScreen->pDFBImageProvider->RenderTo(iSplashScreen->pDFBImageProvider, sfc, NULL) != DFB_OK)
                {
                    DBGPRINT(DBG_ON(DBG_ERROR), ("PEiSplashScreenDisplay: Failed to RenderTo bitmap object!\n"));
                    status = PE_FAILURE;
                    break;
                }
            }

            old_frmt = new_frmt;
        }

        /* when ig starts it is not visible */
        if (disp_layer->SetLevel(disp_layer, DFB_DISPLAYLAYER_IDS_MAX-2) != DFB_OK)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PEiSplashScreenDisplay: Failed to set the level to -1\n"));
            status = PE_FAILURE;
            break;
        }

        if (sfc == NULL)
        {
            /* get the primary surface for this diplay layer */
            if (disp_layer->GetSurface(disp_layer, &sfc) != DFB_OK)
            {
                DbgPrint(("PEiSplashScreenDisplay: Failed to get surface\n"));
                status = PE_FAILURE;
                break;
            }
        }

        /* flip the surface (this needs to happen AFTER setlevel) */
        if (sfc->Flip(sfc, NULL, DSFLIP_NONE) != DFB_OK)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PEiSplashScreenDisplay: Failed to flip surface!\n"));
            status = PE_FAILURE;
            break;
        }

        status = PE_SUCCESS;
        break;
    }

    if (status == PE_SUCCESS)
    {
        /* indicate we are displaying a splashscreen */
        iSplashScreen->SplashScreenId = id;
    }

    /* release the directFB surface */
    if (sfc != NULL)
    {
        sfc->Release( sfc );
    }


    DBGPRINT(DBG_ON(DBG_TRACE), ("PEiSplashScreenDisplay: EXIT\n"));
    return (status);
}

/**
 * Hides the splash screen currently being displayed.
 *
 * @param handle - iSplashScreen handle.
 *
 * @return PE_STATUS - PE Error code.
 */
PE_STATUS PEiSplashScreenHide(PE_HANDLE handle)
{
    ISPLASHSCREENHANDLE* iSplashScreen = ((PEHANDLE*)handle)->iSplashScreen;
    IDirectFBSurface     *sfc = NULL;

    /* validate input */
    if (NULL == iSplashScreen)
    {
        return (PE_INVALID_HANDLE);
    }

    if (PE_ISPLASHCREEN_ID_INVALID != iSplashScreen->SplashScreenId)
    {
        /* when ig starts it is not visible */
        if (disp_layer->SetLevel(disp_layer, -1) != DFB_OK)
        {
            DBGPRINT(DBG_ON(DBG_ERROR), ("PEiSplashScreenHide: Failed to set the level to -1\n"));
        }

        iSplashScreen->SplashScreenId = PE_ISPLASHCREEN_ID_INVALID;
    }

    /* release the directFB surface */
    if (sfc != NULL)
    {
        sfc->Release( sfc );
    }

    return (PE_SUCCESS);
}

/**
 * Returns display status of the splash screen.
 *
 * @param handle - iSplashScreen handle.
 * @param pfIsDisplayed - Pointer to returned BOOLEAN indicating current splash screen state.
 *
 * @return PE_STATUS - PE Error code.
 *
 * @notes
 *        Returned value: TRUE = displayed, FALSE = not displayed.
 */
PE_STATUS PEiSplashScreenIsDisplayed(PE_HANDLE handle, BOOLEAN *pfIsDisplayed)
{
    PE_ISPLASHSCREEN_ID splashScreenId;
    PEiSplashScreenGetDisplayedId(handle, &splashScreenId);
    *pfIsDisplayed = (splashScreenId == PE_ISPLASHCREEN_ID_INVALID) ? false : true;
    return (PE_SUCCESS);
}

/**
 * Returns display status of the splash screen.
 *
 * @param handle - iSplashScreen handle.
 * @param pId - Pointer to returned PE_ISPLASHSCREEN_ID indicating current splash screen id.
 *
 * @return PE_STATUS - PE Error code.
 *
 * @notes
 *        Returned value: PE_ISPLASHSCREEN_ID.
 */
PE_STATUS PEiSplashScreenGetDisplayedId(PE_HANDLE handle, PE_ISPLASHSCREEN_ID *pId)
{
    /* validate input */
    if (NULL == handle)
    {
        return (PE_INVALID_HANDLE);
    }
    if (pId == NULL)
    {
        return (PE_NULL_POINTER);
    }

    *pId = ((PEHANDLE*)handle)->iSplashScreen->SplashScreenId;

    return (PE_SUCCESS);
}

⌨️ 快捷键说明

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