Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(687)

Side by Side Diff: media/capture/video/video_capture_device_client.cc

Issue 2398813002: Cleanup of video capture into GpuMemoryBuffer (Closed)
Patch Set: Rebase Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/strings/stringprintf.h" 14 #include "base/strings/stringprintf.h"
15 #include "base/trace_event/trace_event.h" 15 #include "base/trace_event/trace_event.h"
16 #include "build/build_config.h" 16 #include "build/build_config.h"
17 #include "media/base/bind_to_current_loop.h" 17 #include "media/base/bind_to_current_loop.h"
18 #include "media/base/media_switches.h"
19 #include "media/base/video_capture_types.h" 18 #include "media/base/video_capture_types.h"
20 #include "media/base/video_frame.h" 19 #include "media/base/video_frame.h"
21 #include "media/capture/video/video_capture_buffer_handle.h" 20 #include "media/capture/video/video_capture_buffer_handle.h"
22 #include "media/capture/video/video_capture_buffer_pool.h" 21 #include "media/capture/video/video_capture_buffer_pool.h"
23 #include "media/capture/video/video_capture_jpeg_decoder.h" 22 #include "media/capture/video/video_capture_jpeg_decoder.h"
24 #include "media/capture/video/video_frame_receiver.h" 23 #include "media/capture/video/video_frame_receiver.h"
25 #include "third_party/libyuv/include/libyuv.h" 24 #include "third_party/libyuv/include/libyuv.h"
26 25
27 using media::VideoCaptureFormat; 26 using media::VideoCaptureFormat;
28 using media::VideoFrame; 27 using media::VideoFrame;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 }; 62 };
64 63
65 VideoCaptureDeviceClient::VideoCaptureDeviceClient( 64 VideoCaptureDeviceClient::VideoCaptureDeviceClient(
66 std::unique_ptr<VideoFrameReceiver> receiver, 65 std::unique_ptr<VideoFrameReceiver> receiver,
67 const scoped_refptr<VideoCaptureBufferPool>& buffer_pool, 66 const scoped_refptr<VideoCaptureBufferPool>& buffer_pool,
68 const VideoCaptureJpegDecoderFactoryCB& jpeg_decoder_factory) 67 const VideoCaptureJpegDecoderFactoryCB& jpeg_decoder_factory)
69 : receiver_(std::move(receiver)), 68 : receiver_(std::move(receiver)),
70 jpeg_decoder_factory_callback_(jpeg_decoder_factory), 69 jpeg_decoder_factory_callback_(jpeg_decoder_factory),
71 external_jpeg_decoder_initialized_(false), 70 external_jpeg_decoder_initialized_(false),
72 buffer_pool_(buffer_pool), 71 buffer_pool_(buffer_pool),
73 use_gpu_memory_buffers_(base::CommandLine::ForCurrentProcess()->HasSwitch(
74 switches::kUseGpuMemoryBuffersForCapture)),
75 last_captured_pixel_format_(media::PIXEL_FORMAT_UNKNOWN) {} 72 last_captured_pixel_format_(media::PIXEL_FORMAT_UNKNOWN) {}
76 73
77 VideoCaptureDeviceClient::~VideoCaptureDeviceClient() { 74 VideoCaptureDeviceClient::~VideoCaptureDeviceClient() {
78 // This should be on the platform auxiliary thread since 75 // This should be on the platform auxiliary thread since
79 // |external_jpeg_decoder_| need to be destructed on the same thread as 76 // |external_jpeg_decoder_| need to be destructed on the same thread as
80 // OnIncomingCapturedData. 77 // OnIncomingCapturedData.
81 } 78 }
82 79
83 void VideoCaptureDeviceClient::OnIncomingCapturedData( 80 void VideoCaptureDeviceClient::OnIncomingCapturedData(
84 const uint8_t* data, 81 const uint8_t* data,
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 << rotation; 119 << rotation;
123 libyuv::RotationMode rotation_mode = libyuv::kRotate0; 120 libyuv::RotationMode rotation_mode = libyuv::kRotate0;
124 if (rotation == 90) 121 if (rotation == 90)
125 rotation_mode = libyuv::kRotate90; 122 rotation_mode = libyuv::kRotate90;
126 else if (rotation == 180) 123 else if (rotation == 180)
127 rotation_mode = libyuv::kRotate180; 124 rotation_mode = libyuv::kRotate180;
128 else if (rotation == 270) 125 else if (rotation == 270)
129 rotation_mode = libyuv::kRotate270; 126 rotation_mode = libyuv::kRotate270;
130 127
131 const gfx::Size dimensions(destination_width, destination_height); 128 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; 129 uint8_t *y_plane_data, *u_plane_data, *v_plane_data;
136 std::unique_ptr<Buffer> buffer( 130 std::unique_ptr<Buffer> buffer(
137 ReserveI420OutputBuffer(dimensions, output_pixel_storage, &y_plane_data, 131 ReserveI420OutputBuffer(dimensions, media::PIXEL_STORAGE_CPU,
138 &u_plane_data, &v_plane_data)); 132 &y_plane_data, &u_plane_data, &v_plane_data));
139 #if DCHECK_IS_ON() 133 #if DCHECK_IS_ON()
140 dropped_frame_counter_ = buffer.get() ? 0 : dropped_frame_counter_ + 1; 134 dropped_frame_counter_ = buffer.get() ? 0 : dropped_frame_counter_ + 1;
141 if (dropped_frame_counter_ >= kMaxDroppedFrames) 135 if (dropped_frame_counter_ >= kMaxDroppedFrames)
142 OnError(FROM_HERE, "Too many frames dropped"); 136 OnError(FROM_HERE, "Too many frames dropped");
143 #endif 137 #endif
144 // Failed to reserve I420 output buffer, so drop the frame. 138 // Failed to reserve I420 output buffer, so drop the frame.
145 if (!buffer.get()) 139 if (!buffer.get())
146 return; 140 return;
147 141
148 const int yplane_stride = dimensions.width(); 142 const int yplane_stride = dimensions.width();
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 (flip ? -1 : 1) * frame_format.frame_size.height(), 235 (flip ? -1 : 1) * frame_format.frame_size.height(),
242 new_unrotated_width, new_unrotated_height, 236 new_unrotated_width, new_unrotated_height,
243 rotation_mode, origin_colorspace) != 0) { 237 rotation_mode, origin_colorspace) != 0) {
244 DLOG(WARNING) << "Failed to convert buffer's pixel format to I420 from " 238 DLOG(WARNING) << "Failed to convert buffer's pixel format to I420 from "
245 << media::VideoPixelFormatToString(frame_format.pixel_format); 239 << media::VideoPixelFormatToString(frame_format.pixel_format);
246 return; 240 return;
247 } 241 }
248 242
249 const VideoCaptureFormat output_format = 243 const VideoCaptureFormat output_format =
250 VideoCaptureFormat(dimensions, frame_format.frame_rate, 244 VideoCaptureFormat(dimensions, frame_format.frame_rate,
251 media::PIXEL_FORMAT_I420, output_pixel_storage); 245 media::PIXEL_FORMAT_I420, media::PIXEL_STORAGE_CPU);
252 OnIncomingCapturedBuffer(std::move(buffer), output_format, reference_time, 246 OnIncomingCapturedBuffer(std::move(buffer), output_format, reference_time,
253 timestamp); 247 timestamp);
254 } 248 }
255 249
256 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> 250 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer>
257 VideoCaptureDeviceClient::ReserveOutputBuffer( 251 VideoCaptureDeviceClient::ReserveOutputBuffer(
258 const gfx::Size& frame_size, 252 const gfx::Size& frame_size,
259 media::VideoPixelFormat pixel_format, 253 media::VideoPixelFormat pixel_format,
260 media::VideoPixelStorage pixel_storage) { 254 media::VideoPixelStorage pixel_storage) {
261 DCHECK_GT(frame_size.width(), 0); 255 DCHECK_GT(frame_size.width(), 0);
(...skipping 14 matching lines...) Expand all
276 new AutoReleaseBuffer(buffer_pool_, buffer_id)); 270 new AutoReleaseBuffer(buffer_pool_, buffer_id));
277 } 271 }
278 272
279 void VideoCaptureDeviceClient::OnIncomingCapturedBuffer( 273 void VideoCaptureDeviceClient::OnIncomingCapturedBuffer(
280 std::unique_ptr<Buffer> buffer, 274 std::unique_ptr<Buffer> buffer,
281 const VideoCaptureFormat& frame_format, 275 const VideoCaptureFormat& frame_format,
282 base::TimeTicks reference_time, 276 base::TimeTicks reference_time,
283 base::TimeDelta timestamp) { 277 base::TimeDelta timestamp) {
284 // Currently, only I420 pixel format is supported. 278 // Currently, only I420 pixel format is supported.
285 DCHECK_EQ(media::PIXEL_FORMAT_I420, frame_format.pixel_format); 279 DCHECK_EQ(media::PIXEL_FORMAT_I420, frame_format.pixel_format);
280 DCHECK_EQ(media::PIXEL_STORAGE_CPU, frame_format.pixel_storage);
286 281
287 scoped_refptr<VideoFrame> frame; 282 scoped_refptr<VideoFrame> frame = VideoFrame::WrapExternalSharedMemory(
288 switch (frame_format.pixel_storage) { 283 media::PIXEL_FORMAT_I420, frame_format.frame_size,
289 case media::PIXEL_STORAGE_GPUMEMORYBUFFER: { 284 gfx::Rect(frame_format.frame_size), frame_format.frame_size,
290 // Create a VideoFrame to set the correct storage_type and pixel_format. 285 reinterpret_cast<uint8_t*>(buffer->data()),
291 gfx::GpuMemoryBufferHandle handle; 286 VideoFrame::AllocationSize(media::PIXEL_FORMAT_I420,
292 frame = VideoFrame::WrapExternalYuvGpuMemoryBuffers( 287 frame_format.frame_size),
293 media::PIXEL_FORMAT_I420, frame_format.frame_size, 288 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) 289 if (!frame)
312 return; 290 return;
313 frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE, 291 frame->metadata()->SetDouble(media::VideoFrameMetadata::FRAME_RATE,
314 frame_format.frame_rate); 292 frame_format.frame_rate);
315 frame->metadata()->SetTimeTicks(media::VideoFrameMetadata::REFERENCE_TIME, 293 frame->metadata()->SetTimeTicks(media::VideoFrameMetadata::REFERENCE_TIME,
316 reference_time); 294 reference_time);
317 OnIncomingCapturedVideoFrame(std::move(buffer), frame); 295 OnIncomingCapturedVideoFrame(std::move(buffer), frame);
318 } 296 }
319 297
320 void VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame( 298 void VideoCaptureDeviceClient::OnIncomingCapturedVideoFrame(
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 return buffer_pool_->GetBufferPoolUtilization(); 335 return buffer_pool_->GetBufferPoolUtilization();
358 } 336 }
359 337
360 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer> 338 std::unique_ptr<media::VideoCaptureDevice::Client::Buffer>
361 VideoCaptureDeviceClient::ReserveI420OutputBuffer( 339 VideoCaptureDeviceClient::ReserveI420OutputBuffer(
362 const gfx::Size& dimensions, 340 const gfx::Size& dimensions,
363 media::VideoPixelStorage storage, 341 media::VideoPixelStorage storage,
364 uint8_t** y_plane_data, 342 uint8_t** y_plane_data,
365 uint8_t** u_plane_data, 343 uint8_t** u_plane_data,
366 uint8_t** v_plane_data) { 344 uint8_t** v_plane_data) {
367 DCHECK(storage == media::PIXEL_STORAGE_GPUMEMORYBUFFER || 345 DCHECK(storage == media::PIXEL_STORAGE_CPU);
368 storage == media::PIXEL_STORAGE_CPU);
369 DCHECK(dimensions.height()); 346 DCHECK(dimensions.height());
370 DCHECK(dimensions.width()); 347 DCHECK(dimensions.width());
371 348
372 const media::VideoPixelFormat format = media::PIXEL_FORMAT_I420; 349 const media::VideoPixelFormat format = media::PIXEL_FORMAT_I420;
373 std::unique_ptr<Buffer> buffer( 350 std::unique_ptr<Buffer> buffer(
374 ReserveOutputBuffer(dimensions, media::PIXEL_FORMAT_I420, storage)); 351 ReserveOutputBuffer(dimensions, media::PIXEL_FORMAT_I420, storage));
375 if (!buffer) 352 if (!buffer)
376 return std::unique_ptr<Buffer>(); 353 return std::unique_ptr<Buffer>();
377 354 // TODO(emircan): See http://crbug.com/521068, move this pointer
378 switch (storage) { 355 // arithmetic inside Buffer::data() when this bug is resolved.
379 case media::PIXEL_STORAGE_CPU: 356 *y_plane_data = reinterpret_cast<uint8_t*>(buffer->data());
380 // TODO(emircan): See http://crbug.com/521068, move this pointer 357 *u_plane_data =
381 // arithmetic inside Buffer::data() when this bug is resolved. 358 *y_plane_data +
382 *y_plane_data = reinterpret_cast<uint8_t*>(buffer->data()); 359 VideoFrame::PlaneSize(format, VideoFrame::kYPlane, dimensions).GetArea();
383 *u_plane_data = 360 *v_plane_data =
384 *y_plane_data + 361 *u_plane_data +
385 VideoFrame::PlaneSize(format, VideoFrame::kYPlane, dimensions) 362 VideoFrame::PlaneSize(format, VideoFrame::kUPlane, dimensions).GetArea();
386 .GetArea(); 363 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 } 364 }
404 365
405 } // namespace media 366 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698