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 switch (current_gmb_handle.type) { |
| 249 case gfx::EMPTY_BUFFER: |
| 250 NOTREACHED(); |
| 251 return false; |
| 252 case gfx::SHARED_MEMORY_BUFFER: { |
| 253 DCHECK(base::SharedMemory::IsHandleValid(current_gmb_handle.handle)); |
| 254 base::SharedMemory shared_memory( |
| 255 base::SharedMemory::DuplicateHandle(current_gmb_handle.handle), |
| 256 false); |
| 257 shared_memory.ShareToProcess(process_handle, &new_handle->handle); |
| 258 DCHECK(base::SharedMemory::IsHandleValid(new_handle->handle)); |
| 259 new_handle->type = gfx::SHARED_MEMORY_BUFFER; |
| 260 return true; |
| 261 } |
| 262 case gfx::IO_SURFACE_BUFFER: |
| 263 case gfx::SURFACE_TEXTURE_BUFFER: |
| 264 case gfx::OZONE_NATIVE_PIXMAP: |
| 265 *new_handle = current_gmb_handle; |
| 266 return true; |
| 267 } |
| 268 NOTREACHED(); |
| 269 return true; |
| 270 } |
| 271 |
232 // static | 272 // static |
233 scoped_ptr<VideoCaptureBufferPool::Tracker> | 273 scoped_ptr<VideoCaptureBufferPool::Tracker> |
234 VideoCaptureBufferPool::Tracker::CreateTracker(bool use_gmb) { | 274 VideoCaptureBufferPool::Tracker::CreateTracker(bool use_gmb) { |
235 if (!use_gmb) | 275 if (!use_gmb) |
236 return make_scoped_ptr(new SharedMemTracker()); | 276 return make_scoped_ptr(new SharedMemTracker()); |
237 else | 277 else |
238 return make_scoped_ptr(new GpuMemoryBufferTracker()); | 278 return make_scoped_ptr(new GpuMemoryBufferTracker()); |
239 } | 279 } |
240 | 280 |
241 VideoCaptureBufferPool::Tracker::~Tracker() {} | 281 VideoCaptureBufferPool::Tracker::~Tracker() {} |
242 | 282 |
243 VideoCaptureBufferPool::VideoCaptureBufferPool(int count) | 283 VideoCaptureBufferPool::VideoCaptureBufferPool(int count) |
244 : count_(count), | 284 : count_(count), |
245 next_buffer_id_(0) { | 285 next_buffer_id_(0) { |
246 DCHECK_GT(count, 0); | 286 DCHECK_GT(count, 0); |
247 } | 287 } |
248 | 288 |
249 VideoCaptureBufferPool::~VideoCaptureBufferPool() { | 289 VideoCaptureBufferPool::~VideoCaptureBufferPool() { |
250 STLDeleteValues(&trackers_); | 290 STLDeleteValues(&trackers_); |
251 } | 291 } |
252 | 292 |
253 base::SharedMemoryHandle VideoCaptureBufferPool::ShareToProcess( | 293 bool VideoCaptureBufferPool::ShareToProcess( |
254 int buffer_id, | 294 int buffer_id, |
255 base::ProcessHandle process_handle, | 295 base::ProcessHandle process_handle, |
256 size_t* memory_size) { | 296 base::SharedMemoryHandle* new_handle) { |
257 base::AutoLock lock(lock_); | 297 base::AutoLock lock(lock_); |
258 | 298 |
259 Tracker* tracker = GetTracker(buffer_id); | 299 Tracker* tracker = GetTracker(buffer_id); |
260 if (!tracker) { | 300 if (!tracker) { |
261 NOTREACHED() << "Invalid buffer_id."; | 301 NOTREACHED() << "Invalid buffer_id."; |
262 return base::SharedMemory::NULLHandle(); | 302 return false; |
263 } | 303 } |
264 base::SharedMemoryHandle remote_handle; | 304 if (tracker->ShareToProcess(process_handle, new_handle)) |
265 if (tracker->ShareToProcess(process_handle, &remote_handle)) { | 305 return true; |
266 *memory_size = tracker->mapped_size(); | 306 DPLOG(ERROR) << "Error mapping memory"; |
267 return remote_handle; | 307 return false; |
| 308 } |
| 309 |
| 310 bool VideoCaptureBufferPool::ShareToProcess2( |
| 311 int buffer_id, |
| 312 int plane, |
| 313 base::ProcessHandle process_handle, |
| 314 gfx::GpuMemoryBufferHandle* new_handle) { |
| 315 base::AutoLock lock(lock_); |
| 316 |
| 317 Tracker* tracker = GetTracker(buffer_id); |
| 318 if (!tracker) { |
| 319 NOTREACHED() << "Invalid buffer_id."; |
| 320 return false; |
268 } | 321 } |
269 DPLOG(ERROR) << "Error mapping Shared Memory"; | 322 if (tracker->ShareToProcess2(plane, process_handle, new_handle)) |
270 return base::SharedMemoryHandle(); | 323 return true; |
| 324 DPLOG(ERROR) << "Error mapping memory"; |
| 325 return false; |
271 } | 326 } |
272 | 327 |
273 scoped_ptr<VideoCaptureBufferPool::BufferHandle> | 328 scoped_ptr<VideoCaptureBufferPool::BufferHandle> |
274 VideoCaptureBufferPool::GetBufferHandle(int buffer_id) { | 329 VideoCaptureBufferPool::GetBufferHandle(int buffer_id) { |
275 base::AutoLock lock(lock_); | 330 base::AutoLock lock(lock_); |
276 | 331 |
277 Tracker* tracker = GetTracker(buffer_id); | 332 Tracker* tracker = GetTracker(buffer_id); |
278 if (!tracker) { | 333 if (!tracker) { |
279 NOTREACHED() << "Invalid buffer_id."; | 334 NOTREACHED() << "Invalid buffer_id."; |
280 return scoped_ptr<BufferHandle>(); | 335 return scoped_ptr<BufferHandle>(); |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 return buffer_id; | 462 return buffer_id; |
408 } | 463 } |
409 | 464 |
410 VideoCaptureBufferPool::Tracker* VideoCaptureBufferPool::GetTracker( | 465 VideoCaptureBufferPool::Tracker* VideoCaptureBufferPool::GetTracker( |
411 int buffer_id) { | 466 int buffer_id) { |
412 TrackerMap::const_iterator it = trackers_.find(buffer_id); | 467 TrackerMap::const_iterator it = trackers_.find(buffer_id); |
413 return (it == trackers_.end()) ? NULL : it->second; | 468 return (it == trackers_.end()) ? NULL : it->second; |
414 } | 469 } |
415 | 470 |
416 } // namespace content | 471 } // namespace content |
OLD | NEW |