OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/renderer/extensions/cast_streaming_native_handler.h" | 5 #include "chrome/renderer/extensions/cast_streaming_native_handler.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
11 #include <functional> | 11 #include <functional> |
12 #include <iterator> | 12 #include <iterator> |
13 #include <memory> | 13 #include <memory> |
14 #include <string> | 14 #include <string> |
15 #include <utility> | 15 #include <utility> |
16 #include <vector> | 16 #include <vector> |
17 | 17 |
18 #include "base/location.h" | 18 #include "base/location.h" |
19 #include "base/logging.h" | 19 #include "base/logging.h" |
20 #include "base/macros.h" | 20 #include "base/macros.h" |
21 #include "base/memory/ptr_util.h" | 21 #include "base/memory/ptr_util.h" |
22 #include "base/single_thread_task_runner.h" | 22 #include "base/single_thread_task_runner.h" |
23 #include "base/strings/string_number_conversions.h" | 23 #include "base/strings/string_number_conversions.h" |
24 #include "base/sys_info.h" | |
24 #include "base/threading/thread_task_runner_handle.h" | 25 #include "base/threading/thread_task_runner_handle.h" |
25 #include "chrome/common/extensions/api/cast_streaming_receiver_session.h" | 26 #include "chrome/common/extensions/api/cast_streaming_receiver_session.h" |
26 #include "chrome/common/extensions/api/cast_streaming_rtp_stream.h" | 27 #include "chrome/common/extensions/api/cast_streaming_rtp_stream.h" |
27 #include "chrome/common/extensions/api/cast_streaming_udp_transport.h" | 28 #include "chrome/common/extensions/api/cast_streaming_udp_transport.h" |
28 #include "chrome/renderer/media/cast_receiver_session.h" | 29 #include "chrome/renderer/media/cast_receiver_session.h" |
29 #include "chrome/renderer/media/cast_rtp_stream.h" | 30 #include "chrome/renderer/media/cast_rtp_stream.h" |
30 #include "chrome/renderer/media/cast_session.h" | 31 #include "chrome/renderer/media/cast_session.h" |
31 #include "chrome/renderer/media/cast_udp_transport.h" | 32 #include "chrome/renderer/media/cast_udp_transport.h" |
32 #include "content/public/child/v8_value_converter.h" | 33 #include "content/public/child/v8_value_converter.h" |
33 #include "content/public/renderer/media_stream_utils.h" | 34 #include "content/public/renderer/media_stream_utils.h" |
34 #include "extensions/renderer/script_context.h" | 35 #include "extensions/renderer/script_context.h" |
35 #include "media/base/audio_parameters.h" | 36 #include "media/base/audio_parameters.h" |
37 #include "media/base/limits.h" | |
36 #include "net/base/host_port_pair.h" | 38 #include "net/base/host_port_pair.h" |
37 #include "net/base/ip_address.h" | 39 #include "net/base/ip_address.h" |
38 #include "third_party/WebKit/public/platform/WebMediaStream.h" | 40 #include "third_party/WebKit/public/platform/WebMediaStream.h" |
39 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" | 41 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" |
40 #include "third_party/WebKit/public/platform/WebURL.h" | 42 #include "third_party/WebKit/public/platform/WebURL.h" |
41 #include "third_party/WebKit/public/web/WebDOMMediaStreamTrack.h" | 43 #include "third_party/WebKit/public/web/WebDOMMediaStreamTrack.h" |
42 #include "third_party/WebKit/public/web/WebMediaStreamRegistry.h" | 44 #include "third_party/WebKit/public/web/WebMediaStreamRegistry.h" |
43 #include "url/gurl.h" | 45 #include "url/gurl.h" |
44 | 46 |
45 using content::V8ValueConverter; | 47 using content::V8ValueConverter; |
48 using media::cast::FrameSenderConfig; | |
46 | 49 |
47 // Extension types. | 50 // Extension types. |
48 using extensions::api::cast_streaming_receiver_session::RtpReceiverParams; | 51 using extensions::api::cast_streaming_receiver_session::RtpReceiverParams; |
49 using extensions::api::cast_streaming_rtp_stream::CodecSpecificParams; | |
50 using extensions::api::cast_streaming_rtp_stream::RtpParams; | 52 using extensions::api::cast_streaming_rtp_stream::RtpParams; |
51 using extensions::api::cast_streaming_rtp_stream::RtpPayloadParams; | 53 using extensions::api::cast_streaming_rtp_stream::RtpPayloadParams; |
52 using extensions::api::cast_streaming_udp_transport::IPEndPoint; | 54 using extensions::api::cast_streaming_udp_transport::IPEndPoint; |
53 | 55 |
54 namespace extensions { | 56 namespace extensions { |
55 | 57 |
56 namespace { | 58 namespace { |
59 | |
57 const char kInvalidAesIvMask[] = "Invalid value for AES IV mask"; | 60 const char kInvalidAesIvMask[] = "Invalid value for AES IV mask"; |
58 const char kInvalidAesKey[] = "Invalid value for AES key"; | 61 const char kInvalidAesKey[] = "Invalid value for AES key"; |
59 const char kInvalidAudioParams[] = "Invalid audio params"; | 62 const char kInvalidAudioParams[] = "Invalid audio params"; |
60 const char kInvalidDestination[] = "Invalid destination"; | 63 const char kInvalidDestination[] = "Invalid destination"; |
61 const char kInvalidFPS[] = "Invalid FPS"; | 64 const char kInvalidFPS[] = "Invalid FPS"; |
62 const char kInvalidMediaStreamURL[] = "Invalid MediaStream URL"; | 65 const char kInvalidMediaStreamURL[] = "Invalid MediaStream URL"; |
63 const char kInvalidRtpParams[] = "Invalid value for RTP params"; | 66 const char kInvalidRtpParams[] = "Invalid value for RTP params"; |
64 const char kInvalidLatency[] = "Invalid value for max_latency. (0-1000)"; | 67 const char kInvalidLatency[] = "Invalid value for max_latency. (0-1000)"; |
65 const char kInvalidRtpTimebase[] = "Invalid rtp_timebase. (1000-1000000)"; | 68 const char kInvalidRtpTimebase[] = "Invalid rtp_timebase. (1000-1000000)"; |
66 const char kInvalidStreamArgs[] = "Invalid stream arguments"; | 69 const char kInvalidStreamArgs[] = "Invalid stream arguments"; |
67 const char kRtpStreamNotFound[] = "The RTP stream cannot be found"; | 70 const char kRtpStreamNotFound[] = "The RTP stream cannot be found"; |
68 const char kUdpTransportNotFound[] = "The UDP transport cannot be found"; | 71 const char kUdpTransportNotFound[] = "The UDP transport cannot be found"; |
69 const char kUnableToConvertArgs[] = "Unable to convert arguments"; | 72 const char kUnableToConvertArgs[] = "Unable to convert arguments"; |
70 const char kUnableToConvertParams[] = "Unable to convert params"; | 73 const char kUnableToConvertParams[] = "Unable to convert params"; |
74 const char kCodecNameOpus[] = "OPUS"; | |
75 const char kCodecNameVp8[] = "VP8"; | |
76 const char kCodecNameH264[] = "H264"; | |
71 | 77 |
72 // These helper methods are used to convert between Extension API | 78 // To convert from kilobits per second to bits to per second. |
73 // types and Cast types. | 79 const int kBitrateMultiplier = 1000; |
miu
2016/06/30 21:59:42
nit: s/const/constexpr/
xjz
2016/07/01 23:52:08
Done.
| |
74 void ToCastCodecSpecificParams(const CodecSpecificParams& ext_params, | |
75 CastCodecSpecificParams* cast_params) { | |
76 cast_params->key = ext_params.key; | |
77 cast_params->value = ext_params.value; | |
78 } | |
79 | 80 |
80 void FromCastCodecSpecificParams(const CastCodecSpecificParams& cast_params, | |
81 CodecSpecificParams* ext_params) { | |
82 ext_params->key = cast_params.key; | |
83 ext_params->value = cast_params.value; | |
84 } | |
85 | |
86 namespace { | |
87 bool HexDecode(const std::string& input, std::string* output) { | 81 bool HexDecode(const std::string& input, std::string* output) { |
88 std::vector<uint8_t> bytes; | 82 std::vector<uint8_t> bytes; |
89 if (!base::HexStringToBytes(input, &bytes)) | 83 if (!base::HexStringToBytes(input, &bytes)) |
90 return false; | 84 return false; |
91 output->assign(reinterpret_cast<const char*>(&bytes[0]), bytes.size()); | 85 output->assign(reinterpret_cast<const char*>(&bytes[0]), bytes.size()); |
92 return true; | 86 return true; |
93 } | 87 } |
94 } // namespace | |
95 | 88 |
96 bool ToCastRtpPayloadParamsOrThrow(v8::Isolate* isolate, | 89 int NumberOfEncodeThreads() { |
97 const RtpPayloadParams& ext_params, | 90 // Do not saturate CPU utilization just for encoding. On a lower-end system |
98 CastRtpPayloadParams* cast_params) { | 91 // with only 1 or 2 cores, use only one thread for encoding. On systems with |
99 cast_params->payload_type = ext_params.payload_type; | 92 // more cores, allow half of the cores to be used for encoding. |
100 cast_params->max_latency_ms = ext_params.max_latency; | 93 return std::min(8, (base::SysInfo::NumberOfProcessors() + 1) / 2); |
101 cast_params->min_latency_ms = | 94 } |
102 ext_params.min_latency ? *ext_params.min_latency : ext_params.max_latency; | 95 |
103 cast_params->animated_latency_ms = ext_params.animated_latency | 96 bool ToFrameSenderConfigOrThrow(v8::Isolate* isolate, |
104 ? *ext_params.animated_latency | 97 const RtpPayloadParams& ext_params, |
105 : ext_params.max_latency; | 98 FrameSenderConfig* config) { |
106 cast_params->codec_name = ext_params.codec_name; | 99 config->sender_ssrc = ext_params.ssrc; |
107 cast_params->ssrc = ext_params.ssrc; | 100 config->receiver_ssrc = ext_params.feedback_ssrc; |
108 cast_params->feedback_ssrc = ext_params.feedback_ssrc; | 101 if (config->sender_ssrc == config->receiver_ssrc) { |
109 cast_params->clock_rate = ext_params.clock_rate ? *ext_params.clock_rate : 0; | 102 DVLOG(1) << "sender_ssrc " << config->sender_ssrc |
110 cast_params->min_bitrate = | 103 << " cannot be equal to receiver_ssrc"; |
111 ext_params.min_bitrate ? *ext_params.min_bitrate : 0; | 104 isolate->ThrowException(v8::Exception::Error( |
112 cast_params->max_bitrate = | 105 v8::String::NewFromUtf8(isolate, kInvalidRtpParams))); |
113 ext_params.max_bitrate ? *ext_params.max_bitrate : 0; | 106 return false; |
114 cast_params->channels = ext_params.channels ? *ext_params.channels : 0; | 107 } |
115 cast_params->max_frame_rate = | 108 config->min_playout_delay = base::TimeDelta::FromMilliseconds( |
116 ext_params.max_frame_rate ? *ext_params.max_frame_rate : 0.0; | 109 ext_params.min_latency ? *ext_params.min_latency |
117 if (ext_params.aes_key && | 110 : ext_params.max_latency); |
118 !HexDecode(*ext_params.aes_key, &cast_params->aes_key)) { | 111 config->max_playout_delay = |
112 base::TimeDelta::FromMilliseconds(ext_params.max_latency); | |
113 config->animated_playout_delay = base::TimeDelta::FromMilliseconds( | |
114 ext_params.animated_latency ? *ext_params.animated_latency | |
115 : ext_params.max_latency); | |
116 if (config->min_playout_delay <= base::TimeDelta()) { | |
117 DVLOG(1) << "min_playout_delay " << config->min_playout_delay | |
miu
2016/06/30 21:59:42
nit: Let's say "must be greater than zero" rather
xjz
2016/07/01 23:52:09
Done.
| |
118 << " is too small"; | |
119 isolate->ThrowException(v8::Exception::Error( | |
120 v8::String::NewFromUtf8(isolate, kInvalidRtpParams))); | |
121 return false; | |
122 } | |
123 if (config->min_playout_delay > config->max_playout_delay) { | |
124 DVLOG(1) << "min_playout_delay " << config->min_playout_delay | |
miu
2016/06/30 21:59:42
nit: Let's say "must be less than max playout dela
xjz
2016/07/01 23:52:09
Done.
| |
125 << " is too big"; | |
126 isolate->ThrowException(v8::Exception::Error( | |
127 v8::String::NewFromUtf8(isolate, kInvalidRtpParams))); | |
128 return false; | |
129 } | |
130 if (config->animated_playout_delay < config->min_playout_delay || | |
131 config->animated_playout_delay > config->max_playout_delay) { | |
132 DVLOG(1) << "animated_playout_delay " << config->animated_playout_delay | |
133 << " is out of range"; | |
miu
2016/06/30 21:59:42
nit: Let's say "must be between (inclusive) the mi
xjz
2016/07/01 23:52:09
Done.
| |
134 isolate->ThrowException(v8::Exception::Error( | |
135 v8::String::NewFromUtf8(isolate, kInvalidRtpParams))); | |
136 return false; | |
137 } | |
138 config->min_bitrate = ext_params.min_bitrate | |
139 ? (*ext_params.min_bitrate) * kBitrateMultiplier | |
140 : 0; | |
141 config->max_bitrate = ext_params.max_bitrate | |
142 ? (*ext_params.max_bitrate) * kBitrateMultiplier | |
143 : 0; | |
miu
2016/06/30 21:59:42
Instead of 0, can the default be kDefaultMaxVideoK
xjz
2016/07/01 23:52:08
Done.
| |
144 config->channels = ext_params.channels ? *ext_params.channels : 0; | |
miu
2016/06/30 21:59:42
Let's default this to 1 for video and 2 for audio.
xjz
2016/07/01 23:52:09
Done.
| |
145 config->frequency = ext_params.clock_rate ? *ext_params.clock_rate : 0; | |
miu
2016/06/30 21:59:42
Let's default this to kDefaultAudioSamplingRate.
xjz
2016/07/01 23:52:08
Done.
| |
146 if (ext_params.codec_name == kCodecNameOpus) { | |
147 config->rtp_payload_type = media::cast::RtpPayloadType::AUDIO_OPUS; | |
148 config->codec = media::cast::CODEC_AUDIO_OPUS; | |
149 config->use_external_encoder = false; | |
150 config->min_bitrate = config->max_bitrate; | |
miu
2016/06/30 21:59:42
also: config->start_bitrate = config->max_bitrate
xjz
2016/07/01 23:52:08
Done.
| |
151 // Sampling rate must be one of the Opus-supported values. | |
152 switch (config->frequency) { | |
153 case 48000: | |
154 case 24000: | |
155 case 16000: | |
156 case 12000: | |
157 case 8000: | |
158 break; | |
159 default: | |
160 DVLOG(1) << "frequency " << config->frequency << " is invalid"; | |
161 isolate->ThrowException(v8::Exception::Error( | |
162 v8::String::NewFromUtf8(isolate, kInvalidRtpParams))); | |
163 return false; | |
164 } | |
165 if (config->channels < 1) { | |
166 isolate->ThrowException(v8::Exception::Error( | |
167 v8::String::NewFromUtf8(isolate, kInvalidRtpParams))); | |
168 DVLOG(1) << "channels " << config->channels << " is invalid"; | |
169 return false; | |
170 } | |
miu
2016/06/30 21:59:42
Also for Opus: Let's set config->max_frame_rate to
xjz
2016/07/01 23:52:08
Done.
| |
171 } else if (ext_params.codec_name == kCodecNameVp8 || | |
172 ext_params.codec_name == kCodecNameH264) { | |
173 config->frequency = media::cast::kVideoFrequency; | |
174 if (config->min_bitrate > config->max_bitrate) { | |
175 DVLOG(1) << "min_bitrate " << config->min_bitrate << " is larger than " | |
176 << "max_bitrate " << config->max_bitrate; | |
177 isolate->ThrowException(v8::Exception::Error( | |
178 v8::String::NewFromUtf8(isolate, kInvalidRtpParams))); | |
179 return false; | |
180 } | |
181 config->codec_specific_params.start_bitrate = config->min_bitrate; | |
182 config->max_frame_rate = std::max( | |
183 1.0, ext_params.max_frame_rate ? *ext_params.max_frame_rate : 0.0); | |
184 if (config->max_frame_rate > media::limits::kMaxFramesPerSecond) { | |
185 DVLOG(1) << "max_frame_rate " << config->max_frame_rate << " is invalid"; | |
186 isolate->ThrowException(v8::Exception::Error( | |
187 v8::String::NewFromUtf8(isolate, kInvalidRtpParams))); | |
188 return false; | |
189 } | |
190 if (ext_params.codec_name == kCodecNameVp8) { | |
191 config->rtp_payload_type = media::cast::RtpPayloadType::VIDEO_VP8; | |
192 config->codec = media::cast::CODEC_VIDEO_VP8; | |
193 config->use_external_encoder = | |
194 CastRtpStream::IsHardwareVP8EncodingSupported(); | |
195 } else { | |
196 config->rtp_payload_type = media::cast::RtpPayloadType::VIDEO_H264; | |
197 config->codec = media::cast::CODEC_VIDEO_H264; | |
198 config->use_external_encoder = | |
199 CastRtpStream::IsHardwareH264EncodingSupported(); | |
200 } | |
201 if (!config->use_external_encoder) | |
202 config->codec_specific_params.number_of_encode_threads = | |
203 NumberOfEncodeThreads(); | |
204 } else { | |
205 DVLOG(1) << "codec_name " << ext_params.codec_name << " is invalid"; | |
206 isolate->ThrowException(v8::Exception::Error( | |
207 v8::String::NewFromUtf8(isolate, kInvalidRtpParams))); | |
208 return false; | |
209 } | |
210 if (ext_params.aes_key && !HexDecode(*ext_params.aes_key, &config->aes_key)) { | |
119 isolate->ThrowException(v8::Exception::Error( | 211 isolate->ThrowException(v8::Exception::Error( |
120 v8::String::NewFromUtf8(isolate, kInvalidAesKey))); | 212 v8::String::NewFromUtf8(isolate, kInvalidAesKey))); |
121 return false; | 213 return false; |
122 } | 214 } |
123 if (ext_params.aes_iv_mask && | 215 if (ext_params.aes_iv_mask && |
124 !HexDecode(*ext_params.aes_iv_mask, &cast_params->aes_iv_mask)) { | 216 !HexDecode(*ext_params.aes_iv_mask, &config->aes_iv_mask)) { |
125 isolate->ThrowException(v8::Exception::Error( | 217 isolate->ThrowException(v8::Exception::Error( |
126 v8::String::NewFromUtf8(isolate, kInvalidAesIvMask))); | 218 v8::String::NewFromUtf8(isolate, kInvalidAesIvMask))); |
127 return false; | 219 return false; |
128 } | 220 } |
129 for (size_t i = 0; i < ext_params.codec_specific_params.size(); ++i) { | |
130 CastCodecSpecificParams cast_codec_params; | |
131 ToCastCodecSpecificParams(ext_params.codec_specific_params[i], | |
132 &cast_codec_params); | |
133 cast_params->codec_specific_params.push_back(cast_codec_params); | |
134 } | |
135 return true; | |
136 } | |
137 | |
138 void FromCastRtpPayloadParams(const CastRtpPayloadParams& cast_params, | |
139 RtpPayloadParams* ext_params) { | |
140 ext_params->payload_type = cast_params.payload_type; | |
141 ext_params->max_latency = cast_params.max_latency_ms; | |
142 ext_params->min_latency.reset(new int(cast_params.min_latency_ms)); | |
143 ext_params->animated_latency.reset(new int(cast_params.animated_latency_ms)); | |
144 ext_params->codec_name = cast_params.codec_name; | |
145 ext_params->ssrc = cast_params.ssrc; | |
146 ext_params->feedback_ssrc = cast_params.feedback_ssrc; | |
147 if (cast_params.clock_rate) | |
148 ext_params->clock_rate.reset(new int(cast_params.clock_rate)); | |
149 if (cast_params.min_bitrate) | |
150 ext_params->min_bitrate.reset(new int(cast_params.min_bitrate)); | |
151 if (cast_params.max_bitrate) | |
152 ext_params->max_bitrate.reset(new int(cast_params.max_bitrate)); | |
153 if (cast_params.channels) | |
154 ext_params->channels.reset(new int(cast_params.channels)); | |
155 if (cast_params.max_frame_rate > 0.0) | |
156 ext_params->max_frame_rate.reset(new double(cast_params.max_frame_rate)); | |
157 for (size_t i = 0; i < cast_params.codec_specific_params.size(); ++i) { | |
158 CodecSpecificParams ext_codec_params; | |
159 FromCastCodecSpecificParams(cast_params.codec_specific_params[i], | |
160 &ext_codec_params); | |
161 ext_params->codec_specific_params.push_back(std::move(ext_codec_params)); | |
162 } | |
163 } | |
164 | |
165 void FromCastRtpParams(const CastRtpParams& cast_params, | |
166 RtpParams* ext_params) { | |
167 std::copy(cast_params.rtcp_features.begin(), | |
168 cast_params.rtcp_features.end(), | |
169 std::back_inserter(ext_params->rtcp_features)); | |
170 FromCastRtpPayloadParams(cast_params.payload, &ext_params->payload); | |
171 } | |
172 | |
173 bool ToCastRtpParamsOrThrow(v8::Isolate* isolate, | |
174 const RtpParams& ext_params, | |
175 CastRtpParams* cast_params) { | |
176 std::copy(ext_params.rtcp_features.begin(), | |
177 ext_params.rtcp_features.end(), | |
178 std::back_inserter(cast_params->rtcp_features)); | |
179 if (!ToCastRtpPayloadParamsOrThrow(isolate, | |
180 ext_params.payload, | |
181 &cast_params->payload)) { | |
182 return false; | |
183 } | |
184 return true; | 221 return true; |
185 } | 222 } |
186 | 223 |
224 void FromFrameSenderConfig(const FrameSenderConfig& config, | |
225 RtpPayloadParams* ext_params) { | |
226 ext_params->payload_type = static_cast<int>(config.rtp_payload_type); | |
227 ext_params->max_latency = config.max_playout_delay.InMilliseconds(); | |
228 ext_params->min_latency.reset( | |
229 new int(config.min_playout_delay.InMilliseconds())); | |
230 ext_params->animated_latency.reset( | |
231 new int(config.animated_playout_delay.InMilliseconds())); | |
232 if (config.codec == media::cast::CODEC_AUDIO_OPUS) | |
miu
2016/06/30 21:59:42
With this if...elseif...else statement: I'm thinki
xjz
2016/07/01 23:52:08
Done.
| |
233 ext_params->codec_name = kCodecNameOpus; | |
234 else if (config.codec == media::cast::CODEC_VIDEO_VP8) | |
235 ext_params->codec_name = kCodecNameVp8; | |
236 else | |
237 ext_params->codec_name = kCodecNameH264; | |
238 ext_params->ssrc = config.sender_ssrc; | |
239 ext_params->feedback_ssrc = config.receiver_ssrc; | |
240 if (config.frequency) | |
241 ext_params->clock_rate.reset(new int(config.frequency)); | |
242 if (config.min_bitrate) | |
243 ext_params->min_bitrate.reset(new int(config.min_bitrate)); | |
244 if (config.max_bitrate) | |
245 ext_params->max_bitrate.reset(new int(config.max_bitrate)); | |
246 if (config.channels) | |
247 ext_params->channels.reset(new int(config.channels)); | |
248 if (config.max_frame_rate > 0.0) | |
249 ext_params->max_frame_rate.reset(new double(config.max_frame_rate)); | |
250 } | |
251 | |
187 } // namespace | 252 } // namespace |
188 | 253 |
189 CastStreamingNativeHandler::CastStreamingNativeHandler(ScriptContext* context) | 254 CastStreamingNativeHandler::CastStreamingNativeHandler(ScriptContext* context) |
190 : ObjectBackedNativeHandler(context), | 255 : ObjectBackedNativeHandler(context), |
191 last_transport_id_(1), | 256 last_transport_id_(1), |
192 weak_factory_(this) { | 257 weak_factory_(this) { |
193 RouteFunction("CreateSession", "cast.streaming.session", | 258 RouteFunction("CreateSession", "cast.streaming.session", |
194 base::Bind(&CastStreamingNativeHandler::CreateCastSession, | 259 base::Bind(&CastStreamingNativeHandler::CreateCastSession, |
195 weak_factory_.GetWeakPtr())); | 260 weak_factory_.GetWeakPtr())); |
196 RouteFunction("DestroyCastRtpStream", "cast.streaming.rtpStream", | 261 RouteFunction("DestroyCastRtpStream", "cast.streaming.rtpStream", |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
382 const v8::FunctionCallbackInfo<v8::Value>& args) const { | 447 const v8::FunctionCallbackInfo<v8::Value>& args) const { |
383 CHECK_EQ(1, args.Length()); | 448 CHECK_EQ(1, args.Length()); |
384 CHECK(args[0]->IsInt32()); | 449 CHECK(args[0]->IsInt32()); |
385 | 450 |
386 const int transport_id = args[0]->ToInt32(args.GetIsolate())->Value(); | 451 const int transport_id = args[0]->ToInt32(args.GetIsolate())->Value(); |
387 CastRtpStream* transport = GetRtpStreamOrThrow(transport_id); | 452 CastRtpStream* transport = GetRtpStreamOrThrow(transport_id); |
388 if (!transport) | 453 if (!transport) |
389 return; | 454 return; |
390 | 455 |
391 std::unique_ptr<V8ValueConverter> converter(V8ValueConverter::create()); | 456 std::unique_ptr<V8ValueConverter> converter(V8ValueConverter::create()); |
392 std::vector<CastRtpParams> cast_params = transport->GetSupportedParams(); | 457 std::vector<FrameSenderConfig> configs = transport->GetSupportedConfigs(); |
393 v8::Local<v8::Array> result = | 458 v8::Local<v8::Array> result = |
394 v8::Array::New(args.GetIsolate(), | 459 v8::Array::New(args.GetIsolate(), static_cast<int>(configs.size())); |
395 static_cast<int>(cast_params.size())); | 460 for (size_t i = 0; i < configs.size(); ++i) { |
396 for (size_t i = 0; i < cast_params.size(); ++i) { | |
397 RtpParams params; | 461 RtpParams params; |
398 FromCastRtpParams(cast_params[i], ¶ms); | 462 FromFrameSenderConfig(configs[i], ¶ms.payload); |
399 std::unique_ptr<base::DictionaryValue> params_value = params.ToValue(); | 463 std::unique_ptr<base::DictionaryValue> params_value = params.ToValue(); |
400 result->Set( | 464 result->Set( |
401 static_cast<int>(i), | 465 static_cast<int>(i), |
402 converter->ToV8Value(params_value.get(), context()->v8_context())); | 466 converter->ToV8Value(params_value.get(), context()->v8_context())); |
403 } | 467 } |
404 args.GetReturnValue().Set(result); | 468 args.GetReturnValue().Set(result); |
405 } | 469 } |
406 | 470 |
407 void CastStreamingNativeHandler::StartCastRtpStream( | 471 void CastStreamingNativeHandler::StartCastRtpStream( |
408 const v8::FunctionCallbackInfo<v8::Value>& args) { | 472 const v8::FunctionCallbackInfo<v8::Value>& args) { |
(...skipping 14 matching lines...) Expand all Loading... | |
423 v8::String::NewFromUtf8(args.GetIsolate(), kUnableToConvertParams))); | 487 v8::String::NewFromUtf8(args.GetIsolate(), kUnableToConvertParams))); |
424 return; | 488 return; |
425 } | 489 } |
426 std::unique_ptr<RtpParams> params = RtpParams::FromValue(*params_value); | 490 std::unique_ptr<RtpParams> params = RtpParams::FromValue(*params_value); |
427 if (!params) { | 491 if (!params) { |
428 args.GetIsolate()->ThrowException(v8::Exception::TypeError( | 492 args.GetIsolate()->ThrowException(v8::Exception::TypeError( |
429 v8::String::NewFromUtf8(args.GetIsolate(), kInvalidRtpParams))); | 493 v8::String::NewFromUtf8(args.GetIsolate(), kInvalidRtpParams))); |
430 return; | 494 return; |
431 } | 495 } |
432 | 496 |
433 CastRtpParams cast_params; | 497 FrameSenderConfig config; |
434 v8::Isolate* isolate = context()->v8_context()->GetIsolate(); | 498 v8::Isolate* isolate = context()->v8_context()->GetIsolate(); |
435 if (!ToCastRtpParamsOrThrow(isolate, *params, &cast_params)) | 499 if (!ToFrameSenderConfigOrThrow(isolate, params->payload, &config)) |
436 return; | 500 return; |
437 | 501 |
438 base::Closure start_callback = | 502 base::Closure start_callback = |
439 base::Bind(&CastStreamingNativeHandler::CallStartCallback, | 503 base::Bind(&CastStreamingNativeHandler::CallStartCallback, |
440 weak_factory_.GetWeakPtr(), | 504 weak_factory_.GetWeakPtr(), |
441 transport_id); | 505 transport_id); |
442 base::Closure stop_callback = | 506 base::Closure stop_callback = |
443 base::Bind(&CastStreamingNativeHandler::CallStopCallback, | 507 base::Bind(&CastStreamingNativeHandler::CallStopCallback, |
444 weak_factory_.GetWeakPtr(), | 508 weak_factory_.GetWeakPtr(), |
445 transport_id); | 509 transport_id); |
446 CastRtpStream::ErrorCallback error_callback = | 510 CastRtpStream::ErrorCallback error_callback = |
447 base::Bind(&CastStreamingNativeHandler::CallErrorCallback, | 511 base::Bind(&CastStreamingNativeHandler::CallErrorCallback, |
448 weak_factory_.GetWeakPtr(), | 512 weak_factory_.GetWeakPtr(), |
449 transport_id); | 513 transport_id); |
450 transport->Start(cast_params, start_callback, stop_callback, error_callback); | 514 transport->Start(config, start_callback, stop_callback, error_callback); |
451 } | 515 } |
452 | 516 |
453 void CastStreamingNativeHandler::StopCastRtpStream( | 517 void CastStreamingNativeHandler::StopCastRtpStream( |
454 const v8::FunctionCallbackInfo<v8::Value>& args) { | 518 const v8::FunctionCallbackInfo<v8::Value>& args) { |
455 CHECK_EQ(1, args.Length()); | 519 CHECK_EQ(1, args.Length()); |
456 CHECK(args[0]->IsInt32()); | 520 CHECK(args[0]->IsInt32()); |
457 | 521 |
458 const int transport_id = args[0]->ToInt32(args.GetIsolate())->Value(); | 522 const int transport_id = args[0]->ToInt32(args.GetIsolate())->Value(); |
459 CastRtpStream* transport = GetRtpStreamOrThrow(transport_id); | 523 CastRtpStream* transport = GetRtpStreamOrThrow(transport_id); |
460 if (!transport) | 524 if (!transport) |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
669 config->rtp_max_delay_ms = params->max_latency; | 733 config->rtp_max_delay_ms = params->max_latency; |
670 if (config->rtp_max_delay_ms < 0 || config->rtp_max_delay_ms > 1000) { | 734 if (config->rtp_max_delay_ms < 0 || config->rtp_max_delay_ms > 1000) { |
671 isolate->ThrowException(v8::Exception::TypeError( | 735 isolate->ThrowException(v8::Exception::TypeError( |
672 v8::String::NewFromUtf8(isolate, kInvalidLatency))); | 736 v8::String::NewFromUtf8(isolate, kInvalidLatency))); |
673 return false; | 737 return false; |
674 } | 738 } |
675 config->channels = 2; | 739 config->channels = 2; |
676 if (params->codec_name == "OPUS") { | 740 if (params->codec_name == "OPUS") { |
677 config->codec = media::cast::CODEC_AUDIO_OPUS; | 741 config->codec = media::cast::CODEC_AUDIO_OPUS; |
678 config->rtp_timebase = 48000; | 742 config->rtp_timebase = 48000; |
679 config->rtp_payload_type = media::cast::kDefaultRtpAudioPayloadType; | 743 config->rtp_payload_type = media::cast::RtpPayloadType::AUDIO_OPUS; |
680 } else if (params->codec_name == "PCM16") { | 744 } else if (params->codec_name == "PCM16") { |
681 config->codec = media::cast::CODEC_AUDIO_PCM16; | 745 config->codec = media::cast::CODEC_AUDIO_PCM16; |
682 config->rtp_timebase = 48000; | 746 config->rtp_timebase = 48000; |
683 config->rtp_payload_type = media::cast::kDefaultRtpAudioPayloadType; | 747 config->rtp_payload_type = media::cast::RtpPayloadType::AUDIO_PCM16; |
684 } else if (params->codec_name == "AAC") { | 748 } else if (params->codec_name == "AAC") { |
685 config->codec = media::cast::CODEC_AUDIO_AAC; | 749 config->codec = media::cast::CODEC_AUDIO_AAC; |
686 config->rtp_timebase = 48000; | 750 config->rtp_timebase = 48000; |
687 config->rtp_payload_type = media::cast::kDefaultRtpAudioPayloadType; | 751 config->rtp_payload_type = media::cast::RtpPayloadType::AUDIO_AAC; |
688 } else if (params->codec_name == "VP8") { | 752 } else if (params->codec_name == "VP8") { |
689 config->codec = media::cast::CODEC_VIDEO_VP8; | 753 config->codec = media::cast::CODEC_VIDEO_VP8; |
690 config->rtp_timebase = 90000; | 754 config->rtp_timebase = 90000; |
691 config->rtp_payload_type = media::cast::kDefaultRtpVideoPayloadType; | 755 config->rtp_payload_type = media::cast::RtpPayloadType::VIDEO_VP8; |
692 } else if (params->codec_name == "H264") { | 756 } else if (params->codec_name == "H264") { |
693 config->codec = media::cast::CODEC_VIDEO_H264; | 757 config->codec = media::cast::CODEC_VIDEO_H264; |
694 config->rtp_timebase = 90000; | 758 config->rtp_timebase = 90000; |
695 config->rtp_payload_type = media::cast::kDefaultRtpVideoPayloadType; | 759 config->rtp_payload_type = media::cast::RtpPayloadType::VIDEO_H264; |
696 } | 760 } |
697 if (params->rtp_timebase) { | 761 if (params->rtp_timebase) { |
698 config->rtp_timebase = *params->rtp_timebase; | 762 config->rtp_timebase = *params->rtp_timebase; |
699 if (config->rtp_timebase < 1000 || config->rtp_timebase > 1000000) { | 763 if (config->rtp_timebase < 1000 || config->rtp_timebase > 1000000) { |
700 isolate->ThrowException(v8::Exception::TypeError( | 764 isolate->ThrowException(v8::Exception::TypeError( |
701 v8::String::NewFromUtf8(isolate, kInvalidRtpTimebase))); | 765 v8::String::NewFromUtf8(isolate, kInvalidRtpTimebase))); |
702 return false; | 766 return false; |
703 } | 767 } |
704 } | 768 } |
705 if (params->aes_key && | 769 if (params->aes_key && |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
877 LOG(ERROR) << "Failed to add Cast audio track to media stream."; | 941 LOG(ERROR) << "Failed to add Cast audio track to media stream."; |
878 } | 942 } |
879 if (!content::AddVideoTrackToMediaStream(std::move(video), true, // is_remote | 943 if (!content::AddVideoTrackToMediaStream(std::move(video), true, // is_remote |
880 true, // is_readonly | 944 true, // is_readonly |
881 &web_stream)) { | 945 &web_stream)) { |
882 LOG(ERROR) << "Failed to add Cast video track to media stream."; | 946 LOG(ERROR) << "Failed to add Cast video track to media stream."; |
883 } | 947 } |
884 } | 948 } |
885 | 949 |
886 } // namespace extensions | 950 } // namespace extensions |
OLD | NEW |