0

[Win]media: Correct color space transfer on decoder side for webrtc

This CL aims to ensure end to end color space information is correct
in render, overlay and non-overlay path on Windows.

Verification on Windows has done:
1) Real color space has been used for overlay and SkiaRenderer.
2) Test the feature on Windows with USB and MIPI camera.

Design doc: https://docs.google.com/document/d/11PuPYfxnpUw_6SZWMA8WzBrXw5VuuF1_rIvQPUSnuno/edit?usp=sharing

Change-Id: If1f69cfc68536a59fb1a2639e2bd0c883425b211
Bug: 1449570
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4619628
Reviewed-by: Ilya Nikolaevskiy <ilnik@chromium.org>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Auto-Submit: Shuhai Peng <shuhai.peng@intel.com>
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1184781}
This commit is contained in:
Shuhai Peng
2023-08-17 17:27:54 +00:00
committed by Chromium LUCI CQ
parent 6a3ee6dfb5
commit 5f4d74f9e4
3 changed files with 39 additions and 23 deletions
media/gpu/windows
third_party/blink/renderer/platform/peerconnection

@ -200,17 +200,21 @@ D3D11Status::Or<ComD3D11VideoDecoder> D3D11VideoDecoder::CreateD3D11Decoder() {
// codecs (the decoder doesn't support H264PROFILE_HIGH10PROFILE). We'll get
// a config change once we know the real bit depth if this turns out to be
// wrong.
bit_depth_ =
accelerated_video_decoder_
? accelerated_video_decoder_->GetBitDepth()
: (config_.profile() == VP9PROFILE_PROFILE2 ||
config_.profile() == HEVCPROFILE_REXT ||
config_.profile() == HEVCPROFILE_MAIN10 ||
(config_.color_space_info().GuessGfxColorSpace().IsHDR() &&
config_.codec() != VideoCodec::kH264 &&
config_.profile() != HEVCPROFILE_MAIN)
? 10
: 8);
bit_depth_ = 0;
if (accelerated_video_decoder_) {
bit_depth_ = accelerated_video_decoder_->GetBitDepth();
}
if (!bit_depth_) {
bit_depth_ =
(config_.profile() == VP9PROFILE_PROFILE2 ||
config_.profile() == HEVCPROFILE_REXT ||
config_.profile() == HEVCPROFILE_MAIN10 ||
(config_.color_space_info().GuessGfxColorSpace().IsHDR() &&
config_.codec() != VideoCodec::kH264 &&
config_.profile() != HEVCPROFILE_MAIN)
? 10
: 8);
}
// TODO: supported check?
decoder_configurator_ = D3D11DecoderConfigurator::Create(

@ -723,7 +723,13 @@ RTCVideoDecoderAdapter::DecodeInternal(const webrtc::EncodedImage& input_image,
ChangeStatus(Status::kOk);
}
if (ShouldReinitializeForSettingHDRColorSpace(input_image)) {
// If color space is specified, transmit it to decoder side by
// ReinitializeSync, then we can use the right color space to render and
// overlay instead of gussing for webrtc use case on decoder side.
// This also includes reinitialization for the HDR use case, i.e.
// config_.profile() is media::VP9PROFILE_PROFILE2.
if (ShouldReinitializeForSettingColorSpace(input_image)) {
config_.set_color_space_info(media::VideoColorSpace::FromGfxColorSpace(
blink::WebRtcToGfxColorSpace(*input_image.ColorSpace())));
if (!ReinitializeSync(config_)) {
@ -841,19 +847,25 @@ int32_t RTCVideoDecoderAdapter::Release() {
return WEBRTC_VIDEO_CODEC_OK;
}
bool RTCVideoDecoderAdapter::ShouldReinitializeForSettingHDRColorSpace(
bool RTCVideoDecoderAdapter::ShouldReinitializeForSettingColorSpace(
const webrtc::EncodedImage& input_image) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(decoding_sequence_checker_);
if (config_.profile() == media::VP9PROFILE_PROFILE2 &&
input_image.ColorSpace()) {
const gfx::ColorSpace& new_color_space =
blink::WebRtcToGfxColorSpace(*input_image.ColorSpace());
if (!config_.color_space_info().IsSpecified() ||
new_color_space != config_.color_space_info().ToGfxColorSpace()) {
return true;
}
if (!input_image.ColorSpace()) {
return false;
}
const gfx::ColorSpace& new_color_space =
blink::WebRtcToGfxColorSpace(*input_image.ColorSpace());
if (!new_color_space.IsValid()) {
return false;
}
if (new_color_space != config_.color_space_info().ToGfxColorSpace()) {
DVLOG(2) << __func__ << ", new_color_space:" << new_color_space.ToString();
return true;
}
return false;
}

@ -119,7 +119,7 @@ class PLATFORM_EXPORT RTCVideoDecoderAdapter : public webrtc::VideoDecoder {
const webrtc::EncodedImage& input_image,
bool missing_frames,
int64_t render_time_ms);
bool ShouldReinitializeForSettingHDRColorSpace(
bool ShouldReinitializeForSettingColorSpace(
const webrtc::EncodedImage& input_image) const;
bool ReinitializeSync(const media::VideoDecoderConfig& config);
void ChangeStatus(Status new_status);