| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "content/renderer/media/media_stream_video_source.h" | 5 #include "content/renderer/media/media_stream_video_source.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
| 12 #include "content/renderer/media/media_stream_dependency_factory.h" | 12 #include "content/renderer/media/media_stream_dependency_factory.h" |
| 13 #include "content/renderer/media/media_stream_video_track.h" |
| 13 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h" | 14 #include "content/renderer/media/webrtc/webrtc_video_capturer_adapter.h" |
| 14 | 15 |
| 15 namespace content { | 16 namespace content { |
| 16 | 17 |
| 17 // Constraint keys. Specified by draft-alvestrand-constraints-resolution-00b | 18 // Constraint keys. Specified by draft-alvestrand-constraints-resolution-00b |
| 18 const char MediaStreamVideoSource::kMinAspectRatio[] = "minAspectRatio"; | 19 const char MediaStreamVideoSource::kMinAspectRatio[] = "minAspectRatio"; |
| 19 const char MediaStreamVideoSource::kMaxAspectRatio[] = "maxAspectRatio"; | 20 const char MediaStreamVideoSource::kMaxAspectRatio[] = "maxAspectRatio"; |
| 20 const char MediaStreamVideoSource::kMaxWidth[] = "maxWidth"; | 21 const char MediaStreamVideoSource::kMaxWidth[] = "maxWidth"; |
| 21 const char MediaStreamVideoSource::kMinWidth[] = "minWidth"; | 22 const char MediaStreamVideoSource::kMinWidth[] = "minWidth"; |
| 22 const char MediaStreamVideoSource::kMaxHeight[] = "maxHeight"; | 23 const char MediaStreamVideoSource::kMaxHeight[] = "maxHeight"; |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 if (diff < best_diff) { | 208 if (diff < best_diff) { |
| 208 best_diff = diff; | 209 best_diff = diff; |
| 209 best_it = it; | 210 best_it = it; |
| 210 } | 211 } |
| 211 } | 212 } |
| 212 return *best_it; | 213 return *best_it; |
| 213 } | 214 } |
| 214 | 215 |
| 215 } // anonymous namespace | 216 } // anonymous namespace |
| 216 | 217 |
| 218 // static |
| 219 MediaStreamVideoSource* MediaStreamVideoSource::GetVideoSource( |
| 220 const blink::WebMediaStreamSource& source) { |
| 221 return static_cast<MediaStreamVideoSource*>(source.extraData()); |
| 222 } |
| 223 |
| 217 MediaStreamVideoSource::MediaStreamVideoSource( | 224 MediaStreamVideoSource::MediaStreamVideoSource( |
| 218 MediaStreamDependencyFactory* factory) | 225 MediaStreamDependencyFactory* factory) |
| 219 : state_(NEW), | 226 : state_(NEW), |
| 220 factory_(factory), | 227 factory_(factory), |
| 221 capture_adapter_(NULL) { | 228 capture_adapter_(NULL) { |
| 222 DCHECK(factory_); | 229 DCHECK(factory_); |
| 223 } | 230 } |
| 224 | 231 |
| 225 MediaStreamVideoSource::~MediaStreamVideoSource() { | 232 MediaStreamVideoSource::~MediaStreamVideoSource() { |
| 226 } | 233 } |
| 227 | 234 |
| 228 void MediaStreamVideoSource::AddTrack( | 235 void MediaStreamVideoSource::AddTrack( |
| 229 const blink::WebMediaStreamTrack& track, | 236 MediaStreamVideoTrack* track, |
| 230 const blink::WebMediaConstraints& constraints, | 237 const blink::WebMediaConstraints& constraints, |
| 231 const ConstraintsCallback& callback) { | 238 const ConstraintsCallback& callback) { |
| 232 DCHECK(CalledOnValidThread()); | 239 DCHECK(CalledOnValidThread()); |
| 233 requested_constraints_.push_back(RequestedConstraints(constraints, | 240 DCHECK(std::find(tracks_.begin(), tracks_.end(), |
| 234 callback)); | 241 track) == tracks_.end()); |
| 242 tracks_.push_back(track); |
| 243 |
| 244 requested_constraints_.push_back( |
| 245 RequestedConstraints(constraints, callback)); |
| 246 |
| 235 switch (state_) { | 247 switch (state_) { |
| 236 case NEW: { | 248 case NEW: { |
| 237 // Tab capture and Screen capture needs the maximum requested height | 249 // Tab capture and Screen capture needs the maximum requested height |
| 238 // and width to decide on the resolution. | 250 // and width to decide on the resolution. |
| 239 blink::WebString max_width; | 251 blink::WebString max_width; |
| 240 int max_requested_width = 0; | 252 int max_requested_width = 0; |
| 241 if (constraints.getMandatoryConstraintValue(kMaxWidth, max_width)) | 253 if (constraints.getMandatoryConstraintValue(kMaxWidth, max_width)) |
| 242 base::StringToInt(max_width.utf8(), &max_requested_width); | 254 base::StringToInt(max_width.utf8(), &max_requested_width); |
| 243 | 255 |
| 244 int max_requested_height = 0; | 256 int max_requested_height = 0; |
| 245 blink::WebString max_height; | 257 blink::WebString max_height; |
| 246 if (constraints.getMandatoryConstraintValue(kMaxHeight, max_height)) | 258 if (constraints.getMandatoryConstraintValue(kMaxHeight, max_height)) |
| 247 base::StringToInt(max_height.utf8(), &max_requested_height); | 259 base::StringToInt(max_height.utf8(), &max_requested_height); |
| 248 | 260 |
| 249 state_ = RETRIEVING_CAPABILITIES; | 261 state_ = RETRIEVING_CAPABILITIES; |
| 250 GetCurrentSupportedFormats(max_requested_width, | 262 GetCurrentSupportedFormats(max_requested_width, |
| 251 max_requested_height); | 263 max_requested_height); |
| 252 | 264 |
| 253 break; | 265 break; |
| 254 } | 266 } |
| 255 case STARTING: | 267 case STARTING: |
| 256 case RETRIEVING_CAPABILITIES: { | 268 case RETRIEVING_CAPABILITIES: { |
| 257 // The |callback| will be triggered once the delegate has started or | 269 // The |callback| will be triggered once the source has started or |
| 258 // the capabilitites has been retrieved. | 270 // the capabilities has been retrieved. |
| 259 break; | 271 break; |
| 260 } | 272 } |
| 261 case ENDED: | 273 case ENDED: |
| 262 case STARTED: { | 274 case STARTED: { |
| 263 // Currently, reconfiguring the source is not supported. | 275 // Currently, reconfiguring the source is not supported. |
| 264 FinalizeAddTrack(); | 276 FinalizeAddTrack(); |
| 265 } | 277 } |
| 266 } | 278 } |
| 267 } | 279 } |
| 268 | 280 |
| 269 void MediaStreamVideoSource::RemoveTrack( | 281 void MediaStreamVideoSource::RemoveTrack(MediaStreamVideoTrack* video_track) { |
| 270 const blink::WebMediaStreamTrack& track) { | 282 std::vector<MediaStreamVideoTrack*>::iterator it = |
| 271 // TODO(ronghuawu): What should be done here? Do we really need RemoveTrack? | 283 std::find(tracks_.begin(), tracks_.end(), video_track); |
| 284 DCHECK(it != tracks_.end()); |
| 285 tracks_.erase(it); |
| 272 } | 286 } |
| 273 | 287 |
| 274 void MediaStreamVideoSource::InitAdapter() { | 288 void MediaStreamVideoSource::InitAdapter() { |
| 275 if (adapter_) | 289 if (adapter_) |
| 276 return; | 290 return; |
| 277 // Create the webrtc::MediaStreamVideoSourceInterface adapter. | 291 // Create the webrtc::MediaStreamVideoSourceInterface adapter. |
| 278 // It needs the constraints so that constraints used by a PeerConnection | 292 // It needs the constraints so that constraints used by a PeerConnection |
| 279 // will be available such as constraints for CPU adaptation and a tab | 293 // will be available such as constraints for CPU adaptation and a tab |
| 280 // capture. | 294 // capture. |
| 281 bool is_screeencast = | 295 bool is_screeencast = |
| 282 device_info().device.type == MEDIA_TAB_VIDEO_CAPTURE || | 296 device_info().device.type == MEDIA_TAB_VIDEO_CAPTURE || |
| 283 device_info().device.type == MEDIA_DESKTOP_VIDEO_CAPTURE; | 297 device_info().device.type == MEDIA_DESKTOP_VIDEO_CAPTURE; |
| 284 capture_adapter_ = factory_->CreateVideoCapturer(is_screeencast); | 298 capture_adapter_ = factory_->CreateVideoCapturer(is_screeencast); |
| 285 capture_adapter_->SetRequestedFormat(current_format_); | 299 capture_adapter_->SetRequestedFormat(current_format_); |
| 286 adapter_ = factory_->CreateVideoSource(capture_adapter_, | 300 adapter_ = factory_->CreateVideoSource(capture_adapter_, |
| 287 current_constraints_); | 301 current_constraints_); |
| 288 } | 302 } |
| 289 | 303 |
| 290 webrtc::VideoSourceInterface* MediaStreamVideoSource::GetAdapter() { | 304 webrtc::VideoSourceInterface* MediaStreamVideoSource::GetAdapter() { |
| 291 if (!adapter_) { | 305 if (!adapter_) { |
| 292 InitAdapter(); | 306 InitAdapter(); |
| 293 } | 307 } |
| 294 return adapter_; | 308 return adapter_; |
| 295 } | 309 } |
| 296 | 310 |
| 297 void MediaStreamVideoSource::DoStopSource() { | 311 void MediaStreamVideoSource::DoStopSource() { |
| 298 DVLOG(3) << "DoStopSource()"; | 312 DVLOG(3) << "DoStopSource()"; |
| 299 StopSourceImpl(); | 313 StopSourceImpl(); |
| 300 state_ = ENDED; | 314 state_ = ENDED; |
| 315 SetReadyState(blink::WebMediaStreamSource::ReadyStateEnded); |
| 301 } | 316 } |
| 302 | 317 |
| 303 void MediaStreamVideoSource::DeliverVideoFrame( | 318 void MediaStreamVideoSource::DeliverVideoFrame( |
| 304 const scoped_refptr<media::VideoFrame>& frame) { | 319 const scoped_refptr<media::VideoFrame>& frame) { |
| 305 if (capture_adapter_) | 320 if (capture_adapter_) |
| 306 capture_adapter_->OnFrameCaptured(frame); | 321 capture_adapter_->OnFrameCaptured(frame); |
| 322 |
| 323 for (std::vector<MediaStreamVideoTrack*>::iterator it = tracks_.begin(); |
| 324 it != tracks_.end(); ++it) { |
| 325 (*it)->OnVideoFrame(frame); |
| 326 } |
| 307 } | 327 } |
| 308 | 328 |
| 309 void MediaStreamVideoSource::OnSupportedFormats( | 329 void MediaStreamVideoSource::OnSupportedFormats( |
| 310 const media::VideoCaptureFormats& formats) { | 330 const media::VideoCaptureFormats& formats) { |
| 311 DCHECK(CalledOnValidThread()); | 331 DCHECK(CalledOnValidThread()); |
| 312 DCHECK_EQ(RETRIEVING_CAPABILITIES, state_); | 332 DCHECK_EQ(RETRIEVING_CAPABILITIES, state_); |
| 313 | 333 |
| 314 supported_formats_ = formats; | 334 supported_formats_ = formats; |
| 315 if (!FindBestFormatWithConstraints(supported_formats_, ¤t_format_, | 335 if (!FindBestFormatWithConstraints(supported_formats_, ¤t_format_, |
| 316 ¤t_constraints_)) { | 336 ¤t_constraints_)) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 370 } | 390 } |
| 371 | 391 |
| 372 void MediaStreamVideoSource::FinalizeAddTrack() { | 392 void MediaStreamVideoSource::FinalizeAddTrack() { |
| 373 media::VideoCaptureFormats formats; | 393 media::VideoCaptureFormats formats; |
| 374 formats.push_back(current_format_); | 394 formats.push_back(current_format_); |
| 375 | 395 |
| 376 std::vector<RequestedConstraints> callbacks; | 396 std::vector<RequestedConstraints> callbacks; |
| 377 callbacks.swap(requested_constraints_); | 397 callbacks.swap(requested_constraints_); |
| 378 for (std::vector<RequestedConstraints>::iterator it = callbacks.begin(); | 398 for (std::vector<RequestedConstraints>::iterator it = callbacks.begin(); |
| 379 it != callbacks.end(); ++it) { | 399 it != callbacks.end(); ++it) { |
| 400 |
| 380 bool success = state_ == STARTED && | 401 bool success = state_ == STARTED && |
| 381 !FilterFormats(it->constraints, formats).empty(); | 402 !FilterFormats(it->constraints, formats).empty(); |
| 382 DVLOG(3) << "FinalizeAddTrack() success " << success; | 403 DVLOG(3) << "FinalizeAddTrack() success " << success; |
| 383 if (!it->callback.is_null()) | 404 if (!it->callback.is_null()) |
| 384 it->callback.Run(this, success); | 405 it->callback.Run(this, success); |
| 385 } | 406 } |
| 386 } | 407 } |
| 387 | 408 |
| 388 void MediaStreamVideoSource::SetReadyState( | 409 void MediaStreamVideoSource::SetReadyState( |
| 389 blink::WebMediaStreamSource::ReadyState state) { | 410 blink::WebMediaStreamSource::ReadyState state) { |
| 390 if (!owner().isNull()) { | 411 if (!owner().isNull()) { |
| 391 owner().setReadyState(state); | 412 owner().setReadyState(state); |
| 392 } | 413 } |
| 393 // TODO(perkj): Notify all registered tracks. | 414 for (std::vector<MediaStreamVideoTrack*>::iterator it = tracks_.begin(); |
| 415 it != tracks_.end(); ++it) { |
| 416 (*it)->OnReadyStateChanged(state); |
| 417 } |
| 394 } | 418 } |
| 395 | 419 |
| 396 MediaStreamVideoSource::RequestedConstraints::RequestedConstraints( | 420 MediaStreamVideoSource::RequestedConstraints::RequestedConstraints( |
| 397 const blink::WebMediaConstraints& constraints, | 421 const blink::WebMediaConstraints& constraints, |
| 398 const ConstraintsCallback& callback) | 422 const ConstraintsCallback& callback) |
| 399 : constraints(constraints), callback(callback) { | 423 : constraints(constraints), callback(callback) { |
| 400 } | 424 } |
| 401 | 425 |
| 402 MediaStreamVideoSource::RequestedConstraints::~RequestedConstraints() { | 426 MediaStreamVideoSource::RequestedConstraints::~RequestedConstraints() { |
| 403 } | 427 } |
| 404 | 428 |
| 405 } // namespace content | 429 } // namespace content |
| OLD | NEW |