请教各位ddraw高手如何实现双缓冲绘制yuv数据

coloriy 2011-04-07 10:17:41
现在有经过ffmpeg解码后的yuv图像数据,目前实现了基于copy模式的ddraw surface绘制,但是感觉效率不高,请教哪位高手:
1)如何使用ddraw实现双缓冲绘制?
2)如何实现ddraw绘制yuv420数据高效绘制,是否双缓冲能够提高效率。
3)如果您有效率较高的绘制yuv数据的ddraw代码,请附在下面,谢谢了。

我目前的代码实现:
附代码:
//------------------------------------------------------------------------
/**
使用directshow方式绘制图像
\param pAVFrame 解码后图像帧数据
\return status 状态码
*/
//------------------------------------------------------------------------
VxInt32 CDisplay::ddshow_draw(int imgWidth, int imgHeight, AVFrame* pAVFrame)
{
VxInt32 status = LIVE_OK;

LPBYTE PtrY = (unsigned char *)pAVFrame->data[0];
LPBYTE PtrU = (unsigned char *)pAVFrame->data[1];
LPBYTE PtrV = (unsigned char *)pAVFrame->data[2];

int ddRval = 0;
do
{
ddRval = m_lpDDSOffScr->Lock(NULL, &m_ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
if ( DDERR_SURFACELOST == ddRval)
{
m_lpDDSOffScr->Restore();
ddRval = m_lpDDSOffScr->Lock(NULL, &m_ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
}
} while(ddRval == DDERR_WASSTILLDRAWING);
if(ddRval != DD_OK)
{
DLL_TRACE(__FILE__, __LINE__, "m_lpDDSOffScr->Lock failed ddRval = %d", ddRval);
return LIVE_FAILED;
}

LPBYTE lpSurf = (LPBYTE)m_ddsd.lpSurface;
if(lpSurf)
{
int i = 0;
for (i = 0; i < imgHeight; i++)
{
memcpy(lpSurf, PtrY, imgWidth);
PtrY += pAVFrame->linesize[0];
lpSurf += m_ddsd.lPitch;
}

for (i = 0; i < imgHeight/2; i++)
{
memcpy(lpSurf, PtrV, imgWidth/2);
PtrV += pAVFrame->linesize[1];
lpSurf += m_ddsd.lPitch/2;
}
for (i = 0; i < imgHeight/2; i++)
{
memcpy(lpSurf, PtrU, imgWidth/2);
PtrU += pAVFrame->linesize[2];
lpSurf += m_ddsd.lPitch/2;
}
}
m_lpDDSOffScr->Unlock(NULL);

DDBLTFX ddbltfx;
memset(&ddbltfx, 0, sizeof(ddbltfx));
ddbltfx.dwSize = sizeof(ddbltfx);
ddbltfx.dwROP = SRCCOPY;

RECT rect;
status = this->GetShowRect(rect);
if (ISFAILED(status))
{
DLL_TRACE(__FILE__, __LINE__, "CDisplay::ddshow_draw GetShowRect failed = %d !!!!!", status);
return status;
}

DWORD dret = m_lpDDSPrimary->Blt(&rect, m_lpDDSOffScr, NULL, DDBLT_ROP, &ddbltfx);
if ( DDERR_SURFACELOST == dret)
{
m_lpDDSPrimary->Restore();
DLL_TRACE(__FILE__, __LINE__, "CDisplay::ddshow_draw m_lpDDSPrimary Restore ");
}

// DLL_TRACE(__FILE__, __LINE__, "CDisplay::ddshow_draw dret=%d !!!!!", dret);
return status;
}


...全文
296 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
LiuYinChina 2011-04-15
  • 打赏
  • 举报
回复
我的方法和你的一样,
http://blog.csdn.net/RobertBaker/archive/2010/03/15/5380946.aspx
我不知道你说的效率不高是什么意思,CPU 很高?还是说想要比 copy 更快的办法?
coloriy 2011-04-15
  • 打赏
  • 举报
回复
请问楼上高手,您是如何使用ddraw显示yv12的,能不能贴段代码参考一下,不甚感激。
我把我的ddraw显示yv12的代码附上了,希望对别人有所帮助,但是觉得不是最优,楼上高手能贴一段您的代码吗,谢谢
coloriy 2011-04-15
  • 打赏
  • 举报
回复
我觉得是否CoreAVCDecoder.ax效率高于ffmpeg还是怎么回事,不得而知,不知道为什么人家接收rtsp视频流的效率高。请问楼上是否能给点提示。
coloriy 2011-04-15
  • 打赏
  • 举报
回复
coloriy 2011-04-15
  • 打赏
  • 举报
回复
copy效率是否低,这个小弟不知道,我觉得是否还有更高的效率,我把参数设置为
DWORD dret = m_lpDDSPrimary->Blt(&rect, m_lpDDSOffScr, NULL, DDBLT_WAIT, NULL);
发现效率似乎高点,但仍然有丢帧现象,
我使用live555接收,然后ffmpeg解码显示,directshow绘制,vfw保存avi,发现如果仅仅使用live555接收vfw保存,同一台笔记本上丢帧效率不明显,偶尔丢一帧,如果添加ffmpeg解码live555+ffmpeg解码,和保存则发现保存的avi文件出现比直接保存丢帧现象较为明显,如果再加上ddshow,则丢帧现象更加明显,据说ffmpeg解码效率提升优化空间较小,所以,我猜想是否应该在ddshow上显示部分优化,所以由原来的
DWORD dret = m_lpDDSPrimary->Blt(&rect, m_lpDDSOffScr, NULL, DDBLT_ROP, &ddbltfx);
copy模式,修改为DDBLT_WAIT等待绘制方式,觉得应该能提升一点,但是似乎效果不明显,有人说d3d能够提升显示效率,而且我在使用别的厂家接收rtsp视频流,然后解码显示,同一台笔记本上,他们的效率明显高,看他们的动态库,是基于media的filter的,解码器似乎也是ff的,渲染不知道是什么,这些是他们厂家的文件:

LiuYinChina 2011-04-12
  • 打赏
  • 举报
回复
我的程序上16路预览(DDraw->yv12),16路解码264显示(DDraw->yv12),16路Jpeg 显示(GDI),都行的
怀疑可能不是 DDraw 问题。
coloriy 2011-04-11
  • 打赏
  • 举报
回复
请问1楼高手,有没有相关示例,我参考一下,新手对这块不熟,谢谢。
CyberLogix 2011-04-07
  • 打赏
  • 举报
回复
双缓冲绘制不已经能提高效率,你可以考虑使用D3DAPI
内容概要:本文聚焦于“通过ADMM进行TV-L1去噪”的研究,系统阐述了基于交替方向乘子法(ADMM)实现总变差(Total Variation, TV)正则化与L1范数稀疏约束相结合的图像去噪模型。文中详细解析了TV-L1模型的数学构建及其在抑制椒盐噪声、保持图像边缘结构方面的优越性,重点介绍了ADMM算法如何将复杂的凸优化问题分解为多个可高效求解的子问题,提升收敛效率与数值稳定性。配套提供的Matlab代码实现了完整的去噪流程,便于读者复现算法并开展实验验证。此外,文档还整合了电力系统、信号处理、路径规划、机器学习等多个领域的科研资源,凸显其作为综合性学术资料包的价值。; 适合人群:具备良好数学基础与Matlab编程能力,从事图像处理、信号去噪、优化算法或相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:① 深入理解并复现基于ADMM的TV-L1图像去噪算法;② 掌握总变差正则化与L1范数在稀疏噪声去除中的理论与应用;③ 利用所提供的Matlab代码进行算法调试、性能评估与二次开发;④ 借助附带的多领域科研案例拓展研究思路,推动跨学科技术创新。; 阅读建议:建议读者结合理论推导与Matlab代码实践,逐步跟踪ADMM的迭代过程,观察其收敛行为与去噪效果,同时可参考文档末尾提供的丰富科研资源链接,拓展技术视野与研究深度。

2,554

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