📄 dx_video_render_wce.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) 2003-2005 Intel Corporation. All Rights Reserved.//*/#include "umc_defs.h"#if defined(UMC_ENABLE_DXWCE_VIDEO_RENDER)#include "ippi.h"#include "umc_video_data.h"#include "dx_video_render_wce.h"namespace UMC{DXWCEVideoRenderParams::DXWCEVideoRenderParams() : m_hWnd(NULL){} // DXWCEVideoRenderParams::DXWCEVideoRenderParams() :static DDPIXELFORMAT ddpfOverlayFormats[] ={ {sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('Y','V','1','2'), 0, 0, 0, 0, 0}, // YV12 {sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('Y','U','Y','V'), 0, 0, 0, 0, 0}, // YUYV {sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('U','Y','V','Y'), 0, 0, 0, 0, 0}, // UYVY {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0x7C00, 0x03e0, 0x001F, 0}, // 16-bit RGB 5:5:5 {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0xF800, 0x07e0, 0x001F, 0} // 16-bit RGB 5:6:5};DXWCEVideoRender::DXWCEVideoRender() : m_hWnd(NULL), m_pDD(NULL), m_pDDSPrimary(NULL), m_pDDSOverlay(NULL), m_bShow(true){ memset(&m_SrcRect, 0, sizeof(m_SrcRect)); memset(&m_SrcRect, 0, sizeof(m_DstRect));} // DXWCEVideoRender::DXWCEVideoRender() :DXWCEVideoRender::~DXWCEVideoRender(){ Close();} // DXWCEVideoRender::~DXWCEVideoRender()HRESULT DXWCEVideoRender::InitDDraw(HWND hWnd, UMC::RECT Rect){ HRESULT hRet = DD_OK; LPDIRECTDRAW pDD = NULL; DDSURFACEDESC2 ddsd; DDCAPS ddcaps; if (DD_OK == hRet) { hRet = DirectDrawCreate(NULL, &pDD, NULL); if (DD_OK != hRet) vm_debug_trace(4,VM_STRING("DirectDrawCreate FAILED")); } // Fetch DirectDraw4 interface. if (DD_OK == hRet) { hRet = pDD->QueryInterface(IID_IDirectDraw4, (LPVOID*)&m_pDD); if (hRet != DD_OK) vm_debug_trace(4,VM_STRING("QueryInterface FAILED")); else { pDD->Release(); pDD = NULL; } } // Get normal mode. if (DD_OK == hRet) { hRet = m_pDD->SetCooperativeLevel(hWnd, DDSCL_NORMAL); if (hRet != DD_OK) vm_debug_trace(4,VM_STRING("SetCooperativeLevel FAILED")); } // Get a primary surface interface pointer (only needed for init.) if (DD_OK == hRet) { memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; hRet = m_pDD->CreateSurface(&ddsd, &m_pDDSPrimary, NULL); if (hRet != DD_OK) vm_debug_trace(4,VM_STRING("CreateSurface FAILED")); } // See if we can support overlays. if (DD_OK == hRet) { memset(&ddcaps, 0, sizeof(ddcaps)); ddcaps.dwSize = sizeof(ddcaps); hRet = m_pDD->GetCaps(&ddcaps,NULL); if (hRet != DD_OK) vm_debug_trace(4,VM_STRING("GetCaps FAILED")); } if (DD_OK == hRet && !(ddcaps.dwCaps & DDCAPS_OVERLAY)) { vm_debug_trace(4,VM_STRING("Overlays are not supported in hardware!")); hRet = DDERR_INVALIDSURFACETYPE; } // Get alignment info to compute our overlay surface size. if (DD_OK == hRet) { m_SrcRect.left = Rect.left; m_SrcRect.top = Rect.top; m_SrcRect.right = Rect.right; m_SrcRect.bottom = Rect.bottom; if (ddcaps.dwCaps & DDCAPS_ALIGNSIZESRC && ddcaps.dwAlignSizeSrc) m_SrcRect.right += m_SrcRect.right % ddcaps.dwAlignSizeSrc; // Create the overlay flipping surface. We will attempt the pixel // formats in our table one at a time until we find one that jives. memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_VIDEOMEMORY; ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_BACKBUFFERCOUNT | DDSD_PIXELFORMAT; ddsd.dwWidth = m_SrcRect.right; ddsd.dwHeight = m_SrcRect.bottom; ddsd.dwBackBufferCount = 1;#if defined(_WIN32_WCE) && (defined(x86) || defined(_X86_)) ddsd.ddpfPixelFormat = ddpfOverlayFormats[0];#else // ! defined(_WIN32_WCE) && (defined(x86) || defined(_X86_)) ddsd.ddpfPixelFormat = ddpfOverlayFormats[4];#endif // defined(_WIN32_WCE) && (defined(x86) || defined(_X86_)) hRet = m_pDD->CreateSurface(&ddsd, &m_pDDSOverlay, NULL); if (hRet != DD_OK) vm_debug_trace(4,VM_STRING("Unable to create overlay surface!")); } // Finish setting up the overlay. if (DD_OK == hRet) { int StretchFactor1000 = ddcaps.dwMinOverlayStretch > 1000 ? (ddcaps.dwMinOverlayStretch) : (1000); m_DstRect.left = 0; m_DstRect.top = 0; // Adding 999 takes care of integer truncation problems. m_DstRect.right = (m_SrcRect.right * StretchFactor1000 + 999) / 1000; m_DstRect.bottom = m_SrcRect.bottom * StretchFactor1000 / 1000; if (ddcaps.dwCaps & DDCAPS_ALIGNSIZEDEST && ddcaps.dwAlignSizeDest) { m_DstRect.right = (int)((m_DstRect.right + ddcaps.dwAlignSizeDest - 1) / ddcaps.dwAlignSizeDest) * ddcaps.dwAlignSizeDest; } // Set the flags we'll send to UpdateOverlay DWORD dwUpdateFlags = DDOVER_SHOW; // Does the overlay hardware support source color keying? // If so, we can hide the black background around the image. // This probably won't work with YUV formats DDOVERLAYFX ovfx; memset(&ovfx, 0, sizeof(ovfx)); ovfx.dwSize = sizeof(ovfx); if (ddcaps.dwCKeyCaps & DDCKEYCAPS_SRCOVERLAY) { dwUpdateFlags |= DDOVER_KEYSRCOVERRIDE | DDOVER_DDFX; // Create an overlay FX structure so we can specify a source color // key. This information is ignored if the DDOVER_SRCKEYOVERRIDE // flag isn't set. // black as the color key ovfx.dckSrcColorkey.dwColorSpaceLowValue = 0; ovfx.dckSrcColorkey.dwColorSpaceHighValue = 0; } // Update the overlay parameters. hRet = m_pDDSOverlay->UpdateOverlay(&m_SrcRect, m_pDDSPrimary, &m_DstRect, dwUpdateFlags, &ovfx); if (hRet != DD_OK) vm_debug_trace(4,VM_STRING("Unable to show overlay surface!")); } return hRet;} // HRESULT DXWCEVideoRender::InitDDraw(HWND hWnd, UMC::RECT Rect)Status DXWCEVideoRender::Init(MediaReceiverParams* pInit){ Status umcRes = UMC_OK; DXWCEVideoRenderParams* pParams = DynamicCast<DXWCEVideoRenderParams>(pInit); if (NULL == pParams) umcRes = UMC_NULL_PTR; if (UMC_OK == umcRes) umcRes = MobileVideoRender::Init(pInit); if (UMC_OK == umcRes) { m_hWnd = pParams->m_hWnd; UMCRect2Rect(pParams->disp, m_DstRect); assert(NULL != m_hWnd); if (NULL == m_hWnd) umcRes = UMC_NULL_PTR; } if (UMC_OK == umcRes && !GetWindowRect( m_hWnd, &m_DstRect )) umcRes = UMC_OPERATION_FAILED; HBRUSH hBrush = NULL; if (UMC_OK == umcRes) { hBrush = CreateSolidBrush(0); if (NULL == hBrush) umcRes = UMC_OPERATION_FAILED; } if (UMC_OK == umcRes && 0 == FillRect(GetDC(m_hWnd),&m_DstRect, hBrush)) umcRes = UMC_OPERATION_FAILED; if (UMC_OK == umcRes) { HRESULT hRet = InitDDraw(pParams->m_hWnd, pParams->disp); if (FAILED(hRet)) umcRes = UMC_OPERATION_FAILED; } return umcRes;} // Status DXWCEVideoRender::Init(MediaReceiverParams* pInit)Status DXWCEVideoRender::Close(){ Status umcRes = MobileVideoRender::Close(); if (NULL != m_pDDSOverlay) { // Use UpdateOverlay() with the DDOVER_HIDE flag to remove an overlay // from the display. m_pDDSOverlay->UpdateOverlay(NULL, m_pDDSPrimary, NULL, DDOVER_HIDE, NULL); m_pDDSOverlay->Release(); m_pDDSOverlay = NULL; } if (NULL != m_pDDSPrimary) { m_pDDSPrimary->Release(); m_pDDSPrimary = NULL; } if (NULL != m_pDD) { m_pDD->Release(); m_pDD = NULL; } m_hWnd = 0; memset(&m_SrcRect, 0, sizeof(m_SrcRect)); memset(&m_SrcRect, 0, sizeof(m_DstRect)); return umcRes;} // Status DXWCEVideoRender::Close()// Lock input bufferStatus DXWCEVideoRender::LockInputBuffer(MediaData* pInData){ Status umcRes = UMC_OK; DDSURFACEDESC2 ddsd; memset(&ddsd, 0, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); VideoData* pVideoData = DynamicCast<VideoData>(pInData); if (NULL == pVideoData) umcRes = UMC_NULL_PTR; if (UMC_OK == umcRes && NULL == m_pDDSOverlay) umcRes = UMC_NOT_INITIALIZED; // Wait for the end od prev frame or Stop() while (UMC_OK == umcRes && !m_bStopFlag && m_dfFrameTime != -1.0 && UMC_TIMEOUT == m_ReadySema.Wait(1000)); if (UMC_OK == umcRes && (m_bStopFlag || m_dfFrameTime == -1.0)) umcRes = UMC_END_OF_STREAM; if (UMC_OK == umcRes) { HRESULT hRes = m_pDDSOverlay->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT, NULL); if (FAILED(hRes)) umcRes = UMC_OPERATION_FAILED; } if (UMC_OK == umcRes) { vm_var32 uiSize = ddsd.dwWidth * ddsd.dwHeight; pVideoData->SetDest((LPBYTE)ddsd.lpSurface, ((LPBYTE)ddsd.lpSurface) + uiSize, ((LPBYTE)ddsd.lpSurface) + uiSize + uiSize / 4); if (NULL != ddsd.lpSurface) pVideoData->SetPitch(ddsd.lPitch, ddsd.lPitch / 2, ddsd.lPitch / 2); else pVideoData->SetPitch(0); } else { pVideoData->SetDest(NULL); pVideoData->SetPitch(0); } return umcRes;} // Status DXWCEVideoRender::LockInputBuffer(MediaData* pInData)// Unlock input bufferStatus DXWCEVideoRender::UnLockInputBuffer(MediaData *pInData, Status StreamStatus){ Status umcRes = UMC_OK; VideoData* pVideoData = DynamicCast<VideoData, MediaData>(pInData); if (NULL == pVideoData) umcRes = UMC_NULL_PTR; if (UMC_OK == umcRes && NULL == m_pDDSOverlay) umcRes = UMC_NOT_INITIALIZED; if (UMC_OK == umcRes) { HRESULT hRes = m_pDDSOverlay->Unlock(NULL); if (FAILED(hRes)) umcRes = UMC_OPERATION_FAILED; } if (UMC_OK == umcRes) { double dfEndTime; pVideoData->GetTime(m_dfFrameTime, dfEndTime); umcRes = m_DoneSema.Signal(); } if (UMC_END_OF_STREAM == StreamStatus) Stop(); return umcRes;} // Status DXWCEVideoRender::UnLockInputBuffer(MediaData *pInData,Status DXWCEVideoRender::RenderFrame(){ Status umcRes = UMC_OK; if (NULL == m_pDDSPrimary && NULL == m_pDDSOverlay) umcRes = UMC_NOT_INITIALIZED; if (UMC_OK == umcRes) { DWORD dwShowCmd = m_bShow ? DDOVER_SHOW : DDOVER_HIDE; HRESULT hRes = m_pDDSOverlay->UpdateOverlay(&m_SrcRect, m_pDDSPrimary, &m_DstRect, dwShowCmd, 0); if (FAILED(hRes)) umcRes = UMC_OPERATION_FAILED; } if (UMC_OK == umcRes) umcRes = MobileVideoRender::RenderFrame(); return umcRes;} // Status DXWCEVideoRender::RenderFrame()} // namespace UMC#endif // defined(UMC_ENABLE_DXWCE_VIDEO_RENDER)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -