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/pepper/pepper_media_stream_video_track_host.h" | 5 #include "content/renderer/pepper/pepper_media_stream_video_track_host.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/base64.h" | 9 #include "base/base64.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/macros.h" | 11 #include "base/macros.h" |
12 #include "base/rand_util.h" | 12 #include "base/rand_util.h" |
13 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
14 #include "content/renderer/media/media_stream_video_source.h" | |
15 #include "content/renderer/media/media_stream_video_track.h" | 14 #include "content/renderer/media/media_stream_video_track.h" |
16 #include "media/base/bind_to_current_loop.h" | 15 #include "media/base/bind_to_current_loop.h" |
17 #include "media/base/video_util.h" | 16 #include "media/base/video_util.h" |
18 #include "media/base/yuv_convert.h" | 17 #include "media/base/yuv_convert.h" |
19 #include "ppapi/c/pp_errors.h" | 18 #include "ppapi/c/pp_errors.h" |
20 #include "ppapi/c/ppb_media_stream_video_track.h" | 19 #include "ppapi/c/ppb_media_stream_video_track.h" |
21 #include "ppapi/c/ppb_video_frame.h" | 20 #include "ppapi/c/ppb_video_frame.h" |
22 #include "ppapi/host/dispatch_host_message.h" | 21 #include "ppapi/host/dispatch_host_message.h" |
23 #include "ppapi/host/host_message_context.h" | 22 #include "ppapi/host/host_message_context.h" |
24 #include "ppapi/proxy/ppapi_messages.h" | 23 #include "ppapi/proxy/ppapi_messages.h" |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 PP_Instance instance, | 227 PP_Instance instance, |
229 PP_Resource resource, | 228 PP_Resource resource, |
230 const blink::WebMediaStreamTrack& track) | 229 const blink::WebMediaStreamTrack& track) |
231 : PepperMediaStreamTrackHostBase(host, instance, resource), | 230 : PepperMediaStreamTrackHostBase(host, instance, resource), |
232 track_(track), | 231 track_(track), |
233 number_of_buffers_(kDefaultNumberOfBuffers), | 232 number_of_buffers_(kDefaultNumberOfBuffers), |
234 source_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), | 233 source_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), |
235 plugin_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), | 234 plugin_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), |
236 frame_data_size_(0), | 235 frame_data_size_(0), |
237 type_(kRead), | 236 type_(kRead), |
| 237 output_started_(false), |
238 weak_factory_(this) { | 238 weak_factory_(this) { |
239 DCHECK(!track_.isNull()); | 239 DCHECK(!track_.isNull()); |
240 } | 240 } |
241 | 241 |
242 PepperMediaStreamVideoTrackHost::PepperMediaStreamVideoTrackHost( | 242 PepperMediaStreamVideoTrackHost::PepperMediaStreamVideoTrackHost( |
243 RendererPpapiHost* host, | 243 RendererPpapiHost* host, |
244 PP_Instance instance, | 244 PP_Instance instance, |
245 PP_Resource resource) | 245 PP_Resource resource) |
246 : PepperMediaStreamTrackHostBase(host, instance, resource), | 246 : PepperMediaStreamTrackHostBase(host, instance, resource), |
247 number_of_buffers_(kDefaultNumberOfBuffers), | 247 number_of_buffers_(kDefaultNumberOfBuffers), |
248 source_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), | 248 source_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), |
249 plugin_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), | 249 plugin_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), |
250 frame_data_size_(0), | 250 frame_data_size_(0), |
251 type_(kWrite), | 251 type_(kWrite), |
| 252 output_started_(false), |
252 weak_factory_(this) { | 253 weak_factory_(this) { |
253 InitBlinkTrack(); | 254 InitBlinkTrack(); |
254 DCHECK(!track_.isNull()); | 255 DCHECK(!track_.isNull()); |
255 } | 256 } |
256 | 257 |
257 PepperMediaStreamVideoTrackHost::~PepperMediaStreamVideoTrackHost() { | 258 PepperMediaStreamVideoTrackHost::~PepperMediaStreamVideoTrackHost() { |
258 OnClose(); | 259 OnClose(); |
259 } | 260 } |
260 | 261 |
261 bool PepperMediaStreamVideoTrackHost::IsMediaStreamVideoTrackHost() { | 262 bool PepperMediaStreamVideoTrackHost::IsMediaStreamVideoTrackHost() { |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 return PepperMediaStreamTrackHostBase::OnHostMsgEnqueueBuffer(context, | 315 return PepperMediaStreamTrackHostBase::OnHostMsgEnqueueBuffer(context, |
315 index); | 316 index); |
316 } else { | 317 } else { |
317 return SendFrameToTrack(index); | 318 return SendFrameToTrack(index); |
318 } | 319 } |
319 } | 320 } |
320 | 321 |
321 int32_t PepperMediaStreamVideoTrackHost::SendFrameToTrack(int32_t index) { | 322 int32_t PepperMediaStreamVideoTrackHost::SendFrameToTrack(int32_t index) { |
322 DCHECK_EQ(type_, kWrite); | 323 DCHECK_EQ(type_, kWrite); |
323 | 324 |
324 if (frame_deliverer_) { | 325 if (output_started_) { |
325 // Sends the frame to blink video track. | 326 // Sends the frame to blink video track. |
326 ppapi::MediaStreamBuffer::Video* pp_frame = | 327 ppapi::MediaStreamBuffer::Video* pp_frame = |
327 &(buffer_manager()->GetBufferPointer(index)->video); | 328 &(buffer_manager()->GetBufferPointer(index)->video); |
328 | 329 |
329 int32_t y_stride = plugin_frame_size_.width(); | 330 int32_t y_stride = plugin_frame_size_.width(); |
330 int32_t uv_stride = (plugin_frame_size_.width() + 1) / 2; | 331 int32_t uv_stride = (plugin_frame_size_.width() + 1) / 2; |
331 uint8_t* y_data = static_cast<uint8_t*>(pp_frame->data); | 332 uint8_t* y_data = static_cast<uint8_t*>(pp_frame->data); |
332 // Default to I420 | 333 // Default to I420 |
333 uint8_t* u_data = y_data + plugin_frame_size_.GetArea(); | 334 uint8_t* u_data = y_data + plugin_frame_size_.GetArea(); |
334 uint8_t* v_data = y_data + (plugin_frame_size_.GetArea() * 5 / 4); | 335 uint8_t* v_data = y_data + (plugin_frame_size_.GetArea() * 5 / 4); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 buffer->timestamp = frame->timestamp().InSecondsF(); | 403 buffer->timestamp = frame->timestamp().InSecondsF(); |
403 buffer->format = ppformat; | 404 buffer->format = ppformat; |
404 buffer->size.width = size.width(); | 405 buffer->size.width = size.width(); |
405 buffer->size.height = size.height(); | 406 buffer->size.height = size.height(); |
406 buffer->data_size = frame_data_size_; | 407 buffer->data_size = frame_data_size_; |
407 ConvertFromMediaVideoFrame(frame, ppformat, size, buffer->data); | 408 ConvertFromMediaVideoFrame(frame, ppformat, size, buffer->data); |
408 | 409 |
409 SendEnqueueBufferMessageToPlugin(index); | 410 SendEnqueueBufferMessageToPlugin(index); |
410 } | 411 } |
411 | 412 |
412 class PepperMediaStreamVideoTrackHost::VideoSource final | 413 void PepperMediaStreamVideoTrackHost::GetCurrentSupportedFormats( |
413 : public MediaStreamVideoSource { | 414 int max_requested_width, int max_requested_height, |
414 public: | 415 double max_requested_frame_rate, |
415 explicit VideoSource(base::WeakPtr<PepperMediaStreamVideoTrackHost> host) | 416 const VideoCaptureDeviceFormatsCB& callback) { |
416 : host_(std::move(host)) {} | 417 if (type_ != kWrite) { |
417 | 418 DVLOG(1) << "GetCurrentSupportedFormats is only supported in output mode."; |
418 ~VideoSource() final { StopSourceImpl(); } | 419 callback.Run(media::VideoCaptureFormats()); |
419 | 420 return; |
420 void GetCurrentSupportedFormats( | |
421 int max_requested_width, int max_requested_height, | |
422 double max_requested_frame_rate, | |
423 const VideoCaptureDeviceFormatsCB& callback) final { | |
424 media::VideoCaptureFormats formats; | |
425 if (host_) { | |
426 formats.push_back(media::VideoCaptureFormat( | |
427 host_->plugin_frame_size_, | |
428 kDefaultOutputFrameRate, | |
429 ToPixelFormat(host_->plugin_frame_format_))); | |
430 } | |
431 callback.Run(formats); | |
432 } | 421 } |
433 | 422 |
434 void StartSourceImpl( | 423 media::VideoCaptureFormats formats; |
435 const media::VideoCaptureFormat& format, | 424 formats.push_back( |
436 const blink::WebMediaConstraints& constraints, | 425 media::VideoCaptureFormat(plugin_frame_size_, |
437 const VideoCaptureDeliverFrameCB& frame_callback) final { | 426 kDefaultOutputFrameRate, |
438 if (host_) { | 427 ToPixelFormat(plugin_frame_format_))); |
439 host_->frame_deliverer_ = | 428 callback.Run(formats); |
440 new FrameDeliverer(io_task_runner(), frame_callback); | 429 } |
441 } | |
442 } | |
443 | 430 |
444 void StopSourceImpl() final { | 431 void PepperMediaStreamVideoTrackHost::StartSourceImpl( |
445 if (host_) | 432 const media::VideoCaptureFormat& format, |
446 host_->frame_deliverer_ = nullptr; | 433 const blink::WebMediaConstraints& constraints, |
447 } | 434 const VideoCaptureDeliverFrameCB& frame_callback) { |
| 435 output_started_ = true; |
| 436 frame_deliverer_ = new FrameDeliverer(io_task_runner(), frame_callback); |
| 437 } |
448 | 438 |
449 private: | 439 void PepperMediaStreamVideoTrackHost::StopSourceImpl() { |
450 const base::WeakPtr<PepperMediaStreamVideoTrackHost> host_; | 440 output_started_ = false; |
451 | 441 frame_deliverer_ = NULL; |
452 DISALLOW_COPY_AND_ASSIGN(VideoSource); | 442 } |
453 }; | |
454 | 443 |
455 void PepperMediaStreamVideoTrackHost::DidConnectPendingHostToResource() { | 444 void PepperMediaStreamVideoTrackHost::DidConnectPendingHostToResource() { |
456 if (!MediaStreamVideoSink::connected_track().isNull()) | 445 if (!MediaStreamVideoSink::connected_track().isNull()) |
457 return; | 446 return; |
458 MediaStreamVideoSink::ConnectToTrack( | 447 MediaStreamVideoSink::ConnectToTrack( |
459 track_, | 448 track_, |
460 media::BindToCurrentLoop( | 449 media::BindToCurrentLoop( |
461 base::Bind( | 450 base::Bind( |
462 &PepperMediaStreamVideoTrackHost::OnVideoFrame, | 451 &PepperMediaStreamVideoTrackHost::OnVideoFrame, |
463 weak_factory_.GetWeakPtr()))); | 452 weak_factory_.GetWeakPtr()))); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 } | 504 } |
516 | 505 |
517 void PepperMediaStreamVideoTrackHost::InitBlinkTrack() { | 506 void PepperMediaStreamVideoTrackHost::InitBlinkTrack() { |
518 std::string source_id; | 507 std::string source_id; |
519 base::Base64Encode(base::RandBytesAsString(64), &source_id); | 508 base::Base64Encode(base::RandBytesAsString(64), &source_id); |
520 blink::WebMediaStreamSource webkit_source; | 509 blink::WebMediaStreamSource webkit_source; |
521 webkit_source.initialize(base::UTF8ToUTF16(source_id), | 510 webkit_source.initialize(base::UTF8ToUTF16(source_id), |
522 blink::WebMediaStreamSource::TypeVideo, | 511 blink::WebMediaStreamSource::TypeVideo, |
523 base::UTF8ToUTF16(kPepperVideoSourceName), | 512 base::UTF8ToUTF16(kPepperVideoSourceName), |
524 false /* remote */); | 513 false /* remote */); |
525 MediaStreamVideoSource* const source = | 514 webkit_source.setExtraData(this); |
526 new VideoSource(weak_factory_.GetWeakPtr()); | |
527 webkit_source.setExtraData(source); // Takes ownership of |source|. | |
528 | 515 |
529 const bool enabled = true; | 516 const bool enabled = true; |
530 blink::WebMediaConstraints constraints; | 517 blink::WebMediaConstraints constraints; |
531 constraints.initialize(); | 518 constraints.initialize(); |
532 track_ = MediaStreamVideoTrack::CreateVideoTrack( | 519 track_ = MediaStreamVideoTrack::CreateVideoTrack( |
533 source, constraints, | 520 this, constraints, |
534 base::Bind( | 521 base::Bind( |
535 &PepperMediaStreamVideoTrackHost::OnTrackStarted, | 522 &PepperMediaStreamVideoTrackHost::OnTrackStarted, |
536 base::Unretained(this)), | 523 base::Unretained(this)), |
537 enabled); | 524 enabled); |
538 // Note: The call to CreateVideoTrack() returned a track that holds a | |
539 // ref-counted reference to |webkit_source| (and, implicitly, |source|). | |
540 } | 525 } |
541 | 526 |
542 void PepperMediaStreamVideoTrackHost::OnTrackStarted( | 527 void PepperMediaStreamVideoTrackHost::OnTrackStarted( |
543 MediaStreamSource* source, | 528 MediaStreamSource* source, |
544 MediaStreamRequestResult result, | 529 MediaStreamRequestResult result, |
545 const blink::WebString& result_name) { | 530 const blink::WebString& result_name) { |
546 DVLOG(3) << "OnTrackStarted result: " << result; | 531 DVLOG(3) << "OnTrackStarted result: " << result; |
547 } | 532 } |
548 | 533 |
549 } // namespace content | 534 } // namespace content |
OLD | NEW |