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

Side by Side Diff: content/browser/renderer_host/media/video_capture_buffer_pool.cc

Issue 1204063005: Reland: Video Capture: extract storage info from pixel format in VideoCaptureFormat. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: dcheng@s https://codereview.chromium.org/1210743003/#ps20001 Created 5 years, 6 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) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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_buffer_pool.h" 5 #include "content/browser/renderer_host/media/video_capture_buffer_pool.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/stl_util.h" 9 #include "base/stl_util.h"
10 #include "content/browser/gpu/browser_gpu_memory_buffer_manager.h" 10 #include "content/browser/gpu/browser_gpu_memory_buffer_manager.h"
11 #include "content/common/gpu/client/gpu_memory_buffer_impl.h" 11 #include "content/common/gpu/client/gpu_memory_buffer_impl.h"
12 #include "content/public/browser/browser_thread.h" 12 #include "content/public/browser/browser_thread.h"
13 #include "media/base/video_frame.h"
14
15 using media::VideoFrame;
16 13
17 namespace content { 14 namespace content {
18 15
19 const int VideoCaptureBufferPool::kInvalidId = -1; 16 const int VideoCaptureBufferPool::kInvalidId = -1;
20 17
21 VideoFrame::Format VideoPixelFormatToVideoFrameFormat(
22 media::VideoPixelFormat pixel_format) {
23 static struct {
24 media::VideoPixelFormat pixel_format;
25 VideoFrame::Format frame_format;
26 } const kVideoPixelFormatToVideoFrameFormat[] = {
27 {media::PIXEL_FORMAT_I420, VideoFrame::I420},
28 {media::PIXEL_FORMAT_TEXTURE, VideoFrame::ARGB},
29 {media::PIXEL_FORMAT_GPUMEMORYBUFFER, VideoFrame::ARGB},
30 };
31
32 for (const auto& format_pair : kVideoPixelFormatToVideoFrameFormat) {
33 if (format_pair.pixel_format == pixel_format)
34 return format_pair.frame_format;
35 }
36 LOG(ERROR) << "Unsupported VideoPixelFormat "
37 << media::VideoCaptureFormat::PixelFormatToString(pixel_format);
38 return VideoFrame::UNKNOWN;
39 }
40
41 VideoFrame::StorageType VideoPixelFormatToVideoFrameStorageType(
42 media::VideoPixelFormat pixel_format) {
43 static struct {
44 media::VideoPixelFormat pixel_format;
45 VideoFrame::StorageType storage_type;
46 } const kVideoPixelFormatToVideoFrameStorageType[] = {
47 {media::PIXEL_FORMAT_I420, VideoFrame::STORAGE_SHMEM},
48 {media::PIXEL_FORMAT_TEXTURE, VideoFrame::STORAGE_OPAQUE},
49 {media::PIXEL_FORMAT_GPUMEMORYBUFFER, VideoFrame::STORAGE_OPAQUE},
50 };
51
52 for (const auto& format_pair : kVideoPixelFormatToVideoFrameStorageType) {
53 if (format_pair.pixel_format == pixel_format)
54 return format_pair.storage_type;
55 }
56 LOG(ERROR) << "Unsupported VideoPixelFormat "
57 << media::VideoCaptureFormat::PixelFormatToString(pixel_format);
58 return VideoFrame::STORAGE_UNKNOWN;
59 }
60
61 // A simple holder of a memory-backed buffer and accesors to it. 18 // A simple holder of a memory-backed buffer and accesors to it.
62 class SimpleBufferHandle final : public VideoCaptureBufferPool::BufferHandle { 19 class SimpleBufferHandle final : public VideoCaptureBufferPool::BufferHandle {
63 public: 20 public:
64 SimpleBufferHandle(void* data, size_t size, base::SharedMemoryHandle handle) 21 SimpleBufferHandle(void* data, size_t size, base::SharedMemoryHandle handle)
65 : data_(data), size_(size), handle_(handle) {} 22 : data_(data), size_(size), handle_(handle) {}
66 ~SimpleBufferHandle() override {} 23 ~SimpleBufferHandle() override {}
67 24
68 size_t size() const override { return size_; } 25 size_t size() const override { return size_; }
69 void* data() override { return data_; } 26 void* data() override { return data_; }
70 ClientBuffer AsClientBuffer() override { return nullptr; } 27 ClientBuffer AsClientBuffer() override { return nullptr; }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 private: 74 private:
118 gfx::GpuMemoryBuffer* const gmb_; 75 gfx::GpuMemoryBuffer* const gmb_;
119 scoped_ptr<void*[]> data_; 76 scoped_ptr<void*[]> data_;
120 const size_t size_; 77 const size_t size_;
121 }; 78 };
122 79
123 // Tracker specifics for SharedMemory. 80 // Tracker specifics for SharedMemory.
124 class VideoCaptureBufferPool::SharedMemTracker final : public Tracker { 81 class VideoCaptureBufferPool::SharedMemTracker final : public Tracker {
125 public: 82 public:
126 SharedMemTracker(); 83 SharedMemTracker();
127 bool Init(VideoFrame::Format format, 84 bool Init(media::VideoPixelFormat format,
128 media::VideoFrame::StorageType storage_type, 85 media::VideoPixelStorage storage_type,
129 const gfx::Size& dimensions) override; 86 const gfx::Size& dimensions) override;
130 87
131 size_t mapped_size() const override { return shared_memory_.mapped_size(); } 88 size_t mapped_size() const override { return shared_memory_.mapped_size(); }
132 89
133 scoped_ptr<BufferHandle> GetBufferHandle() override { 90 scoped_ptr<BufferHandle> GetBufferHandle() override {
134 return make_scoped_ptr(new SimpleBufferHandle( 91 return make_scoped_ptr(new SimpleBufferHandle(
135 shared_memory_.memory(), mapped_size(), shared_memory_.handle())); 92 shared_memory_.memory(), mapped_size(), shared_memory_.handle()));
136 } 93 }
137 94
138 bool ShareToProcess(base::ProcessHandle process_handle, 95 bool ShareToProcess(base::ProcessHandle process_handle,
139 base::SharedMemoryHandle* new_handle) override { 96 base::SharedMemoryHandle* new_handle) override {
140 return shared_memory_.ShareToProcess(process_handle, new_handle); 97 return shared_memory_.ShareToProcess(process_handle, new_handle);
141 } 98 }
142 99
143 private: 100 private:
144 // The memory created to be shared with renderer processes. 101 // The memory created to be shared with renderer processes.
145 base::SharedMemory shared_memory_; 102 base::SharedMemory shared_memory_;
146 }; 103 };
147 104
148 // Tracker specifics for GpuMemoryBuffer. Owns one GpuMemoryBuffer and its 105 // Tracker specifics for GpuMemoryBuffer. Owns one GpuMemoryBuffer and its
149 // associated pixel dimensions. 106 // associated pixel dimensions.
150 class VideoCaptureBufferPool::GpuMemoryBufferTracker final : public Tracker { 107 class VideoCaptureBufferPool::GpuMemoryBufferTracker final : public Tracker {
151 public: 108 public:
152 GpuMemoryBufferTracker(); 109 GpuMemoryBufferTracker();
153 bool Init(VideoFrame::Format format, 110 bool Init(media::VideoPixelFormat format,
154 media::VideoFrame::StorageType storage_type, 111 media::VideoPixelStorage storage_type,
155 const gfx::Size& dimensions) override; 112 const gfx::Size& dimensions) override;
156 ~GpuMemoryBufferTracker() override; 113 ~GpuMemoryBufferTracker() override;
157 114
158 size_t mapped_size() const override { return packed_size_; } 115 size_t mapped_size() const override { return packed_size_; }
159 scoped_ptr<BufferHandle> GetBufferHandle() override { 116 scoped_ptr<BufferHandle> GetBufferHandle() override {
160 return make_scoped_ptr(new GpuMemoryBufferBufferHandle( 117 return make_scoped_ptr(new GpuMemoryBufferBufferHandle(
161 gpu_memory_buffer_.get(), packed_size_)); 118 gpu_memory_buffer_.get(), packed_size_));
162 } 119 }
163 120
164 bool ShareToProcess(base::ProcessHandle process_handle, 121 bool ShareToProcess(base::ProcessHandle process_handle,
165 base::SharedMemoryHandle* new_handle) override { 122 base::SharedMemoryHandle* new_handle) override {
166 return true; 123 return true;
167 } 124 }
168 125
169 private: 126 private:
170 size_t packed_size_; 127 size_t packed_size_;
171 scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_; 128 scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_;
172 }; 129 };
173 130
174 VideoCaptureBufferPool::SharedMemTracker::SharedMemTracker() : Tracker() { 131 VideoCaptureBufferPool::SharedMemTracker::SharedMemTracker() : Tracker() {
175 } 132 }
176 133
177 bool VideoCaptureBufferPool::SharedMemTracker::Init( 134 bool VideoCaptureBufferPool::SharedMemTracker::Init(
178 VideoFrame::Format format, 135 media::VideoPixelFormat format,
179 media::VideoFrame::StorageType storage_type, 136 media::VideoPixelStorage storage_type,
180 const gfx::Size& dimensions) { 137 const gfx::Size& dimensions) {
181 DVLOG(2) << "allocating ShMem of " << dimensions.ToString(); 138 DVLOG(2) << "allocating ShMem of " << dimensions.ToString();
182 set_pixel_format(format); 139 set_pixel_format(format);
183 set_storage_type(storage_type); 140 set_storage_type(storage_type);
184 // Input |dimensions| can be 0x0 for trackers that do not require memory 141 // |dimensions| can be 0x0 for trackers that do not require memory backing.
185 // backing. The allocated size is calculated using VideoFrame methods since
186 // this will be the abstraction used to wrap the underlying data.
187 set_pixel_count(dimensions.GetArea()); 142 set_pixel_count(dimensions.GetArea());
188 const size_t byte_count = VideoFrame::AllocationSize(format, dimensions); 143 const size_t byte_count =
144 media::VideoCaptureFormat(dimensions, 0.0f, format, storage_type)
145 .ImageAllocationSize();
189 if (!byte_count) 146 if (!byte_count)
190 return true; 147 return true;
191 return shared_memory_.CreateAndMapAnonymous(byte_count); 148 return shared_memory_.CreateAndMapAnonymous(byte_count);
192 } 149 }
193 150
194 VideoCaptureBufferPool::GpuMemoryBufferTracker::GpuMemoryBufferTracker() 151 VideoCaptureBufferPool::GpuMemoryBufferTracker::GpuMemoryBufferTracker()
195 : Tracker(), gpu_memory_buffer_(nullptr) {} 152 : Tracker(), packed_size_(0u), gpu_memory_buffer_(nullptr) {
153 }
196 154
197 VideoCaptureBufferPool::GpuMemoryBufferTracker::~GpuMemoryBufferTracker() { 155 VideoCaptureBufferPool::GpuMemoryBufferTracker::~GpuMemoryBufferTracker() {
198 if (gpu_memory_buffer_->IsMapped()) 156 if (gpu_memory_buffer_->IsMapped())
199 gpu_memory_buffer_->Unmap(); 157 gpu_memory_buffer_->Unmap();
200 } 158 }
201 159
202 bool VideoCaptureBufferPool::GpuMemoryBufferTracker::Init( 160 bool VideoCaptureBufferPool::GpuMemoryBufferTracker::Init(
203 VideoFrame::Format format, 161 media::VideoPixelFormat format,
204 media::VideoFrame::StorageType storage_type, 162 media::VideoPixelStorage storage_type,
205 const gfx::Size& dimensions) { 163 const gfx::Size& dimensions) {
206 DVLOG(2) << "allocating GMB for " << dimensions.ToString(); 164 DVLOG(2) << "allocating GMB for " << dimensions.ToString();
207 // BrowserGpuMemoryBufferManager::current() may not be accessed on IO Thread. 165 // BrowserGpuMemoryBufferManager::current() may not be accessed on IO Thread.
208 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO)); 166 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
209 DCHECK(BrowserGpuMemoryBufferManager::current()); 167 DCHECK(BrowserGpuMemoryBufferManager::current());
210 set_pixel_format(format); 168 set_pixel_format(format);
211 set_storage_type(storage_type); 169 set_storage_type(storage_type);
212 set_pixel_count(dimensions.GetArea()); 170 set_pixel_count(dimensions.GetArea());
171 // |dimensions| can be 0x0 for trackers that do not require memory backing.
172 if (dimensions.GetArea() == 0u)
173 return true;
213 gpu_memory_buffer_ = 174 gpu_memory_buffer_ =
214 BrowserGpuMemoryBufferManager::current()->AllocateGpuMemoryBuffer( 175 BrowserGpuMemoryBufferManager::current()->AllocateGpuMemoryBuffer(
215 dimensions, 176 dimensions,
216 gfx::GpuMemoryBuffer::BGRA_8888, 177 gfx::GpuMemoryBuffer::BGRA_8888,
217 gfx::GpuMemoryBuffer::MAP); 178 gfx::GpuMemoryBuffer::MAP);
218 DLOG_IF(ERROR, !gpu_memory_buffer_.get()) << "Allocating GpuMemoryBuffer"; 179 DLOG_IF(ERROR, !gpu_memory_buffer_.get()) << "Allocating GpuMemoryBuffer";
219 if (!gpu_memory_buffer_.get()) 180 if (!gpu_memory_buffer_.get())
220 return false; 181 return false;
221 int plane_sizes; 182 int plane_sizes;
222 gpu_memory_buffer_->GetStride(&plane_sizes); 183 gpu_memory_buffer_->GetStride(&plane_sizes);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 if (!tracker) { 234 if (!tracker) {
274 NOTREACHED() << "Invalid buffer_id."; 235 NOTREACHED() << "Invalid buffer_id.";
275 return scoped_ptr<BufferHandle>(); 236 return scoped_ptr<BufferHandle>();
276 } 237 }
277 238
278 DCHECK(tracker->held_by_producer()); 239 DCHECK(tracker->held_by_producer());
279 return tracker->GetBufferHandle(); 240 return tracker->GetBufferHandle();
280 } 241 }
281 242
282 int VideoCaptureBufferPool::ReserveForProducer(media::VideoPixelFormat format, 243 int VideoCaptureBufferPool::ReserveForProducer(media::VideoPixelFormat format,
244 media::VideoPixelStorage storage,
283 const gfx::Size& dimensions, 245 const gfx::Size& dimensions,
284 int* buffer_id_to_drop) { 246 int* buffer_id_to_drop) {
285 base::AutoLock lock(lock_); 247 base::AutoLock lock(lock_);
286 return ReserveForProducerInternal(format, dimensions, buffer_id_to_drop); 248 return ReserveForProducerInternal(format, storage, dimensions,
249 buffer_id_to_drop);
287 } 250 }
288 251
289 void VideoCaptureBufferPool::RelinquishProducerReservation(int buffer_id) { 252 void VideoCaptureBufferPool::RelinquishProducerReservation(int buffer_id) {
290 base::AutoLock lock(lock_); 253 base::AutoLock lock(lock_);
291 Tracker* tracker = GetTracker(buffer_id); 254 Tracker* tracker = GetTracker(buffer_id);
292 if (!tracker) { 255 if (!tracker) {
293 NOTREACHED() << "Invalid buffer_id."; 256 NOTREACHED() << "Invalid buffer_id.";
294 return; 257 return;
295 } 258 }
296 DCHECK(tracker->held_by_producer()); 259 DCHECK(tracker->held_by_producer());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 int num_buffers_held = 0; 297 int num_buffers_held = 0;
335 for (const auto& entry : trackers_) { 298 for (const auto& entry : trackers_) {
336 Tracker* const tracker = entry.second; 299 Tracker* const tracker = entry.second;
337 if (tracker->held_by_producer() || tracker->consumer_hold_count() > 0) 300 if (tracker->held_by_producer() || tracker->consumer_hold_count() > 0)
338 ++num_buffers_held; 301 ++num_buffers_held;
339 } 302 }
340 return static_cast<double>(num_buffers_held) / count_; 303 return static_cast<double>(num_buffers_held) / count_;
341 } 304 }
342 305
343 int VideoCaptureBufferPool::ReserveForProducerInternal( 306 int VideoCaptureBufferPool::ReserveForProducerInternal(
344 media::VideoPixelFormat format, 307 media::VideoPixelFormat pixel_format,
308 media::VideoPixelStorage storage_type,
345 const gfx::Size& dimensions, 309 const gfx::Size& dimensions,
346 int* buffer_id_to_drop) { 310 int* buffer_id_to_drop) {
347 DCHECK(format == media::PIXEL_FORMAT_I420 ||
348 format == media::PIXEL_FORMAT_TEXTURE ||
349 format == media::PIXEL_FORMAT_GPUMEMORYBUFFER );
350 lock_.AssertAcquired(); 311 lock_.AssertAcquired();
351 *buffer_id_to_drop = kInvalidId; 312 *buffer_id_to_drop = kInvalidId;
352 313
353 const size_t size_in_pixels = dimensions.GetArea(); 314 const size_t size_in_pixels = dimensions.GetArea();
354 const media::VideoFrame::Format pixel_format =
355 VideoPixelFormatToVideoFrameFormat(format);
356 const media::VideoFrame::StorageType storage_type =
357 VideoPixelFormatToVideoFrameStorageType(format);
358 // Look for a tracker that's allocated, big enough, and not in use. Track the 315 // Look for a tracker that's allocated, big enough, and not in use. Track the
359 // largest one that's not big enough, in case we have to reallocate a tracker. 316 // largest one that's not big enough, in case we have to reallocate a tracker.
360 *buffer_id_to_drop = kInvalidId; 317 *buffer_id_to_drop = kInvalidId;
361 size_t largest_size_in_pixels = 0; 318 size_t largest_size_in_pixels = 0;
362 TrackerMap::iterator tracker_to_drop = trackers_.end(); 319 TrackerMap::iterator tracker_to_drop = trackers_.end();
363 for (TrackerMap::iterator it = trackers_.begin(); it != trackers_.end(); 320 for (TrackerMap::iterator it = trackers_.begin(); it != trackers_.end();
364 ++it) { 321 ++it) {
365 Tracker* const tracker = it->second; 322 Tracker* const tracker = it->second;
366 if (!tracker->consumer_hold_count() && !tracker->held_by_producer()) { 323 if (!tracker->consumer_hold_count() && !tracker->held_by_producer()) {
367 if (tracker->pixel_count() >= size_in_pixels && 324 if (tracker->pixel_count() >= size_in_pixels &&
(...skipping 18 matching lines...) Expand all
386 return kInvalidId; 343 return kInvalidId;
387 } 344 }
388 *buffer_id_to_drop = tracker_to_drop->first; 345 *buffer_id_to_drop = tracker_to_drop->first;
389 delete tracker_to_drop->second; 346 delete tracker_to_drop->second;
390 trackers_.erase(tracker_to_drop); 347 trackers_.erase(tracker_to_drop);
391 } 348 }
392 349
393 // Create the new tracker. 350 // Create the new tracker.
394 const int buffer_id = next_buffer_id_++; 351 const int buffer_id = next_buffer_id_++;
395 352
396 scoped_ptr<Tracker> tracker = 353 scoped_ptr<Tracker> tracker = Tracker::CreateTracker(
397 Tracker::CreateTracker(format == media::PIXEL_FORMAT_GPUMEMORYBUFFER); 354 storage_type == media::PIXEL_STORAGE_GPUMEMORYBUFFER);
398 if (!tracker->Init(pixel_format, storage_type, dimensions)) { 355 if (!tracker->Init(pixel_format, storage_type, dimensions)) {
399 DLOG(ERROR) << "Error initializing Tracker"; 356 DLOG(ERROR) << "Error initializing Tracker";
400 return kInvalidId; 357 return kInvalidId;
401 } 358 }
402 tracker->set_held_by_producer(true); 359 tracker->set_held_by_producer(true);
403 trackers_[buffer_id] = tracker.release(); 360 trackers_[buffer_id] = tracker.release();
404 361
405 return buffer_id; 362 return buffer_id;
406 } 363 }
407 364
408 VideoCaptureBufferPool::Tracker* VideoCaptureBufferPool::GetTracker( 365 VideoCaptureBufferPool::Tracker* VideoCaptureBufferPool::GetTracker(
409 int buffer_id) { 366 int buffer_id) {
410 TrackerMap::const_iterator it = trackers_.find(buffer_id); 367 TrackerMap::const_iterator it = trackers_.find(buffer_id);
411 return (it == trackers_.end()) ? NULL : it->second; 368 return (it == trackers_.end()) ? NULL : it->second;
412 } 369 }
413 370
414 } // namespace content 371 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698