📄 blt_video_render.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 "blt_video_render.h"#if defined(UMC_ENABLE_BLT_VIDEO_RENDER)#include "vm_debug.h"#define INIT_DIRECTDRAW_STRUCT(x) (ZeroMemory(&x, sizeof(x)), x.dwSize=sizeof(x))namespace UMC{BLTVideoRender::BLTVideoRender(){} // BLTVideoRender::BLTVideoRender()BLTVideoRender::~BLTVideoRender(){ Close();} // BLTVideoRender::~BLTVideoRender()Status BLTVideoRender::Init(MediaReceiverParams* pInit){ Status umcRes = UMC_OK; DXVideoRenderParams *pParams = DynamicCast<DXVideoRenderParams> (pInit); if (UMC_OK == umcRes) umcRes = m_SuncMut.Init(); assert(NULL != pParams); if (UMC_OK == umcRes) umcRes = InitDDObjs(); if (UMC_OK == umcRes) { m_hWnd = pParams->m_hWnd; if (!m_hd_caps.overlay_support && !m_hd_caps.colorkey_support || !m_DDrawObj) umcRes = UMC_NOT_INITIALIZED; } if (UMC_OK == umcRes) { HRESULT hRes = m_DDrawObj->SetCooperativeLevel(m_hWnd, DDSCL_NORMAL); if (DD_OK != hRes) umcRes = UMC_OPERATION_FAILED; } if (UMC_OK == umcRes) { // Create the primary surface INIT_DIRECTDRAW_STRUCT(m_ddsd); m_ddsd.dwFlags = DDSD_CAPS; m_ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; if (DD_OK != m_DDrawObj->CreateSurface(&m_ddsd, &m_primary, 0)) { vm_debug_msg(0xFFFFFFFF, VM_STRING("Failed to create the DirectDraw primary surface")); umcRes = UMC_FAILED_TO_ALLOCATE_BUFFER; } } LPDIRECTDRAWCLIPPER clipper = NULL; if (UMC_OK == umcRes && FAILED(m_DDrawObj->CreateClipper(0, &clipper, 0))) { vm_debug_msg(0xFFFFFFFF, VM_STRING("Failed to create clipper for the primary surface")); umcRes = UMC_OPERATION_FAILED; } if (UMC_OK == umcRes && DD_OK != clipper->SetHWnd(0, m_hWnd)) umcRes = UMC_OPERATION_FAILED; if (UMC_OK == umcRes && DD_OK != m_primary->SetClipper(clipper)) umcRes = UMC_OPERATION_FAILED; // Create additional buffers for out of order rendering DDSURFACEDESC ddsdBuffer; INIT_DIRECTDRAW_STRUCT(ddsdBuffer); if (UMC_OK == umcRes) { ddsdBuffer.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; ddsdBuffer.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT; ddsdBuffer.dwWidth = pParams->info.width; ddsdBuffer.dwHeight= pParams->info.height; umcRes = GetOverlayFormat(pParams->color_format, ddsdBuffer.ddpfPixelFormat); } if (UMC_OK == umcRes) { HRESULT hRes = DD_OK; memset(m_Buffers,0,sizeof(m_Buffers)); for (m_iBuffersNum = 0; DD_OK == hRes && m_iBuffersNum < MAX_FRAME_BUFFERS; m_iBuffersNum++) { LPDIRECTDRAWSURFACE *surf = (LPDIRECTDRAWSURFACE *)&m_Buffers[m_iBuffersNum].surface; hRes = m_DDrawObj->CreateSurface(&ddsdBuffer, surf, NULL); } umcRes = (DD_OK == hRes) ? UMC_OK : UMC_FAILED_TO_ALLOCATE_BUFFER; } if (UMC_OK == umcRes && m_iBuffersNum < MIN_FRAME_BUFFERS) { vm_debug_msg(0xFFFFFFFF, VM_STRING("Unsupported YUV format or fail to allocate enough back buffers for this format")); umcRes = UMC_FAILED_TO_ALLOCATE_BUFFER; } if (UMC_OK == umcRes) umcRes = BaseVideoRender::Init(pInit); return umcRes;} // Status BLTVideoRender::Init(MediaReceiverParams* pInit)Status BLTVideoRender::Close(){ m_SuncMut.LockIfInitialized(); for (int i=0;i<m_iBuffersNum;i++) { if (m_Buffers[i].surface) { ((IDirectDrawSurface*)m_Buffers[i].surface)->Release(); m_Buffers[i].surface = NULL; } } m_iBuffersNum = 0; if (m_primary) { LPDIRECTDRAWCLIPPER clipper; if (!FAILED(m_primary->GetClipper(&clipper))) clipper->Release(); assert(NULL != clipper); } m_SuncMut.UnlockIfInitialized(); return DXVideoRender::Close();} // Status BLTVideoRender::Close()Status BLTVideoRender::SetFullScreen(ModuleContext& rContext, bool full){ Status umcRes = UMC_OK; HWNDModuleContext *pHWNDCont = DynamicCast<HWNDModuleContext> (&rContext); if (NULL == pHWNDCont) umcRes = UMC_NULL_PTR; m_SuncMut.Lock(); if (UMC_OK == umcRes && m_primary) { LPDIRECTDRAWCLIPPER clipper; if (!FAILED(m_primary->GetClipper(&clipper))) clipper->SetHWnd(0, pHWNDCont->m_hWnd); else { umcRes = UMC_OPERATION_FAILED; assert(false); } } m_SuncMut.Unlock(); if (UMC_OK == umcRes) umcRes = DXVideoRender::SetFullScreen(rContext, full); return umcRes;} // Status BLTVideoRender::SetFullScreen(ModuleContext& rContext, bool full)Status BLTVideoRender::RenderFrame(){ ::RECT dst, src; Status umcRes = (m_iReadIndex >= 0 && NULL != m_primary) ? (UMC_OK) : (UMC_NOT_INITIALIZED); m_SuncMut.Lock(); IDirectDrawSurface* surface = NULL; if (UMC_OK == umcRes) { surface = (IDirectDrawSurface*)m_Buffers[m_iReadIndex].surface; m_SuncMut.Unlock(); UMCRect2Rect(m_dst_rect, dst); UMCRect2Rect(m_src_rect, src); HRESULT hRes = m_primary->Blt(&dst, surface, &src, DDBLT_WAIT, 0); m_SuncMut.Lock(); assert( DD_OK == hRes || DDERR_SURFACELOST == hRes); HRESULT hRestore; if (DDERR_SURFACELOST == hRes) { if (m_primary->IsLost()) m_primary->Restore(); if (surface->IsLost()) surface->Restore(); m_SuncMut.Unlock(); while (DDERR_SURFACELOST == (hRes = m_primary->Blt(&dst, surface, &src, DDBLT_WAIT, 0))){ hRestore = surface->Restore(); hRestore = m_primary->Restore(); Sleep(5); } hRes = m_primary->Blt(&dst, surface, &src, DDBLT_WAIT, 0); m_SuncMut.Lock(); assert( DD_OK == hRes ); } if( DD_OK != hRes ) umcRes = UMC_OPERATION_FAILED; } m_hFreeBufSemaCount++; if(UMC_OK == umcRes) m_hFreeBufSema.Signal(); m_SuncMut.Unlock(); return umcRes;} // Status BLTVideoRender::RenderFrame()Status BLTVideoRender::ShowLastFrame(){ ::RECT dst, src; Status umcRes = (m_iReadIndex >= 0 && NULL != m_primary) ? (UMC_OK) : (UMC_NOT_INITIALIZED); m_SuncMut.Lock(); IDirectDrawSurface* surface = NULL; if (UMC_OK == umcRes) { surface = (IDirectDrawSurface*)m_Buffers[m_iReadIndex].surface; m_SuncMut.Unlock(); UMCRect2Rect(m_dst_rect, dst); UMCRect2Rect(m_src_rect, src); HRESULT hRes = m_primary->Blt(&dst, surface, &src, DDBLT_WAIT, 0); m_SuncMut.Lock(); assert( DD_OK == hRes || DDERR_SURFACELOST == hRes); if (DDERR_SURFACELOST == hRes) { if (m_primary->IsLost()) m_primary->Restore(); if (surface->IsLost()) surface->Restore(); m_SuncMut.Unlock(); hRes = m_primary->Blt(&dst, surface, &src, DDBLT_WAIT, 0); m_SuncMut.Lock(); assert( DD_OK == hRes ); } if( DD_OK != hRes ) umcRes = UMC_OPERATION_FAILED; } m_SuncMut.Unlock(); return umcRes;} // Status BLTVideoRender::ShowLastFrame()} // namespace UMC#endif // defined(UMC_ENABLE_BLT_VIDEO_RENDER)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -