首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将颜色从RGB转换为NV12

将颜色从RGB转换为NV12
EN

Stack Overflow用户
提问于 2018-09-21 01:59:58
回答 1查看 1.2K关注 0票数 2

我正在开发一个用媒体基金会h264编码器编码视频的应用程序。接收器写入器crashes on Windows 7在VRAM中输入RGB,上面写着"0x8876086C D3DERR_INVALIDCALL“,所以我在GPU上实现了自己的RGB->NV12转换,节省了60%以上的PCI带宽。

以下是我的媒体类型中的输入(NV12)和输出(h264):

代码语言:javascript
复制
mt->SetUINT32( MF_MT_VIDEO_CHROMA_SITING, MFVideoChromaSubsampling_MPEG2 ); // Specifies the chroma encoding scheme for MPEG-2 video. Chroma samples are aligned horizontally with the luma samples, but are not aligned vertically. The U and V planes are aligned vertically.
mt->SetUINT32( MF_MT_YUV_MATRIX, MFVideoTransferMatrix_BT709 ); // ITU-R BT.709 transfer matrix.
mt->SetUINT32( MF_MT_VIDEO_NOMINAL_RANGE, MFNominalRange_0_255 ); // The normalized range [0...1] maps to [0...255] for 8-bit samples or [0...1023] for 10-bit samples.
mt->SetUINT32( MF_MT_TRANSFER_FUNCTION, MFVideoTransFunc_10 );  // Linear RGB (gamma = 1.0).

到目前为止,我对这个公式的最佳结果是:

代码语言:javascript
复制
inline float3 yuvFromRgb(float3 rgba)
{
    float3 res;
    res.x = dot( rgba, float3( 0.182585880, 0.614230573, 0.0620070584 ) );
    res.y = dot( rgba, float3( -0.121760942, -0.409611613, 0.531372547 ) );
    res.z = dot( rgba, float3( 0.531372547, -0.482648790, -0.0487237722 ) );
    res += float3( 0.0627451017, 0.500000000, 0.500000000 );
    return saturate( res );
}

让我担心的是,这个公式与我在互联网上读到的所有东西、代码样本和国际电联的官方规范相矛盾。

对于Y,公式很好,我取了BT.709系数,并将它们线性缩放到映射0.255到16.235,正如规范中所写的那样。亮度没问题。

规格说明我必须缩放U和V,才能从0.255映射到16.240。然而,我的眼睛告诉我它是不饱和的。为了得到正确的颜色,我必须用另一种方式缩放U&V,从0. 255降到- 8,255+8。

为什么在h264编码和解码之后,我需要用另一种方式来实现正确的颜色?这个代码在其他人的电脑上工作吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-21 19:59:09

问题是色度采样伪影。当我问这个问题时,我正在看彩色控制台文本。

今天,我尝试了编码更好的图像,这个:

有了这个图像,很明显正确的公式是在这些标准中指定的。

下面是正确的系数:

代码语言:javascript
复制
// Convert RGB color into ITU-R BT.709 YUV color
inline float3 yuvFromRgb( float3 rgb )
{
    float3 res;
    res.x = dot( rgb, float3( 0.18258588, 0.61423057, 0.06200706 ) );
    res.y = dot( rgb, float3( -0.10064373, -0.33857197, 0.43921569 ) );
    res.z = dot( rgb, float3( 0.43921569, -0.39894217, -0.04027352 ) );
    res += float3( 0.06274510, 0.50196081, 0.50196081 );
    return res;
}

他们仍然给我逐个错误,但对于我的特殊问题,0.39%的错误是可以接受的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52435591

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档