gpt4 book ai didi

c++ - 使用 Direct3D 9 在硬件中将 RGB 表面转换为 YUV

转载 作者:行者123 更新时间:2023-11-30 16:30:08 25 4
gpt4 key购买 nike

我有一个 ARGB Direct3D9 表面,需要将其传输到相同尺寸的 UYVY 表面。两个表面都在系统内存中。我怎样才能做到这一点?

UpdateSurface and StretchRect fail.

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

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

最佳答案

DirectXTex有用于执行所有这些转换的代码,您可以查看以供引用。旧版 Direct3D 9 D3DFMT_UYVY 格式与 DXGI_FORMAT_YUY2 相同,但有一些 channel 混合。

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

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_FORMAT_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));

对于D3DFMT_UYVY,您将使用:

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));

关于c++ - 使用 Direct3D 9 在硬件中将 RGB 表面转换为 YUV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51434806/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com