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

📄 dx_drv.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*
 *
 *               INTEL CORPORATION PROPRIETARY INFORMATION
 *  This software is supplied under the terms of a license agreement or
 *  nondisclosure agreement with Intel Corporation and may not be copied
 *  or disclosed except in accordance with the terms of that agreement.
 *       Copyright(c) 2001-2006 Intel Corporation. All Rights Reserved.
 *
 */

#include <umc_defs.h>

#ifdef UMC_ENABLE_DX_VIDEO_RENDER

/* -------------------------------------------------------------------------- */

#include "dx_drv.h"
#include <stdio.h>
#include <ipps.h>

/* -------------------------------------------------------------------------- */

#define MODULE              "DX(video driver)"
#define FUNCTION            "<Undefined Function>"
#define ERR_STRING(msg)     VIDEO_DRV_ERR_STRING(MODULE, FUNCTION, msg)
#define ERR_SET(err, msg)   VIDEO_DRV_ERR_SET   (MODULE, err, FUNCTION, msg)
#define WRN_SET(err, msg)   VIDEO_DRV_WRN_SET   (MODULE, err, FUNCTION, msg)
#define DBG_SET(msg)        VIDEO_DRV_DBG_SET   (MODULE, FUNCTION, msg)

/* -------------------------------------------------------------------------- */

const VideoDrvSpec DXVideoDrvSpec =
{
    VM_STRING(MODULE),
    VideoDrvFalse,
    VideoDrvVideoMemLibrary,
    umc_dx_Init,
    umc_dx_Close,
    umc_dx_CreateBuffers,
    umc_dx_FreeBuffers,
    NULL,
    NULL,
    umc_dx_LockSurface,
    umc_dx_UnlockSurface,
    umc_dx_RenderFrame,
    umc_dx_SetVideoMode,
    umc_dx_GetWindow,
    NULL
};

/* -------------------------------------------------------------------------- */

#define INIT_DIRECTDRAW_STRUCT(x) (ZeroMemory(&x, sizeof(x)), x.dwSize=sizeof(x))

/* -------------------------------------------------------------------------- */

const DDPIXELFORMAT umc_dx_overlay_formats[] =
{
    {sizeof(DDPIXELFORMAT), DDPF_FOURCC | DDPF_YUV, MAKEFOURCC('Y','V','1','2'), 12, 0, 0, 0, 0},   /* YV12 */
    {sizeof(DDPIXELFORMAT), DDPF_FOURCC | DDPF_YUV, MAKEFOURCC('Y','U','Y','2'), 16, 0, 0, 0, 0},   /* YUY2 */
    {sizeof(DDPIXELFORMAT), DDPF_FOURCC | DDPF_YUV, MAKEFOURCC('U','Y','V','Y'), 16, 0, 0, 0, 0},   /* UYVY */
    {sizeof(DDPIXELFORMAT), DDPF_FOURCC | DDPF_YUV, MAKEFOURCC('N','V','1','2'), 12, 0, 0, 0, 0},   /* NV12 */
    {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0xf800, 0x07e0, 0x001f, 0}                             /* RGB565 */
};

/* -------------------------------------------------------------------------- */

vm_status umc_dx_InitDDObjs (VideoDriver *driver)
{
#undef  FUNCTION
#define FUNCTION "umc_dx_InitDDObjs"
    vm_status   result  = VM_OK;
    DXDrv*      drv     = (DXDrv*)((NULL != driver)? driver->m_pDrv: NULL);
    DDCAPS      caps;

    DBG_SET("+");
    if (drv == NULL)
    {
        ERR_SET(VM_OPERATION_FAILED, "null ptr");
    }
    if (VM_OK == result)
    {
        /* Creating DDraw object:
         *  NULL        - indicates active display driver,
         *  drv->dd_obj - DD object what will be created,
         *  NULL        - unused now (should be set to NULL).
         */
        if (FAILED(::DirectDrawCreate(NULL, &(drv->dd_obj), NULL)))
        {
            drv->dd_obj = NULL;
            ERR_SET(VM_OPERATION_FAILED, "DirectDrawCreate");
        }
    }
    if (VM_OK == result)
    {
        INIT_DIRECTDRAW_STRUCT(caps);
        if (FAILED(drv->dd_obj->GetCaps(&caps, NULL)))
        {
            ERR_SET(VM_OPERATION_FAILED, "IDirectDraw::GetCaps");
        }
        drv->dd_support_overlay     = (0 != (caps.dwCaps & DDCAPS_OVERLAY));
        drv->dd_support_colorkey    = (0 != (caps.dwCaps & DDCKEYCAPS_DESTOVERLAYYUV));
    }
    DBG_SET("-");
    return result;
}

