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

Side by Side Diff: content/renderer/media/video_capture_impl.cc

Issue 2398463003: 16 bit capture and GPU&CPU memory buffer support.
Patch Set: fixes. 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 // Notes about usage of this object by VideoCaptureImplManager. 5 // Notes about usage of this object by VideoCaptureImplManager.
6 // 6 //
7 // VideoCaptureImplManager access this object by using a Unretained() 7 // VideoCaptureImplManager access this object by using a Unretained()
8 // binding and tasks on the IO thread. It is then important that 8 // binding and tasks on the IO thread. It is then important that
9 // VideoCaptureImpl never post task to itself. All operations must be 9 // VideoCaptureImpl never post task to itself. All operations must be
10 // synchronous. 10 // synchronous.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
46 const size_t buffer_size_; 46 const size_t buffer_size_;
47 47
48 DISALLOW_COPY_AND_ASSIGN(ClientBuffer); 48 DISALLOW_COPY_AND_ASSIGN(ClientBuffer);
49 }; 49 };
50 50
51 // A holder of a GpuMemoryBuffer-backed buffer, Map()ed on ctor and Unmap()ed on 51 // A holder of a GpuMemoryBuffer-backed buffer, Map()ed on ctor and Unmap()ed on
52 // dtor. Creates and owns GpuMemoryBuffer instances. 52 // dtor. Creates and owns GpuMemoryBuffer instances.
53 class VideoCaptureImpl::ClientBuffer2 53 class VideoCaptureImpl::ClientBuffer2
54 : public base::RefCountedThreadSafe<ClientBuffer2> { 54 : public base::RefCountedThreadSafe<ClientBuffer2> {
55 public: 55 public:
56 ClientBuffer2( 56 ClientBuffer2(const std::vector<gfx::GpuMemoryBufferHandle>& client_handles,
57 const std::vector<gfx::GpuMemoryBufferHandle>& client_handles, 57 const gfx::Size& size,
58 const gfx::Size& size) 58 media::VideoPixelFormat format)
59 : handles_(client_handles), 59 : handles_(client_handles) {
60 size_(size) { 60 DCHECK(format == media::PIXEL_FORMAT_I420 ||
61 const media::VideoPixelFormat format = media::PIXEL_FORMAT_I420; 61 format == media::PIXEL_FORMAT_Y16);
62 DCHECK_EQ(handles_.size(), media::VideoFrame::NumPlanes(format)); 62 DCHECK_EQ(handles_.size(), media::VideoFrame::NumPlanes(format));
63 for (size_t i = 0; i < handles_.size(); ++i) { 63 for (size_t i = 0; i < handles_.size(); ++i) {
64 const size_t width = media::VideoFrame::Columns(i, format, size_.width()); 64 const size_t width = media::VideoFrame::Columns(i, format, size.width());
65 const size_t height = media::VideoFrame::Rows(i, format, size_.height()); 65 const size_t height = media::VideoFrame::Rows(i, format, size.height());
66 buffers_.push_back(gpu::GpuMemoryBufferImpl::CreateFromHandle( 66 buffers_.push_back(gpu::GpuMemoryBufferImpl::CreateFromHandle(
67 handles_[i], gfx::Size(width, height), gfx::BufferFormat::R_8, 67 handles_[i], gfx::Size(width, height),
68 media::VideoFrame::BufferFormat(format),
68 gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, 69 gfx::BufferUsage::GPU_READ_CPU_READ_WRITE,
69 base::Bind(&ClientBuffer2::DestroyGpuMemoryBuffer, 70 base::Bind(&ClientBuffer2::DestroyGpuMemoryBuffer,
70 base::Unretained(this)))); 71 base::Unretained(this))));
71 bool rv = buffers_[i]->Map(); 72 bool rv = buffers_[i]->Map();
72 DCHECK(rv); 73 DCHECK(rv);
73 data_[i] = reinterpret_cast<uint8_t*>(buffers_[i]->memory(0u)); 74 data_[i] = reinterpret_cast<uint8_t*>(buffers_[i]->memory(0u));
74 strides_[i] = width; 75 strides_[i] = width;
75 } 76 }
76 } 77 }
77 78
78 uint8_t* data(int plane) const { return data_[plane]; } 79 uint8_t* data(int plane) const { return data_[plane]; }
79 int32_t stride(int plane) const { return strides_[plane]; } 80 int32_t stride(int plane) const { return strides_[plane]; }
80 std::vector<gfx::GpuMemoryBufferHandle> gpu_memory_buffer_handles() { 81 std::vector<gfx::GpuMemoryBufferHandle> gpu_memory_buffer_handles() {
81 return handles_; 82 return handles_;
82 } 83 }
83 84
84 private: 85 private:
85 friend class base::RefCountedThreadSafe<ClientBuffer2>; 86 friend class base::RefCountedThreadSafe<ClientBuffer2>;
86 87
87 virtual ~ClientBuffer2() { 88 virtual ~ClientBuffer2() {
88 for (auto* buffer : buffers_) 89 for (auto* buffer : buffers_)
89 buffer->Unmap(); 90 buffer->Unmap();
90 } 91 }
91 92
92 void DestroyGpuMemoryBuffer(const gpu::SyncToken& sync_token) {} 93 void DestroyGpuMemoryBuffer(const gpu::SyncToken& sync_token) {}
93 94
94 const std::vector<gfx::GpuMemoryBufferHandle> handles_; 95 const std::vector<gfx::GpuMemoryBufferHandle> handles_;
95 const gfx::Size size_;
96 ScopedVector<gfx::GpuMemoryBuffer> buffers_; 96 ScopedVector<gfx::GpuMemoryBuffer> buffers_;
97 uint8_t* data_[media::VideoFrame::kMaxPlanes]; 97 uint8_t* data_[media::VideoFrame::kMaxPlanes];
98 int32_t strides_[media::VideoFrame::kMaxPlanes]; 98 int32_t strides_[media::VideoFrame::kMaxPlanes];
99 99
100 DISALLOW_COPY_AND_ASSIGN(ClientBuffer2); 100 DISALLOW_COPY_AND_ASSIGN(ClientBuffer2);
101 }; 101 };
102 102
103 VideoCaptureImpl::ClientInfo::ClientInfo() {} 103 VideoCaptureImpl::ClientInfo::ClientInfo() {}
104 VideoCaptureImpl::ClientInfo::ClientInfo(const ClientInfo& other) = default; 104 VideoCaptureImpl::ClientInfo::ClientInfo(const ClientInfo& other) = default;
105 VideoCaptureImpl::ClientInfo::~ClientInfo() {} 105 VideoCaptureImpl::ClientInfo::~ClientInfo() {}
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 client_buffers_.insert(std::make_pair( 252 client_buffers_.insert(std::make_pair(
253 buffer_id, 253 buffer_id,
254 new ClientBuffer(std::move(shm), length))) 254 new ClientBuffer(std::move(shm), length)))
255 .second; 255 .second;
256 DCHECK(inserted); 256 DCHECK(inserted);
257 } 257 }
258 258
259 void VideoCaptureImpl::OnBufferCreated2( 259 void VideoCaptureImpl::OnBufferCreated2(
260 const std::vector<gfx::GpuMemoryBufferHandle>& handles, 260 const std::vector<gfx::GpuMemoryBufferHandle>& handles,
261 const gfx::Size& size, 261 const gfx::Size& size,
262 media::VideoPixelFormat format,
262 int buffer_id) { 263 int buffer_id) {
263 DCHECK(io_task_runner_->BelongsToCurrentThread()); 264 DCHECK(io_task_runner_->BelongsToCurrentThread());
264 265
265 // In case client calls StopCapture before the arrival of created buffer, 266 // In case client calls StopCapture before the arrival of created buffer,
266 // just close this buffer and return. 267 // just close this buffer and return.
267 if (state_ != VIDEO_CAPTURE_STATE_STARTED) 268 if (state_ != VIDEO_CAPTURE_STATE_STARTED)
268 return; 269 return;
269 270
270 const bool inserted = 271 const bool inserted =
271 client_buffer2s_.insert(std::make_pair(buffer_id, 272 client_buffer2s_
272 new ClientBuffer2(handles, size))) 273 .insert(std::make_pair(buffer_id,
274 new ClientBuffer2(handles, size, format)))
273 .second; 275 .second;
274 DCHECK(inserted); 276 DCHECK(inserted);
275 } 277 }
276 278
277 void VideoCaptureImpl::OnBufferDestroyed(int buffer_id) { 279 void VideoCaptureImpl::OnBufferDestroyed(int buffer_id) {
278 DCHECK(io_task_runner_->BelongsToCurrentThread()); 280 DCHECK(io_task_runner_->BelongsToCurrentThread());
279 281
280 const auto& cb_iter = client_buffers_.find(buffer_id); 282 const auto& cb_iter = client_buffers_.find(buffer_id);
281 if (cb_iter != client_buffers_.end()) { 283 if (cb_iter != client_buffers_.end()) {
282 DCHECK(!cb_iter->second.get() || cb_iter->second->HasOneRef()) 284 DCHECK(!cb_iter->second.get() || cb_iter->second->HasOneRef())
(...skipping 12 matching lines...) Expand all
295 void VideoCaptureImpl::OnBufferReceived( 297 void VideoCaptureImpl::OnBufferReceived(
296 int buffer_id, 298 int buffer_id,
297 base::TimeDelta timestamp, 299 base::TimeDelta timestamp,
298 const base::DictionaryValue& metadata, 300 const base::DictionaryValue& metadata,
299 media::VideoPixelFormat pixel_format, 301 media::VideoPixelFormat pixel_format,
300 media::VideoFrame::StorageType storage_type, 302 media::VideoFrame::StorageType storage_type,
301 const gfx::Size& coded_size, 303 const gfx::Size& coded_size,
302 const gfx::Rect& visible_rect) { 304 const gfx::Rect& visible_rect) {
303 DCHECK(io_task_runner_->BelongsToCurrentThread()); 305 DCHECK(io_task_runner_->BelongsToCurrentThread());
304 if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_ || 306 if (state_ != VIDEO_CAPTURE_STATE_STARTED || suspended_ ||
305 pixel_format != media::PIXEL_FORMAT_I420 || 307 (pixel_format != media::PIXEL_FORMAT_I420 &&
308 pixel_format != media::PIXEL_FORMAT_Y16) ||
306 (storage_type != media::VideoFrame::STORAGE_SHMEM && 309 (storage_type != media::VideoFrame::STORAGE_SHMEM &&
307 storage_type != media::VideoFrame::STORAGE_GPU_MEMORY_BUFFERS)) { 310 storage_type != media::VideoFrame::STORAGE_GPU_MEMORY_BUFFERS)) {
308 // Crash in debug builds since the host should not have provided a buffer 311 // Crash in debug builds since the host should not have provided a buffer
309 // with an unsupported pixel format or storage type. 312 // with an unsupported pixel format or storage type.
310 DCHECK_EQ(media::PIXEL_FORMAT_I420, pixel_format); 313 DCHECK(media::PIXEL_FORMAT_I420 == pixel_format ||
314 media::PIXEL_FORMAT_Y16 == pixel_format);
311 DCHECK(storage_type == media::VideoFrame::STORAGE_SHMEM || 315 DCHECK(storage_type == media::VideoFrame::STORAGE_SHMEM ||
312 storage_type == media::VideoFrame::STORAGE_GPU_MEMORY_BUFFERS); 316 storage_type == media::VideoFrame::STORAGE_GPU_MEMORY_BUFFERS);
313 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id, 317 Send(new VideoCaptureHostMsg_BufferReady(device_id_, buffer_id,
314 gpu::SyncToken(), -1.0)); 318 gpu::SyncToken(), -1.0));
315 return; 319 return;
316 } 320 }
317 321
318 base::TimeTicks reference_time; 322 base::TimeTicks reference_time;
319 media::VideoFrameMetadata frame_metadata; 323 media::VideoFrameMetadata frame_metadata;
320 frame_metadata.MergeInternalValuesFrom(metadata); 324 frame_metadata.MergeInternalValuesFrom(metadata);
(...skipping 21 matching lines...) Expand all
342 346
343 scoped_refptr<media::VideoFrame> frame; 347 scoped_refptr<media::VideoFrame> frame;
344 BufferFinishedCallback buffer_finished_callback; 348 BufferFinishedCallback buffer_finished_callback;
345 std::unique_ptr<gpu::SyncToken> release_sync_token(new gpu::SyncToken); 349 std::unique_ptr<gpu::SyncToken> release_sync_token(new gpu::SyncToken);
346 switch (storage_type) { 350 switch (storage_type) {
347 case media::VideoFrame::STORAGE_GPU_MEMORY_BUFFERS: { 351 case media::VideoFrame::STORAGE_GPU_MEMORY_BUFFERS: {
348 const auto& iter = client_buffer2s_.find(buffer_id); 352 const auto& iter = client_buffer2s_.find(buffer_id);
349 DCHECK(iter != client_buffer2s_.end()); 353 DCHECK(iter != client_buffer2s_.end());
350 scoped_refptr<ClientBuffer2> buffer = iter->second; 354 scoped_refptr<ClientBuffer2> buffer = iter->second;
351 const auto& handles = buffer->gpu_memory_buffer_handles(); 355 const auto& handles = buffer->gpu_memory_buffer_handles();
352 frame = media::VideoFrame::WrapExternalYuvGpuMemoryBuffers( 356 frame =
353 media::PIXEL_FORMAT_I420, coded_size, gfx::Rect(coded_size), 357 (pixel_format == media::PIXEL_FORMAT_I420)
354 coded_size, buffer->stride(media::VideoFrame::kYPlane), 358 ? media::VideoFrame::WrapExternalYuvGpuMemoryBuffers(
355 buffer->stride(media::VideoFrame::kUPlane), 359 media::PIXEL_FORMAT_I420, coded_size, gfx::Rect(coded_size),
356 buffer->stride(media::VideoFrame::kVPlane), 360 coded_size, buffer->stride(media::VideoFrame::kYPlane),
357 buffer->data(media::VideoFrame::kYPlane), 361 buffer->stride(media::VideoFrame::kUPlane),
358 buffer->data(media::VideoFrame::kUPlane), 362 buffer->stride(media::VideoFrame::kVPlane),
359 buffer->data(media::VideoFrame::kVPlane), 363 buffer->data(media::VideoFrame::kYPlane),
360 handles[media::VideoFrame::kYPlane], 364 buffer->data(media::VideoFrame::kUPlane),
361 handles[media::VideoFrame::kUPlane], 365 buffer->data(media::VideoFrame::kVPlane),
362 handles[media::VideoFrame::kVPlane], timestamp); 366 handles[media::VideoFrame::kYPlane],
367 handles[media::VideoFrame::kUPlane],
368 handles[media::VideoFrame::kVPlane], timestamp)
369 : media::VideoFrame::WrapExternalGpuMemoryBuffer(
370 pixel_format, coded_size, gfx::Rect(coded_size), coded_size,
371 buffer->data(0), handles[0], timestamp);
363 buffer_finished_callback = media::BindToCurrentLoop( 372 buffer_finished_callback = media::BindToCurrentLoop(
364 base::Bind(&VideoCaptureImpl::OnClientBufferFinished2, 373 base::Bind(&VideoCaptureImpl::OnClientBufferFinished2,
365 weak_factory_.GetWeakPtr(), buffer_id, buffer)); 374 weak_factory_.GetWeakPtr(), buffer_id, buffer));
366 break; 375 break;
367 } 376 }
368 case media::VideoFrame::STORAGE_SHMEM: { 377 case media::VideoFrame::STORAGE_SHMEM: {
369 const auto& iter = client_buffers_.find(buffer_id); 378 const auto& iter = client_buffers_.find(buffer_id);
370 DCHECK(iter != client_buffers_.end()); 379 DCHECK(iter != client_buffers_.end());
371 const scoped_refptr<ClientBuffer> buffer = iter->second; 380 const scoped_refptr<ClientBuffer> buffer = iter->second;
372 frame = media::VideoFrame::WrapExternalSharedMemory( 381 frame = media::VideoFrame::WrapExternalSharedMemory(
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 double consumer_resource_utilization = -1.0; 571 double consumer_resource_utilization = -1.0;
563 if (!metadata->GetDouble(media::VideoFrameMetadata::RESOURCE_UTILIZATION, 572 if (!metadata->GetDouble(media::VideoFrameMetadata::RESOURCE_UTILIZATION,
564 &consumer_resource_utilization)) { 573 &consumer_resource_utilization)) {
565 consumer_resource_utilization = -1.0; 574 consumer_resource_utilization = -1.0;
566 } 575 }
567 576
568 callback_to_io_thread.Run(*release_sync_token, consumer_resource_utilization); 577 callback_to_io_thread.Run(*release_sync_token, consumer_resource_utilization);
569 } 578 }
570 579
571 } // namespace content 580 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/video_capture_impl.h ('k') | content/renderer/media/video_capture_message_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698