| 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 |