| 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 "media/capture/video/video_capture_device_client.h" | 5 #include "media/capture/video/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 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 << rotation; | 122 << rotation; |
| 123 libyuv::RotationMode rotation_mode = libyuv::kRotate0; | 123 libyuv::RotationMode rotation_mode = libyuv::kRotate0; |
| 124 if (rotation == 90) | 124 if (rotation == 90) |
| 125 rotation_mode = libyuv::kRotate90; | 125 rotation_mode = libyuv::kRotate90; |
| 126 else if (rotation == 180) | 126 else if (rotation == 180) |
| 127 rotation_mode = libyuv::kRotate180; | 127 rotation_mode = libyuv::kRotate180; |
| 128 else if (rotation == 270) | 128 else if (rotation == 270) |
| 129 rotation_mode = libyuv::kRotate270; | 129 rotation_mode = libyuv::kRotate270; |
| 130 | 130 |
| 131 const gfx::Size dimensions(destination_width, destination_height); | 131 const gfx::Size dimensions(destination_width, destination_height); |
| 132 const media::VideoPixelStorage output_pixel_storage = | |
| 133 use_gpu_memory_buffers_ ? media::PIXEL_STORAGE_GPUMEMORYBUFFER | |
| 134 : media::PIXEL_STORAGE_CPU; | |
| 135 uint8_t *y_plane_data, *u_plane_data, *v_plane_data; | 132 uint8_t *y_plane_data, *u_plane_data, *v_plane_data; |
| 136 std::unique_ptr<Buffer> buffer( | 133 std::unique_ptr<Buffer> buffer( |
| 137 ReserveI420OutputBuffer(dimensions, output_pixel_storage, &y_plane_data, | 134 ReserveI420OutputBuffer(dimensions, media::PIXEL_STORAGE_CPU, |
| 138 &u_plane_data, &v_plane_data)); | 135 &y_plane_data, &u_plane_data, &v_plane_data)); |
| 139 #if DCHECK_IS_ON() | 136 #if DCHECK_IS_ON() |
| 140 dropped_frame_counter_ = buffer.get() ? 0 : dropped_frame_counter_ + 1; | 137 dropped_frame_counter_ = buffer.get() ? 0 : dropped_frame_counter_ + 1; |
| 141 if (dropped_frame_counter_ >= kMaxDroppedFrames) | 138 if (dropped_frame_counter_ >= kMaxDroppedFrames) |
| 142 OnError(FROM_HERE, "Too many frames dropped"); | 139 OnError(FROM_HERE, "Too many frames dropped"); |
| 143 #endif | 140 #endif |
| 144 // Failed to reserve I420 output buffer, so drop the frame. | 141 // Failed to reserve I420 output buffer, so drop the frame. |
| 145 if (!buffer.get()) | 142 if (!buffer.get()) |
| 146 return; | 143 return; |
| 147 | 144 |
| 148 const int yplane_stride = dimensions.width(); | 145 const int yplane_stride = dimensions.width(); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 (flip ? -1 : 1) * frame_format.frame_size.height(), | 238 (flip ? -1 : 1) * frame_format.frame_size.height(), |
| 242 new_unrotated_width, new_unrotated_height, | 239 new_unrotated_width, new_unrotated_height, |
| 243 rotation_mode, origin_colorspace) != 0) { | 240 rotation_mode, origin_colorspace) != 0) { |
| 244 DLOG(WARNING) << "Failed to convert buffer's pixel format to I420 from " | 241 DLOG(WARNING) << "Failed to convert buffer's pixel format to I420 from " |
| 245 << media::VideoPixelFormatToString(frame_format.pixel_format); | 242 << media::VideoPixelFormatToString(frame_format.pixel_format); |
| 246 return; | 243 return; |
| 247 } | 244 } |
| 248 | 245 |
| 249 const VideoCaptureFormat output_format = | 246 const VideoCaptureFormat output_format = |
| 250 VideoCaptureFormat(dimensions, frame_format.frame_rate, | 247 VideoCaptureFormat(dimensions, frame_format.frame_rate, |
| 251 media::PIXEL_FORMAT_I420, output_pixel_storage); | 248 media::PIXEL_FORMAT_I420, media::PIXEL_STORAGE_CPU); |
| 252 OnIncomingCapturedBuffer(std::move(buffer), output_format, reference_time, | 249 OnIncomingCapturedBuffer(std::move(buffer), output_format, reference_time, |
| 253 timestamp); | 250 timestamp); |
| 254 } | 251 } |
| 255 | 252 |
| 256 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> | 253 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> |
| 257 VideoCaptureDeviceClient::ReserveOutputBuffer( | 254 VideoCaptureDeviceClient::ReserveOutputBuffer( |
| 258 const gfx::Size& frame_size, | 255 const gfx::Size& frame_size, |
| 259 media::VideoPixelFormat pixel_format, | 256 media::VideoPixelFormat pixel_format, |
| 260 media::VideoPixelStorage pixel_storage) { | 257 media::VideoPixelStorage pixel_storage) { |
| 261 DCHECK_GT(frame_size.width(), 0); | 258 DCHECK_GT(frame_size.width(), 0); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 276 new AutoReleaseBuffer(buffer_pool_, buffer_id)); | 273 new AutoReleaseBuffer(buffer_pool_, buffer_id)); |
| 277 } | 274 } |
| 278 | 275 |
| 279 void VideoCaptureDeviceClient::OnIncomingCapturedBuffer( | 276 void VideoCaptureDeviceClient::OnIncomingCapturedBuffer( |
| 280 std::unique_ptr<Buffer> buffer, | 277 std::unique_ptr<Buffer> buffer, |
| 281 const VideoCaptureFormat& frame_format, | 278 const VideoCaptureFormat& frame_format, |
| 282 base::TimeTicks reference_time, | 279 base::TimeTicks reference_time, |
| 283 base::TimeDelta timestamp) { | 280 base::TimeDelta timestamp) { |
| 284 // Currently, only I420 pixel format is supported. | 281 // Currently, only I420 pixel format is supported. |
| 285 DCHECK_EQ(media::PIXEL_FORMAT_I420, frame_format.pixel_format); | 282 DCHECK_EQ(media::PIXEL_FORMAT_I420, frame_format.pixel_format); |
| 283 DCHECK_EQ(media::PIXEL_STORAGE_CPU, frame_format.pixel_storage); |
| 286 | 284 |
| 287 scoped_refptr<VideoFrame> frame; | 285 scoped_refptr<VideoFrame> frame = VideoFrame::WrapExternalSharedMemory( |
| 288 switch (frame_format.pixel_storage) { | 286 media::PIXEL_FORMAT_I420, frame_format.frame_size, |
| 289 case media::PIXEL_STORAGE_GPUMEMORYBUFFER: { | 287 gfx::Rect(frame_format.frame_size), frame_format.frame_size, |
| 290 // Create a VideoFrame to set the correct storage_type and pixel_format. | 288 reinterpret_cast<uint8_t*>(buffer->data()), |
| 291 gfx::GpuMemoryBufferHandle handle; | 289 VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420, |
| 292 frame = VideoFrame::WrapExternalYuvGpuMemoryBuffers( | 290 frame_format.frame_size), |
| 293 media::PIXEL_FORMAT_I420, frame_format.frame_size, | 291 base::SharedMemory::NULLHandle(), 0u, timestamp); |
| 294 gfx::Rect(frame_format.frame_size), frame_format.frame_size, 0, 0, 0, | |
| 295 reinterpret_cast<uint8_t*>(buffer->data(media::VideoFrame::kYPlane)), | |
| 296 reinterpret_cast<uint8_t*>(buffer->data(media::VideoFrame::kUPlane)), | |
| 297 reinterpret_cast<uint8_t*>(buffer->data(media::VideoFrame::kVPlane)), | |
| 298 handle, handle, handle, timestamp); | |
| 299 break; | |
| 300 } | |
| 301 case media::PIXEL_STORAGE_CPU: | |
| 302 frame = VideoFrame::WrapExternalSharedMemory( | |
| 303 media::PIXEL_FORMAT_I420, frame_format.frame_size, | |
| 304 gfx::Rect(frame_format.frame_size), frame_format.frame_size, | |
| 305 reinterpret_cast<uint8_t*>(buffer->data()), | |
| 306 VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420, | |
| 307 frame_format.frame_size), | |
| 308 base::SharedMemory::NULLHandle(), 0u, timestamp); | |
| 309 break; | |
| 310 } | |
| 311 if (!frame) | 292 if (!frame) |
| 312 return; | 293 return; |
| 313 frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE, | 294 frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE, |
| 314 frame_format.frame_rate); | 295 frame_format.frame_rate); |
| 315 frame->metadata()->SetTimeTicks(media::VideoFrameMetadata::REFERENCE_TIME, | 296 frame->metadata()->SetTimeTicks(media::VideoFrameMetadata::REFERENCE_TIME, |
| 316 reference_time); | 297 reference_time); |
| 317 OnIncomingCapturedVideoFrame(std::move(buffer), frame); | 298 OnIncomingCapturedVideoFrame(std::move(buffer), frame); |
| 318 } | 299 } |
| 319 | 300 |
| 320 void VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame( | 301 void VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame( |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 return buffer_pool_->GetBufferPoolUtilization(); | 338 return buffer_pool_->GetBufferPoolUtilization(); |
| 358 } | 339 } |
| 359 | 340 |
| 360 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> | 341 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> |
| 361 VideoCaptureDeviceClient::ReserveI420OutputBuffer( | 342 VideoCaptureDeviceClient::ReserveI420OutputBuffer( |
| 362 const gfx::Size& dimensions, | 343 const gfx::Size& dimensions, |
| 363 media::VideoPixelStorage storage, | 344 media::VideoPixelStorage storage, |
| 364 uint8_t** y_plane_data, | 345 uint8_t** y_plane_data, |
| 365 uint8_t** u_plane_data, | 346 uint8_t** u_plane_data, |
| 366 uint8_t** v_plane_data) { | 347 uint8_t** v_plane_data) { |
| 367 DCHECK(storage == media::PIXEL_STORAGE_GPUMEMORYBUFFER || | 348 DCHECK(storage == media::PIXEL_STORAGE_CPU); |
| 368 storage == media::PIXEL_STORAGE_CPU); | |
| 369 DCHECK(dimensions.height()); | 349 DCHECK(dimensions.height()); |
| 370 DCHECK(dimensions.width()); | 350 DCHECK(dimensions.width()); |
| 371 | 351 |
| 372 const media::VideoPixelFormat format = media::PIXEL_FORMAT_I420; | 352 const media::VideoPixelFormat format = media::PIXEL_FORMAT_I420; |
| 373 std::unique_ptr<Buffer> buffer( | 353 std::unique_ptr<Buffer> buffer( |
| 374 ReserveOutputBuffer(dimensions, media::PIXEL_FORMAT_I420, storage)); | 354 ReserveOutputBuffer(dimensions, media::PIXEL_FORMAT_I420, storage)); |
| 375 if (!buffer) | 355 if (!buffer) |
| 376 return std::unique_ptr<Buffer>(); | 356 return std::unique_ptr<Buffer>(); |
| 377 | 357 // TODO(emircan): See http://crbug.com/521068, move this pointer |
| 378 switch (storage) { | 358 // arithmetic inside Buffer::data() when this bug is resolved. |
| 379 case media::PIXEL_STORAGE_CPU: | 359 *y_plane_data = reinterpret_cast<uint8_t*>(buffer->data()); |
| 380 // TODO(emircan): See http://crbug.com/521068, move this pointer | 360 *u_plane_data = |
| 381 // arithmetic inside Buffer::data() when this bug is resolved. | 361 *y_plane_data + |
| 382 *y_plane_data = reinterpret_cast<uint8_t*>(buffer->data()); | 362 VideoFrame::PlaneSize(format, VideoFrame::kYPlane, dimensions).GetArea(); |
| 383 *u_plane_data = | 363 *v_plane_data = |
| 384 *y_plane_data + | 364 *u_plane_data + |
| 385 VideoFrame::PlaneSize(format, VideoFrame::kYPlane, dimensions) | 365 VideoFrame::PlaneSize(format, VideoFrame::kUPlane, dimensions).GetArea(); |
| 386 .GetArea(); | 366 return buffer; |
| 387 *v_plane_data = | |
| 388 *u_plane_data + | |
| 389 VideoFrame::PlaneSize(format, VideoFrame::kUPlane, dimensions) | |
| 390 .GetArea(); | |
| 391 return buffer; | |
| 392 case media::PIXEL_STORAGE_GPUMEMORYBUFFER: | |
| 393 *y_plane_data = | |
| 394 reinterpret_cast<uint8_t*>(buffer->data(VideoFrame::kYPlane)); | |
| 395 *u_plane_data = | |
| 396 reinterpret_cast<uint8_t*>(buffer->data(VideoFrame::kUPlane)); | |
| 397 *v_plane_data = | |
| 398 reinterpret_cast<uint8_t*>(buffer->data(VideoFrame::kVPlane)); | |
| 399 return buffer; | |
| 400 } | |
| 401 NOTREACHED(); | |
| 402 return std::unique_ptr<Buffer>(); | |
| 403 } | 367 } |
| 404 | 368 |
| 405 } // namespace media | 369 } // namespace media |
| OLD | NEW |