技术标签: 多媒体 directdraw 视频渲染 YUV 摄像头
LPDIRECTDRAW7 m_lpDDraw; // DirectDraw 对象指针
LPDIRECTDRAWSURFACE7 m_lpDDSPrimary; // DirectDraw 主表面指针
LPDIRECTDRAWSURFACE7 m_lpDDSOverlay; // DirectDraw 离屏表面指针
DDSURFACEDESC2 m_stPrimaryDdsd; // DirectDraw 表面描述
DDSURFACEDESC2 m_stOverlayDdsd; // DirectDraw 表面描述
LPDIRECTDRAWCLIPPER m_pDirectDrawCliper ;/
DirectDrawCreateEx(NULL, (LPVOID*)&m_lpDDraw,IID_IDirectDraw7, NULL);
m_lpDDraw->SetCooperativeLevel(m_hMainWnd, DDSCL_NORMAL);
DDSURFACEDESC2 m_stPrimaryDdsd;
ZeroMemory(&m_stPrimaryDdsd, sizeof(DDSURFACEDESC2));
m_stPrimaryDdsd.dwSize = sizeof(DDSURFACEDESC2);
m_stPrimaryDdsd.dwFlags = DDSD_CAPS ;
m_stPrimaryDdsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
hr = m_lpDDraw->CreateSurface(&m_stPrimaryDdsd, &m_lpDDSPrimary, NULL);
ZeroMemory(&m_stOverlayDdsd, sizeof(DDSURFACEDESC2));
m_stOverlayDdsd.dwSize = sizeof(DDSURFACEDESC2);
m_stOverlayDdsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN ;
m_stOverlayDdsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT ;
m_stOverlayDdsd.dwWidth = m_dwWidth;
m_stOverlayDdsd.dwHeight = m_dwHeight;
m_stOverlayDdsd.ddpfPixelFormat = pixfmt ;
m_stOverlayDdsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
hr = m_lpDDraw->CreateSurface(&m_stOverlayDdsd, &m_lpDDSOverlay, NULL);
if (FAILED(hr))
{
m_stOverlayDdsd.ddsCaps.dwCaps = DDSCAPS_SYSTEMMEMORY | DDSCAPS_OFFSCREENPLAIN ;//使用内存再次尝试创建。
hr = m_lpDDraw->CreateSurface(&m_stOverlayDdsd, &m_lpDDSOverlay, NULL);
if (FAILED(hr))
return hr ;
}
hr = m_lpDDraw->CreateClipper(0,&m_pDirectDrawCliper,NULL);
if (FAILED(hr))
return hr;
hr = m_pDirectDrawCliper->SetHWnd(0,m_hPlayWnd);
if (FAILED(hr))
return hr;
hr = m_lpDDSPrimary->SetClipper(m_pDirectDrawCliper);
if (FAILED(hr))
return hr;
HRESULT CDXImageDrawer::DisplayPlane(LPCBYTE pBuf[3],DWORD dwWidthDeflate[3],DWORD dwHeightDeflate[3])
{
HRESULT hr; // DirectDraw 函数返回值
hr = m_lpDDSOverlay->Lock(NULL,&m_stOverlayDdsd,DDLOCK_WAIT|DDLOCK_WRITEONLY,NULL);
if (FAILED(hr))
return hr;
LPCBYTE Y = pBuf[0];
LPCBYTE U = pBuf[1];
LPCBYTE V = pBuf[2];
LPBYTE lpSurface = (LPBYTE)m_stOverlayDdsd.lpSurface;
if(lpSurface)
{
//Y
DWORD dwLineWidth = m_stOverlayDdsd.dwWidth >> dwWidthDeflate[0] ;
DWORD dwLineHeight = m_stOverlayDdsd.dwHeight >> dwHeightDeflate[0] ;
DWORD dwLinePitch = m_stOverlayDdsd.lPitch >> dwWidthDeflate[0] ;
for (DWORD i=0;i<dwLineHeight;i++)
{
memcpy(lpSurface, Y, dwLineWidth);
Y += dwLineWidth;
lpSurface += dwLinePitch;
}
//V
dwLineWidth = m_stOverlayDdsd.dwWidth >> dwWidthDeflate[2] ;
dwLineHeight = m_stOverlayDdsd.dwHeight >> dwHeightDeflate[2] ;
dwLinePitch = m_stOverlayDdsd.lPitch >> dwWidthDeflate[2] ;
for (DWORD i=0;i<dwLineHeight;i++)
{
memcpy(lpSurface, V, dwLineWidth);
V += dwLineWidth;
lpSurface += dwLinePitch;
}
//U
dwLineWidth = m_stOverlayDdsd.dwWidth >> dwWidthDeflate[1] ;
dwLineHeight = m_stOverlayDdsd.dwHeight >> dwHeightDeflate[1] ;
dwLinePitch = m_stOverlayDdsd.lPitch >> dwWidthDeflate[1] ;
for (DWORD i=0;i<dwLineHeight;i++)
{
memcpy(lpSurface, U, dwLineWidth);
U += dwLineWidth;
lpSurface += dwLinePitch;
}
}
hr = m_lpDDSOverlay->Unlock(NULL);
if (FAILED(hr))
return hr;
RECT rect;
::GetClientRect(m_hPlayWnd,&rect);
POINT point = {0,0};
::ClientToScreen(m_hPlayWnd,&point);
rect.right = rect.right - rect.left + point.x;
rect.left = point.x;
rect.bottom = rect.bottom - rect.top + point.y;
rect.top = point.y;
hr = m_lpDDSPrimary->Blt(&rect, m_lpDDSOverlay, NULL, DDBLT_WAIT, NULL);
if (FAILED(hr))
return hr;
return S_OK ;
}
HRESULT CDXImageDrawer::DisplayLine(LPCBYTE pBuf,int nPixelBytes)
{
HRESULT hr; // DirectDraw 函数返回值
hr = m_lpDDSOverlay->Lock(NULL,&m_stOverlayDdsd,DDLOCK_WAIT|DDLOCK_WRITEONLY,NULL);
if (FAILED(hr))
return hr;
LPCBYTE p_YUV_RGB = pBuf ;
DWORD dwByteCountPerLine = m_stOverlayDdsd.dwWidth*nPixelBytes; //m_stOverlayDdsd.ddpfPixelFormat.dwRGBBitCount/8 ;
LPBYTE lpSurface = (LPBYTE)m_stOverlayDdsd.lpSurface;
if(lpSurface)
{
for (DWORD i=0;i<m_stOverlayDdsd.dwHeight;i++)
{
memcpy(lpSurface, p_YUV_RGB, dwByteCountPerLine);
p_YUV_RGB += dwByteCountPerLine;
lpSurface += m_stOverlayDdsd.lPitch;
}
}
hr = m_lpDDSOverlay->Unlock(NULL);
if (FAILED(hr))
return hr;
RECT rect;
::GetClientRect(m_hPlayWnd,&rect);
POINT point = {0,0};
::ClientToScreen(m_hPlayWnd,&point);
rect.right = rect.right - rect.left + point.x;
rect.left = point.x;
rect.bottom = rect.bottom - rect.top + point.y;
rect.top = point.y;
hr = m_lpDDSPrimary->Blt(&rect, m_lpDDSOverlay, NULL, DDBLT_WAIT, NULL);
if (FAILED(hr))
return hr;
return S_OK ;
}
文章目录前言什么是虚拟化为什么要用虚拟化虚拟化技术的优势KVM简介关于KVM关于Virtual Machine Manager其他虚拟化软件KVM虚拟化平台部署前言什么是虚拟化在计算机技术中,虚拟化(技术)或虚拟技术(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源(CPU、内存、磁盘空间、网络适配器等),予以抽象、转换后呈现出来并可供分区、组合为一个或多个电脑配置环境。由此,打破实体结构间的不可切割的障碍,使用户可以比原本的配置更好的方式来应用这些电脑硬件资源。这_1671465600
为什么要用spl_autoload_register其实我觉得这一段话基本可以解决所有的问题尽管 __autoload() 函数也能自动加载类和接口,但更建议使用 spl_autoload_register() 函数。spl_autoload_register() 提供了一种更加灵活的方式来实现类的自动加载(同一个应用中,可以支持任意数量的加载器,比如第三方库中的)。因此,不再建议使用 __a...
介绍BeanDefinition 是 Spring 用来描述用来生成 Bean 的类的元数据信息的一个接口。容器中的 BeanDefinitionMap 是 IOC 的一个基础的组成部分,也是非常重要的一个组件。BeanDefinition 是一个接口,它的继承关系如下:AbstractBeanDefinition是一个抽象类,它的三个子类都具有各自的特点,下会重点分析。BeanDefi...
用Python编程很久了,总感觉写的很low,可不能总这样呢。程序员逼格很重要,特别是以后还得不断进阶。于是学习一下别人Pythonic的风格,以备不时之需.............1.简洁的编码汇总1.1 快速生成字典&gt;&gt;&gt; dict(zip('张李王','三四五')){'张': '三', '李': '四', '王': '五'}&gt;&gt;&gt...
由于项目需要我们不得不对华为push进行研究。按照国际惯例先百度一波,发现各个大牛都是对于华为push的填坑,很明显,这个推送的问题还是有很多的。这里引用:Android集成华为推送踩坑问题总结使用老版push还是新版push PushReceiver中的onEvent()回调触发问题 APP接收到推送后,点击消息,总是会先打开启动页 如何自定义动作intent如何解决请跳转链...
简介LightGBM是微软开源的一套梯度boosting的框架,使用基于决策树的分布式的,高效的学习算法。是对GDBT的一种改进。LightGBM在哪些地方进行了优化基于Histogram的决策树算法带深度限制的Leaf-wise的叶子生长策略直方图做差加速直接支持类别特征(Categorical Feature)Cache命中率优化基于直方图的稀疏特征优化多线程优化基本原...
package com.bi.net;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.hbase.*;import org.apache.hadoop.hbase.client.*;import org.apache.hadoop.hbase.filt...
1 Temporal Noise Shaping (TNS)原理TNS是在1996年提出的一种能够自适应于输入信号特性来降低前回声效应的新技术。它利用应用于信号频谱的处理来实现时域噪声形状的控制,能够对量化噪声的细微时域结构(甚至在一个滤波器组窗口内)进行控制。它的提出基于如下的考虑:时域一频域对偶性的考虑:TNS技术利用时域和频域之间的对偶性,以一种新的形式发展了己有的预测编码...
翻译:小君君(才云)技术校对:星空下的文仔(才云)、bot(才云)大多数开发人员都认为在部署集群时选择合适的存储技术极为重要。但是,在 Kubernetes 这片市场上,人们对于存储技术的选择并没有一个标准的答案。本文将 介绍 Kubernetes 中常用的 6 种存储,分析它们的使用场景和优缺点,并对它们进行性能测试,找出哪种存储解决方案才是最理想的选择。存储技术的选择在很大程度上取决于工程师...
2019独角兽企业重金招聘Python工程师标准>>> ...
数据挖掘需要挖掘事物之间的关联性,A-Priori是一个购物篮模型,实质上是一个教你快速统计频繁项集的方法,其根据频繁项集的单调性,来减少扫描的次数比如我有很多购物篮,每个篮子里有若干物品,如{青菜,黄瓜}{黄瓜,蘑菇,冬笋}{面条,酱油}{苗条,青菜}我要推断那些物品会同时出现,这样方便推荐,或者说我能发现哪些物品之间有一定的关联性;A-Priori就是干这个的这个算法比较简单,就是
java进程爆cpu的快速定位1、背景在程序开发的过程中,难免遇到进程占用cpu过高(现网居多、开发环境)的情况,现网出现这种情况就需要及时的能定位到问题,快速解决,否则就导致系统不可用,用户投诉等多种一系列的问题。2、java进程占用CPU过高常见的两种情况:代码中有死循环或者接近死循环的操作快速创建大量临时变量,导致频繁触发gc回收3、在windows中的定位方法如图所示:...