| 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 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 // This should be on the platform auxiliary thread since | 78 // This should be on the platform auxiliary thread since |
| 79 // |external_jpeg_decoder_| need to be destructed on the same thread as | 79 // |external_jpeg_decoder_| need to be destructed on the same thread as |
| 80 // OnIncomingCapturedData. | 80 // OnIncomingCapturedData. |
| 81 } | 81 } |
| 82 | 82 |
| 83 void VideoCaptureDeviceClient::OnIncomingCapturedData( | 83 void VideoCaptureDeviceClient::OnIncomingCapturedData( |
| 84 const uint8_t* data, | 84 const uint8_t* data, |
| 85 int length, | 85 int length, |
| 86 const VideoCaptureFormat& frame_format, | 86 const VideoCaptureFormat& frame_format, |
| 87 int rotation, | 87 int rotation, |
| 88 const base::TimeTicks& timestamp) { | 88 base::TimeTicks reference_time, |
| 89 base::TimeDelta timestamp) { |
| 89 TRACE_EVENT0("video", "VideoCaptureDeviceClient::OnIncomingCapturedData"); | 90 TRACE_EVENT0("video", "VideoCaptureDeviceClient::OnIncomingCapturedData"); |
| 90 DCHECK_EQ(media::PIXEL_STORAGE_CPU, frame_format.pixel_storage); | 91 DCHECK_EQ(media::PIXEL_STORAGE_CPU, frame_format.pixel_storage); |
| 91 | 92 |
| 92 if (last_captured_pixel_format_ != frame_format.pixel_format) { | 93 if (last_captured_pixel_format_ != frame_format.pixel_format) { |
| 93 OnLog("Pixel format: " + | 94 OnLog("Pixel format: " + |
| 94 media::VideoPixelFormatToString(frame_format.pixel_format)); | 95 media::VideoPixelFormatToString(frame_format.pixel_format)); |
| 95 last_captured_pixel_format_ = frame_format.pixel_format; | 96 last_captured_pixel_format_ = frame_format.pixel_format; |
| 96 | 97 |
| 97 if (frame_format.pixel_format == media::PIXEL_FORMAT_MJPEG && | 98 if (frame_format.pixel_format == media::PIXEL_FORMAT_MJPEG && |
| 98 !external_jpeg_decoder_initialized_) { | 99 !external_jpeg_decoder_initialized_) { |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 DCHECK_GE(static_cast<size_t>(length), frame_format.ImageAllocationSize()); | 218 DCHECK_GE(static_cast<size_t>(length), frame_format.ImageAllocationSize()); |
| 218 | 219 |
| 219 if (external_jpeg_decoder_) { | 220 if (external_jpeg_decoder_) { |
| 220 const VideoCaptureGpuJpegDecoder::STATUS status = | 221 const VideoCaptureGpuJpegDecoder::STATUS status = |
| 221 external_jpeg_decoder_->GetStatus(); | 222 external_jpeg_decoder_->GetStatus(); |
| 222 if (status == VideoCaptureGpuJpegDecoder::FAILED) { | 223 if (status == VideoCaptureGpuJpegDecoder::FAILED) { |
| 223 external_jpeg_decoder_.reset(); | 224 external_jpeg_decoder_.reset(); |
| 224 } else if (status == VideoCaptureGpuJpegDecoder::INIT_PASSED && | 225 } else if (status == VideoCaptureGpuJpegDecoder::INIT_PASSED && |
| 225 frame_format.pixel_format == media::PIXEL_FORMAT_MJPEG && | 226 frame_format.pixel_format == media::PIXEL_FORMAT_MJPEG && |
| 226 rotation == 0 && !flip) { | 227 rotation == 0 && !flip) { |
| 227 external_jpeg_decoder_->DecodeCapturedData(data, length, frame_format, | 228 // TODO(qiangchen): Pass timestamp into DecodeCapturedData. |
| 228 timestamp, std::move(buffer)); | 229 external_jpeg_decoder_->DecodeCapturedData( |
| 230 data, length, frame_format, reference_time, std::move(buffer)); |
| 229 return; | 231 return; |
| 230 } | 232 } |
| 231 } | 233 } |
| 232 | 234 |
| 233 if (libyuv::ConvertToI420(data, | 235 if (libyuv::ConvertToI420(data, |
| 234 length, | 236 length, |
| 235 y_plane_data, | 237 y_plane_data, |
| 236 yplane_stride, | 238 yplane_stride, |
| 237 u_plane_data, | 239 u_plane_data, |
| 238 uv_plane_stride, | 240 uv_plane_stride, |
| 239 v_plane_data, | 241 v_plane_data, |
| 240 uv_plane_stride, | 242 uv_plane_stride, |
| 241 crop_x, | 243 crop_x, |
| 242 crop_y, | 244 crop_y, |
| 243 frame_format.frame_size.width(), | 245 frame_format.frame_size.width(), |
| 244 (flip ? -1 : 1) * frame_format.frame_size.height(), | 246 (flip ? -1 : 1) * frame_format.frame_size.height(), |
| 245 new_unrotated_width, | 247 new_unrotated_width, |
| 246 new_unrotated_height, | 248 new_unrotated_height, |
| 247 rotation_mode, | 249 rotation_mode, |
| 248 origin_colorspace) != 0) { | 250 origin_colorspace) != 0) { |
| 249 DLOG(WARNING) << "Failed to convert buffer's pixel format to I420 from " | 251 DLOG(WARNING) << "Failed to convert buffer's pixel format to I420 from " |
| 250 << media::VideoPixelFormatToString(frame_format.pixel_format); | 252 << media::VideoPixelFormatToString(frame_format.pixel_format); |
| 251 return; | 253 return; |
| 252 } | 254 } |
| 253 | 255 |
| 254 const VideoCaptureFormat output_format = VideoCaptureFormat( | 256 const VideoCaptureFormat output_format = VideoCaptureFormat( |
| 255 dimensions, frame_format.frame_rate, | 257 dimensions, frame_format.frame_rate, |
| 256 media::PIXEL_FORMAT_I420, output_pixel_storage); | 258 media::PIXEL_FORMAT_I420, output_pixel_storage); |
| 257 OnIncomingCapturedBuffer(std::move(buffer), output_format, timestamp); | 259 OnIncomingCapturedBuffer(std::move(buffer), output_format, reference_time, |
| 260 timestamp); |
| 258 } | 261 } |
| 259 | 262 |
| 260 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> | 263 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> |
| 261 VideoCaptureDeviceClient::ReserveOutputBuffer( | 264 VideoCaptureDeviceClient::ReserveOutputBuffer( |
| 262 const gfx::Size& frame_size, | 265 const gfx::Size& frame_size, |
| 263 media::VideoPixelFormat pixel_format, | 266 media::VideoPixelFormat pixel_format, |
| 264 media::VideoPixelStorage pixel_storage) { | 267 media::VideoPixelStorage pixel_storage) { |
| 265 DCHECK_GT(frame_size.width(), 0); | 268 DCHECK_GT(frame_size.width(), 0); |
| 266 DCHECK_GT(frame_size.height(), 0); | 269 DCHECK_GT(frame_size.height(), 0); |
| 267 // Currently, only I420 pixel format is supported. | 270 // Currently, only I420 pixel format is supported. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 280 } | 283 } |
| 281 if (buffer_id == VideoCaptureBufferPool::kInvalidId) | 284 if (buffer_id == VideoCaptureBufferPool::kInvalidId) |
| 282 return nullptr; | 285 return nullptr; |
| 283 return base::WrapUnique<Buffer>( | 286 return base::WrapUnique<Buffer>( |
| 284 new AutoReleaseBuffer(buffer_pool_, buffer_id)); | 287 new AutoReleaseBuffer(buffer_pool_, buffer_id)); |
| 285 } | 288 } |
| 286 | 289 |
| 287 void VideoCaptureDeviceClient::OnIncomingCapturedBuffer( | 290 void VideoCaptureDeviceClient::OnIncomingCapturedBuffer( |
| 288 std::unique_ptr<Buffer> buffer, | 291 std::unique_ptr<Buffer> buffer, |
| 289 const VideoCaptureFormat& frame_format, | 292 const VideoCaptureFormat& frame_format, |
| 290 const base::TimeTicks& timestamp) { | 293 base::TimeTicks reference_time, |
| 294 base::TimeDelta timestamp) { |
| 291 // Currently, only I420 pixel format is supported. | 295 // Currently, only I420 pixel format is supported. |
| 292 DCHECK_EQ(media::PIXEL_FORMAT_I420, frame_format.pixel_format); | 296 DCHECK_EQ(media::PIXEL_FORMAT_I420, frame_format.pixel_format); |
| 293 | 297 |
| 294 scoped_refptr<VideoFrame> frame; | 298 scoped_refptr<VideoFrame> frame; |
| 295 switch (frame_format.pixel_storage) { | 299 switch (frame_format.pixel_storage) { |
| 296 case media::PIXEL_STORAGE_GPUMEMORYBUFFER: { | 300 case media::PIXEL_STORAGE_GPUMEMORYBUFFER: { |
| 297 // Create a VideoFrame to set the correct storage_type and pixel_format. | 301 // Create a VideoFrame to set the correct storage_type and pixel_format. |
| 298 gfx::GpuMemoryBufferHandle handle; | 302 gfx::GpuMemoryBufferHandle handle; |
| 299 frame = VideoFrame::WrapExternalYuvGpuMemoryBuffers( | 303 frame = VideoFrame::WrapExternalYuvGpuMemoryBuffers( |
| 300 media::PIXEL_FORMAT_I420, frame_format.frame_size, | 304 media::PIXEL_FORMAT_I420, frame_format.frame_size, |
| 301 gfx::Rect(frame_format.frame_size), frame_format.frame_size, 0, 0, 0, | 305 gfx::Rect(frame_format.frame_size), frame_format.frame_size, 0, 0, 0, |
| 302 reinterpret_cast<uint8_t*>(buffer->data(media::VideoFrame::kYPlane)), | 306 reinterpret_cast<uint8_t*>(buffer->data(media::VideoFrame::kYPlane)), |
| 303 reinterpret_cast<uint8_t*>(buffer->data(media::VideoFrame::kUPlane)), | 307 reinterpret_cast<uint8_t*>(buffer->data(media::VideoFrame::kUPlane)), |
| 304 reinterpret_cast<uint8_t*>(buffer->data(media::VideoFrame::kVPlane)), | 308 reinterpret_cast<uint8_t*>(buffer->data(media::VideoFrame::kVPlane)), |
| 305 handle, handle, handle, base::TimeDelta()); | 309 handle, handle, handle, timestamp); |
| 306 break; | 310 break; |
| 307 } | 311 } |
| 308 case media::PIXEL_STORAGE_CPU: | 312 case media::PIXEL_STORAGE_CPU: |
| 309 frame = VideoFrame::WrapExternalSharedMemory( | 313 frame = VideoFrame::WrapExternalSharedMemory( |
| 310 media::PIXEL_FORMAT_I420, frame_format.frame_size, | 314 media::PIXEL_FORMAT_I420, frame_format.frame_size, |
| 311 gfx::Rect(frame_format.frame_size), frame_format.frame_size, | 315 gfx::Rect(frame_format.frame_size), frame_format.frame_size, |
| 312 reinterpret_cast<uint8_t*>(buffer->data()), | 316 reinterpret_cast<uint8_t*>(buffer->data()), |
| 313 VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420, | 317 VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420, |
| 314 frame_format.frame_size), | 318 frame_format.frame_size), |
| 315 base::SharedMemory::NULLHandle(), 0u, base::TimeDelta()); | 319 base::SharedMemory::NULLHandle(), 0u, timestamp); |
| 316 break; | 320 break; |
| 317 } | 321 } |
| 318 if (!frame) | 322 if (!frame) |
| 319 return; | 323 return; |
| 320 frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE, | 324 frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE, |
| 321 frame_format.frame_rate); | 325 frame_format.frame_rate); |
| 322 OnIncomingCapturedVideoFrame(std::move(buffer), frame, timestamp); | 326 OnIncomingCapturedVideoFrame(std::move(buffer), frame, reference_time); |
| 323 } | 327 } |
| 324 | 328 |
| 325 void VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame( | 329 void VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame( |
| 326 std::unique_ptr<Buffer> buffer, | 330 std::unique_ptr<Buffer> buffer, |
| 327 const scoped_refptr<VideoFrame>& frame, | 331 const scoped_refptr<VideoFrame>& frame, |
| 328 const base::TimeTicks& timestamp) { | 332 base::TimeTicks reference_time) { |
| 333 // TODO(qiangchen): Dive into DoIncomingCapturedVideoFrameOnIOThread to |
| 334 // process timestamp. |
| 329 BrowserThread::PostTask( | 335 BrowserThread::PostTask( |
| 330 BrowserThread::IO, | 336 BrowserThread::IO, FROM_HERE, |
| 331 FROM_HERE, | |
| 332 base::Bind( | 337 base::Bind( |
| 333 &VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread, | 338 &VideoCaptureController::DoIncomingCapturedVideoFrameOnIOThread, |
| 334 controller_, | 339 controller_, base::Passed(&buffer), frame, reference_time)); |
| 335 base::Passed(&buffer), | |
| 336 frame, | |
| 337 timestamp)); | |
| 338 } | 340 } |
| 339 | 341 |
| 340 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> | 342 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> |
| 341 VideoCaptureDeviceClient::ResurrectLastOutputBuffer( | 343 VideoCaptureDeviceClient::ResurrectLastOutputBuffer( |
| 342 const gfx::Size& dimensions, | 344 const gfx::Size& dimensions, |
| 343 media::VideoPixelFormat format, | 345 media::VideoPixelFormat format, |
| 344 media::VideoPixelStorage storage) { | 346 media::VideoPixelStorage storage) { |
| 345 const int buffer_id = | 347 const int buffer_id = |
| 346 buffer_pool_->ResurrectLastForProducer(dimensions, format, storage); | 348 buffer_pool_->ResurrectLastForProducer(dimensions, format, storage); |
| 347 if (buffer_id == VideoCaptureBufferPool::kInvalidId) | 349 if (buffer_id == VideoCaptureBufferPool::kInvalidId) |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 reinterpret_cast<uint8_t*>(buffer->data(VideoFrame::kUPlane)); | 418 reinterpret_cast<uint8_t*>(buffer->data(VideoFrame::kUPlane)); |
| 417 *v_plane_data = | 419 *v_plane_data = |
| 418 reinterpret_cast<uint8_t*>(buffer->data(VideoFrame::kVPlane)); | 420 reinterpret_cast<uint8_t*>(buffer->data(VideoFrame::kVPlane)); |
| 419 return buffer; | 421 return buffer; |
| 420 } | 422 } |
| 421 NOTREACHED(); | 423 NOTREACHED(); |
| 422 return std::unique_ptr<Buffer>(); | 424 return std::unique_ptr<Buffer>(); |
| 423 } | 425 } |
| 424 | 426 |
| 425 } // namespace content | 427 } // namespace content |
| OLD | NEW |