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

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

Issue 1179323002: Video Capture: extract storage info from pixel format in VideoCaptureFormat. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: second round of comments from hubbe@. Rebase 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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 private: 66 private:
110 gfx::GpuMemoryBuffer* const gmb_; 67 gfx::GpuMemoryBuffer* const gmb_;
111 scoped_ptr<void*[]> data_; 68 scoped_ptr<void*[]> data_;
112 const size_t size_; 69 const size_t size_;
113 }; 70 };
114 71
115 // Tracker specifics for SharedMemory. 72 // Tracker specifics for SharedMemory.
116 class VideoCaptureBufferPool::SharedMemTracker final : public Tracker { 73 class VideoCaptureBufferPool::SharedMemTracker final : public Tracker {
117 public: 74 public:
118 SharedMemTracker(); 75 SharedMemTracker();
119 bool Init(VideoFrame::Format format, 76 bool Init(media::VideoPixelFormat format,
120 media::VideoFrame::StorageType storage_type, 77 media::VideoPixelStorage storage_type,
121 const gfx::Size& dimensions) override; 78 const gfx::Size& dimensions) override;
122 79
123 size_t mapped_size() const override { return shared_memory_.mapped_size(); } 80 size_t mapped_size() const override { return shared_memory_.mapped_size(); }
124 81
125 scoped_ptr<BufferHandle> GetBufferHandle() override { 82 scoped_ptr<BufferHandle> GetBufferHandle() override {
126 return make_scoped_ptr(new SimpleBufferHandle( 83 return make_scoped_ptr(new SimpleBufferHandle(
127 shared_memory_.memory(), mapped_size(), shared_memory_.handle())); 84 shared_memory_.memory(), mapped_size(), shared_memory_.handle()));
128 } 85 }
129 86
130 bool ShareToProcess(base::ProcessHandle process_handle, 87 bool ShareToProcess(base::ProcessHandle process_handle,
131 base::SharedMemoryHandle* new_handle) override { 88 base::SharedMemoryHandle* new_handle) override {
132 return shared_memory_.ShareToProcess(process_handle, new_handle); 89 return shared_memory_.ShareToProcess(process_handle, new_handle);
133 } 90 }
134 91
135 private: 92 private:
136 // The memory created to be shared with renderer processes. 93 // The memory created to be shared with renderer processes.
137 base::SharedMemory shared_memory_; 94 base::SharedMemory shared_memory_;
138 }; 95 };
139 96
140 // Tracker specifics for GpuMemoryBuffer. Owns one GpuMemoryBuffer and its 97 // Tracker specifics for GpuMemoryBuffer. Owns one GpuMemoryBuffer and its
141 // associated pixel dimensions. 98 // associated pixel dimensions.
142 class VideoCaptureBufferPool::GpuMemoryBufferTracker final : public Tracker { 99 class VideoCaptureBufferPool::GpuMemoryBufferTracker final : public Tracker {
143 public: 100 public:
144 GpuMemoryBufferTracker(); 101 GpuMemoryBufferTracker();
145 bool Init(VideoFrame::Format format, 102 bool Init(media::VideoPixelFormat format,
146 media::VideoFrame::StorageType storage_type, 103 media::VideoPixelStorage storage_type,
147 const gfx::Size& dimensions) override; 104 const gfx::Size& dimensions) override;
148 ~GpuMemoryBufferTracker() override; 105 ~GpuMemoryBufferTracker() override;
149 106
150 size_t mapped_size() const override { return packed_size_; } 107 size_t mapped_size() const override { return packed_size_; }
151 scoped_ptr<BufferHandle> GetBufferHandle() override { 108 scoped_ptr<BufferHandle> GetBufferHandle() override {
152 return make_scoped_ptr(new GpuMemoryBufferBufferHandle( 109 return make_scoped_ptr(new GpuMemoryBufferBufferHandle(
153 gpu_memory_buffer_.get(), packed_size_)); 110 gpu_memory_buffer_.get(), packed_size_));
154 } 111 }
155 112
156 bool ShareToProcess(base::ProcessHandle process_handle, 113 bool ShareToProcess(base::ProcessHandle process_handle,
157 base::SharedMemoryHandle* new_handle) override { 114 base::SharedMemoryHandle* new_handle) override {
158 return true; 115 return true;
159 } 116 }
160 117
161 private: 118 private:
162 size_t packed_size_; 119 size_t packed_size_;
163 scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_; 120 scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_;
164 }; 121 };
165 122
166 VideoCaptureBufferPool::SharedMemTracker::SharedMemTracker() : Tracker() { 123 VideoCaptureBufferPool::SharedMemTracker::SharedMemTracker() : Tracker() {
167 } 124 }
168 125
169 bool VideoCaptureBufferPool::SharedMemTracker::Init( 126 bool VideoCaptureBufferPool::SharedMemTracker::Init(
170 VideoFrame::Format format, 127 media::VideoPixelFormat format,
171 media::VideoFrame::StorageType storage_type, 128 media::VideoPixelStorage storage_type,
172 const gfx::Size& dimensions) { 129 const gfx::Size& dimensions) {
173 DVLOG(2) << "allocating ShMem of " << dimensions.ToString(); 130 DVLOG(2) << "allocating ShMem of " << dimensions.ToString();
174 set_pixel_format(format); 131 set_pixel_format(format);
175 set_storage_type(storage_type); 132 set_storage_type(storage_type);
176 // Input |dimensions| can be 0x0 for trackers that do not require memory 133 // |dimensions| can be 0x0 for trackers that do not require memory backing.
177 // backing. The allocated size is calculated using VideoFrame methods since
178 // this will be the abstraction used to wrap the underlying data.
179 set_pixel_count(dimensions.GetArea()); 134 set_pixel_count(dimensions.GetArea());
180 const size_t byte_count = VideoFrame::AllocationSize(format, dimensions); 135 const size_t byte_count =
136 media::VideoCaptureFormat(dimensions, 0.0f, format, storage_type)
137 .ImageAllocationSize();
181 if (!byte_count) 138 if (!byte_count)
182 return true; 139 return true;
183 return shared_memory_.CreateAndMapAnonymous(byte_count); 140 return shared_memory_.CreateAndMapAnonymous(byte_count);
184 } 141 }
185 142
186 VideoCaptureBufferPool::GpuMemoryBufferTracker::GpuMemoryBufferTracker() 143 VideoCaptureBufferPool::GpuMemoryBufferTracker::GpuMemoryBufferTracker()
187 : Tracker(), gpu_memory_buffer_(nullptr) {} 144 : Tracker(), packed_size_(0u), gpu_memory_buffer_(nullptr) {}
188 145
189 VideoCaptureBufferPool::GpuMemoryBufferTracker::~GpuMemoryBufferTracker() { 146 VideoCaptureBufferPool::GpuMemoryBufferTracker::~GpuMemoryBufferTracker() {
190 if (gpu_memory_buffer_->IsMapped()) 147 if (gpu_memory_buffer_->IsMapped())
191 gpu_memory_buffer_->Unmap(); 148 gpu_memory_buffer_->Unmap();
192 } 149 }
193 150
194 bool VideoCaptureBufferPool::GpuMemoryBufferTracker::Init( 151 bool VideoCaptureBufferPool::GpuMemoryBufferTracker::Init(
195 VideoFrame::Format format, 152 media::VideoPixelFormat format,
196 media::VideoFrame::StorageType storage_type, 153 media::VideoPixelStorage storage_type,
197 const gfx::Size& dimensions) { 154 const gfx::Size& dimensions) {
198 DVLOG(2) << "allocating GMB for " << dimensions.ToString(); 155 DVLOG(2) << "allocating GMB for " << dimensions.ToString();
199 // BrowserGpuMemoryBufferManager::current() may not be accessed on IO Thread. 156 // BrowserGpuMemoryBufferManager::current() may not be accessed on IO Thread.
200 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO)); 157 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
201 DCHECK(BrowserGpuMemoryBufferManager::current()); 158 DCHECK(BrowserGpuMemoryBufferManager::current());
202 set_pixel_format(format); 159 set_pixel_format(format);
203 set_storage_type(storage_type); 160 set_storage_type(storage_type);
204 set_pixel_count(dimensions.GetArea()); 161 set_pixel_count(dimensions.GetArea());
162 // |dimensions| can be 0x0 for trackers that do not require memory backing.
163 if (dimensions.GetArea() == 0u)
164 return true;
205 gpu_memory_buffer_ = 165 gpu_memory_buffer_ =
206 BrowserGpuMemoryBufferManager::current()->AllocateGpuMemoryBuffer( 166 BrowserGpuMemoryBufferManager::current()->AllocateGpuMemoryBuffer(
207 dimensions, 167 dimensions,
208 gfx::GpuMemoryBuffer::BGRA_8888, 168 gfx::GpuMemoryBuffer::BGRA_8888,
209 gfx::GpuMemoryBuffer::MAP); 169 gfx::GpuMemoryBuffer::MAP);
210 DLOG_IF(ERROR, !gpu_memory_buffer_.get()) << "Allocating GpuMemoryBuffer"; 170 DLOG_IF(ERROR, !gpu_memory_buffer_.get()) << "Allocating GpuMemoryBuffer";
211 if (!gpu_memory_buffer_.get()) 171 if (!gpu_memory_buffer_.get())
212 return false; 172 return false;
213 int plane_sizes; 173 int plane_sizes;
214 gpu_memory_buffer_->GetStride(&plane_sizes); 174 gpu_memory_buffer_->GetStride(&plane_sizes);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 if (!tracker) { 225 if (!tracker) {
266 NOTREACHED() << "Invalid buffer_id."; 226 NOTREACHED() << "Invalid buffer_id.";
267 return scoped_ptr<BufferHandle>(); 227 return scoped_ptr<BufferHandle>();
268 } 228 }
269 229
270 DCHECK(tracker->held_by_producer()); 230 DCHECK(tracker->held_by_producer());
271 return tracker->GetBufferHandle(); 231 return tracker->GetBufferHandle();
272 } 232 }
273 233
274 int VideoCaptureBufferPool::ReserveForProducer(media::VideoPixelFormat format, 234 int VideoCaptureBufferPool::ReserveForProducer(media::VideoPixelFormat format,
235 media::VideoPixelStorage storage,
275 const gfx::Size& dimensions, 236 const gfx::Size& dimensions,
276 int* buffer_id_to_drop) { 237 int* buffer_id_to_drop) {
277 base::AutoLock lock(lock_); 238 base::AutoLock lock(lock_);
278 return ReserveForProducerInternal(format, dimensions, buffer_id_to_drop); 239 return ReserveForProducerInternal(format, storage, dimensions,
240 buffer_id_to_drop);
279 } 241 }
280 242
281 void VideoCaptureBufferPool::RelinquishProducerReservation(int buffer_id) { 243 void VideoCaptureBufferPool::RelinquishProducerReservation(int buffer_id) {
282 base::AutoLock lock(lock_); 244 base::AutoLock lock(lock_);
283 Tracker* tracker = GetTracker(buffer_id); 245 Tracker* tracker = GetTracker(buffer_id);
284 if (!tracker) { 246 if (!tracker) {
285 NOTREACHED() << "Invalid buffer_id."; 247 NOTREACHED() << "Invalid buffer_id.";
286 return; 248 return;
287 } 249 }
288 DCHECK(tracker->held_by_producer()); 250 DCHECK(tracker->held_by_producer());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 int num_buffers_held = 0; 288 int num_buffers_held = 0;
327 for (const auto& entry : trackers_) { 289 for (const auto& entry : trackers_) {
328 Tracker* const tracker = entry.second; 290 Tracker* const tracker = entry.second;
329 if (tracker->held_by_producer() || tracker->consumer_hold_count() > 0) 291 if (tracker->held_by_producer() || tracker->consumer_hold_count() > 0)
330 ++num_buffers_held; 292 ++num_buffers_held;
331 } 293 }
332 return static_cast<double>(num_buffers_held) / count_; 294 return static_cast<double>(num_buffers_held) / count_;
333 } 295 }
334 296
335 int VideoCaptureBufferPool::ReserveForProducerInternal( 297 int VideoCaptureBufferPool::ReserveForProducerInternal(
336 media::VideoPixelFormat format, 298 media::VideoPixelFormat pixel_format,
299 media::VideoPixelStorage storage_type,
337 const gfx::Size& dimensions, 300 const gfx::Size& dimensions,
338 int* buffer_id_to_drop) { 301 int* buffer_id_to_drop) {
339 DCHECK(format == media::PIXEL_FORMAT_I420 ||
340 format == media::PIXEL_FORMAT_TEXTURE ||
341 format == media::PIXEL_FORMAT_GPUMEMORYBUFFER );
342 lock_.AssertAcquired(); 302 lock_.AssertAcquired();
343 *buffer_id_to_drop = kInvalidId; 303 *buffer_id_to_drop = kInvalidId;
344 304
345 const size_t size_in_pixels = dimensions.GetArea(); 305 const size_t size_in_pixels = dimensions.GetArea();
346 const media::VideoFrame::Format pixel_format =
347 VideoPixelFormatToVideoFrameFormat(format);
348 const media::VideoFrame::StorageType storage_type =
349 VideoPixelFormatToVideoFrameStorageType(format);
350 // Look for a tracker that's allocated, big enough, and not in use. Track the 306 // Look for a tracker that's allocated, big enough, and not in use. Track the
351 // largest one that's not big enough, in case we have to reallocate a tracker. 307 // largest one that's not big enough, in case we have to reallocate a tracker.
352 *buffer_id_to_drop = kInvalidId; 308 *buffer_id_to_drop = kInvalidId;
353 size_t largest_size_in_pixels = 0; 309 size_t largest_size_in_pixels = 0;
354 TrackerMap::iterator tracker_to_drop = trackers_.end(); 310 TrackerMap::iterator tracker_to_drop = trackers_.end();
355 for (TrackerMap::iterator it = trackers_.begin(); it != trackers_.end(); 311 for (TrackerMap::iterator it = trackers_.begin(); it != trackers_.end();
356 ++it) { 312 ++it) {
357 Tracker* const tracker = it->second; 313 Tracker* const tracker = it->second;
358 if (!tracker->consumer_hold_count() && !tracker->held_by_producer()) { 314 if (!tracker->consumer_hold_count() && !tracker->held_by_producer()) {
359 if (tracker->pixel_count() >= size_in_pixels && 315 if (tracker->pixel_count() >= size_in_pixels &&
(...skipping 18 matching lines...) Expand all
378 return kInvalidId; 334 return kInvalidId;
379 } 335 }
380 *buffer_id_to_drop = tracker_to_drop->first; 336 *buffer_id_to_drop = tracker_to_drop->first;
381 delete tracker_to_drop->second; 337 delete tracker_to_drop->second;
382 trackers_.erase(tracker_to_drop); 338 trackers_.erase(tracker_to_drop);
383 } 339 }
384 340
385 // Create the new tracker. 341 // Create the new tracker.
386 const int buffer_id = next_buffer_id_++; 342 const int buffer_id = next_buffer_id_++;
387 343
388 scoped_ptr<Tracker> tracker = 344 scoped_ptr<Tracker> tracker = Tracker::CreateTracker(
389 Tracker::CreateTracker(format == media::PIXEL_FORMAT_GPUMEMORYBUFFER); 345 storage_type == media::PIXEL_STORAGE_GPUMEMORYBUFFER);
390 if (!tracker->Init(pixel_format, storage_type, dimensions)) { 346 if (!tracker->Init(pixel_format, storage_type, dimensions)) {
391 DLOG(ERROR) << "Error initializing Tracker"; 347 DLOG(ERROR) << "Error initializing Tracker";
392 return kInvalidId; 348 return kInvalidId;
393 } 349 }
394 tracker->set_held_by_producer(true); 350 tracker->set_held_by_producer(true);
395 trackers_[buffer_id] = tracker.release(); 351 trackers_[buffer_id] = tracker.release();
396 352
397 return buffer_id; 353 return buffer_id;
398 } 354 }
399 355
400 VideoCaptureBufferPool::Tracker* VideoCaptureBufferPool::GetTracker( 356 VideoCaptureBufferPool::Tracker* VideoCaptureBufferPool::GetTracker(
401 int buffer_id) { 357 int buffer_id) {
402 TrackerMap::const_iterator it = trackers_.find(buffer_id); 358 TrackerMap::const_iterator it = trackers_.find(buffer_id);
403 return (it == trackers_.end()) ? NULL : it->second; 359 return (it == trackers_.end()) ? NULL : it->second;
404 } 360 }
405 361
406 } // namespace content 362 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698