| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2013 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 "content/renderer/pepper/pepper_media_stream_video_track_host.h" |
| 6 |
| 7 #include "content/public/renderer/render_thread.h" |
| 8 #include "ppapi/c/pp_errors.h" |
| 9 #include "ppapi/c/ppb_video_frame.h" |
| 10 #include "ppapi/host/dispatch_host_message.h" |
| 11 #include "ppapi/host/ppapi_host.h" |
| 12 #include "ppapi/proxy/host_dispatcher.h" |
| 13 #include "ppapi/proxy/ppapi_messages.h" |
| 14 #include "ppapi/proxy/resource_message_params.h" |
| 15 #include "ppapi/shared_impl/video_frame.h" |
| 16 |
| 17 using media::VideoFrame; |
| 18 using ppapi::host::HostMessageContext; |
| 19 using ppapi::host::ReplyMessageContext; |
| 20 |
| 21 namespace { |
| 22 |
| 23 PP_VideoFrame_Format ToPpapiFormat(media::VideoFrame::Format format) { |
| 24 switch (format) { |
| 25 case media::VideoFrame::YV12: |
| 26 return PP_VIDEOFRAME_FORMAT_YV12; |
| 27 case media::VideoFrame::YV16: |
| 28 return PP_VIDEOFRAME_FORMAT_YV16; |
| 29 case media::VideoFrame::I420: |
| 30 return PP_VIDEOFRAME_FORMAT_I420; |
| 31 case media::VideoFrame::YV12A: |
| 32 return PP_VIDEOFRAME_FORMAT_YV12A; |
| 33 case media::VideoFrame::YV12J: |
| 34 return PP_VIDEOFRAME_FORMAT_YV12J; |
| 35 default: |
| 36 DVLOG(1) << "Unsupported pixel format " << format; |
| 37 return PP_VIDEOFRAME_FORMAT_UNKNOWN; |
| 38 } |
| 39 } |
| 40 |
| 41 } // namespace |
| 42 |
| 43 namespace content { |
| 44 |
| 45 PepperMediaStreamVideoTrackHost::PepperMediaStreamVideoTrackHost( |
| 46 RendererPpapiHost* host, |
| 47 PP_Instance instance, |
| 48 PP_Resource resource, |
| 49 const blink::WebMediaStreamTrack& track) |
| 50 : PepperIOStreamHost(host, instance, resource, false), |
| 51 track_(track), |
| 52 frame_buffer_size_(2), |
| 53 frame_format_(VideoFrame::UNKNOWN), |
| 54 frame_data_size_(0), |
| 55 slot_size_(0) { |
| 56 DCHECK(!track_.isNull()); |
| 57 } |
| 58 |
| 59 PepperMediaStreamVideoTrackHost::~PepperMediaStreamVideoTrackHost() { |
| 60 MediaStreamVideoSink::RemoveFromVideoTrack(this, track_); |
| 61 } |
| 62 |
| 63 int32_t PepperMediaStreamVideoTrackHost::OnResourceMessageReceived( |
| 64 const IPC::Message& msg, |
| 65 HostMessageContext* context) { |
| 66 IPC_BEGIN_MESSAGE_MAP(PepperMediaStreamVideoTrackHost, msg) |
| 67 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( |
| 68 PpapiHostMsg_MediaStreamVideoTrack_StartCapture, OnHostMsgStartCapture) |
| 69 IPC_END_MESSAGE_MAP() |
| 70 return PepperIOStreamHost::OnResourceMessageReceived(msg, context); |
| 71 } |
| 72 |
| 73 void PepperMediaStreamVideoTrackHost::OnVideoFrame( |
| 74 const scoped_refptr<VideoFrame>& frame) { |
| 75 DCHECK(frame); |
| 76 PP_VideoFrame_Format ppformat = ToPpapiFormat(frame->format()); |
| 77 if (ppformat == PP_VIDEOFRAME_FORMAT_UNKNOWN) |
| 78 return; |
| 79 |
| 80 if (frame_size_ != frame->coded_size() || frame_format_ != frame->format()) { |
| 81 frame_size_ = frame->coded_size(); |
| 82 frame_format_ = frame->format(); |
| 83 AllocFrameBuffers(); |
| 84 } |
| 85 |
| 86 ppapi::VideoFrame* ppframe = NULL; |
| 87 if (Lock(reinterpret_cast<void**>(&ppframe), slot_size_) != PP_OK) { |
| 88 return; |
| 89 } |
| 90 |
| 91 ppframe->timestamp = frame->GetTimestamp().InSecondsF(); |
| 92 ppframe->format = ppformat; |
| 93 ppframe->size.width = frame->coded_size().width(); |
| 94 ppframe->size.height = frame->coded_size().height(); |
| 95 ppframe->data_size = frame_data_size_; |
| 96 |
| 97 COMPILE_ASSERT(VideoFrame::kYPlane == 0, y_plane_should_be_0); |
| 98 COMPILE_ASSERT(VideoFrame::kUPlane == 1, u_plane_should_be_1); |
| 99 COMPILE_ASSERT(VideoFrame::kVPlane == 2, v_plane_should_be_2); |
| 100 |
| 101 uint8_t* dst = ppframe->data; |
| 102 for (size_t i = 0; i < VideoFrame::NumPlanes(frame->format()); ++i) { |
| 103 const uint8_t* src = frame->data(i); |
| 104 const size_t row_bytes = frame->row_bytes(i); |
| 105 const size_t src_stride = frame->stride(i); |
| 106 for (int j = 0; j < frame->rows(i); ++j) { |
| 107 memcpy(dst, src, row_bytes); |
| 108 dst += row_bytes; |
| 109 src += src_stride; |
| 110 } |
| 111 } |
| 112 Unlock(ppframe); |
| 113 } |
| 114 |
| 115 void PepperMediaStreamVideoTrackHost::DidConnectPendingHostToResource() { |
| 116 MediaStreamVideoSink::AddToVideoTrack(this, track_); |
| 117 } |
| 118 |
| 119 int32_t PepperMediaStreamVideoTrackHost::OnHostMsgStartCapture( |
| 120 HostMessageContext* context) { |
| 121 MediaStreamVideoSink::AddToVideoTrack(this, track_); |
| 122 return PP_OK; |
| 123 } |
| 124 |
| 125 void PepperMediaStreamVideoTrackHost::AllocFrameBuffers() { |
| 126 frame_data_size_ = VideoFrame::AllocationSize(frame_format_, frame_size_); |
| 127 slot_size_ = sizeof(ppapi::VideoFrame) + frame_data_size_; |
| 128 InitSharedBufferAndNotifyPlugin(frame_buffer_size_ * slot_size_); |
| 129 } |
| 130 |
| 131 } // namespace content |
| OLD | NEW |