OLD | NEW |
---|---|
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/memory/scoped_vector.h" | 9 #include "base/memory/scoped_vector.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
11 #include "content/browser/gpu/browser_gpu_memory_buffer_manager.h" | 11 #include "content/browser/gpu/browser_gpu_memory_buffer_manager.h" |
12 #include "content/public/browser/browser_thread.h" | 12 #include "content/public/browser/browser_thread.h" |
13 #include "ui/gfx/buffer_format_util.h" | 13 #include "ui/gfx/buffer_format_util.h" |
14 | 14 |
15 namespace content { | 15 namespace content { |
16 | 16 |
17 const int VideoCaptureBufferPool::kInvalidId = -1; | 17 const int VideoCaptureBufferPool::kInvalidId = -1; |
18 | 18 |
19 // A simple holder of a memory-backed buffer and accessors to it. | 19 // A simple holder of a memory-backed buffer and accessors to it. |
20 class SimpleBufferHandle final : public VideoCaptureBufferPool::BufferHandle { | 20 class SimpleBufferHandle final : public VideoCaptureBufferPool::BufferHandle { |
21 public: | 21 public: |
22 SimpleBufferHandle(void* data, size_t size, base::SharedMemoryHandle handle) | 22 SimpleBufferHandle(void* data, |
23 size_t mapped_size, | |
24 base::SharedMemoryHandle handle) | |
23 : data_(data), | 25 : data_(data), |
24 size_(size) | 26 mapped_size_(mapped_size) |
25 #if defined(OS_POSIX) | 27 #if defined(OS_POSIX) |
26 , handle_(handle) | 28 , |
29 handle_(handle) | |
27 #endif | 30 #endif |
28 { | 31 { |
29 } | 32 } |
30 ~SimpleBufferHandle() override {} | 33 ~SimpleBufferHandle() override {} |
31 | 34 |
32 size_t size() const override { return size_; } | 35 gfx::Size dimensions() const override { |
36 NOTREACHED(); | |
37 return gfx::Size(); | |
38 } | |
39 size_t mapped_size() const override { return mapped_size_; } | |
33 void* data(int plane) override { | 40 void* data(int plane) override { |
34 DCHECK_EQ(plane, 0); | 41 DCHECK_EQ(plane, 0); |
35 return data_; | 42 return data_; |
36 } | 43 } |
37 ClientBuffer AsClientBuffer(int plane) override { | 44 ClientBuffer AsClientBuffer(int plane) override { |
38 NOTREACHED(); | 45 NOTREACHED(); |
39 return nullptr; | 46 return nullptr; |
40 } | 47 } |
41 #if defined(OS_POSIX) | 48 #if defined(OS_POSIX) |
42 base::FileDescriptor AsPlatformFile() override { | 49 base::FileDescriptor AsPlatformFile() override { |
43 #if defined(OS_MACOSX) | 50 #if defined(OS_MACOSX) |
44 return handle_.GetFileDescriptor(); | 51 return handle_.GetFileDescriptor(); |
45 #else | 52 #else |
46 return handle_; | 53 return handle_; |
47 #endif // defined(OS_MACOSX) | 54 #endif // defined(OS_MACOSX) |
48 } | 55 } |
49 #endif | 56 #endif |
50 | 57 |
51 private: | 58 private: |
52 void* const data_; | 59 void* const data_; |
53 const size_t size_; | 60 const size_t mapped_size_; |
54 #if defined(OS_POSIX) | 61 #if defined(OS_POSIX) |
55 const base::SharedMemoryHandle handle_; | 62 const base::SharedMemoryHandle handle_; |
56 #endif | 63 #endif |
57 }; | 64 }; |
58 | 65 |
59 // A holder of a GpuMemoryBuffer-backed buffer. Holds weak references to | 66 // A holder of a GpuMemoryBuffer-backed buffer. Holds weak references to |
60 // GpuMemoryBuffer-backed buffers and provides accessors to their data. | 67 // GpuMemoryBuffer-backed buffers and provides accessors to their data. |
61 class GpuMemoryBufferBufferHandle final | 68 class GpuMemoryBufferBufferHandle final |
62 : public VideoCaptureBufferPool::BufferHandle { | 69 : public VideoCaptureBufferPool::BufferHandle { |
63 public: | 70 public: |
64 GpuMemoryBufferBufferHandle(std::vector<void*>* data, | 71 GpuMemoryBufferBufferHandle(std::vector<void*>* data, |
65 const gfx::Size& dimensions, | 72 const gfx::Size& dimensions, |
66 ScopedVector<gfx::GpuMemoryBuffer>* gmbs) | 73 ScopedVector<gfx::GpuMemoryBuffer>* gmbs) |
67 : data_(data), dimensions_(dimensions), gmbs_(gmbs) { | 74 : data_(data), dimensions_(dimensions), gmbs_(gmbs) { |
68 #ifndef NDEBUG | 75 #ifndef NDEBUG |
69 DCHECK_EQ(data->size(), gmbs->size()); | 76 DCHECK_EQ(data->size(), gmbs->size()); |
70 for (const auto& gmb : *gmbs) | 77 for (const auto& gmb : *gmbs) |
71 DCHECK(gmb && gmb->IsMapped()); | 78 DCHECK(gmb && gmb->IsMapped()); |
72 for (const auto& data_ptr : *data) | 79 for (const auto& data_ptr : *data) |
73 DCHECK(data_ptr); | 80 DCHECK(data_ptr); |
74 #endif | 81 #endif |
75 } | 82 } |
76 ~GpuMemoryBufferBufferHandle() override {} | 83 ~GpuMemoryBufferBufferHandle() override {} |
77 | 84 |
78 size_t size() const override { | 85 gfx::Size dimensions() const override { return dimensions_; } |
79 return dimensions_.GetArea(); | 86 size_t mapped_size() const override { return dimensions_.GetArea(); } |
80 } | |
81 void* data(int plane) override { | 87 void* data(int plane) override { |
82 DCHECK_GE(plane, media::VideoFrame::kYPlane); | 88 DCHECK_GE(plane, media::VideoFrame::kYPlane); |
83 DCHECK_LT(plane, static_cast<int>(data_->size())); | 89 DCHECK_LT(plane, static_cast<int>(data_->size())); |
84 return data_->at(plane); | 90 return data_->at(plane); |
85 } | 91 } |
86 ClientBuffer AsClientBuffer(int plane) override { | 92 ClientBuffer AsClientBuffer(int plane) override { |
87 DCHECK_GE(plane, media::VideoFrame::kYPlane); | 93 DCHECK_GE(plane, media::VideoFrame::kYPlane); |
88 DCHECK_LT(plane, static_cast<int>(gmbs_->size())); | 94 DCHECK_LT(plane, static_cast<int>(gmbs_->size())); |
89 return (*gmbs_)[plane]->AsClientBuffer(); | 95 return (*gmbs_)[plane]->AsClientBuffer(); |
90 } | 96 } |
(...skipping 11 matching lines...) Expand all Loading... | |
102 }; | 108 }; |
103 | 109 |
104 // Tracker specifics for SharedMemory. | 110 // Tracker specifics for SharedMemory. |
105 class VideoCaptureBufferPool::SharedMemTracker final : public Tracker { | 111 class VideoCaptureBufferPool::SharedMemTracker final : public Tracker { |
106 public: | 112 public: |
107 SharedMemTracker(); | 113 SharedMemTracker(); |
108 bool Init(media::VideoCapturePixelFormat format, | 114 bool Init(media::VideoCapturePixelFormat format, |
109 media::VideoPixelStorage storage_type, | 115 media::VideoPixelStorage storage_type, |
110 const gfx::Size& dimensions) override; | 116 const gfx::Size& dimensions) override; |
111 | 117 |
112 size_t mapped_size() const override { return shared_memory_.mapped_size(); } | |
113 | |
114 scoped_ptr<BufferHandle> GetBufferHandle() override { | 118 scoped_ptr<BufferHandle> GetBufferHandle() override { |
115 return make_scoped_ptr(new SimpleBufferHandle( | 119 return make_scoped_ptr(new SimpleBufferHandle( |
116 shared_memory_.memory(), mapped_size(), shared_memory_.handle())); | 120 shared_memory_.memory(), mapped_size_, shared_memory_.handle())); |
117 } | 121 } |
118 | 122 bool ShareToProcess(int plane, |
119 bool ShareToProcess(base::ProcessHandle process_handle, | 123 base::ProcessHandle process_handle, |
120 base::SharedMemoryHandle* new_handle) override { | 124 void* new_handle) override { |
121 return shared_memory_.ShareToProcess(process_handle, new_handle); | 125 return shared_memory_.ShareToProcess( |
126 process_handle, static_cast<base::SharedMemoryHandle*>(new_handle)); | |
122 } | 127 } |
123 | 128 |
124 private: | 129 private: |
125 // The memory created to be shared with renderer processes. | 130 // The memory created to be shared with renderer processes. |
126 base::SharedMemory shared_memory_; | 131 base::SharedMemory shared_memory_; |
132 size_t mapped_size_; | |
127 }; | 133 }; |
128 | 134 |
129 // Tracker specifics for GpuMemoryBuffer. Owns GpuMemoryBuffers and its | 135 // Tracker specifics for GpuMemoryBuffer. Owns GpuMemoryBuffers and its |
130 // associated pixel dimensions. | 136 // associated pixel dimensions. |
131 class VideoCaptureBufferPool::GpuMemoryBufferTracker final : public Tracker { | 137 class VideoCaptureBufferPool::GpuMemoryBufferTracker final : public Tracker { |
132 public: | 138 public: |
133 GpuMemoryBufferTracker(); | 139 GpuMemoryBufferTracker(); |
134 bool Init(media::VideoCapturePixelFormat format, | 140 bool Init(media::VideoCapturePixelFormat format, |
135 media::VideoPixelStorage storage_type, | 141 media::VideoPixelStorage storage_type, |
136 const gfx::Size& dimensions) override; | 142 const gfx::Size& dimensions) override; |
137 ~GpuMemoryBufferTracker() override; | 143 ~GpuMemoryBufferTracker() override; |
138 | 144 |
139 size_t mapped_size() const override { | |
140 NOTREACHED(); | |
141 return 0; | |
142 } | |
143 scoped_ptr<BufferHandle> GetBufferHandle() override { | 145 scoped_ptr<BufferHandle> GetBufferHandle() override { |
144 return make_scoped_ptr(new GpuMemoryBufferBufferHandle( | 146 return make_scoped_ptr(new GpuMemoryBufferBufferHandle( |
145 &data_, dimensions_, &gpu_memory_buffers_)); | 147 &data_, dimensions_, &gpu_memory_buffers_)); |
146 } | 148 } |
147 bool ShareToProcess(base::ProcessHandle process_handle, | 149 bool ShareToProcess(int plane, |
148 base::SharedMemoryHandle* new_handle) override { | 150 base::ProcessHandle process_handle, |
149 return true; | 151 void* new_handle) override; |
150 } | |
151 | 152 |
152 private: | 153 private: |
153 std::vector<void*> data_; | 154 std::vector<void*> data_; |
154 gfx::Size dimensions_; | 155 gfx::Size dimensions_; |
155 // Owned references to GpuMemoryBuffers. | 156 // Owned references to GpuMemoryBuffers. |
156 ScopedVector<gfx::GpuMemoryBuffer> gpu_memory_buffers_; | 157 ScopedVector<gfx::GpuMemoryBuffer> gpu_memory_buffers_; |
157 }; | 158 }; |
158 | 159 |
159 VideoCaptureBufferPool::SharedMemTracker::SharedMemTracker() : Tracker() { | 160 VideoCaptureBufferPool::SharedMemTracker::SharedMemTracker() : Tracker() {} |
160 } | |
161 | 161 |
162 bool VideoCaptureBufferPool::SharedMemTracker::Init( | 162 bool VideoCaptureBufferPool::SharedMemTracker::Init( |
163 media::VideoCapturePixelFormat format, | 163 media::VideoCapturePixelFormat format, |
164 media::VideoPixelStorage storage_type, | 164 media::VideoPixelStorage storage_type, |
165 const gfx::Size& dimensions) { | 165 const gfx::Size& dimensions) { |
166 DVLOG(2) << "allocating ShMem of " << dimensions.ToString(); | 166 DVLOG(2) << "allocating ShMem of " << dimensions.ToString(); |
167 set_pixel_format(format); | 167 set_pixel_format(format); |
168 set_storage_type(storage_type); | 168 set_storage_type(storage_type); |
169 // |dimensions| can be 0x0 for trackers that do not require memory backing. | 169 // |dimensions| can be 0x0 for trackers that do not require memory backing. |
170 set_pixel_count(dimensions.GetArea()); | 170 set_pixel_count(dimensions.GetArea()); |
171 const size_t byte_count = | 171 mapped_size_ = |
172 media::VideoCaptureFormat(dimensions, 0.0f, format, storage_type) | 172 media::VideoCaptureFormat(dimensions, 0.0f, format, storage_type) |
173 .ImageAllocationSize(); | 173 .ImageAllocationSize(); |
174 if (!byte_count) | 174 if (!mapped_size_) |
175 return true; | 175 return true; |
176 return shared_memory_.CreateAndMapAnonymous(byte_count); | 176 return shared_memory_.CreateAndMapAnonymous(mapped_size_); |
177 } | 177 } |
178 | 178 |
179 VideoCaptureBufferPool::GpuMemoryBufferTracker::GpuMemoryBufferTracker() | 179 VideoCaptureBufferPool::GpuMemoryBufferTracker::GpuMemoryBufferTracker() |
180 : Tracker() { | 180 : Tracker() { |
181 } | 181 } |
182 | 182 |
183 VideoCaptureBufferPool::GpuMemoryBufferTracker::~GpuMemoryBufferTracker() { | 183 VideoCaptureBufferPool::GpuMemoryBufferTracker::~GpuMemoryBufferTracker() { |
184 for (const auto& gmb : gpu_memory_buffers_) { | 184 for (const auto& gmb : gpu_memory_buffers_) { |
185 if (gmb->IsMapped()) | 185 if (gmb->IsMapped()) |
186 gmb->Unmap(); | 186 gmb->Unmap(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
222 return false; | 222 return false; |
223 | 223 |
224 void* temp_data = nullptr; | 224 void* temp_data = nullptr; |
225 gpu_memory_buffers_[i]->Map(&temp_data); | 225 gpu_memory_buffers_[i]->Map(&temp_data); |
226 DCHECK(temp_data); | 226 DCHECK(temp_data); |
227 data_.push_back(temp_data); | 227 data_.push_back(temp_data); |
228 } | 228 } |
229 return true; | 229 return true; |
230 } | 230 } |
231 | 231 |
232 bool VideoCaptureBufferPool::GpuMemoryBufferTracker::ShareToProcess( | |
233 int plane, | |
234 base::ProcessHandle process_handle, | |
235 void* new_handle) { | |
236 DCHECK_LE(plane, static_cast<int>(gpu_memory_buffers_.size())); | |
237 | |
238 const auto& cur_gmb_handle = gpu_memory_buffers_[plane]->GetHandle(); | |
mcasas
2015/08/21 03:57:25
current_gmb_handle?
emircan
2015/08/22 03:13:26
Done.
| |
239 gfx::GpuMemoryBufferHandle* const new_gmb_handle = | |
240 static_cast<gfx::GpuMemoryBufferHandle*>(new_handle); | |
241 switch (cur_gmb_handle.type) { | |
242 case gfx::EMPTY_BUFFER: { | |
mcasas
2015/08/21 03:57:25
I don't think {} are needed in this or l.257-260 c
emircan
2015/08/22 03:13:26
Done.
| |
243 NOTREACHED(); | |
244 return false; | |
245 } | |
246 case gfx::SHARED_MEMORY_BUFFER: { | |
247 DCHECK(base::SharedMemory::IsHandleValid(cur_gmb_handle.handle)); | |
248 base::SharedMemory shared_memory( | |
249 base::SharedMemory::DuplicateHandle(cur_gmb_handle.handle), false); | |
250 shared_memory.ShareToProcess(process_handle, &new_gmb_handle->handle); | |
251 DCHECK(base::SharedMemory::IsHandleValid(new_gmb_handle->handle)); | |
252 new_gmb_handle->type = gfx::SHARED_MEMORY_BUFFER; | |
253 return true; | |
254 } | |
255 case gfx::IO_SURFACE_BUFFER: | |
256 case gfx::SURFACE_TEXTURE_BUFFER: | |
257 case gfx::OZONE_NATIVE_PIXMAP: { | |
258 *new_gmb_handle = cur_gmb_handle; | |
259 return true; | |
260 } | |
mcasas
2015/08/21 03:57:25
default:
NOTREACHED();
?
emircan
2015/08/22 03:13:26
If new formats are added, it should throw a compil
| |
261 } | |
262 return true; | |
263 } | |
264 | |
232 // static | 265 // static |
233 scoped_ptr<VideoCaptureBufferPool::Tracker> | 266 scoped_ptr<VideoCaptureBufferPool::Tracker> |
234 VideoCaptureBufferPool::Tracker::CreateTracker(bool use_gmb) { | 267 VideoCaptureBufferPool::Tracker::CreateTracker(bool use_gmb) { |
235 if (!use_gmb) | 268 if (!use_gmb) |
236 return make_scoped_ptr(new SharedMemTracker()); | 269 return make_scoped_ptr(new SharedMemTracker()); |
237 else | 270 else |
238 return make_scoped_ptr(new GpuMemoryBufferTracker()); | 271 return make_scoped_ptr(new GpuMemoryBufferTracker()); |
239 } | 272 } |
240 | 273 |
241 VideoCaptureBufferPool::Tracker::~Tracker() {} | 274 VideoCaptureBufferPool::Tracker::~Tracker() {} |
242 | 275 |
243 VideoCaptureBufferPool::VideoCaptureBufferPool(int count) | 276 VideoCaptureBufferPool::VideoCaptureBufferPool(int count) |
244 : count_(count), | 277 : count_(count), |
245 next_buffer_id_(0) { | 278 next_buffer_id_(0) { |
246 DCHECK_GT(count, 0); | 279 DCHECK_GT(count, 0); |
247 } | 280 } |
248 | 281 |
249 VideoCaptureBufferPool::~VideoCaptureBufferPool() { | 282 VideoCaptureBufferPool::~VideoCaptureBufferPool() { |
250 STLDeleteValues(&trackers_); | 283 STLDeleteValues(&trackers_); |
251 } | 284 } |
252 | 285 |
253 base::SharedMemoryHandle VideoCaptureBufferPool::ShareToProcess( | 286 bool VideoCaptureBufferPool::ShareToProcess( |
254 int buffer_id, | 287 int buffer_id, |
288 int plane, | |
255 base::ProcessHandle process_handle, | 289 base::ProcessHandle process_handle, |
256 size_t* memory_size) { | 290 void* new_handle) { |
257 base::AutoLock lock(lock_); | 291 base::AutoLock lock(lock_); |
258 | 292 |
259 Tracker* tracker = GetTracker(buffer_id); | 293 Tracker* tracker = GetTracker(buffer_id); |
260 if (!tracker) { | 294 if (!tracker) { |
261 NOTREACHED() << "Invalid buffer_id."; | 295 NOTREACHED() << "Invalid buffer_id."; |
262 return base::SharedMemory::NULLHandle(); | 296 return false; |
263 } | 297 } |
264 base::SharedMemoryHandle remote_handle; | 298 if (tracker->ShareToProcess(plane, process_handle, new_handle)) { |
mcasas
2015/08/21 03:57:24
no {} needed
emircan
2015/08/22 03:13:26
Done.
| |
265 if (tracker->ShareToProcess(process_handle, &remote_handle)) { | 299 return true; |
266 *memory_size = tracker->mapped_size(); | |
267 return remote_handle; | |
268 } | 300 } |
269 DPLOG(ERROR) << "Error mapping Shared Memory"; | 301 DPLOG(ERROR) << "Error mapping memory"; |
270 return base::SharedMemoryHandle(); | 302 return false; |
271 } | 303 } |
272 | 304 |
273 scoped_ptr<VideoCaptureBufferPool::BufferHandle> | 305 scoped_ptr<VideoCaptureBufferPool::BufferHandle> |
274 VideoCaptureBufferPool::GetBufferHandle(int buffer_id) { | 306 VideoCaptureBufferPool::GetBufferHandle(int buffer_id) { |
275 base::AutoLock lock(lock_); | 307 base::AutoLock lock(lock_); |
276 | 308 |
277 Tracker* tracker = GetTracker(buffer_id); | 309 Tracker* tracker = GetTracker(buffer_id); |
278 if (!tracker) { | 310 if (!tracker) { |
279 NOTREACHED() << "Invalid buffer_id."; | 311 NOTREACHED() << "Invalid buffer_id."; |
280 return scoped_ptr<BufferHandle>(); | 312 return scoped_ptr<BufferHandle>(); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
407 return buffer_id; | 439 return buffer_id; |
408 } | 440 } |
409 | 441 |
410 VideoCaptureBufferPool::Tracker* VideoCaptureBufferPool::GetTracker( | 442 VideoCaptureBufferPool::Tracker* VideoCaptureBufferPool::GetTracker( |
411 int buffer_id) { | 443 int buffer_id) { |
412 TrackerMap::const_iterator it = trackers_.find(buffer_id); | 444 TrackerMap::const_iterator it = trackers_.find(buffer_id); |
413 return (it == trackers_.end()) ? NULL : it->second; | 445 return (it == trackers_.end()) ? NULL : it->second; |
414 } | 446 } |
415 | 447 |
416 } // namespace content | 448 } // namespace content |
OLD | NEW |