Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用Direct3D 9在硬件中将RGB曲面转换为YUV_C++_C_Windows_Directx_Direct3d - Fatal编程技术网

C++ 使用Direct3D 9在硬件中将RGB曲面转换为YUV

C++ 使用Direct3D 9在硬件中将RGB曲面转换为YUV,c++,c,windows,directx,direct3d,C++,C,Windows,Directx,Direct3d,我有一个ARGB Direct3D9曲面,我需要将它快速插入相同尺寸的UYVY曲面。两个表面都在系统内存中。我怎样才能做到这一点 UpdateSurface和StretchRect失败 如果需要,我愿意使用纹理而不是曲面 这必须在GPU中完成,即使用硬件加速。中有执行所有这些转换的代码,您可以查看以供参考。传统的Direct3D 9D3DFMT_UYVY格式与DXGI_格式_uy2格式相同,但存在一些频道切换 这些格式对每个图像像素中的两个可见像素进行编码: struct XMUBYTEN4 {

我有一个
ARGB Direct3D9
曲面,我需要将它快速插入相同尺寸的
UYVY
曲面。两个表面都在系统内存中。我怎样才能做到这一点

UpdateSurface和StretchRect失败

如果需要,我愿意使用纹理而不是曲面

这必须在GPU中完成,即使用硬件加速。

中有执行所有这些转换的代码,您可以查看以供参考。传统的Direct3D 9
D3DFMT_UYVY
格式与
DXGI_格式_uy2
格式相同,但存在一些频道切换

这些格式对每个图像像素中的两个可见像素进行编码:

struct XMUBYTEN4 { // DirectXMath data type
  uint8_t x;
  uint8_t y;
  uint8_t z;
  uint8_t w;
};

XMUBYTEN4 rgb1, rgb2 = // Input pixel pair

int y0 = ((66 * rgb1.x + 129 * rgb1.y + 25 * rgb1.z + 128) >> 8) + 16;
int u0 = ((-38 * rgb1.x - 74 * rgb1.y + 112 * rgb1.z + 128) >> 8) + 128;
int v0 = ((112 * rgb1.x - 94 * rgb1.y - 18 * rgb1.z + 128) >> 8) + 128;

int y1 = ((66 * rgb2.x + 129 * rgb2.y + 25 * rgb2.z + 128) >> 8) + 16;
int u1 = ((-38 * rgb2.x - 74 * rgb2.y + 112 * rgb2.z + 128) >> 8) + 128;
int v1 = ((112 * rgb2.x - 94 * rgb2.y - 18 * rgb2.z + 128) >> 8) + 128;
对于
DXGI\u格式\u YUY2
您将使用:

XMUBYTEN4 *dPtr = // Output pixel pair

dPtr->x = static_cast<uint8_t>(std::min<int>(std::max<int>(y0, 0), 255));
dPtr->y = static_cast<uint8_t>(std::min<int>(std::max<int>((u0 + u1) >> 1, 0), 255));
dPtr->z = static_cast<uint8_t>(std::min<int>(std::max<int>(y1, 0), 255));
dPtr->w = static_cast<uint8_t>(std::min<int>(std::max<int>((v0 + v1) >> 1, 0), 255));
dPtr->x = static_cast<uint8_t>(std::min<int>(std::max<int>((u0 + u1) >> 1, 0), 255));
dPtr->y = static_cast<uint8_t>(std::min<int>(std::max<int>(y0, 0), 255));
dPtr->z = static_cast<uint8_t>(std::min<int>(std::max<int>((v0 + v1) >> 1, 0), 255));
dPtr->w = static_cast<uint8_t>(std::min<int>(std::max<int>(y1, 0), 255));

为什么要使用传统的Direct3D 9?DirectX 11是所有Direct3D开发的更好选择,DirectX 11视频通常比旧的API更好地与Direct3D集成。有没有办法在DX 11中完成此任务?抱歉,忘了提到我需要在GPU端完成,即硬件加速,这就是为什么这不是一个选项。我会更新问题如果表面在系统内存中,你不能在GPU上进行。如果我将其复制到VRAM中的表面会怎么样?那么我能做些什么吗?关键是如果它已经在系统内存中,那么在CPU上做可能会更快。将数据上传到VRAM和从VRAM上传数据都需要时间,而且您还没有描述打算如何使用结果。在任何情况下,由于旧着色器模型的HLSL限制,在Direct3D 9中执行此操作的选项都受到限制。直到Shader Model 4.0才真正支持全精度整数,这意味着您最好使用Direct3D 11。