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" |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 PP_VideoFrame_Format plugin) { | 90 PP_VideoFrame_Format plugin) { |
91 return plugin != PP_VIDEOFRAME_FORMAT_UNKNOWN ? plugin : source; | 91 return plugin != PP_VIDEOFRAME_FORMAT_UNKNOWN ? plugin : source; |
92 } | 92 } |
93 | 93 |
94 void ConvertFromMediaVideoFrame(const scoped_refptr<media::VideoFrame>& src, | 94 void ConvertFromMediaVideoFrame(const scoped_refptr<media::VideoFrame>& src, |
95 PP_VideoFrame_Format dst_format, | 95 PP_VideoFrame_Format dst_format, |
96 const gfx::Size& dst_size, | 96 const gfx::Size& dst_size, |
97 uint8_t* dst) { | 97 uint8_t* dst) { |
98 CHECK(src->format() == VideoFrame::YV12 || src->format() == VideoFrame::I420); | 98 CHECK(src->format() == VideoFrame::YV12 || src->format() == VideoFrame::I420); |
99 if (dst_format == PP_VIDEOFRAME_FORMAT_BGRA) { | 99 if (dst_format == PP_VIDEOFRAME_FORMAT_BGRA) { |
100 if (src->coded_size() == dst_size) { | 100 if (src->visible_rect().size() == dst_size) { |
101 libyuv::I420ToARGB(src->data(VideoFrame::kYPlane), | 101 libyuv::I420ToARGB(src->visible_data(VideoFrame::kYPlane), |
102 src->stride(VideoFrame::kYPlane), | 102 src->stride(VideoFrame::kYPlane), |
103 src->data(VideoFrame::kUPlane), | 103 src->visible_data(VideoFrame::kUPlane), |
104 src->stride(VideoFrame::kUPlane), | 104 src->stride(VideoFrame::kUPlane), |
105 src->data(VideoFrame::kVPlane), | 105 src->visible_data(VideoFrame::kVPlane), |
106 src->stride(VideoFrame::kVPlane), | 106 src->stride(VideoFrame::kVPlane), |
107 dst, | 107 dst, |
108 dst_size.width() * 4, | 108 dst_size.width() * 4, |
109 dst_size.width(), | 109 dst_size.width(), |
110 dst_size.height()); | 110 dst_size.height()); |
111 } else { | 111 } else { |
112 media::ScaleYUVToRGB32(src->data(VideoFrame::kYPlane), | 112 media::ScaleYUVToRGB32(src->visible_data(VideoFrame::kYPlane), |
113 src->data(VideoFrame::kUPlane), | 113 src->visible_data(VideoFrame::kUPlane), |
114 src->data(VideoFrame::kVPlane), | 114 src->visible_data(VideoFrame::kVPlane), |
115 dst, | 115 dst, |
116 src->coded_size().width(), | 116 src->visible_rect().width(), |
117 src->coded_size().height(), | 117 src->visible_rect().height(), |
118 dst_size.width(), | 118 dst_size.width(), |
119 dst_size.height(), | 119 dst_size.height(), |
120 src->stride(VideoFrame::kYPlane), | 120 src->stride(VideoFrame::kYPlane), |
121 src->stride(VideoFrame::kUPlane), | 121 src->stride(VideoFrame::kUPlane), |
122 dst_size.width() * 4, | 122 dst_size.width() * 4, |
123 media::YV12, | 123 media::YV12, |
124 media::ROTATE_0, | 124 media::ROTATE_0, |
125 media::FILTER_BILINEAR); | 125 media::FILTER_BILINEAR); |
126 } | 126 } |
127 } else if (dst_format == PP_VIDEOFRAME_FORMAT_YV12 || | 127 } else if (dst_format == PP_VIDEOFRAME_FORMAT_YV12 || |
128 dst_format == PP_VIDEOFRAME_FORMAT_I420) { | 128 dst_format == PP_VIDEOFRAME_FORMAT_I420) { |
129 static const size_t kPlanesOrder[][3] = { | 129 static const size_t kPlanesOrder[][3] = { |
130 {VideoFrame::kYPlane, VideoFrame::kVPlane, | 130 {VideoFrame::kYPlane, VideoFrame::kVPlane, |
131 VideoFrame::kUPlane}, // YV12 | 131 VideoFrame::kUPlane}, // YV12 |
132 {VideoFrame::kYPlane, VideoFrame::kUPlane, | 132 {VideoFrame::kYPlane, VideoFrame::kUPlane, |
133 VideoFrame::kVPlane}, // I420 | 133 VideoFrame::kVPlane}, // I420 |
134 }; | 134 }; |
135 const int plane_order = (dst_format == PP_VIDEOFRAME_FORMAT_YV12) ? 0 : 1; | 135 const int plane_order = (dst_format == PP_VIDEOFRAME_FORMAT_YV12) ? 0 : 1; |
136 int dst_width = dst_size.width(); | 136 int dst_width = dst_size.width(); |
137 int dst_height = dst_size.height(); | 137 int dst_height = dst_size.height(); |
138 libyuv::ScalePlane(src->data(kPlanesOrder[plane_order][0]), | 138 libyuv::ScalePlane(src->visible_data(kPlanesOrder[plane_order][0]), |
139 src->stride(kPlanesOrder[plane_order][0]), | 139 src->stride(kPlanesOrder[plane_order][0]), |
140 src->coded_size().width(), | 140 src->visible_rect().width(), |
141 src->coded_size().height(), | 141 src->visible_rect().height(), |
142 dst, | 142 dst, |
143 dst_width, | 143 dst_width, |
144 dst_width, | 144 dst_width, |
145 dst_height, | 145 dst_height, |
146 kFilterMode); | 146 kFilterMode); |
147 dst += dst_width * dst_height; | 147 dst += dst_width * dst_height; |
148 const int src_halfwidth = (src->coded_size().width() + 1) >> 1; | 148 const int src_halfwidth = (src->visible_rect().width() + 1) >> 1; |
149 const int src_halfheight = (src->coded_size().height() + 1) >> 1; | 149 const int src_halfheight = (src->visible_rect().height() + 1) >> 1; |
150 const int dst_halfwidth = (dst_width + 1) >> 1; | 150 const int dst_halfwidth = (dst_width + 1) >> 1; |
151 const int dst_halfheight = (dst_height + 1) >> 1; | 151 const int dst_halfheight = (dst_height + 1) >> 1; |
152 libyuv::ScalePlane(src->data(kPlanesOrder[plane_order][1]), | 152 libyuv::ScalePlane(src->visible_data(kPlanesOrder[plane_order][1]), |
153 src->stride(kPlanesOrder[plane_order][1]), | 153 src->stride(kPlanesOrder[plane_order][1]), |
154 src_halfwidth, | 154 src_halfwidth, |
155 src_halfheight, | 155 src_halfheight, |
156 dst, | 156 dst, |
157 dst_halfwidth, | 157 dst_halfwidth, |
158 dst_halfwidth, | 158 dst_halfwidth, |
159 dst_halfheight, | 159 dst_halfheight, |
160 kFilterMode); | 160 kFilterMode); |
161 dst += dst_halfwidth * dst_halfheight; | 161 dst += dst_halfwidth * dst_halfheight; |
162 libyuv::ScalePlane(src->data(kPlanesOrder[plane_order][2]), | 162 libyuv::ScalePlane(src->visible_data(kPlanesOrder[plane_order][2]), |
163 src->stride(kPlanesOrder[plane_order][2]), | 163 src->stride(kPlanesOrder[plane_order][2]), |
164 src_halfwidth, | 164 src_halfwidth, |
165 src_halfheight, | 165 src_halfheight, |
166 dst, | 166 dst, |
167 dst_halfwidth, | 167 dst_halfwidth, |
168 dst_halfwidth, | 168 dst_halfwidth, |
169 dst_halfheight, | 169 dst_halfheight, |
170 kFilterMode); | 170 kFilterMode); |
171 } else { | 171 } else { |
172 NOTREACHED(); | 172 NOTREACHED(); |
173 } | 173 } |
174 } | 174 } |
175 | 175 |
176 } // namespace | 176 } // namespace |
177 | 177 |
178 namespace content { | 178 namespace content { |
179 | 179 |
180 // Internal class used for delivering video frames on the IO-thread to | 180 // Internal class used for delivering video frames on the IO-thread to |
181 // the MediaStreamVideoSource implementation. | 181 // the MediaStreamVideoSource implementation. |
182 class PepperMediaStreamVideoTrackHost::FrameDeliverer | 182 class PepperMediaStreamVideoTrackHost::FrameDeliverer |
183 : public base::RefCountedThreadSafe<FrameDeliverer> { | 183 : public base::RefCountedThreadSafe<FrameDeliverer> { |
184 public: | 184 public: |
185 FrameDeliverer( | 185 FrameDeliverer( |
186 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy, | 186 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy, |
187 const VideoCaptureDeliverFrameCB& new_frame_callback); | 187 const VideoCaptureDeliverFrameCB& new_frame_callback); |
188 | 188 |
189 void DeliverVideoFrame(const scoped_refptr<media::VideoFrame>& frame, | 189 void DeliverVideoFrame(const scoped_refptr<media::VideoFrame>& frame); |
190 const media::VideoCaptureFormat& format); | |
191 | 190 |
192 private: | 191 private: |
193 friend class base::RefCountedThreadSafe<FrameDeliverer>; | 192 friend class base::RefCountedThreadSafe<FrameDeliverer>; |
194 virtual ~FrameDeliverer(); | 193 virtual ~FrameDeliverer(); |
195 | 194 |
196 void DeliverFrameOnIO(const scoped_refptr<media::VideoFrame>& frame, | 195 void DeliverFrameOnIO(const scoped_refptr<media::VideoFrame>& frame); |
197 const media::VideoCaptureFormat& format); | |
198 | 196 |
199 scoped_refptr<base::MessageLoopProxy> io_message_loop_; | 197 scoped_refptr<base::MessageLoopProxy> io_message_loop_; |
200 VideoCaptureDeliverFrameCB new_frame_callback_; | 198 VideoCaptureDeliverFrameCB new_frame_callback_; |
201 | 199 |
202 DISALLOW_COPY_AND_ASSIGN(FrameDeliverer); | 200 DISALLOW_COPY_AND_ASSIGN(FrameDeliverer); |
203 }; | 201 }; |
204 | 202 |
205 PepperMediaStreamVideoTrackHost::FrameDeliverer::FrameDeliverer( | 203 PepperMediaStreamVideoTrackHost::FrameDeliverer::FrameDeliverer( |
206 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy, | 204 const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy, |
207 const VideoCaptureDeliverFrameCB& new_frame_callback) | 205 const VideoCaptureDeliverFrameCB& new_frame_callback) |
208 : io_message_loop_(io_message_loop_proxy), | 206 : io_message_loop_(io_message_loop_proxy), |
209 new_frame_callback_(new_frame_callback) { | 207 new_frame_callback_(new_frame_callback) { |
210 } | 208 } |
211 | 209 |
212 PepperMediaStreamVideoTrackHost::FrameDeliverer::~FrameDeliverer() { | 210 PepperMediaStreamVideoTrackHost::FrameDeliverer::~FrameDeliverer() { |
213 } | 211 } |
214 | 212 |
215 void PepperMediaStreamVideoTrackHost::FrameDeliverer::DeliverVideoFrame( | 213 void PepperMediaStreamVideoTrackHost::FrameDeliverer::DeliverVideoFrame( |
216 const scoped_refptr<media::VideoFrame>& frame, | 214 const scoped_refptr<media::VideoFrame>& frame) { |
217 const media::VideoCaptureFormat& format) { | |
218 io_message_loop_->PostTask( | 215 io_message_loop_->PostTask( |
219 FROM_HERE, | 216 FROM_HERE, |
220 base::Bind(&FrameDeliverer::DeliverFrameOnIO, | 217 base::Bind(&FrameDeliverer::DeliverFrameOnIO, this, frame)); |
221 this, frame, format)); | |
222 } | 218 } |
223 | 219 |
224 void PepperMediaStreamVideoTrackHost::FrameDeliverer::DeliverFrameOnIO( | 220 void PepperMediaStreamVideoTrackHost::FrameDeliverer::DeliverFrameOnIO( |
225 const scoped_refptr<media::VideoFrame>& frame, | 221 const scoped_refptr<media::VideoFrame>& frame) { |
226 const media::VideoCaptureFormat& format) { | |
227 DCHECK(io_message_loop_->BelongsToCurrentThread()); | 222 DCHECK(io_message_loop_->BelongsToCurrentThread()); |
228 // The time when this frame is generated is unknown so give a null value to | 223 // The time when this frame is generated is unknown so give a null value to |
229 // |estimated_capture_time|. | 224 // |estimated_capture_time|. |
230 new_frame_callback_.Run(frame, format, base::TimeTicks()); | 225 new_frame_callback_.Run(frame, base::TimeTicks()); |
231 } | 226 } |
232 | 227 |
233 PepperMediaStreamVideoTrackHost::PepperMediaStreamVideoTrackHost( | 228 PepperMediaStreamVideoTrackHost::PepperMediaStreamVideoTrackHost( |
234 RendererPpapiHost* host, | 229 RendererPpapiHost* host, |
235 PP_Instance instance, | 230 PP_Instance instance, |
236 PP_Resource resource, | 231 PP_Resource resource, |
237 const blink::WebMediaStreamTrack& track) | 232 const blink::WebMediaStreamTrack& track) |
238 : PepperMediaStreamTrackHostBase(host, instance, resource), | 233 : PepperMediaStreamTrackHostBase(host, instance, resource), |
239 track_(track), | 234 track_(track), |
240 connected_(false), | 235 connected_(false), |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 plugin_frame_size_, | 357 plugin_frame_size_, |
363 y_stride, | 358 y_stride, |
364 uv_stride, | 359 uv_stride, |
365 uv_stride, | 360 uv_stride, |
366 y_data, | 361 y_data, |
367 u_data, | 362 u_data, |
368 v_data, | 363 v_data, |
369 base::TimeDelta::FromMilliseconds(ts_ms), | 364 base::TimeDelta::FromMilliseconds(ts_ms), |
370 base::Closure()); | 365 base::Closure()); |
371 | 366 |
372 frame_deliverer_->DeliverVideoFrame( | 367 frame_deliverer_->DeliverVideoFrame(frame); |
373 frame, | |
374 media::VideoCaptureFormat(plugin_frame_size_, | |
375 kDefaultOutputFrameRate, | |
376 ToPixelFormat(plugin_frame_format_))); | |
377 } | 368 } |
378 | 369 |
379 // Makes the frame available again for plugin. | 370 // Makes the frame available again for plugin. |
380 SendEnqueueBufferMessageToPlugin(index); | 371 SendEnqueueBufferMessageToPlugin(index); |
381 return PP_OK; | 372 return PP_OK; |
382 } | 373 } |
383 | 374 |
384 void PepperMediaStreamVideoTrackHost::OnVideoFrame( | 375 void PepperMediaStreamVideoTrackHost::OnVideoFrame( |
385 const scoped_refptr<VideoFrame>& frame, | 376 const scoped_refptr<VideoFrame>& frame, |
386 const media::VideoCaptureFormat& format, | |
387 const base::TimeTicks& estimated_capture_time) { | 377 const base::TimeTicks& estimated_capture_time) { |
388 DCHECK(frame.get()); | 378 DCHECK(frame.get()); |
389 // TODO(penghuang): Check |frame->end_of_stream()| and close the track. | 379 // TODO(penghuang): Check |frame->end_of_stream()| and close the track. |
390 PP_VideoFrame_Format ppformat = ToPpapiFormat(frame->format()); | 380 PP_VideoFrame_Format ppformat = ToPpapiFormat(frame->format()); |
391 if (ppformat == PP_VIDEOFRAME_FORMAT_UNKNOWN) | 381 if (ppformat == PP_VIDEOFRAME_FORMAT_UNKNOWN) |
392 return; | 382 return; |
393 | 383 |
394 if (source_frame_size_.IsEmpty()) { | 384 if (source_frame_size_.IsEmpty()) { |
395 source_frame_size_ = frame->coded_size(); | 385 source_frame_size_ = frame->visible_rect().size(); |
396 source_frame_format_ = ppformat; | 386 source_frame_format_ = ppformat; |
397 InitBuffers(); | 387 InitBuffers(); |
398 } | 388 } |
399 | 389 |
400 int32_t index = buffer_manager()->DequeueBuffer(); | 390 int32_t index = buffer_manager()->DequeueBuffer(); |
401 // Drop frames if the underlying buffer is full. | 391 // Drop frames if the underlying buffer is full. |
402 if (index < 0) { | 392 if (index < 0) { |
403 DVLOG(1) << "A frame is dropped."; | 393 DVLOG(1) << "A frame is dropped."; |
404 return; | 394 return; |
405 } | 395 } |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 } | 529 } |
540 | 530 |
541 void PepperMediaStreamVideoTrackHost::OnTrackStarted( | 531 void PepperMediaStreamVideoTrackHost::OnTrackStarted( |
542 MediaStreamSource* source, | 532 MediaStreamSource* source, |
543 MediaStreamRequestResult result, | 533 MediaStreamRequestResult result, |
544 const blink::WebString& result_name) { | 534 const blink::WebString& result_name) { |
545 DVLOG(3) << "OnTrackStarted result: " << result; | 535 DVLOG(3) << "OnTrackStarted result: " << result; |
546 } | 536 } |
547 | 537 |
548 } // namespace content | 538 } // namespace content |
OLD | NEW |