1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/mirroring/service/mirror_settings.h"
6
7 #include <algorithm>
8 #include <string>
9
10 #include "base/environment.h"
11 #include "base/logging.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "media/base/audio_parameters.h"
14
15 using media::ResolutionChangePolicy;
16 using media::cast::Codec;
17 using media::cast::FrameSenderConfig;
18 using media::cast::RtpPayloadType;
19
20 namespace mirroring {
21
22 namespace {
23
24 // Default end-to-end latency. Currently adaptive latency control is disabled
25 // because of audio playout regressions (b/32876644).
26 // TODO(openscreen/44): Re-enable in port to Open Screen.
27 constexpr base::TimeDelta kDefaultPlayoutDelay =
28 base::TimeDelta::FromMilliseconds(400);
29
30 constexpr int kAudioTimebase = 48000;
31 constexpr int kVidoTimebase = 90000;
32 constexpr int kAudioChannels = 2;
33 constexpr int kAudioFramerate = 100; // 100 FPS for 10ms packets.
34 constexpr int kMinVideoBitrate = 300000;
35 constexpr int kMaxVideoBitrate = 5000000;
36 constexpr int kAudioBitrate = 0; // 0 means automatic.
37 constexpr int kMaxFrameRate = 30; // The maximum frame rate for captures.
38 constexpr int kMaxWidth = 1920; // Maximum video width in pixels.
39 constexpr int kMaxHeight = 1080; // Maximum video height in pixels.
40 constexpr int kMinWidth = 180; // Minimum video frame width in pixels.
41 constexpr int kMinHeight = 180; // Minimum video frame height in pixels.
42
GetPlayoutDelayImpl()43 base::TimeDelta GetPlayoutDelayImpl() {
44 // Currently min, max, and animated playout delay are the same.
45 constexpr char kPlayoutDelayVariable[] = "CHROME_MIRRORING_PLAYOUT_DELAY";
46
47 auto environment = base::Environment::Create();
48 if (!environment->HasVar(kPlayoutDelayVariable)) {
49 return kDefaultPlayoutDelay;
50 }
51
52 std::string playout_delay_arg;
53 if (!environment->GetVar(kPlayoutDelayVariable, &playout_delay_arg) ||
54 playout_delay_arg.empty()) {
55 return kDefaultPlayoutDelay;
56 }
57
58 int playout_delay;
59 if (!base::StringToInt(playout_delay_arg, &playout_delay) ||
60 playout_delay < 1 || playout_delay > 65535) {
61 VLOG(1) << "Invalid custom mirroring playout delay passed, must be between "
62 "1 and 65535 milliseconds. Using default value instead.";
63 return kDefaultPlayoutDelay;
64 }
65
66 VLOG(1) << "Using custom mirroring playout delay value of: " << playout_delay
67 << "ms...";
68 return base::TimeDelta::FromMilliseconds(playout_delay);
69 }
70
GetPlayoutDelay()71 base::TimeDelta GetPlayoutDelay() {
72 static base::TimeDelta playout_delay = GetPlayoutDelayImpl();
73 return playout_delay;
74 }
75
76 } // namespace
77
MirrorSettings()78 MirrorSettings::MirrorSettings()
79 : min_width_(kMinWidth),
80 min_height_(kMinHeight),
81 max_width_(kMaxWidth),
82 max_height_(kMaxHeight) {}
83
~MirrorSettings()84 MirrorSettings::~MirrorSettings() {}
85
86 // static
GetDefaultAudioConfig(RtpPayloadType payload_type,Codec codec)87 FrameSenderConfig MirrorSettings::GetDefaultAudioConfig(
88 RtpPayloadType payload_type,
89 Codec codec) {
90 FrameSenderConfig config;
91 config.sender_ssrc = 1;
92 config.receiver_ssrc = 2;
93 const base::TimeDelta playout_delay = GetPlayoutDelay();
94 config.min_playout_delay = playout_delay;
95 config.max_playout_delay = playout_delay;
96 config.animated_playout_delay = playout_delay;
97 config.rtp_payload_type = payload_type;
98 config.rtp_timebase = kAudioTimebase;
99 config.channels = kAudioChannels;
100 config.min_bitrate = config.max_bitrate = config.start_bitrate =
101 kAudioBitrate;
102 config.max_frame_rate = kAudioFramerate; // 10 ms audio frames
103 config.codec = codec;
104 return config;
105 }
106
107 // static
GetDefaultVideoConfig(RtpPayloadType payload_type,Codec codec)108 FrameSenderConfig MirrorSettings::GetDefaultVideoConfig(
109 RtpPayloadType payload_type,
110 Codec codec) {
111 FrameSenderConfig config;
112 config.sender_ssrc = 11;
113 config.receiver_ssrc = 12;
114 const base::TimeDelta playout_delay = GetPlayoutDelay();
115 config.min_playout_delay = playout_delay;
116 config.max_playout_delay = playout_delay;
117 config.animated_playout_delay = playout_delay;
118 config.rtp_payload_type = payload_type;
119 config.rtp_timebase = kVidoTimebase;
120 config.channels = 1;
121 config.min_bitrate = kMinVideoBitrate;
122 config.max_bitrate = kMaxVideoBitrate;
123 config.start_bitrate = kMinVideoBitrate;
124 config.max_frame_rate = kMaxFrameRate;
125 config.codec = codec;
126 return config;
127 }
128
SetResolutionConstraints(int max_width,int max_height)129 void MirrorSettings::SetResolutionConstraints(int max_width, int max_height) {
130 max_width_ = std::max(max_width, min_width_);
131 max_height_ = std::max(max_height, min_height_);
132 }
133
SetSenderSideLetterboxingEnabled(bool enabled)134 void MirrorSettings::SetSenderSideLetterboxingEnabled(bool enabled) {
135 enable_sender_side_letterboxing_ = enabled;
136 }
137
GetVideoCaptureParams()138 media::VideoCaptureParams MirrorSettings::GetVideoCaptureParams() {
139 media::VideoCaptureParams params;
140 params.requested_format =
141 media::VideoCaptureFormat(gfx::Size(max_width_, max_height_),
142 kMaxFrameRate, media::PIXEL_FORMAT_I420);
143 if (max_height_ == min_height_ && max_width_ == min_width_) {
144 params.resolution_change_policy = ResolutionChangePolicy::FIXED_RESOLUTION;
145 } else if (enable_sender_side_letterboxing_) {
146 params.resolution_change_policy =
147 ResolutionChangePolicy::FIXED_ASPECT_RATIO;
148 } else {
149 params.resolution_change_policy = ResolutionChangePolicy::ANY_WITHIN_LIMIT;
150 }
151 DCHECK(params.IsValid());
152 return params;
153 }
154
GetAudioCaptureParams()155 media::AudioParameters MirrorSettings::GetAudioCaptureParams() {
156 media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
157 media::CHANNEL_LAYOUT_STEREO, kAudioTimebase,
158 kAudioTimebase / 100);
159 DCHECK(params.IsValid());
160 return params;
161 }
162
163 } // namespace mirroring
164