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

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

Issue 1154153003: Relanding 1143663007: VideoFrame: Separate Pixel Format from Storage Type. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added NV12 support in CrOS 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" 13 #include "media/base/video_frame.h"
14 14
15 using media::VideoFrame; 15 using media::VideoFrame;
16 16
17 namespace content { 17 namespace content {
18 18
19 const int VideoCaptureBufferPool::kInvalidId = -1; 19 const int VideoCaptureBufferPool::kInvalidId = -1;
20 20
21 VideoFrame::Format VideoPixelFormatToVideoFrameFormat( 21 VideoFrame::Format VideoPixelFormatToVideoFrameFormat(
22 media::VideoPixelFormat pixel_format) { 22 media::VideoPixelFormat pixel_format) {
23 static struct { 23 static struct {
24 media::VideoPixelFormat pixel_format; 24 media::VideoPixelFormat pixel_format;
25 VideoFrame::Format frame_format; 25 VideoFrame::Format frame_format;
26 } const kVideoPixelFormatToVideoFrameFormat[] = { 26 } const kVideoPixelFormatToVideoFrameFormat[] = {
27 {media::PIXEL_FORMAT_I420, VideoFrame::I420}, 27 {media::PIXEL_FORMAT_I420, VideoFrame::I420},
28 {media::PIXEL_FORMAT_TEXTURE, VideoFrame::NATIVE_TEXTURE}, 28 {media::PIXEL_FORMAT_TEXTURE, VideoFrame::ARGB},
29 {media::PIXEL_FORMAT_GPUMEMORYBUFFER, VideoFrame::NATIVE_TEXTURE}, 29 {media::PIXEL_FORMAT_GPUMEMORYBUFFER, VideoFrame::ARGB},
30 }; 30 };
31 31
32 for (const auto& format_pair : kVideoPixelFormatToVideoFrameFormat) { 32 for (const auto& format_pair : kVideoPixelFormatToVideoFrameFormat) {
33 if (format_pair.pixel_format == pixel_format) 33 if (format_pair.pixel_format == pixel_format)
34 return format_pair.frame_format; 34 return format_pair.frame_format;
35 } 35 }
36 LOG(ERROR) << "Unsupported VideoPixelFormat " 36 LOG(ERROR) << "Unsupported VideoPixelFormat "
37 << media::VideoCaptureFormat::PixelFormatToString(pixel_format); 37 << media::VideoCaptureFormat::PixelFormatToString(pixel_format);
38 return VideoFrame::UNKNOWN; 38 return VideoFrame::UNKNOWN;
39 } 39 }
40 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_TEXTURE},
49 {media::PIXEL_FORMAT_GPUMEMORYBUFFER, VideoFrame::STORAGE_TEXTURE},
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
41 // A simple holder of a memory-backed buffer and accesors to it. 61 // A simple holder of a memory-backed buffer and accesors to it.
42 class SimpleBufferHandle final : public VideoCaptureBufferPool::BufferHandle { 62 class SimpleBufferHandle final : public VideoCaptureBufferPool::BufferHandle {
43 public: 63 public:
44 SimpleBufferHandle(void* data, size_t size) : data_(data), size_(size) {} 64 SimpleBufferHandle(void* data, size_t size) : data_(data), size_(size) {}
45 ~SimpleBufferHandle() override {} 65 ~SimpleBufferHandle() override {}
46 66
47 size_t size() const override { return size_; } 67 size_t size() const override { return size_; }
48 void* data() override { return data_; } 68 void* data() override { return data_; }
49 gfx::GpuMemoryBufferType GetType() override { 69 gfx::GpuMemoryBufferType GetType() override {
50 return gfx::SHARED_MEMORY_BUFFER; 70 return gfx::SHARED_MEMORY_BUFFER;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 private: 103 private:
84 gfx::GpuMemoryBuffer* const gmb_; 104 gfx::GpuMemoryBuffer* const gmb_;
85 scoped_ptr<void*[]> data_; 105 scoped_ptr<void*[]> data_;
86 const size_t size_; 106 const size_t size_;
87 }; 107 };
88 108
89 // Tracker specifics for SharedMemory. 109 // Tracker specifics for SharedMemory.
90 class VideoCaptureBufferPool::SharedMemTracker final : public Tracker { 110 class VideoCaptureBufferPool::SharedMemTracker final : public Tracker {
91 public: 111 public:
92 SharedMemTracker(); 112 SharedMemTracker();
93 bool Init(VideoFrame::Format format, const gfx::Size& dimensions) override; 113 bool Init(VideoFrame::Format format,
114 media::VideoFrame::StorageType storage_type,
115 const gfx::Size& dimensions) override;
94 116
95 size_t mapped_size() const override { return shared_memory_.mapped_size(); } 117 size_t mapped_size() const override { return shared_memory_.mapped_size(); }
96 118
97 scoped_ptr<BufferHandle> GetBufferHandle() override { 119 scoped_ptr<BufferHandle> GetBufferHandle() override {
98 return make_scoped_ptr( 120 return make_scoped_ptr(
99 new SimpleBufferHandle(shared_memory_.memory(), mapped_size())); 121 new SimpleBufferHandle(shared_memory_.memory(), mapped_size()));
100 } 122 }
101 123
102 bool ShareToProcess(base::ProcessHandle process_handle, 124 bool ShareToProcess(base::ProcessHandle process_handle,
103 base::SharedMemoryHandle* new_handle) override { 125 base::SharedMemoryHandle* new_handle) override {
104 return shared_memory_.ShareToProcess(process_handle, new_handle); 126 return shared_memory_.ShareToProcess(process_handle, new_handle);
105 } 127 }
106 128
107 private: 129 private:
108 // The memory created to be shared with renderer processes. 130 // The memory created to be shared with renderer processes.
109 base::SharedMemory shared_memory_; 131 base::SharedMemory shared_memory_;
110 }; 132 };
111 133
112 // Tracker specifics for GpuMemoryBuffer. Owns one GpuMemoryBuffer and its 134 // Tracker specifics for GpuMemoryBuffer. Owns one GpuMemoryBuffer and its
113 // associated pixel dimensions. 135 // associated pixel dimensions.
114 class VideoCaptureBufferPool::GpuMemoryBufferTracker final : public Tracker { 136 class VideoCaptureBufferPool::GpuMemoryBufferTracker final : public Tracker {
115 public: 137 public:
116 GpuMemoryBufferTracker(); 138 GpuMemoryBufferTracker();
117 bool Init(VideoFrame::Format format, const gfx::Size& dimensions) override; 139 bool Init(VideoFrame::Format format,
140 media::VideoFrame::StorageType storage_type,
141 const gfx::Size& dimensions) override;
118 ~GpuMemoryBufferTracker() override; 142 ~GpuMemoryBufferTracker() override;
119 143
120 size_t mapped_size() const override { return packed_size_; } 144 size_t mapped_size() const override { return packed_size_; }
121 scoped_ptr<BufferHandle> GetBufferHandle() override { 145 scoped_ptr<BufferHandle> GetBufferHandle() override {
122 return make_scoped_ptr(new GpuMemoryBufferBufferHandle( 146 return make_scoped_ptr(new GpuMemoryBufferBufferHandle(
123 gpu_memory_buffer_.get(), packed_size_)); 147 gpu_memory_buffer_.get(), packed_size_));
124 } 148 }
125 149
126 bool ShareToProcess(base::ProcessHandle process_handle, 150 bool ShareToProcess(base::ProcessHandle process_handle,
127 base::SharedMemoryHandle* new_handle) override { 151 base::SharedMemoryHandle* new_handle) override {
128 return true; 152 return true;
129 } 153 }
130 154
131 private: 155 private:
132 size_t packed_size_; 156 size_t packed_size_;
133 scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_; 157 scoped_ptr<gfx::GpuMemoryBuffer> gpu_memory_buffer_;
134 }; 158 };
135 159
136 VideoCaptureBufferPool::SharedMemTracker::SharedMemTracker() : Tracker() { 160 VideoCaptureBufferPool::SharedMemTracker::SharedMemTracker() : Tracker() {
137 } 161 }
138 162
139 bool VideoCaptureBufferPool::SharedMemTracker::Init( 163 bool VideoCaptureBufferPool::SharedMemTracker::Init(
140 VideoFrame::Format format, 164 VideoFrame::Format format,
165 media::VideoFrame::StorageType storage_type,
141 const gfx::Size& dimensions) { 166 const gfx::Size& dimensions) {
142 DVLOG(2) << "allocating ShMem of " << dimensions.ToString(); 167 DVLOG(2) << "allocating ShMem of " << dimensions.ToString();
143 set_pixel_format(format); 168 set_pixel_format(format);
169 set_storage_type(storage_type);
144 // Input |dimensions| can be 0x0 for trackers that do not require memory 170 // Input |dimensions| can be 0x0 for trackers that do not require memory
145 // backing. The allocated size is calculated using VideoFrame methods since 171 // backing. The allocated size is calculated using VideoFrame methods since
146 // this will be the abstraction used to wrap the underlying data. 172 // this will be the abstraction used to wrap the underlying data.
147 set_pixel_count(dimensions.GetArea()); 173 set_pixel_count(dimensions.GetArea());
148 const size_t byte_count = VideoFrame::AllocationSize(format, dimensions); 174 const size_t byte_count = VideoFrame::AllocationSize(format, dimensions);
149 if (!byte_count) 175 if (!byte_count)
150 return true; 176 return true;
151 return shared_memory_.CreateAndMapAnonymous(byte_count); 177 return shared_memory_.CreateAndMapAnonymous(byte_count);
152 } 178 }
153 179
154 VideoCaptureBufferPool::GpuMemoryBufferTracker::GpuMemoryBufferTracker() 180 VideoCaptureBufferPool::GpuMemoryBufferTracker::GpuMemoryBufferTracker()
155 : Tracker(), gpu_memory_buffer_(nullptr) {} 181 : Tracker(), gpu_memory_buffer_(nullptr) {}
156 182
157 VideoCaptureBufferPool::GpuMemoryBufferTracker::~GpuMemoryBufferTracker() { 183 VideoCaptureBufferPool::GpuMemoryBufferTracker::~GpuMemoryBufferTracker() {
158 if (gpu_memory_buffer_->IsMapped()) 184 if (gpu_memory_buffer_->IsMapped())
159 gpu_memory_buffer_->Unmap(); 185 gpu_memory_buffer_->Unmap();
160 } 186 }
161 187
162 bool VideoCaptureBufferPool::GpuMemoryBufferTracker::Init( 188 bool VideoCaptureBufferPool::GpuMemoryBufferTracker::Init(
163 VideoFrame::Format format, 189 VideoFrame::Format format,
190 media::VideoFrame::StorageType storage_type,
164 const gfx::Size& dimensions) { 191 const gfx::Size& dimensions) {
165 DVLOG(2) << "allocating GMB for " << dimensions.ToString(); 192 DVLOG(2) << "allocating GMB for " << dimensions.ToString();
166 // BrowserGpuMemoryBufferManager::current() may not be accessed on IO Thread. 193 // BrowserGpuMemoryBufferManager::current() may not be accessed on IO Thread.
167 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO)); 194 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO));
168 DCHECK(BrowserGpuMemoryBufferManager::current()); 195 DCHECK(BrowserGpuMemoryBufferManager::current());
169 set_pixel_format(format); 196 set_pixel_format(format);
197 set_storage_type(storage_type);
170 set_pixel_count(dimensions.GetArea()); 198 set_pixel_count(dimensions.GetArea());
171 gpu_memory_buffer_ = 199 gpu_memory_buffer_ =
172 BrowserGpuMemoryBufferManager::current()->AllocateGpuMemoryBuffer( 200 BrowserGpuMemoryBufferManager::current()->AllocateGpuMemoryBuffer(
173 dimensions, 201 dimensions,
174 gfx::GpuMemoryBuffer::BGRA_8888, 202 gfx::GpuMemoryBuffer::BGRA_8888,
175 gfx::GpuMemoryBuffer::MAP); 203 gfx::GpuMemoryBuffer::MAP);
176 DLOG_IF(ERROR, !gpu_memory_buffer_.get()) << "Allocating GpuMemoryBuffer"; 204 DLOG_IF(ERROR, !gpu_memory_buffer_.get()) << "Allocating GpuMemoryBuffer";
177 if (!gpu_memory_buffer_.get()) 205 if (!gpu_memory_buffer_.get())
178 return false; 206 return false;
179 int plane_sizes; 207 int plane_sizes;
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 media::VideoPixelFormat format, 319 media::VideoPixelFormat format,
292 const gfx::Size& dimensions, 320 const gfx::Size& dimensions,
293 int* buffer_id_to_drop) { 321 int* buffer_id_to_drop) {
294 DCHECK(format == media::PIXEL_FORMAT_I420 || 322 DCHECK(format == media::PIXEL_FORMAT_I420 ||
295 format == media::PIXEL_FORMAT_TEXTURE || 323 format == media::PIXEL_FORMAT_TEXTURE ||
296 format == media::PIXEL_FORMAT_GPUMEMORYBUFFER ); 324 format == media::PIXEL_FORMAT_GPUMEMORYBUFFER );
297 lock_.AssertAcquired(); 325 lock_.AssertAcquired();
298 *buffer_id_to_drop = kInvalidId; 326 *buffer_id_to_drop = kInvalidId;
299 327
300 const size_t size_in_pixels = dimensions.GetArea(); 328 const size_t size_in_pixels = dimensions.GetArea();
329 const media::VideoFrame::Format pixel_format =
330 VideoPixelFormatToVideoFrameFormat(format);
331 const media::VideoFrame::StorageType storage_type =
332 VideoPixelFormatToVideoFrameStorageType(format);
301 // Look for a tracker that's allocated, big enough, and not in use. Track the 333 // Look for a tracker that's allocated, big enough, and not in use. Track the
302 // largest one that's not big enough, in case we have to reallocate a tracker. 334 // largest one that's not big enough, in case we have to reallocate a tracker.
303 *buffer_id_to_drop = kInvalidId; 335 *buffer_id_to_drop = kInvalidId;
304 size_t largest_size_in_pixels = 0; 336 size_t largest_size_in_pixels = 0;
305 TrackerMap::iterator tracker_to_drop = trackers_.end(); 337 TrackerMap::iterator tracker_to_drop = trackers_.end();
306 for (TrackerMap::iterator it = trackers_.begin(); it != trackers_.end(); 338 for (TrackerMap::iterator it = trackers_.begin(); it != trackers_.end();
307 ++it) { 339 ++it) {
308 Tracker* const tracker = it->second; 340 Tracker* const tracker = it->second;
309 if (!tracker->consumer_hold_count() && !tracker->held_by_producer()) { 341 if (!tracker->consumer_hold_count() && !tracker->held_by_producer()) {
310 if (tracker->pixel_count() >= size_in_pixels && 342 if (tracker->pixel_count() >= size_in_pixels &&
311 (tracker->pixel_format() == 343 (tracker->pixel_format() == pixel_format) &&
312 VideoPixelFormatToVideoFrameFormat(format))) { 344 (tracker->storage_type() == storage_type)) {
313 // Existing tracker is big enough and has correct format. Reuse it. 345 // Existing tracker is big enough and has correct format. Reuse it.
314 tracker->set_held_by_producer(true); 346 tracker->set_held_by_producer(true);
315 return it->first; 347 return it->first;
316 } 348 }
317 if (tracker->pixel_count() > largest_size_in_pixels) { 349 if (tracker->pixel_count() > largest_size_in_pixels) {
318 largest_size_in_pixels = tracker->pixel_count(); 350 largest_size_in_pixels = tracker->pixel_count();
319 tracker_to_drop = it; 351 tracker_to_drop = it;
320 } 352 }
321 } 353 }
322 } 354 }
323 355
324 // Preferably grow the pool by creating a new tracker. If we're at maximum 356 // Preferably grow the pool by creating a new tracker. If we're at maximum
325 // size, then reallocate by deleting an existing one instead. 357 // size, then reallocate by deleting an existing one instead.
326 if (trackers_.size() == static_cast<size_t>(count_)) { 358 if (trackers_.size() == static_cast<size_t>(count_)) {
327 if (tracker_to_drop == trackers_.end()) { 359 if (tracker_to_drop == trackers_.end()) {
328 // We're out of space, and can't find an unused tracker to reallocate. 360 // We're out of space, and can't find an unused tracker to reallocate.
329 return kInvalidId; 361 return kInvalidId;
330 } 362 }
331 *buffer_id_to_drop = tracker_to_drop->first; 363 *buffer_id_to_drop = tracker_to_drop->first;
332 delete tracker_to_drop->second; 364 delete tracker_to_drop->second;
333 trackers_.erase(tracker_to_drop); 365 trackers_.erase(tracker_to_drop);
334 } 366 }
335 367
336 // Create the new tracker. 368 // Create the new tracker.
337 const int buffer_id = next_buffer_id_++; 369 const int buffer_id = next_buffer_id_++;
338 370
339 scoped_ptr<Tracker> tracker = 371 scoped_ptr<Tracker> tracker =
340 Tracker::CreateTracker(format == media::PIXEL_FORMAT_GPUMEMORYBUFFER); 372 Tracker::CreateTracker(format == media::PIXEL_FORMAT_GPUMEMORYBUFFER);
341 if (!tracker->Init(VideoPixelFormatToVideoFrameFormat(format), dimensions)) { 373 if (!tracker->Init(pixel_format, storage_type, dimensions)) {
342 DLOG(ERROR) << "Error initializing Tracker"; 374 DLOG(ERROR) << "Error initializing Tracker";
343 return kInvalidId; 375 return kInvalidId;
344 } 376 }
345 tracker->set_held_by_producer(true); 377 tracker->set_held_by_producer(true);
346 trackers_[buffer_id] = tracker.release(); 378 trackers_[buffer_id] = tracker.release();
347 379
348 return buffer_id; 380 return buffer_id;
349 } 381 }
350 382
351 VideoCaptureBufferPool::Tracker* VideoCaptureBufferPool::GetTracker( 383 VideoCaptureBufferPool::Tracker* VideoCaptureBufferPool::GetTracker(
352 int buffer_id) { 384 int buffer_id) {
353 TrackerMap::const_iterator it = trackers_.find(buffer_id); 385 TrackerMap::const_iterator it = trackers_.find(buffer_id);
354 return (it == trackers_.end()) ? NULL : it->second; 386 return (it == trackers_.end()) ? NULL : it->second;
355 } 387 }
356 388
357 } // namespace content 389 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698