123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ui/gfx/color_space_win.h"
- #include "base/logging.h"
- #include "third_party/skia/modules/skcms/skcms.h"
- namespace gfx {
- DXVA2_ExtendedFormat ColorSpaceWin::GetExtendedFormat(
- const ColorSpace& color_space) {
- DXVA2_ExtendedFormat format;
- memset(&format, 0, sizeof(format));
- format.SampleFormat = DXVA2_SampleProgressiveFrame;
- format.VideoLighting = DXVA2_VideoLighting_dim;
- format.NominalRange = DXVA2_NominalRange_16_235;
- format.VideoTransferMatrix = DXVA2_VideoTransferMatrix_BT709;
- format.VideoPrimaries = DXVA2_VideoPrimaries_BT709;
- format.VideoTransferFunction = DXVA2_VideoTransFunc_709;
- switch (color_space.GetRangeID()) {
- case gfx::ColorSpace::RangeID::LIMITED:
- format.NominalRange = DXVA2_NominalRange_16_235;
- break;
- case gfx::ColorSpace::RangeID::FULL:
- format.NominalRange = DXVA2_NominalRange_0_255;
- break;
- case gfx::ColorSpace::RangeID::DERIVED:
- case gfx::ColorSpace::RangeID::INVALID:
- // Not handled
- break;
- }
- switch (color_space.GetMatrixID()) {
- case gfx::ColorSpace::MatrixID::BT709:
- format.VideoTransferMatrix = DXVA2_VideoTransferMatrix_BT709;
- break;
- case gfx::ColorSpace::MatrixID::BT470BG:
- case gfx::ColorSpace::MatrixID::SMPTE170M:
- format.VideoTransferMatrix = DXVA2_VideoTransferMatrix_BT601;
- break;
- case gfx::ColorSpace::MatrixID::SMPTE240M:
- format.VideoTransferMatrix = DXVA2_VideoTransferMatrix_SMPTE240M;
- break;
- case gfx::ColorSpace::MatrixID::RGB:
- case gfx::ColorSpace::MatrixID::GBR:
- case gfx::ColorSpace::MatrixID::FCC:
- case gfx::ColorSpace::MatrixID::YCOCG:
- case gfx::ColorSpace::MatrixID::BT2020_NCL:
- case gfx::ColorSpace::MatrixID::BT2020_CL:
- case gfx::ColorSpace::MatrixID::YDZDX:
- case gfx::ColorSpace::MatrixID::INVALID:
- // Not handled
- break;
- }
- switch (color_space.GetPrimaryID()) {
- case gfx::ColorSpace::PrimaryID::BT709:
- format.VideoPrimaries = DXVA2_VideoPrimaries_BT709;
- break;
- case gfx::ColorSpace::PrimaryID::BT470M:
- format.VideoPrimaries = DXVA2_VideoPrimaries_BT470_2_SysM;
- break;
- case gfx::ColorSpace::PrimaryID::BT470BG:
- format.VideoPrimaries = DXVA2_VideoPrimaries_BT470_2_SysBG;
- break;
- case gfx::ColorSpace::PrimaryID::SMPTE170M:
- format.VideoPrimaries = DXVA2_VideoPrimaries_SMPTE170M;
- break;
- case gfx::ColorSpace::PrimaryID::SMPTE240M:
- format.VideoPrimaries = DXVA2_VideoPrimaries_SMPTE240M;
- break;
- case gfx::ColorSpace::PrimaryID::FILM:
- case gfx::ColorSpace::PrimaryID::BT2020:
- case gfx::ColorSpace::PrimaryID::SMPTEST428_1:
- case gfx::ColorSpace::PrimaryID::SMPTEST431_2:
- case gfx::ColorSpace::PrimaryID::P3:
- case gfx::ColorSpace::PrimaryID::XYZ_D50:
- case gfx::ColorSpace::PrimaryID::ADOBE_RGB:
- case gfx::ColorSpace::PrimaryID::APPLE_GENERIC_RGB:
- case gfx::ColorSpace::PrimaryID::WIDE_GAMUT_COLOR_SPIN:
- case gfx::ColorSpace::PrimaryID::CUSTOM:
- case gfx::ColorSpace::PrimaryID::INVALID:
- // Not handled
- break;
- }
- switch (color_space.GetTransferID()) {
- case gfx::ColorSpace::TransferID::BT709:
- case gfx::ColorSpace::TransferID::SMPTE170M:
- format.VideoTransferFunction = DXVA2_VideoTransFunc_709;
- break;
- case gfx::ColorSpace::TransferID::SMPTE240M:
- format.VideoTransferFunction = DXVA2_VideoTransFunc_240M;
- break;
- case gfx::ColorSpace::TransferID::GAMMA22:
- format.VideoTransferFunction = DXVA2_VideoTransFunc_22;
- break;
- case gfx::ColorSpace::TransferID::GAMMA28:
- format.VideoTransferFunction = DXVA2_VideoTransFunc_28;
- break;
- case gfx::ColorSpace::TransferID::LINEAR:
- case gfx::ColorSpace::TransferID::LINEAR_HDR:
- case gfx::ColorSpace::TransferID::SCRGB_LINEAR_80_NITS:
- format.VideoTransferFunction = DXVA2_VideoTransFunc_10;
- break;
- case gfx::ColorSpace::TransferID::SRGB:
- case gfx::ColorSpace::TransferID::SRGB_HDR:
- format.VideoTransferFunction = DXVA2_VideoTransFunc_sRGB;
- break;
- case gfx::ColorSpace::TransferID::LOG:
- case gfx::ColorSpace::TransferID::LOG_SQRT:
- case gfx::ColorSpace::TransferID::IEC61966_2_4:
- case gfx::ColorSpace::TransferID::BT1361_ECG:
- case gfx::ColorSpace::TransferID::BT2020_10:
- case gfx::ColorSpace::TransferID::BT2020_12:
- case gfx::ColorSpace::TransferID::PQ:
- case gfx::ColorSpace::TransferID::SMPTEST428_1:
- case gfx::ColorSpace::TransferID::HLG:
- case gfx::ColorSpace::TransferID::BT709_APPLE:
- case gfx::ColorSpace::TransferID::GAMMA18:
- case gfx::ColorSpace::TransferID::GAMMA24:
- case gfx::ColorSpace::TransferID::CUSTOM:
- case gfx::ColorSpace::TransferID::CUSTOM_HDR:
- case gfx::ColorSpace::TransferID::PIECEWISE_HDR:
- case gfx::ColorSpace::TransferID::INVALID:
- // Not handled
- break;
- }
- return format;
- }
- DXGI_COLOR_SPACE_TYPE ColorSpaceWin::GetDXGIColorSpace(
- const ColorSpace& color_space,
- bool force_yuv) {
- // Treat invalid color space as sRGB.
- if (!color_space.IsValid())
- return DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
- if (color_space.GetMatrixID() == gfx::ColorSpace::MatrixID::RGB &&
- !force_yuv) {
- // For RGB, we default to FULL
- if (color_space.GetRangeID() == gfx::ColorSpace::RangeID::LIMITED) {
- if (color_space.GetPrimaryID() == gfx::ColorSpace::PrimaryID::BT2020) {
- if (color_space.GetTransferID() == gfx::ColorSpace::TransferID::PQ) {
- return DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020;
- } else {
- return DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P2020;
- }
- } else {
- return DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709;
- }
- } else {
- if (color_space.GetPrimaryID() == gfx::ColorSpace::PrimaryID::BT2020) {
- if (color_space.GetTransferID() == gfx::ColorSpace::TransferID::PQ) {
- return DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020;
- } else {
- return DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020;
- }
- } else {
- if (color_space.GetTransferID() ==
- gfx::ColorSpace::TransferID::LINEAR ||
- color_space.GetTransferID() ==
- gfx::ColorSpace::TransferID::LINEAR_HDR ||
- color_space.GetTransferID() ==
- gfx::ColorSpace::TransferID::SCRGB_LINEAR_80_NITS) {
- return DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709;
- } else if (color_space.GetTransferID() ==
- gfx::ColorSpace::TransferID::CUSTOM_HDR) {
- skcms_TransferFunction fn;
- color_space.GetTransferFunction(&fn);
- if (fn.g == 1.f)
- return DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709;
- else
- DLOG(ERROR) << "Windows HDR only supports gamma=1.0.";
- }
- return DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
- }
- }
- } else {
- if (color_space.GetPrimaryID() == gfx::ColorSpace::PrimaryID::BT2020) {
- if (color_space.GetTransferID() == gfx::ColorSpace::TransferID::PQ) {
- return DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_LEFT_P2020;
- // Could also be:
- // DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_TOPLEFT_P2020
- } else if (color_space.GetTransferID() ==
- gfx::ColorSpace::TransferID::HLG) {
- // Note: This may not always work. See https://crbug.com/1144260#c6.
- return DXGI_COLOR_SPACE_YCBCR_STUDIO_GHLG_TOPLEFT_P2020;
- } else {
- // For YUV, we default to LIMITED
- if (color_space.GetRangeID() == gfx::ColorSpace::RangeID::FULL) {
- return DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P2020;
- } else {
- return DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P2020;
- // Could also be:
- // DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_TOPLEFT_P2020
- }
- }
- } else if (color_space.GetPrimaryID() ==
- gfx::ColorSpace::PrimaryID::BT470BG ||
- color_space.GetPrimaryID() ==
- gfx::ColorSpace::PrimaryID::SMPTE170M) {
- // For YUV, we default to LIMITED
- if (color_space.GetRangeID() == gfx::ColorSpace::RangeID::FULL) {
- return DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P601;
- } else {
- return DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P601;
- }
- } else {
- // For YUV, we default to LIMITED
- if (color_space.GetRangeID() == gfx::ColorSpace::RangeID::FULL) {
- // TODO(hubbe): Check if this is correct.
- if (color_space.GetTransferID() ==
- gfx::ColorSpace::TransferID::SMPTE170M) {
- return DXGI_COLOR_SPACE_YCBCR_FULL_G22_NONE_P709_X601;
- } else {
- return DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P709;
- }
- } else {
- return DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709;
- }
- }
- }
- }
- DXGI_FORMAT ColorSpaceWin::GetDXGIFormat(const gfx::ColorSpace& color_space) {
- // The PQ transfer function needs 10 bits.
- if (color_space.GetTransferID() == gfx::ColorSpace::TransferID::PQ)
- return DXGI_FORMAT_R10G10B10A2_UNORM;
- // Non-PQ HDR color spaces use half-float.
- if (color_space.IsHDR())
- return DXGI_FORMAT_R16G16B16A16_FLOAT;
- // For now just give everything else 8 bits. We will want to use 10 or 16 bits
- // for BT2020 gamuts.
- return DXGI_FORMAT_B8G8R8A8_UNORM;
- }
- D3D11_VIDEO_PROCESSOR_COLOR_SPACE ColorSpaceWin::GetD3D11ColorSpace(
- const ColorSpace& color_space) {
- D3D11_VIDEO_PROCESSOR_COLOR_SPACE ret = {0};
- if (color_space.GetRangeID() == gfx::ColorSpace::RangeID::FULL) {
- ret.RGB_Range = 0; // FULL
- ret.Nominal_Range = D3D11_VIDEO_PROCESSOR_NOMINAL_RANGE_0_255;
- } else {
- ret.RGB_Range = 1; // LIMITED
- ret.Nominal_Range = D3D11_VIDEO_PROCESSOR_NOMINAL_RANGE_16_235;
- }
- switch (color_space.GetMatrixID()) {
- case gfx::ColorSpace::MatrixID::BT709:
- ret.YCbCr_Matrix = 1;
- break;
- case gfx::ColorSpace::MatrixID::BT470BG:
- case gfx::ColorSpace::MatrixID::SMPTE170M:
- ret.YCbCr_Matrix = 0;
- break;
- case gfx::ColorSpace::MatrixID::SMPTE240M:
- case gfx::ColorSpace::MatrixID::RGB:
- case gfx::ColorSpace::MatrixID::GBR:
- case gfx::ColorSpace::MatrixID::FCC:
- case gfx::ColorSpace::MatrixID::YCOCG:
- case gfx::ColorSpace::MatrixID::BT2020_NCL:
- case gfx::ColorSpace::MatrixID::BT2020_CL:
- case gfx::ColorSpace::MatrixID::YDZDX:
- case gfx::ColorSpace::MatrixID::INVALID:
- // Not handled
- break;
- }
- return ret;
- }
- } // namespace gfx
|