OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/browser/renderer_host/media/video_capture_device_client.h" | 5 #include "content/browser/renderer_host/media/video_capture_device_client.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <utility> |
8 | 9 |
9 #include "base/bind.h" | 10 #include "base/bind.h" |
10 #include "base/command_line.h" | 11 #include "base/command_line.h" |
11 #include "base/location.h" | 12 #include "base/location.h" |
12 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
13 #include "base/trace_event/trace_event.h" | 14 #include "base/trace_event/trace_event.h" |
14 #include "build/build_config.h" | 15 #include "build/build_config.h" |
15 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" | 16 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h" |
16 #include "content/browser/renderer_host/media/video_capture_controller.h" | 17 #include "content/browser/renderer_host/media/video_capture_controller.h" |
17 #include "content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h" | 18 #include "content/browser/renderer_host/media/video_capture_gpu_jpeg_decoder.h" |
(...skipping 11 matching lines...) Expand all Loading... |
29 namespace content { | 30 namespace content { |
30 | 31 |
31 // Class combining a Client::Buffer interface implementation and a pool buffer | 32 // Class combining a Client::Buffer interface implementation and a pool buffer |
32 // implementation to guarantee proper cleanup on destruction on our side. | 33 // implementation to guarantee proper cleanup on destruction on our side. |
33 class AutoReleaseBuffer : public media::VideoCaptureDevice::Client::Buffer { | 34 class AutoReleaseBuffer : public media::VideoCaptureDevice::Client::Buffer { |
34 public: | 35 public: |
35 AutoReleaseBuffer(const scoped_refptr<VideoCaptureBufferPool>& pool, | 36 AutoReleaseBuffer(const scoped_refptr<VideoCaptureBufferPool>& pool, |
36 int buffer_id) | 37 int buffer_id) |
37 : id_(buffer_id), | 38 : id_(buffer_id), |
38 pool_(pool), | 39 pool_(pool), |
39 buffer_handle_(pool_->GetBufferHandle(buffer_id).Pass()) { | 40 buffer_handle_(pool_->GetBufferHandle(buffer_id)) { |
40 DCHECK(pool_.get()); | 41 DCHECK(pool_.get()); |
41 } | 42 } |
42 int id() const override { return id_; } | 43 int id() const override { return id_; } |
43 gfx::Size dimensions() const override { return buffer_handle_->dimensions(); } | 44 gfx::Size dimensions() const override { return buffer_handle_->dimensions(); } |
44 size_t mapped_size() const override { return buffer_handle_->mapped_size(); } | 45 size_t mapped_size() const override { return buffer_handle_->mapped_size(); } |
45 void* data(int plane) override { return buffer_handle_->data(plane); } | 46 void* data(int plane) override { return buffer_handle_->data(plane); } |
46 ClientBuffer AsClientBuffer(int plane) override { | 47 ClientBuffer AsClientBuffer(int plane) override { |
47 return buffer_handle_->AsClientBuffer(plane); | 48 return buffer_handle_->AsClientBuffer(plane); |
48 } | 49 } |
49 #if defined(OS_POSIX) && !(defined(OS_MACOSX) && !defined(OS_IOS)) | 50 #if defined(OS_POSIX) && !(defined(OS_MACOSX) && !defined(OS_IOS)) |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 | 217 |
217 if (external_jpeg_decoder_) { | 218 if (external_jpeg_decoder_) { |
218 const VideoCaptureGpuJpegDecoder::STATUS status = | 219 const VideoCaptureGpuJpegDecoder::STATUS status = |
219 external_jpeg_decoder_->GetStatus(); | 220 external_jpeg_decoder_->GetStatus(); |
220 if (status == VideoCaptureGpuJpegDecoder::FAILED) { | 221 if (status == VideoCaptureGpuJpegDecoder::FAILED) { |
221 external_jpeg_decoder_.reset(); | 222 external_jpeg_decoder_.reset(); |
222 } else if (status == VideoCaptureGpuJpegDecoder::INIT_PASSED && | 223 } else if (status == VideoCaptureGpuJpegDecoder::INIT_PASSED && |
223 frame_format.pixel_format == media::PIXEL_FORMAT_MJPEG && | 224 frame_format.pixel_format == media::PIXEL_FORMAT_MJPEG && |
224 rotation == 0 && !flip) { | 225 rotation == 0 && !flip) { |
225 external_jpeg_decoder_->DecodeCapturedData(data, length, frame_format, | 226 external_jpeg_decoder_->DecodeCapturedData(data, length, frame_format, |
226 timestamp, buffer.Pass()); | 227 timestamp, std::move(buffer)); |
227 return; | 228 return; |
228 } | 229 } |
229 } | 230 } |
230 | 231 |
231 if (libyuv::ConvertToI420(data, | 232 if (libyuv::ConvertToI420(data, |
232 length, | 233 length, |
233 y_plane_data, | 234 y_plane_data, |
234 yplane_stride, | 235 yplane_stride, |
235 u_plane_data, | 236 u_plane_data, |
236 uv_plane_stride, | 237 uv_plane_stride, |
237 v_plane_data, | 238 v_plane_data, |
238 uv_plane_stride, | 239 uv_plane_stride, |
239 crop_x, | 240 crop_x, |
240 crop_y, | 241 crop_y, |
241 frame_format.frame_size.width(), | 242 frame_format.frame_size.width(), |
242 (flip ? -1 : 1) * frame_format.frame_size.height(), | 243 (flip ? -1 : 1) * frame_format.frame_size.height(), |
243 new_unrotated_width, | 244 new_unrotated_width, |
244 new_unrotated_height, | 245 new_unrotated_height, |
245 rotation_mode, | 246 rotation_mode, |
246 origin_colorspace) != 0) { | 247 origin_colorspace) != 0) { |
247 DLOG(WARNING) << "Failed to convert buffer's pixel format to I420 from " | 248 DLOG(WARNING) << "Failed to convert buffer's pixel format to I420 from " |
248 << media::VideoPixelFormatToString(frame_format.pixel_format); | 249 << media::VideoPixelFormatToString(frame_format.pixel_format); |
249 return; | 250 return; |
250 } | 251 } |
251 | 252 |
252 const VideoCaptureFormat output_format = VideoCaptureFormat( | 253 const VideoCaptureFormat output_format = VideoCaptureFormat( |
253 dimensions, frame_format.frame_rate, | 254 dimensions, frame_format.frame_rate, |
254 media::PIXEL_FORMAT_I420, output_pixel_storage); | 255 media::PIXEL_FORMAT_I420, output_pixel_storage); |
255 OnIncomingCapturedBuffer(buffer.Pass(), output_format, timestamp); | 256 OnIncomingCapturedBuffer(std::move(buffer), output_format, timestamp); |
256 } | 257 } |
257 | 258 |
258 void VideoCaptureDeviceClient::OnIncomingCapturedYuvData( | 259 void VideoCaptureDeviceClient::OnIncomingCapturedYuvData( |
259 const uint8_t* y_data, | 260 const uint8_t* y_data, |
260 const uint8_t* u_data, | 261 const uint8_t* u_data, |
261 const uint8_t* v_data, | 262 const uint8_t* v_data, |
262 size_t y_stride, | 263 size_t y_stride, |
263 size_t u_stride, | 264 size_t u_stride, |
264 size_t v_stride, | 265 size_t v_stride, |
265 const VideoCaptureFormat& frame_format, | 266 const VideoCaptureFormat& frame_format, |
(...skipping 29 matching lines...) Expand all Loading... |
295 v_data, v_stride, | 296 v_data, v_stride, |
296 y_plane_data, dst_y_stride, | 297 y_plane_data, dst_y_stride, |
297 u_plane_data, dst_u_stride, | 298 u_plane_data, dst_u_stride, |
298 v_plane_data, dst_v_stride, | 299 v_plane_data, dst_v_stride, |
299 frame_format.frame_size.width(), | 300 frame_format.frame_size.width(), |
300 frame_format.frame_size.height())) { | 301 frame_format.frame_size.height())) { |
301 DLOG(WARNING) << "Failed to copy buffer"; | 302 DLOG(WARNING) << "Failed to copy buffer"; |
302 return; | 303 return; |
303 } | 304 } |
304 | 305 |
305 OnIncomingCapturedBuffer(buffer.Pass(), frame_format, timestamp); | 306 OnIncomingCapturedBuffer(std::move(buffer), frame_format, timestamp); |
306 }; | 307 }; |
307 | 308 |
308 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> | 309 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> |
309 VideoCaptureDeviceClient::ReserveOutputBuffer( | 310 VideoCaptureDeviceClient::ReserveOutputBuffer( |
310 const gfx::Size& frame_size, | 311 const gfx::Size& frame_size, |
311 media::VideoPixelFormat pixel_format, | 312 media::VideoPixelFormat pixel_format, |
312 media::VideoPixelStorage pixel_storage) { | 313 media::VideoPixelStorage pixel_storage) { |
313 DCHECK_GT(frame_size.width(), 0); | 314 DCHECK_GT(frame_size.width(), 0); |
314 DCHECK_GT(frame_size.height(), 0); | 315 DCHECK_GT(frame_size.height(), 0); |
315 // Currently, only I420 pixel format is supported. | 316 // Currently, only I420 pixel format is supported. |
(...skipping 10 matching lines...) Expand all Loading... |
326 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> output_buffer( | 327 scoped_ptr<media::VideoCaptureDevice::Client::Buffer> output_buffer( |
327 new AutoReleaseBuffer(buffer_pool_, buffer_id)); | 328 new AutoReleaseBuffer(buffer_pool_, buffer_id)); |
328 | 329 |
329 if (buffer_id_to_drop != VideoCaptureBufferPool::kInvalidId) { | 330 if (buffer_id_to_drop != VideoCaptureBufferPool::kInvalidId) { |
330 BrowserThread::PostTask(BrowserThread::IO, | 331 BrowserThread::PostTask(BrowserThread::IO, |
331 FROM_HERE, | 332 FROM_HERE, |
332 base::Bind(&VideoCaptureController::DoBufferDestroyedOnIOThread, | 333 base::Bind(&VideoCaptureController::DoBufferDestroyedOnIOThread, |
333 controller_, buffer_id_to_drop)); | 334 controller_, buffer_id_to_drop)); |
334 } | 335 } |
335 | 336 |
336 return output_buffer.Pass(); | 337 return output_buffer; |
337 } | 338 } |
338 | 339 |
339 void VideoCaptureDeviceClient::OnIncomingCapturedBuffer( | 340 void VideoCaptureDeviceClient::OnIncomingCapturedBuffer( |
340 scoped_ptr<Buffer> buffer, | 341 scoped_ptr<Buffer> buffer, |
341 const VideoCaptureFormat& frame_format, | 342 const VideoCaptureFormat& frame_format, |
342 const base::TimeTicks& timestamp) { | 343 const base::TimeTicks& timestamp) { |
343 // Currently, only I420 pixel format is supported. | 344 // Currently, only I420 pixel format is supported. |
344 DCHECK_EQ(media::PIXEL_FORMAT_I420, frame_format.pixel_format); | 345 DCHECK_EQ(media::PIXEL_FORMAT_I420, frame_format.pixel_format); |
345 | 346 |
346 scoped_refptr<VideoFrame> frame; | 347 scoped_refptr<VideoFrame> frame; |
(...skipping 16 matching lines...) Expand all Loading... |
363 gfx::Rect(frame_format.frame_size), frame_format.frame_size, | 364 gfx::Rect(frame_format.frame_size), frame_format.frame_size, |
364 reinterpret_cast<uint8_t*>(buffer->data()), | 365 reinterpret_cast<uint8_t*>(buffer->data()), |
365 VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420, | 366 VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420, |
366 frame_format.frame_size), | 367 frame_format.frame_size), |
367 base::SharedMemory::NULLHandle(), 0u, base::TimeDelta()); | 368 base::SharedMemory::NULLHandle(), 0u, base::TimeDelta()); |
368 break; | 369 break; |
369 } | 370 } |
370 DCHECK(frame.get()); | 371 DCHECK(frame.get()); |
371 frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE, | 372 frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE, |
372 frame_format.frame_rate); | 373 frame_format.frame_rate); |
373 OnIncomingCapturedVideoFrame(buffer.Pass(), frame, timestamp); | 374 OnIncomingCapturedVideoFrame(std::move(buffer), frame, timestamp); |
374 } | 375 } |
375 | 376 |
376 void VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame( | 377 void VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame( |
377 scoped_ptr<Buffer> buffer, | 378 scoped_ptr<Buffer> buffer, |
378 const scoped_refptr<VideoFrame>& frame, | 379 const scoped_refptr<VideoFrame>& frame, |
379 const base::TimeTicks& timestamp) { | 380 const base::TimeTicks& timestamp) { |
380 BrowserThread::PostTask( | 381 BrowserThread::PostTask( |
381 BrowserThread::IO, | 382 BrowserThread::IO, |
382 FROM_HERE, | 383 FROM_HERE, |
383 base::Bind( | 384 base::Bind( |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 // arithmetic inside Buffer::data() when this bug is resolved. | 440 // arithmetic inside Buffer::data() when this bug is resolved. |
440 *y_plane_data = reinterpret_cast<uint8_t*>(buffer->data()); | 441 *y_plane_data = reinterpret_cast<uint8_t*>(buffer->data()); |
441 *u_plane_data = | 442 *u_plane_data = |
442 *y_plane_data + | 443 *y_plane_data + |
443 VideoFrame::PlaneSize(format, VideoFrame::kYPlane, dimensions) | 444 VideoFrame::PlaneSize(format, VideoFrame::kYPlane, dimensions) |
444 .GetArea(); | 445 .GetArea(); |
445 *v_plane_data = | 446 *v_plane_data = |
446 *u_plane_data + | 447 *u_plane_data + |
447 VideoFrame::PlaneSize(format, VideoFrame::kUPlane, dimensions) | 448 VideoFrame::PlaneSize(format, VideoFrame::kUPlane, dimensions) |
448 .GetArea(); | 449 .GetArea(); |
449 return buffer.Pass(); | 450 return buffer; |
450 case media::PIXEL_STORAGE_GPUMEMORYBUFFER: | 451 case media::PIXEL_STORAGE_GPUMEMORYBUFFER: |
451 *y_plane_data = | 452 *y_plane_data = |
452 reinterpret_cast<uint8_t*>(buffer->data(VideoFrame::kYPlane)); | 453 reinterpret_cast<uint8_t*>(buffer->data(VideoFrame::kYPlane)); |
453 *u_plane_data = | 454 *u_plane_data = |
454 reinterpret_cast<uint8_t*>(buffer->data(VideoFrame::kUPlane)); | 455 reinterpret_cast<uint8_t*>(buffer->data(VideoFrame::kUPlane)); |
455 *v_plane_data = | 456 *v_plane_data = |
456 reinterpret_cast<uint8_t*>(buffer->data(VideoFrame::kVPlane)); | 457 reinterpret_cast<uint8_t*>(buffer->data(VideoFrame::kVPlane)); |
457 return buffer.Pass(); | 458 return buffer; |
458 } | 459 } |
459 NOTREACHED(); | 460 NOTREACHED(); |
460 return scoped_ptr<Buffer>(); | 461 return scoped_ptr<Buffer>(); |
461 } | 462 } |
462 | 463 |
463 } // namespace content | 464 } // namespace content |
OLD | NEW |