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 "media/capture/video/video_capture_buffer_pool_impl.h" | 5 #include "media/capture/video/video_capture_buffer_pool_impl.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 } | 50 } |
51 | 51 |
52 DCHECK(tracker->held_by_producer()); | 52 DCHECK(tracker->held_by_producer()); |
53 return tracker->GetBufferHandle(); | 53 return tracker->GetBufferHandle(); |
54 } | 54 } |
55 | 55 |
56 int VideoCaptureBufferPoolImpl::ReserveForProducer( | 56 int VideoCaptureBufferPoolImpl::ReserveForProducer( |
57 const gfx::Size& dimensions, | 57 const gfx::Size& dimensions, |
58 media::VideoPixelFormat format, | 58 media::VideoPixelFormat format, |
59 media::VideoPixelStorage storage, | 59 media::VideoPixelStorage storage, |
| 60 int frame_feedback_id, |
60 int* buffer_id_to_drop) { | 61 int* buffer_id_to_drop) { |
61 base::AutoLock lock(lock_); | 62 base::AutoLock lock(lock_); |
62 return ReserveForProducerInternal(dimensions, format, storage, | 63 return ReserveForProducerInternal(dimensions, format, storage, |
63 buffer_id_to_drop); | 64 frame_feedback_id, buffer_id_to_drop); |
64 } | 65 } |
65 | 66 |
66 void VideoCaptureBufferPoolImpl::RelinquishProducerReservation(int buffer_id) { | 67 void VideoCaptureBufferPoolImpl::RelinquishProducerReservation(int buffer_id) { |
67 base::AutoLock lock(lock_); | 68 base::AutoLock lock(lock_); |
68 VideoCaptureBufferTracker* tracker = GetTracker(buffer_id); | 69 VideoCaptureBufferTracker* tracker = GetTracker(buffer_id); |
69 if (!tracker) { | 70 if (!tracker) { |
70 NOTREACHED() << "Invalid buffer_id."; | 71 NOTREACHED() << "Invalid buffer_id."; |
71 return; | 72 return; |
72 } | 73 } |
73 DCHECK(tracker->held_by_producer()); | 74 DCHECK(tracker->held_by_producer()); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 if (tracker->held_by_producer() || tracker->consumer_hold_count() > 0) | 145 if (tracker->held_by_producer() || tracker->consumer_hold_count() > 0) |
145 ++num_buffers_held; | 146 ++num_buffers_held; |
146 } | 147 } |
147 return static_cast<double>(num_buffers_held) / count_; | 148 return static_cast<double>(num_buffers_held) / count_; |
148 } | 149 } |
149 | 150 |
150 int VideoCaptureBufferPoolImpl::ReserveForProducerInternal( | 151 int VideoCaptureBufferPoolImpl::ReserveForProducerInternal( |
151 const gfx::Size& dimensions, | 152 const gfx::Size& dimensions, |
152 media::VideoPixelFormat pixel_format, | 153 media::VideoPixelFormat pixel_format, |
153 media::VideoPixelStorage storage_type, | 154 media::VideoPixelStorage storage_type, |
| 155 int frame_feedback_id, |
154 int* buffer_id_to_drop) { | 156 int* buffer_id_to_drop) { |
155 lock_.AssertAcquired(); | 157 lock_.AssertAcquired(); |
156 | 158 |
157 const size_t size_in_pixels = dimensions.GetArea(); | 159 const size_t size_in_pixels = dimensions.GetArea(); |
158 // Look for a tracker that's allocated, big enough, and not in use. Track the | 160 // Look for a tracker that's allocated, big enough, and not in use. Track the |
159 // largest one that's not big enough, in case we have to reallocate a tracker. | 161 // largest one that's not big enough, in case we have to reallocate a tracker. |
160 *buffer_id_to_drop = kInvalidId; | 162 *buffer_id_to_drop = kInvalidId; |
161 size_t largest_size_in_pixels = 0; | 163 size_t largest_size_in_pixels = 0; |
162 auto tracker_of_last_resort = trackers_.end(); | 164 auto tracker_of_last_resort = trackers_.end(); |
163 auto tracker_to_drop = trackers_.end(); | 165 auto tracker_to_drop = trackers_.end(); |
164 for (auto it = trackers_.begin(); it != trackers_.end(); ++it) { | 166 for (auto it = trackers_.begin(); it != trackers_.end(); ++it) { |
165 VideoCaptureBufferTracker* const tracker = it->second.get(); | 167 VideoCaptureBufferTracker* const tracker = it->second.get(); |
166 if (!tracker->consumer_hold_count() && !tracker->held_by_producer()) { | 168 if (!tracker->consumer_hold_count() && !tracker->held_by_producer()) { |
167 if (tracker->max_pixel_count() >= size_in_pixels && | 169 if (tracker->max_pixel_count() >= size_in_pixels && |
168 (tracker->pixel_format() == pixel_format) && | 170 (tracker->pixel_format() == pixel_format) && |
169 (tracker->storage_type() == storage_type)) { | 171 (tracker->storage_type() == storage_type)) { |
170 if (it->first == last_relinquished_buffer_id_) { | 172 if (it->first == last_relinquished_buffer_id_) { |
171 // This buffer would do just fine, but avoid returning it because the | 173 // This buffer would do just fine, but avoid returning it because the |
172 // client may want to resurrect it. It will be returned perforce if | 174 // client may want to resurrect it. It will be returned perforce if |
173 // the pool has reached it's maximum limit (see code below). | 175 // the pool has reached it's maximum limit (see code below). |
174 tracker_of_last_resort = it; | 176 tracker_of_last_resort = it; |
175 continue; | 177 continue; |
176 } | 178 } |
177 // Existing tracker is big enough and has correct format. Reuse it. | 179 // Existing tracker is big enough and has correct format. Reuse it. |
178 tracker->set_dimensions(dimensions); | 180 tracker->set_dimensions(dimensions); |
179 tracker->set_held_by_producer(true); | 181 tracker->set_held_by_producer(true); |
| 182 tracker->set_frame_feedback_id(frame_feedback_id); |
180 return it->first; | 183 return it->first; |
181 } | 184 } |
182 if (tracker->max_pixel_count() > largest_size_in_pixels) { | 185 if (tracker->max_pixel_count() > largest_size_in_pixels) { |
183 largest_size_in_pixels = tracker->max_pixel_count(); | 186 largest_size_in_pixels = tracker->max_pixel_count(); |
184 tracker_to_drop = it; | 187 tracker_to_drop = it; |
185 } | 188 } |
186 } | 189 } |
187 } | 190 } |
188 | 191 |
189 // Preferably grow the pool by creating a new tracker. If we're at maximum | 192 // Preferably grow the pool by creating a new tracker. If we're at maximum |
190 // size, then try using |tracker_of_last_resort| or reallocate by deleting an | 193 // size, then try using |tracker_of_last_resort| or reallocate by deleting an |
191 // existing one instead. | 194 // existing one instead. |
192 if (trackers_.size() == static_cast<size_t>(count_)) { | 195 if (trackers_.size() == static_cast<size_t>(count_)) { |
193 if (tracker_of_last_resort != trackers_.end()) { | 196 if (tracker_of_last_resort != trackers_.end()) { |
194 last_relinquished_buffer_id_ = kInvalidId; | 197 last_relinquished_buffer_id_ = kInvalidId; |
195 tracker_of_last_resort->second->set_dimensions(dimensions); | 198 tracker_of_last_resort->second->set_dimensions(dimensions); |
196 tracker_of_last_resort->second->set_held_by_producer(true); | 199 tracker_of_last_resort->second->set_held_by_producer(true); |
| 200 tracker_of_last_resort->second->set_frame_feedback_id(frame_feedback_id); |
197 return tracker_of_last_resort->first; | 201 return tracker_of_last_resort->first; |
198 } | 202 } |
199 if (tracker_to_drop == trackers_.end()) { | 203 if (tracker_to_drop == trackers_.end()) { |
200 // We're out of space, and can't find an unused tracker to reallocate. | 204 // We're out of space, and can't find an unused tracker to reallocate. |
201 return kInvalidId; | 205 return kInvalidId; |
202 } | 206 } |
203 if (tracker_to_drop->first == last_relinquished_buffer_id_) | 207 if (tracker_to_drop->first == last_relinquished_buffer_id_) |
204 last_relinquished_buffer_id_ = kInvalidId; | 208 last_relinquished_buffer_id_ = kInvalidId; |
205 *buffer_id_to_drop = tracker_to_drop->first; | 209 *buffer_id_to_drop = tracker_to_drop->first; |
206 trackers_.erase(tracker_to_drop); | 210 trackers_.erase(tracker_to_drop); |
207 } | 211 } |
208 | 212 |
209 // Create the new tracker. | 213 // Create the new tracker. |
210 const int buffer_id = next_buffer_id_++; | 214 const int buffer_id = next_buffer_id_++; |
211 | 215 |
212 std::unique_ptr<VideoCaptureBufferTracker> tracker = | 216 std::unique_ptr<VideoCaptureBufferTracker> tracker = |
213 buffer_tracker_factory_->CreateTracker(storage_type); | 217 buffer_tracker_factory_->CreateTracker(storage_type); |
214 // TODO(emircan): We pass the lock here to solve GMB allocation issue, see | 218 // TODO(emircan): We pass the lock here to solve GMB allocation issue, see |
215 // crbug.com/545238. | 219 // crbug.com/545238. |
216 if (!tracker->Init(dimensions, pixel_format, storage_type, &lock_)) { | 220 if (!tracker->Init(dimensions, pixel_format, storage_type, &lock_)) { |
217 DLOG(ERROR) << "Error initializing VideoCaptureBufferTracker"; | 221 DLOG(ERROR) << "Error initializing VideoCaptureBufferTracker"; |
218 return kInvalidId; | 222 return kInvalidId; |
219 } | 223 } |
220 | 224 |
221 tracker->set_held_by_producer(true); | 225 tracker->set_held_by_producer(true); |
| 226 tracker->set_frame_feedback_id(frame_feedback_id); |
222 trackers_[buffer_id] = std::move(tracker); | 227 trackers_[buffer_id] = std::move(tracker); |
223 | 228 |
224 return buffer_id; | 229 return buffer_id; |
225 } | 230 } |
226 | 231 |
227 VideoCaptureBufferTracker* VideoCaptureBufferPoolImpl::GetTracker( | 232 VideoCaptureBufferTracker* VideoCaptureBufferPoolImpl::GetTracker( |
228 int buffer_id) { | 233 int buffer_id) { |
229 auto it = trackers_.find(buffer_id); | 234 auto it = trackers_.find(buffer_id); |
230 return (it == trackers_.end()) ? nullptr : it->second.get(); | 235 return (it == trackers_.end()) ? nullptr : it->second.get(); |
231 } | 236 } |
232 | 237 |
233 } // namespace media | 238 } // namespace media |
OLD | NEW |