| 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 "base/base64.h" | 7 #include "base/base64.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/rand_util.h" | 9 #include "base/rand_util.h" |
| 10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
| 11 #include "content/renderer/media/media_stream_video_track.h" | 11 #include "content/renderer/media/media_stream_video_track.h" |
| 12 #include "media/base/bind_to_current_loop.h" |
| 12 #include "media/base/yuv_convert.h" | 13 #include "media/base/yuv_convert.h" |
| 13 #include "ppapi/c/pp_errors.h" | 14 #include "ppapi/c/pp_errors.h" |
| 14 #include "ppapi/c/ppb_media_stream_video_track.h" | 15 #include "ppapi/c/ppb_media_stream_video_track.h" |
| 15 #include "ppapi/c/ppb_video_frame.h" | 16 #include "ppapi/c/ppb_video_frame.h" |
| 16 #include "ppapi/host/dispatch_host_message.h" | 17 #include "ppapi/host/dispatch_host_message.h" |
| 17 #include "ppapi/host/host_message_context.h" | 18 #include "ppapi/host/host_message_context.h" |
| 18 #include "ppapi/proxy/ppapi_messages.h" | 19 #include "ppapi/proxy/ppapi_messages.h" |
| 19 #include "ppapi/shared_impl/media_stream_buffer.h" | 20 #include "ppapi/shared_impl/media_stream_buffer.h" |
| 20 | 21 |
| 21 // IS_ALIGNED is also defined in | 22 // IS_ALIGNED is also defined in |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 PP_Resource resource, | 234 PP_Resource resource, |
| 234 const blink::WebMediaStreamTrack& track) | 235 const blink::WebMediaStreamTrack& track) |
| 235 : PepperMediaStreamTrackHostBase(host, instance, resource), | 236 : PepperMediaStreamTrackHostBase(host, instance, resource), |
| 236 track_(track), | 237 track_(track), |
| 237 connected_(false), | 238 connected_(false), |
| 238 number_of_buffers_(kDefaultNumberOfBuffers), | 239 number_of_buffers_(kDefaultNumberOfBuffers), |
| 239 source_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), | 240 source_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), |
| 240 plugin_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), | 241 plugin_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), |
| 241 frame_data_size_(0), | 242 frame_data_size_(0), |
| 242 type_(kRead), | 243 type_(kRead), |
| 243 output_started_(false) { | 244 output_started_(false), |
| 245 weak_factory_(this) { |
| 244 DCHECK(!track_.isNull()); | 246 DCHECK(!track_.isNull()); |
| 245 } | 247 } |
| 246 | 248 |
| 247 PepperMediaStreamVideoTrackHost::PepperMediaStreamVideoTrackHost( | 249 PepperMediaStreamVideoTrackHost::PepperMediaStreamVideoTrackHost( |
| 248 RendererPpapiHost* host, | 250 RendererPpapiHost* host, |
| 249 PP_Instance instance, | 251 PP_Instance instance, |
| 250 PP_Resource resource) | 252 PP_Resource resource) |
| 251 : PepperMediaStreamTrackHostBase(host, instance, resource), | 253 : PepperMediaStreamTrackHostBase(host, instance, resource), |
| 252 connected_(false), | 254 connected_(false), |
| 253 number_of_buffers_(kDefaultNumberOfBuffers), | 255 number_of_buffers_(kDefaultNumberOfBuffers), |
| 254 source_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), | 256 source_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), |
| 255 plugin_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), | 257 plugin_frame_format_(PP_VIDEOFRAME_FORMAT_UNKNOWN), |
| 256 frame_data_size_(0), | 258 frame_data_size_(0), |
| 257 type_(kWrite), | 259 type_(kWrite), |
| 258 output_started_(false) { | 260 output_started_(false), |
| 261 weak_factory_(this) { |
| 259 InitBlinkTrack(); | 262 InitBlinkTrack(); |
| 260 DCHECK(!track_.isNull()); | 263 DCHECK(!track_.isNull()); |
| 261 } | 264 } |
| 262 | 265 |
| 263 bool PepperMediaStreamVideoTrackHost::IsMediaStreamVideoTrackHost() { | 266 bool PepperMediaStreamVideoTrackHost::IsMediaStreamVideoTrackHost() { |
| 264 return true; | 267 return true; |
| 265 } | 268 } |
| 266 | 269 |
| 267 PepperMediaStreamVideoTrackHost::~PepperMediaStreamVideoTrackHost() { | 270 PepperMediaStreamVideoTrackHost::~PepperMediaStreamVideoTrackHost() { |
| 268 OnClose(); | 271 OnClose(); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 | 308 |
| 306 // Make all the frames avaiable to the plugin. | 309 // Make all the frames avaiable to the plugin. |
| 307 std::vector<int32_t> indices = buffer_manager()->DequeueBuffers(); | 310 std::vector<int32_t> indices = buffer_manager()->DequeueBuffers(); |
| 308 SendEnqueueBuffersMessageToPlugin(indices); | 311 SendEnqueueBuffersMessageToPlugin(indices); |
| 309 } | 312 } |
| 310 } | 313 } |
| 311 | 314 |
| 312 void PepperMediaStreamVideoTrackHost::OnClose() { | 315 void PepperMediaStreamVideoTrackHost::OnClose() { |
| 313 if (connected_) { | 316 if (connected_) { |
| 314 MediaStreamVideoSink::RemoveFromVideoTrack(this, track_); | 317 MediaStreamVideoSink::RemoveFromVideoTrack(this, track_); |
| 318 weak_factory_.InvalidateWeakPtrs(); |
| 315 connected_ = false; | 319 connected_ = false; |
| 316 } | 320 } |
| 317 } | 321 } |
| 318 | 322 |
| 319 int32_t PepperMediaStreamVideoTrackHost::OnHostMsgEnqueueBuffer( | 323 int32_t PepperMediaStreamVideoTrackHost::OnHostMsgEnqueueBuffer( |
| 320 ppapi::host::HostMessageContext* context, int32_t index) { | 324 ppapi::host::HostMessageContext* context, int32_t index) { |
| 321 if (type_ == kRead) { | 325 if (type_ == kRead) { |
| 322 return PepperMediaStreamTrackHostBase::OnHostMsgEnqueueBuffer(context, | 326 return PepperMediaStreamTrackHostBase::OnHostMsgEnqueueBuffer(context, |
| 323 index); | 327 index); |
| 324 } else { | 328 } else { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 kDefaultOutputFrameRate, | 373 kDefaultOutputFrameRate, |
| 370 ToPixelFormat(plugin_frame_format_))); | 374 ToPixelFormat(plugin_frame_format_))); |
| 371 } | 375 } |
| 372 | 376 |
| 373 // Makes the frame available again for plugin. | 377 // Makes the frame available again for plugin. |
| 374 SendEnqueueBufferMessageToPlugin(index); | 378 SendEnqueueBufferMessageToPlugin(index); |
| 375 return PP_OK; | 379 return PP_OK; |
| 376 } | 380 } |
| 377 | 381 |
| 378 void PepperMediaStreamVideoTrackHost::OnVideoFrame( | 382 void PepperMediaStreamVideoTrackHost::OnVideoFrame( |
| 379 const scoped_refptr<VideoFrame>& frame) { | 383 const scoped_refptr<VideoFrame>& frame, |
| 384 const media::VideoCaptureFormat& format) { |
| 380 DCHECK(frame); | 385 DCHECK(frame); |
| 381 // TODO(penghuang): Check |frame->end_of_stream()| and close the track. | 386 // TODO(penghuang): Check |frame->end_of_stream()| and close the track. |
| 382 PP_VideoFrame_Format ppformat = ToPpapiFormat(frame->format()); | 387 PP_VideoFrame_Format ppformat = ToPpapiFormat(frame->format()); |
| 383 if (ppformat == PP_VIDEOFRAME_FORMAT_UNKNOWN) | 388 if (ppformat == PP_VIDEOFRAME_FORMAT_UNKNOWN) |
| 384 return; | 389 return; |
| 385 | 390 |
| 386 if (source_frame_size_.IsEmpty()) { | 391 if (source_frame_size_.IsEmpty()) { |
| 387 source_frame_size_ = frame->coded_size(); | 392 source_frame_size_ = frame->coded_size(); |
| 388 source_frame_format_ = ppformat; | 393 source_frame_format_ = ppformat; |
| 389 InitBuffers(); | 394 InitBuffers(); |
| 390 } | 395 } |
| 391 | 396 |
| 392 int32_t index = buffer_manager()->DequeueBuffer(); | 397 int32_t index = buffer_manager()->DequeueBuffer(); |
| 393 // Drop frames if the underlying buffer is full. | 398 // Drop frames if the underlying buffer is full. |
| 394 if (index < 0) { | 399 if (index < 0) { |
| 395 DVLOG(1) << "A frame is dropped."; | 400 DVLOG(1) << "A frame is dropped."; |
| 396 return; | 401 return; |
| 397 } | 402 } |
| 398 | 403 |
| 399 CHECK(frame->coded_size() == source_frame_size_) << "Frame size is changed"; | 404 CHECK(frame->coded_size() == source_frame_size_) << "Frame size is changed"; |
| 400 CHECK_EQ(ppformat, source_frame_format_) << "Frame format is changed."; | 405 CHECK_EQ(ppformat, source_frame_format_) << "Frame format is changed."; |
| 401 | 406 |
| 402 gfx::Size size = GetTargetSize(source_frame_size_, plugin_frame_size_); | 407 gfx::Size size = GetTargetSize(source_frame_size_, plugin_frame_size_); |
| 403 PP_VideoFrame_Format format = | 408 ppformat = |
| 404 GetTargetFormat(source_frame_format_, plugin_frame_format_); | 409 GetTargetFormat(source_frame_format_, plugin_frame_format_); |
| 405 ppapi::MediaStreamBuffer::Video* buffer = | 410 ppapi::MediaStreamBuffer::Video* buffer = |
| 406 &(buffer_manager()->GetBufferPointer(index)->video); | 411 &(buffer_manager()->GetBufferPointer(index)->video); |
| 407 buffer->header.size = buffer_manager()->buffer_size(); | 412 buffer->header.size = buffer_manager()->buffer_size(); |
| 408 buffer->header.type = ppapi::MediaStreamBuffer::TYPE_VIDEO; | 413 buffer->header.type = ppapi::MediaStreamBuffer::TYPE_VIDEO; |
| 409 buffer->timestamp = frame->timestamp().InSecondsF(); | 414 buffer->timestamp = frame->timestamp().InSecondsF(); |
| 410 buffer->format = format; | 415 buffer->format = ppformat; |
| 411 buffer->size.width = size.width(); | 416 buffer->size.width = size.width(); |
| 412 buffer->size.height = size.height(); | 417 buffer->size.height = size.height(); |
| 413 buffer->data_size = frame_data_size_; | 418 buffer->data_size = frame_data_size_; |
| 414 ConvertFromMediaVideoFrame(frame, format, size, buffer->data); | 419 ConvertFromMediaVideoFrame(frame, ppformat, size, buffer->data); |
| 415 | 420 |
| 416 SendEnqueueBufferMessageToPlugin(index); | 421 SendEnqueueBufferMessageToPlugin(index); |
| 417 } | 422 } |
| 418 | 423 |
| 419 void PepperMediaStreamVideoTrackHost::GetCurrentSupportedFormats( | 424 void PepperMediaStreamVideoTrackHost::GetCurrentSupportedFormats( |
| 420 int max_requested_width, int max_requested_height, | 425 int max_requested_width, int max_requested_height, |
| 421 const VideoCaptureDeviceFormatsCB& callback) { | 426 const VideoCaptureDeviceFormatsCB& callback) { |
| 422 if (type_ != kWrite) { | 427 if (type_ != kWrite) { |
| 423 DVLOG(1) << "GetCurrentSupportedFormats is only supported in output mode."; | 428 DVLOG(1) << "GetCurrentSupportedFormats is only supported in output mode."; |
| 424 callback.Run(media::VideoCaptureFormats()); | 429 callback.Run(media::VideoCaptureFormats()); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 440 frame_deliverer_ = new FrameDeliverer(io_message_loop(), frame_callback); | 445 frame_deliverer_ = new FrameDeliverer(io_message_loop(), frame_callback); |
| 441 } | 446 } |
| 442 | 447 |
| 443 void PepperMediaStreamVideoTrackHost::StopSourceImpl() { | 448 void PepperMediaStreamVideoTrackHost::StopSourceImpl() { |
| 444 output_started_ = false; | 449 output_started_ = false; |
| 445 frame_deliverer_ = NULL; | 450 frame_deliverer_ = NULL; |
| 446 } | 451 } |
| 447 | 452 |
| 448 void PepperMediaStreamVideoTrackHost::DidConnectPendingHostToResource() { | 453 void PepperMediaStreamVideoTrackHost::DidConnectPendingHostToResource() { |
| 449 if (!connected_) { | 454 if (!connected_) { |
| 450 MediaStreamVideoSink::AddToVideoTrack(this, track_); | 455 MediaStreamVideoSink::AddToVideoTrack( |
| 456 this, |
| 457 media::BindToCurrentLoop( |
| 458 base::Bind( |
| 459 &PepperMediaStreamVideoTrackHost::OnVideoFrame, |
| 460 weak_factory_.GetWeakPtr())), |
| 461 track_); |
| 451 connected_ = true; | 462 connected_ = true; |
| 452 } | 463 } |
| 453 } | 464 } |
| 454 | 465 |
| 455 int32_t PepperMediaStreamVideoTrackHost::OnResourceMessageReceived( | 466 int32_t PepperMediaStreamVideoTrackHost::OnResourceMessageReceived( |
| 456 const IPC::Message& msg, | 467 const IPC::Message& msg, |
| 457 HostMessageContext* context) { | 468 HostMessageContext* context) { |
| 458 IPC_BEGIN_MESSAGE_MAP(PepperMediaStreamVideoTrackHost, msg) | 469 IPC_BEGIN_MESSAGE_MAP(PepperMediaStreamVideoTrackHost, msg) |
| 459 PPAPI_DISPATCH_HOST_RESOURCE_CALL( | 470 PPAPI_DISPATCH_HOST_RESOURCE_CALL( |
| 460 PpapiHostMsg_MediaStreamVideoTrack_Configure, OnHostMsgConfigure) | 471 PpapiHostMsg_MediaStreamVideoTrack_Configure, OnHostMsgConfigure) |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 base::Unretained(this)), | 533 base::Unretained(this)), |
| 523 enabled); | 534 enabled); |
| 524 } | 535 } |
| 525 | 536 |
| 526 void PepperMediaStreamVideoTrackHost::OnTrackStarted( | 537 void PepperMediaStreamVideoTrackHost::OnTrackStarted( |
| 527 MediaStreamSource* source, bool success) { | 538 MediaStreamSource* source, bool success) { |
| 528 DVLOG(3) << "OnTrackStarted result: " << success; | 539 DVLOG(3) << "OnTrackStarted result: " << success; |
| 529 } | 540 } |
| 530 | 541 |
| 531 } // namespace content | 542 } // namespace content |
| OLD | NEW |