| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "components/cast_streaming/browser/receiver_config_conversions.h" |
| |
| #include <algorithm> |
| |
| #include "base/time/time.h" |
| #include "components/cast_streaming/browser/public/receiver_config.h" |
| #include "components/cast_streaming/public/config_conversions.h" |
| #include "media/base/audio_codecs.h" |
| #include "media/base/channel_layout.h" |
| #include "media/base/video_codecs.h" |
| #include "third_party/openscreen/src/cast/streaming/constants.h" |
| #include "ui/gfx/geometry/rect.h" |
| |
| namespace cast_streaming { |
| namespace { |
| |
| int GetMaxChannelCount(media::ChannelLayout channel_layout) { |
| switch (channel_layout) { |
| case media::CHANNEL_LAYOUT_MONO: |
| return 1; |
| case media::CHANNEL_LAYOUT_STEREO: |
| case media::CHANNEL_LAYOUT_STEREO_DOWNMIX: |
| return 2; |
| case media::CHANNEL_LAYOUT_2_1: |
| case media::CHANNEL_LAYOUT_SURROUND: |
| case media::CHANNEL_LAYOUT_2POINT1: |
| case media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC: |
| return 3; |
| case media::CHANNEL_LAYOUT_4_0: |
| case media::CHANNEL_LAYOUT_2_2: |
| case media::CHANNEL_LAYOUT_QUAD: |
| case media::CHANNEL_LAYOUT_3_1: |
| return 4; |
| case media::CHANNEL_LAYOUT_5_0: |
| case media::CHANNEL_LAYOUT_5_0_BACK: |
| case media::CHANNEL_LAYOUT_4_1: |
| case media::CHANNEL_LAYOUT_4_1_QUAD_SIDE: |
| return 5; |
| case media::CHANNEL_LAYOUT_5_1: |
| case media::CHANNEL_LAYOUT_5_1_BACK: |
| case media::CHANNEL_LAYOUT_6_0: |
| case media::CHANNEL_LAYOUT_6_0_FRONT: |
| case media::CHANNEL_LAYOUT_HEXAGONAL: |
| case media::CHANNEL_LAYOUT_5_1_4_DOWNMIX: |
| return 6; |
| case media::CHANNEL_LAYOUT_7_0: |
| case media::CHANNEL_LAYOUT_6_1: |
| case media::CHANNEL_LAYOUT_6_1_BACK: |
| case media::CHANNEL_LAYOUT_6_1_FRONT: |
| case media::CHANNEL_LAYOUT_7_0_FRONT: |
| return 7; |
| case media::CHANNEL_LAYOUT_7_1: |
| case media::CHANNEL_LAYOUT_7_1_WIDE: |
| case media::CHANNEL_LAYOUT_7_1_WIDE_BACK: |
| case media::CHANNEL_LAYOUT_OCTAGONAL: |
| return 8; |
| default: |
| return 1; |
| } |
| } |
| |
| openscreen::cast::Dimensions ToOpenscreenType(const gfx::Rect& rect, |
| int frame_rate) { |
| return openscreen::cast::Dimensions{ |
| rect.width(), rect.height(), {frame_rate, 1}}; |
| } |
| |
| openscreen::cast::VideoLimits ToOpenscreenVideoLimitsType( |
| const ReceiverConfig::VideoLimits& limits) { |
| openscreen::cast::VideoLimits osp_limits; |
| |
| if (limits.codec) { |
| osp_limits.applies_to_all_codecs = false; |
| osp_limits.codec = ToVideoCaptureConfigCodec(limits.codec.value()); |
| } else { |
| osp_limits.applies_to_all_codecs = true; |
| } |
| |
| osp_limits.max_dimensions = |
| ToOpenscreenType(limits.max_dimensions, limits.max_frame_rate); |
| osp_limits.max_delay = |
| std::chrono::milliseconds(limits.max_delay.InMilliseconds()); |
| osp_limits.max_pixels_per_second = limits.max_pixels_per_second; |
| osp_limits.min_bit_rate = limits.min_bit_rate; |
| osp_limits.max_bit_rate = limits.max_bit_rate; |
| |
| return osp_limits; |
| } |
| |
| openscreen::cast::AudioLimits ToOpenscreenAudioLimitsType( |
| const ReceiverConfig::AudioLimits& limits) { |
| openscreen::cast::AudioLimits osp_limits; |
| |
| if (limits.codec) { |
| osp_limits.applies_to_all_codecs = false; |
| osp_limits.codec = ToAudioCaptureConfigCodec(limits.codec.value()); |
| } else { |
| osp_limits.applies_to_all_codecs = true; |
| } |
| |
| osp_limits.max_channels = GetMaxChannelCount(limits.channel_layout); |
| osp_limits.max_delay = |
| std::chrono::milliseconds(limits.max_delay.InMilliseconds()); |
| osp_limits.max_sample_rate = limits.max_sample_rate; |
| osp_limits.min_bit_rate = limits.min_bit_rate; |
| osp_limits.max_bit_rate = limits.max_bit_rate; |
| |
| return osp_limits; |
| } |
| |
| openscreen::cast::Display ToOpenscreenDisplayType( |
| const ReceiverConfig::Display& display) { |
| openscreen::cast::Display osp_display; |
| osp_display.dimensions = |
| ToOpenscreenType(display.dimensions, display.max_frame_rate); |
| osp_display.can_scale_content = display.can_scale_content; |
| return osp_display; |
| } |
| |
| openscreen::cast::RemotingConstraints ToOpenscreenRemotingConstraintsType( |
| const ReceiverConfig::RemotingConstraints& constraints) { |
| openscreen::cast::RemotingConstraints osp_constraints; |
| osp_constraints.supports_chrome_audio_codecs = |
| constraints.supports_chrome_audio_codecs; |
| osp_constraints.supports_4k = constraints.supports_4k; |
| return osp_constraints; |
| } |
| |
| } // namespace |
| |
| openscreen::cast::ReceiverConstraints ToOpenscreenConstraints( |
| const ReceiverConfig& config) { |
| openscreen::cast::ReceiverConstraints constraints; |
| |
| constraints.audio_codecs.reserve(config.audio_codecs.size()); |
| std::transform(config.audio_codecs.begin(), config.audio_codecs.end(), |
| std::back_inserter(constraints.audio_codecs), |
| ToAudioCaptureConfigCodec); |
| |
| constraints.video_codecs.reserve(config.video_codecs.size()); |
| std::transform(config.video_codecs.begin(), config.video_codecs.end(), |
| std::back_inserter(constraints.video_codecs), |
| ToVideoCaptureConfigCodec); |
| |
| constraints.audio_limits.reserve(config.audio_limits.size()); |
| std::transform(config.audio_limits.begin(), config.audio_limits.end(), |
| std::back_inserter(constraints.audio_limits), |
| ToOpenscreenAudioLimitsType); |
| |
| constraints.video_limits.reserve(config.video_limits.size()); |
| std::transform(config.video_limits.begin(), config.video_limits.end(), |
| std::back_inserter(constraints.video_limits), |
| ToOpenscreenVideoLimitsType); |
| |
| if (config.display_description) { |
| constraints.display_description = |
| std::make_unique<openscreen::cast::Display>( |
| ToOpenscreenDisplayType(config.display_description.value())); |
| } |
| |
| if (config.remoting) { |
| constraints.remoting = |
| std::make_unique<openscreen::cast::RemotingConstraints>( |
| ToOpenscreenRemotingConstraintsType(config.remoting.value())); |
| } |
| |
| return constraints; |
| } |
| |
| } // namespace cast_streaming |