/* -------------------------------------------------------------------------- */

/* vm_status */
VIDEO_DRV_INIT_FUNC (umc_dx_Init, driver, params)
{
#undef  FUNCTION
#define FUNCTION "umc_dx_Init"
    vm_status           result  = VM_OK;
    DXDrv*              drv     = (DXDrv*)ippsMalloc_8u(sizeof(DXDrv));
    DXVideoDrvParams*   pParams = (DXVideoDrvParams*) params;
    DDCOLORKEY          key;

    DBG_SET("+");
    if (VM_OK == result)
    {
        if (NULL == drv)
        {
            ERR_SET(VM_OPERATION_FAILED, "memory allocation");
        }
    }
    if (VM_OK == result)
    {
        if ((NULL == driver) || (NULL == pParams))
        {
            ERR_SET(VM_NULL_PTR, "null ptr");
        }
    }
    if (VM_OK == result)
    {
        driver->m_pDrv          = drv;
        driver->img_width       = pParams->common.img_width;
        driver->img_height      = pParams->common.img_height;
        driver->m_VideoMemType  = VideoDrvVideoMemLibrary;
        ippsZero_8u((Ipp8u*)&(driver->m_VideoMemInfo), sizeof(VideoDrvVideoMemInfo));
        ippsCopy_8u((const Ipp8u*)&DXVideoDrvSpec, (Ipp8u*)&(driver->m_DrvSpec), sizeof(VideoDrvSpec));

        ippsZero_8u((Ipp8u*)drv, sizeof(DXDrv));
        drv->win        = pParams->win;
        drv->win_width  = pParams->common.win_rect.w;
        drv->win_height = pParams->common.win_rect.h;
        drv->dd_fmt     = pParams->dd_fmt;
    }
    if (VM_OK == result)
    {
        result = umc_dx_InitDDObjs(driver);
    }
    if (VM_OK == result)
    {
        if ((NULL == drv->dd_obj) || (false == drv->dd_support_overlay))
        {
            ERR_SET(VM_NOT_INITIALIZED, "initialization");
        }
    }
    if (VM_OK == result)
    {
        if (FAILED(drv->dd_obj->SetCooperativeLevel(drv->win, DDSCL_NORMAL)))
        {
            ERR_SET(VM_OPERATION_FAILED, "IDirectDraw::SetCooperativeLevel");
        }
    }
    if (VM_OK == result)
    {
        /* Creating the primary surface. */
        INIT_DIRECTDRAW_STRUCT(drv->dd_srf_desc);
        drv->dd_srf_desc.dwFlags        = DDSD_CAPS;
        drv->dd_srf_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

        if (FAILED(drv->dd_obj->CreateSurface(&(drv->dd_srf_desc),
                                              &(drv->dd_srf_primary), 0)))
        {
            ERR_SET(VM_OPERATION_FAILED, "IDirectDraw::CreateSurface");
        }
    }
    if (VM_OK == result)
    {
        drv->dd_support_colorkey = pParams->use_color_key;
        if (drv->dd_support_colorkey)
        {
            /* Setting color key. */
            key.dwColorSpaceLowValue    = pParams->color_key;
            key.dwColorSpaceHighValue   = pParams->color_key;
            if (FAILED(drv->dd_srf_primary->SetColorKey(DDCKEY_DESTOVERLAY,&key)))
            {
                ERR_SET(VM_OPERATION_FAILED, "IDirectDrawSurface::SetColorKey");
            }
        }
    }
    if (VM_OK != result)
    {
        if (drv != NULL) { ippsFree(drv); driver->m_pDrv = NULL; }
    }
    DBG_SET("-");
    return result;
}

/* -------------------------------------------------------------------------- */

