📄 dx_drv.cpp
字号:
/*
*
* 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 + -