社区
图形处理/算法
帖子详情
如何用DirectX显示YUV格式的图像
HanZhu1
2003-01-18 03:58:59
个位高手您好:
能否用DirectX显示YUV格式的图像
...全文
736
9
打赏
收藏
如何用DirectX显示YUV格式的图像
个位高手您好: 能否用DirectX显示YUV格式的图像
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
9 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
weiweizeng
2003-03-26
打赏
举报
回复
study @^@
HanZhu1
2003-03-25
打赏
举报
回复
多谢!!!!
duwenyong
2003-03-07
打赏
举报
回复
#include <stdio.h>
#include <conio.h>
#include <sys/stat.h>
#include <ddraw.h>
unsigned char *y;
unsigned char *u;
unsigned char *v;
bool testsize(int w, int h, int s, int *pw, int *ph);
int main(int argc, char *argv[])
{
HRESULT hr;
LPDIRECTDRAW lpDD;
DDSURFACEDESC ddsd;
LPDIRECTDRAWSURFACE lpPrimary;
LPDIRECTDRAWSURFACE lpOverlay;
RECT rcSrc;
FILE *fd;
int i, j, f;
char name[256];
unsigned char *py, *pu, *pv;
unsigned int *dst;
int ffirst, fcount, ms_per_frame;
int width, height, size;
int width2, height2, size2;
int t1, t2;
char c;
bool done, wait;
if (argc != 4 && argc != 6 && argc != 7)
{
fprintf(stderr, "vidplay template first count [width height [ms_per_frame]]");
return -1;
}
sscanf(argv[2], "%d", &ffirst);
sscanf(argv[3], "%d", &fcount);
if (argc == 7)
{
sscanf(argv[6], "%d", &ms_per_frame);
}
else
{
ms_per_frame = 33;
}
if (argc >= 6)
{
sscanf(argv[4], "%d", &width);
sscanf(argv[5], "%d", &height);
}
else
{
struct _stat st;
sprintf(name, argv[1], ffirst);
if (_stat(name, &st) != 0)
return -1;
size = st.st_size;
if (!(testsize( 176, 144, size, &width, &height)
|| testsize( 352, 240, size, &width, &height)
|| testsize( 352, 480, size, &width, &height)
|| testsize( 704, 480, size, &width, &height)
|| testsize( 720, 480, size, &width, &height)
|| testsize( 352, 288, size, &width, &height)
|| testsize( 352, 576, size, &width, &height)
|| testsize( 704, 576, size, &width, &height)
|| testsize( 720, 576, size, &width, &height)
|| testsize( 8, 8, size, &width, &height)
|| testsize( 16, 16, size, &width, &height)
|| testsize( 32, 32, size, &width, &height)
|| testsize( 64, 64, size, &width, &height)
|| testsize( 128, 128, size, &width, &height)
|| testsize( 256, 256, size, &width, &height)
|| testsize( 512, 512, size, &width, &height)
|| testsize(1024,1024, size, &width, &height)))
{
fprintf(stderr, "Nonstandard picture size: specify width and height\n");
return -1;
}
}
width2 = width/2;
height2 = height/2;
size = width*height;
size2 = width2*height2;
y = (unsigned char *)malloc(size);
u = (unsigned char *)malloc(size2);
v = (unsigned char *)malloc(size2);
if (y == NULL || u == NULL || v ==NULL)
{
fprintf(stderr, "Out of memory\n");
return -1;
}
hr = DirectDrawCreate(NULL, &lpDD, NULL);
if (FAILED(hr)) { fprintf(stderr, "DirectDrawCreate failed\n"); return -1; }
hr = lpDD->SetCooperativeLevel(NULL, DDSCL_NORMAL);
if (FAILED(hr)) { fprintf(stderr, "SetCooperativeLevel failed\n"); return -1; }
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
hr = lpDD->CreateSurface(&ddsd, &lpPrimary, NULL);
if (FAILED(hr)) { fprintf(stderr, "CreateSurface (primary) failed\n"); return -1; }
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY;
ddsd.dwWidth = width;
ddsd.dwHeight = height;
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
ddsd.ddpfPixelFormat.dwFourCC = 0x32595559; // YUY2
hr = lpDD->CreateSurface(&ddsd, &lpOverlay, NULL);
if (FAILED(hr)) { fprintf(stderr, "CreateSurface (overlay) failed\n"); return -1; }
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
hr = lpOverlay->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR, NULL);
if (FAILED(hr)) { fprintf(stderr, "Lock failed\n"); return -1; }
for (i=0; i<height; i++)
{
dst = (unsigned int *)(((unsigned char *)ddsd.lpSurface) + i * ddsd.lPitch);
for (j=0; j<width2; j++)
{
dst[j] = 0x00800080;
}
}
hr = lpOverlay->Unlock(NULL);
SetRect(&rcSrc, 0, 0, width, height);
hr = lpOverlay->UpdateOverlay(NULL, lpPrimary, NULL, DDOVER_SHOW, NULL);
if (FAILED(hr)) { fprintf(stderr, "UpdateOverlay failed\n"); return -1; }
done = false;
wait = false;
while (!done)
{
t1 = timeGetTime();
for (f=ffirst; f<ffirst+fcount; f++)
{
sprintf(name, argv[1], f);
fd = fopen(name, "rb");
if (fd != NULL)
{
fread(y, 1, size, fd);
fread(u, 1, size2, fd);
fread(v, 1, size2, fd);
fclose(fd);
}
else
{
char name1[256];
sprintf(name1, "%s.Y", name);
fd = fopen(name1, "rb");
if (fd != NULL)
{
fread(y, 1, size, fd);
fclose(fd);
sprintf(name1, "%s.U", name);
fd = fopen(name1, "rb");
fread(u, 1, size2, fd);
fclose(fd);
sprintf(name1, "%s.V", name);
fd = fopen(name1, "rb");
fread(v, 1, size2, fd);
fclose(fd);
}
}
if (fd != NULL)
{
t2 = t1 - timeGetTime();
if (t2 > 0) Sleep(t2);
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
hr = lpOverlay->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR, NULL);
if (SUCCEEDED(hr))
{
for (i=0; i<height; i++)
{
dst = (unsigned int *)(((unsigned char *)ddsd.lpSurface) + i * ddsd.lPitch);
py = &y[width*i];
pu = &u[width2*(i>>1)];
pv = &v[width2*(i>>1)];
for (j=0; j<width2; j++)
{
dst[j] = py[j<<1] | (pu[j]<<8) | (py[(j<<1)+1]<<16) | (pv[j]<<24);
}
}
hr = lpOverlay->Unlock(NULL);
}
if (wait || _kbhit())
{
c = _getch();
if (c=='q')
{
done = true;
break;
}
else if (c==' ')
wait = true;
else
{
wait = false;
t1 = timeGetTime();
}
}
}
t1 += ms_per_frame;
}
t2 = t1 - timeGetTime();
if (t2 > 0) Sleep(t2);
}
hr = lpOverlay->UpdateOverlay(NULL, lpPrimary, NULL, DDOVER_HIDE, NULL);
lpOverlay->Release();
lpPrimary->Release();
lpDD->Release();
return 0;
}
bool testsize(int w, int h, int s, int *pw, int *ph)
{
if (s == w*h || s == (w*h*3)/2)
{
*pw = w;
*ph = h;
return true;
}
return false;
}
xiaodong88
2003-03-07
打赏
举报
回复
我试了一下,该程序
Failed to create surfaces.
The directdraw device may not support overlays.
与我的显卡有关系?
chenghl
2003-03-07
打赏
举报
回复
"...\DXVcSDK8\samples\Multimedia\DirectDraw\OverlayAnimate" 就是用显示的例子,曾对我有所帮助,希望对你也有所启发。
xiaodong88
2003-03-06
打赏
举报
回复
初学DX,请问楼上朋友,YUV文件中的每一帧在转化为RGB之后,怎样用DirectDraw来显示?
RGB的点阵在内存中,创建位图,创建表面,然后将位图绘到表面上。
我试了一下,屏幕上什么也没有,怎么回事?
DX9搞得更复杂了,不知道到哪里去找接口了。
希望得到你的指教!
RadAsm
2003-01-19
打赏
举报
回复
DirectX(准确的说是大部分显卡)是支持YUV格式直接显示的,并且有硬件加速(硬件色彩空间转换),最好是用Overlay表面来显示,DirectX不支持软件模拟Overlay。所以要么先作RGB转换然后用普通DirectDraw表面显示,要么用Overlay直接显示。我的想法是如果显卡连Overlay都不支持,那也太老了,普通DirectDraw表面显示也不会有好的效果,所以直接用Overlay显示就可以了。
mymmsc
2003-01-18
打赏
举报
回复
我来学习一下
jinkaoyan
2003-01-18
打赏
举报
回复
yuv和RGB是呈线性关系的,用个Matrix转化一下不就行了?
MFC窗口
显示
YUV
数据的两种方法
将解码出来的
YUV
数据直接
显示
在MFC的窗口上,包含了两种
显示
方式,能自动选择最佳方式。只需要创建一个类并调用一个接口就可以
显示
。
C# wpf 使用d3d渲染
yuv
视频数据
在wpf中可以使用hwnd渲染视频,但是有一个缺点,和wpf的控件不太契合,无法在播放框放控件,也无法改变形状,导致一些界面需求较难实现。为了解决这一问题,找到了一种可以和wpf绘制兼容的视频渲染方式,使用d3d渲染。原文链接:https://blog.csdn.net/u013113678/article/details/121296452
directX
的静态SDK
directX
的静态SDK,支持直接
显示
yuv
等数据,
显示
图像
的时候能大大的减少使用VC自带的
显示
接口的CPU 消耗
h.264编码器和简易播放器_可导出bmp
图像
这是我们多媒体的作业。我自己做的,x264encode工程生成的exe可以将
YUV
格式
数据编码为avi标准
格式
。x264player可以播放用h.264编码的avi文件。采用dshow技术进行视频帧渲染,效率挺高的,支持3840x2160的超大分辨率。里面有可执行文件。如果要变异源代码,需要安装
directX
的SDK。AVI文件操作基于VFW库。还可以将AVI导出bmp
格式
的
图像
。界面使用MFC实现。
direct3d的贴图代码
direct3d的贴图代码,使用
directx
9.0,所以需要安装
directx
SDK9.0,在exe目录中包含了要读取的图片文件和需要的效果图以及目前的效果图
由于图片的大小已经固定,所以对direct3d初始化时使用了固定的大小,目前问题:
1. 这是主要的,后面的暂时不重要。
图像
的颜色失真。有可能是
yuv
格式
不正确造成的吗?但在对d3d初始化时,使用
yuv
之外的
格式
好象都不成功
2. 如何向表面上写字?
3. 使用渲染如何做?我现在使用贴图的方式(我这种提法没有问题吧?)。渲染和贴图哪个效率高一些?
有解决问题的,请给我留言或者发邮件都可以,非常感谢!
图形处理/算法
19,468
社区成员
50,698
社区内容
发帖
与我相关
我的任务
图形处理/算法
VC/MFC 图形处理/算法
复制链接
扫一扫
分享
社区描述
VC/MFC 图形处理/算法
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章