/* vm_status */
VIDEO_DRV_CREATE_BUFFERS_FUNC(umc_dx_CreateBuffers,
                              driver, min_b, max_b, bufs,
                              video_mem_type, video_mem_info)
{
#undef  FUNCTION
#define FUNCTION "umc_dx_CreateBuffers"
    vm_status           result  = VM_OK;
    DXDrv*              drv     = (DXDrv*)((NULL != driver)? driver->m_pDrv: NULL);
    Ipp32u              bufs_num = 0, i;
    DDSURFACEDESC       ddsdOverlay;
    IDirectDrawSurface* surface = NULL;
    HRESULT             hRes = DD_OK;

    DBG_SET("+");
    if (VM_OK == result)
    {
        if ((NULL == driver) || (NULL == bufs))
        {
            ERR_SET(VM_NULL_PTR, "null ptr");
        }
    }
    if (VM_OK == result)
    {
        if ((min_b > max_b) || (0 == max_b))
        {
            ERR_SET(VM_OPERATION_FAILED, "number of buffers");
        }
    }
    if (VM_OK == result)
    {
        if (!(driver->m_DrvSpec.drv_videomem_type & video_mem_type))
        {
            ERR_SET(VM_OPERATION_FAILED,"specified video memory type is unsupported");
        }
    }
    if (VM_OK == result)
    {
        /* Copying video memory information. */
        if (NULL != video_mem_info)
        {
            ippsCopy_8u((const Ipp8u*)video_mem_info, (Ipp8u*)&(driver->m_VideoMemInfo),
                        sizeof(VideoDrvVideoMemInfo));
        }
        /* Creating overlay buffers. */
        INIT_DIRECTDRAW_STRUCT(ddsdOverlay);
        ddsdOverlay.ddsCaps.dwCaps  = DDSCAPS_OVERLAY | DDSCAPS_FLIP |
                                      DDSCAPS_COMPLEX | DDSCAPS_VIDEOMEMORY;
        ddsdOverlay.dwFlags         = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH |
                                      DDSD_BACKBUFFERCOUNT| DDSD_PIXELFORMAT;
        ddsdOverlay.dwWidth         = driver->img_width;
        ddsdOverlay.dwHeight        = driver->img_height;
        ddsdOverlay.ddpfPixelFormat = umc_dx_overlay_formats[drv->dd_fmt];

        /* Trying to create max_b, max_b-1, ..., min_b overlays. */
        for (bufs_num = max_b; bufs_num >= min_b; --bufs_num)
        {
            ddsdOverlay.dwBackBufferCount = bufs_num;
            hRes = drv->dd_obj->CreateSurface(&ddsdOverlay, &drv->dd_srf_front, NULL);
            if (SUCCEEDED(hRes))
                break;
        }
        if ((bufs_num < min_b) || FAILED(hRes))
        {
            ERR_SET(VM_OPERATION_FAILED, "IDirectDraw::CreateSurface");
        }
    }
    if (VM_OK == result)
    {
        /* Obtaining chained overlay surfaces. */
        ippsZero_8u((Ipp8u*)bufs, max_b*sizeof(void*));
        bufs[0] = drv->dd_srf_front;
        for (i = 1; i < bufs_num; ++i)
        {
            surface = (IDirectDrawSurface*)(bufs[i-1]);
            hRes = surface->GetAttachedSurface(&ddsdOverlay.ddsCaps,
                                               (IDirectDrawSurface**)&(bufs[i]));
            if (FAILED(hRes))
            {
                ERR_SET(VM_OPERATION_FAILED, "GetAttachedSurface");
                break;
            }
        }
    }
    DBG_SET("-");
    return result;
}

/* -------------------------------------------------------------------------- */

/* void */
VIDEO_DRV_FREE_BUFFERS_FUNC(umc_dx_FreeBuffers, driver, num_b, bufs)
{
#undef  FUNCTION
#define FUNCTION "umc_dx_FreeBuffers"
    vm_status   result  = VM_OK;
    DXDrv*      drv     = (DXDrv*)((NULL != driver)? driver->m_pDrv: NULL);
    Ipp32u      i;

    DBG_SET("+");
    if (VM_OK == result)
    {
        if ((NULL == driver) || (NULL == drv) || (NULL == bufs))
        {
            ERR_SET(VM_NULL_PTR, "null ptr");
        }
    }
    if (VM_OK == result)
    {
        if (NULL != drv->dd_srf_front)
        {
            if (FAILED(drv->dd_srf_front->IsLost())) drv->dd_srf_front->Restore();
            drv->dd_srf_front->Release();
            drv->dd_srf_front = NULL;
        }
        if (NULL != drv->dd_srf_primary)
        {
            if (FAILED(drv->dd_srf_primary->IsLost())) drv->dd_srf_primary->Restore();

⌨️ 快捷键说明

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