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 | |
119 bool ShareToProcess(base::ProcessHandle process_handle, | 122 bool ShareToProcess(base::ProcessHandle process_handle, |
120 base::SharedMemoryHandle* new_handle) override { | 123 base::SharedMemoryHandle* new_handle) override { |
121 return shared_memory_.ShareToProcess(process_handle, new_handle); | 124 return shared_memory_.ShareToProcess(process_handle, new_handle); |
122 } | 125 } |
126 bool ShareToProcess2(int plane, | |
127 base::ProcessHandle process_handle, | |
128 gfx::GpuMemoryBufferHandle* new_handle) override { | |
129 NOTREACHED(); | |
130 return false; | |
131 } | |
123 | 132 |
124 private: | 133 private: |
125 // The memory created to be shared with renderer processes. | 134 // The memory created to be shared with renderer processes. |
126 base::SharedMemory shared_memory_; | 135 base::SharedMemory shared_memory_; |
136 size_t mapped_size_; | |
127 }; | 137 }; |
128 | 138 |
129 // Tracker specifics for GpuMemoryBuffer. Owns GpuMemoryBuffers and its | 139 // Tracker specifics for GpuMemoryBuffer. Owns GpuMemoryBuffers and its |
130 // associated pixel dimensions. | 140 // associated pixel dimensions. |
131 class VideoCaptureBufferPool::GpuMemoryBufferTracker final : public Tracker { | 141 class VideoCaptureBufferPool::GpuMemoryBufferTracker final : public Tracker { |
132 public: | 142 public: |
133 GpuMemoryBufferTracker(); | 143 GpuMemoryBufferTracker(); |
134 bool Init(media::VideoCapturePixelFormat format, | 144 bool Init(media::VideoCapturePixelFormat format, |
135 media::VideoPixelStorage storage_type, | 145 media::VideoPixelStorage storage_type, |
136 const gfx::Size& dimensions) override; | 146 const gfx::Size& dimensions) override; |
137 ~GpuMemoryBufferTracker() override; | 147 ~GpuMemoryBufferTracker() override; |
138 | 148 |
139 size_t mapped_size() const override { | |
140 NOTREACHED(); | |
141 return 0; | |
142 } | |
143 scoped_ptr<BufferHandle> GetBufferHandle() override { | 149 scoped_ptr<BufferHandle> GetBufferHandle() override { |
144 return make_scoped_ptr(new GpuMemoryBufferBufferHandle( | 150 return make_scoped_ptr(new GpuMemoryBufferBufferHandle( |
145 &data_, dimensions_, &gpu_memory_buffers_)); | 151 &data_, dimensions_, &gpu_memory_buffers_)); |
146 } | 152 } |
147 bool ShareToProcess(base::ProcessHandle process_handle, | 153 bool ShareToProcess(base::ProcessHandle process_handle, |
148 base::SharedMemoryHandle* new_handle) override { | 154 base::SharedMemoryHandle* new_handle) override { |
149 return true; | 155 NOTREACHED(); |
156 return false; | |
150 } | 157 } |
158 bool ShareToProcess2(int plane, | |
159 base::ProcessHandle process_handle, | |
160 gfx::GpuMemoryBufferHandle* new_handle) override; | |
151 | 161 |
152 private: | 162 private: |
153 std::vector<void*> data_; | 163 std::vector<void*> data_; |
154 gfx::Size dimensions_; | 164 gfx::Size dimensions_; |
155 // Owned references to GpuMemoryBuffers. | 165 // Owned references to GpuMemoryBuffers. |
156 ScopedVector<gfx::GpuMemoryBuffer> gpu_memory_buffers_; | 166 ScopedVector<gfx::GpuMemoryBuffer> gpu_memory_buffers_; |
157 }; | 167 }; |
158 | 168 |
159 VideoCaptureBufferPool::SharedMemTracker::SharedMemTracker() : Tracker() { | 169 VideoCaptureBufferPool::SharedMemTracker::SharedMemTracker() : Tracker() {} |
160 } | |
161 | 170 |
162 bool VideoCaptureBufferPool::SharedMemTracker::Init( | 171 bool VideoCaptureBufferPool::SharedMemTracker::Init( |
163 media::VideoCapturePixelFormat format, | 172 media::VideoCapturePixelFormat format, |
164 media::VideoPixelStorage storage_type, | 173 media::VideoPixelStorage storage_type, |
165 const gfx::Size& dimensions) { | 174 const gfx::Size& dimensions) { |
166 DVLOG(2) << "allocating ShMem of " << dimensions.ToString(); | 175 DVLOG(2) << "allocating ShMem of " << dimensions.ToString(); |
167 set_pixel_format(format); | 176 set_pixel_format(format); |
168 set_storage_type(storage_type); | 177 set_storage_type(storage_type); |
169 // |dimensions| can be 0x0 for trackers that do not require memory backing. | 178 // |dimensions| can be 0x0 for trackers that do not require memory backing. |
170 set_pixel_count(dimensions.GetArea()); | 179 set_pixel_count(dimensions.GetArea()); |
171 const size_t byte_count = | 180 mapped_size_ = |
172 media::VideoCaptureFormat(dimensions, 0.0f, format, storage_type) | 181 media::VideoCaptureFormat(dimensions, 0.0f, format, storage_type) |
173 .ImageAllocationSize(); | 182 .ImageAllocationSize(); |
174 if (!byte_count) | 183 if (!mapped_size_) |
175 return true; | 184 return true; |
176 return shared_memory_.CreateAndMapAnonymous(byte_count); | 185 return shared_memory_.CreateAndMapAnonymous(mapped_size_); |
177 } | 186 } |
178 | 187 |
179 VideoCaptureBufferPool::GpuMemoryBufferTracker::GpuMemoryBufferTracker() | 188 VideoCaptureBufferPool::GpuMemoryBufferTracker::GpuMemoryBufferTracker() |
180 : Tracker() { | 189 : Tracker() { |
181 } | 190 } |
182 | 191 |
183 VideoCaptureBufferPool::GpuMemoryBufferTracker::~GpuMemoryBufferTracker() { | 192 VideoCaptureBufferPool::GpuMemoryBufferTracker::~GpuMemoryBufferTracker() { |
184 for (const auto& gmb : gpu_memory_buffers_) { | 193 for (const auto& gmb : gpu_memory_buffers_) { |
185 if (gmb->IsMapped()) | 194 if (gmb->IsMapped()) |
186 gmb->Unmap(); | 195 gmb->Unmap(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
222 return false; | 231 return false; |
223 | 232 |
224 void* temp_data = nullptr; | 233 void* temp_data = nullptr; |
225 gpu_memory_buffers_[i]->Map(&temp_data); | 234 gpu_memory_buffers_[i]->Map(&temp_data); |
226 DCHECK(temp_data); | 235 DCHECK(temp_data); |
227 data_.push_back(temp_data); | 236 data_.push_back(temp_data); |
228 } | 237 } |
229 return true; | 238 return true; |
230 } | 239 } |
231 | 240 |
241 bool VideoCaptureBufferPool::GpuMemoryBufferTracker::ShareToProcess2( | |
242 int plane, | |
243 base::ProcessHandle process_handle, | |
244 gfx::GpuMemoryBufferHandle* new_handle) { | |
245 DCHECK_LE(plane, static_cast<int>(gpu_memory_buffers_.size())); | |
246 | |
247 const auto& current_gmb_handle = gpu_memory_buffers_[plane]->GetHandle(); | |
248 gfx::GpuMemoryBufferHandle* const new_gmb_handle = | |
mcasas
2015/08/27 18:26:55
Remove |new_gmb_handle| as talked offline.
emircan
2015/08/27 22:01:06
Done.
| |
249 static_cast<gfx::GpuMemoryBufferHandle*>(new_handle); | |
250 switch (current_gmb_handle.type) { | |
251 case gfx::EMPTY_BUFFER: | |
252 NOTREACHED(); | |
253 return false; | |
254 case gfx::SHARED_MEMORY_BUFFER: { | |
255 DCHECK(base::SharedMemory::IsHandleValid(current_gmb_handle.handle)); | |
256 base::SharedMemory shared_memory( | |
257 base::SharedMemory::DuplicateHandle(current_gmb_handle.handle), | |
258 false); | |
259 shared_memory.ShareToProcess(process_handle, &new_gmb_handle->handle); | |
260 DCHECK(base::SharedMemory::IsHandleValid(new_gmb_handle->handle)); | |
261 new_gmb_handle->type = gfx::SHARED_MEMORY_BUFFER; | |
mcasas
2015/08/27 18:26:55
When |new_gmb_handle| is removed, should this
chan
emircan
2015/08/27 22:01:06
We still need to set it because |new_handle| comes
| |
262 return true; | |
263 } | |
264 case gfx::IO_SURFACE_BUFFER: | |
265 case gfx::SURFACE_TEXTURE_BUFFER: | |
266 case gfx::OZONE_NATIVE_PIXMAP: | |
267 *new_gmb_handle = current_gmb_handle; | |
268 return true; | |
269 } | |
270 NOTREACHED(); | |
271 return true; | |
272 } | |
273 | |
232 // static | 274 // static |
233 scoped_ptr<VideoCaptureBufferPool::Tracker> | 275 scoped_ptr<VideoCaptureBufferPool::Tracker> |
234 VideoCaptureBufferPool::Tracker::CreateTracker(bool use_gmb) { | 276 VideoCaptureBufferPool::Tracker::CreateTracker(bool use_gmb) { |
235 if (!use_gmb) | 277 if (!use_gmb) |
236 return make_scoped_ptr(new SharedMemTracker()); | 278 return make_scoped_ptr(new SharedMemTracker()); |
237 else | 279 else |
238 return make_scoped_ptr(new GpuMemoryBufferTracker()); | 280 return make_scoped_ptr(new GpuMemoryBufferTracker()); |
239 } | 281 } |
240 | 282 |
241 VideoCaptureBufferPool::Tracker::~Tracker() {} | 283 VideoCaptureBufferPool::Tracker::~Tracker() {} |
242 | 284 |
243 VideoCaptureBufferPool::VideoCaptureBufferPool(int count) | 285 VideoCaptureBufferPool::VideoCaptureBufferPool(int count) |
244 : count_(count), | 286 : count_(count), |
245 next_buffer_id_(0) { | 287 next_buffer_id_(0) { |
246 DCHECK_GT(count, 0); | 288 DCHECK_GT(count, 0); |
247 } | 289 } |
248 | 290 |
249 VideoCaptureBufferPool::~VideoCaptureBufferPool() { | 291 VideoCaptureBufferPool::~VideoCaptureBufferPool() { |
250 STLDeleteValues(&trackers_); | 292 STLDeleteValues(&trackers_); |
251 } | 293 } |
252 | 294 |
253 base::SharedMemoryHandle VideoCaptureBufferPool::ShareToProcess( | 295 bool VideoCaptureBufferPool::ShareToProcess( |
254 int buffer_id, | 296 int buffer_id, |
255 base::ProcessHandle process_handle, | 297 base::ProcessHandle process_handle, |
256 size_t* memory_size) { | 298 base::SharedMemoryHandle* new_handle) { |
257 base::AutoLock lock(lock_); | 299 base::AutoLock lock(lock_); |
258 | 300 |
259 Tracker* tracker = GetTracker(buffer_id); | 301 Tracker* tracker = GetTracker(buffer_id); |
260 if (!tracker) { | 302 if (!tracker) { |
261 NOTREACHED() << "Invalid buffer_id."; | 303 NOTREACHED() << "Invalid buffer_id."; |
262 return base::SharedMemory::NULLHandle(); | 304 return false; |
263 } | 305 } |
264 base::SharedMemoryHandle remote_handle; | 306 if (tracker->ShareToProcess(process_handle, new_handle)) |
265 if (tracker->ShareToProcess(process_handle, &remote_handle)) { | 307 return true; |
266 *memory_size = tracker->mapped_size(); | 308 DPLOG(ERROR) << "Error mapping memory"; |
267 return remote_handle; | 309 return false; |
310 } | |
311 | |
312 bool VideoCaptureBufferPool::ShareToProcess2( | |
mcasas
2015/08/27 18:26:55
See my comments in video_capture_controller.cc
abo
| |
313 int buffer_id, | |
314 int plane, | |
315 base::ProcessHandle process_handle, | |
316 gfx::GpuMemoryBufferHandle* new_handle) { | |
317 base::AutoLock lock(lock_); | |
318 | |
319 Tracker* tracker = GetTracker(buffer_id); | |
320 if (!tracker) { | |
321 NOTREACHED() << "Invalid buffer_id."; | |
322 return false; | |
268 } | 323 } |
269 DPLOG(ERROR) << "Error mapping Shared Memory"; | 324 if (tracker->ShareToProcess2(plane, process_handle, new_handle)) |
270 return base::SharedMemoryHandle(); | 325 return true; |
326 DPLOG(ERROR) << "Error mapping memory"; | |
327 return false; | |
271 } | 328 } |
272 | 329 |
273 scoped_ptr<VideoCaptureBufferPool::BufferHandle> | 330 scoped_ptr<VideoCaptureBufferPool::BufferHandle> |
274 VideoCaptureBufferPool::GetBufferHandle(int buffer_id) { | 331 VideoCaptureBufferPool::GetBufferHandle(int buffer_id) { |
275 base::AutoLock lock(lock_); | 332 base::AutoLock lock(lock_); |
276 | 333 |
277 Tracker* tracker = GetTracker(buffer_id); | 334 Tracker* tracker = GetTracker(buffer_id); |
278 if (!tracker) { | 335 if (!tracker) { |
279 NOTREACHED() << "Invalid buffer_id."; | 336 NOTREACHED() << "Invalid buffer_id."; |
280 return scoped_ptr<BufferHandle>(); | 337 return scoped_ptr<BufferHandle>(); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
407 return buffer_id; | 464 return buffer_id; |
408 } | 465 } |
409 | 466 |
410 VideoCaptureBufferPool::Tracker* VideoCaptureBufferPool::GetTracker( | 467 VideoCaptureBufferPool::Tracker* VideoCaptureBufferPool::GetTracker( |
411 int buffer_id) { | 468 int buffer_id) { |
412 TrackerMap::const_iterator it = trackers_.find(buffer_id); | 469 TrackerMap::const_iterator it = trackers_.find(buffer_id); |
413 return (it == trackers_.end()) ? NULL : it->second; | 470 return (it == trackers_.end()) ? NULL : it->second; |
414 } | 471 } |
415 | 472 |
416 } // namespace content | 473 } // namespace content |
OLD | NEW |