Chromium Code Reviews| Index: content/browser/renderer_host/media/video_capture_buffer_pool.cc |
| diff --git a/content/browser/renderer_host/media/video_capture_buffer_pool.cc b/content/browser/renderer_host/media/video_capture_buffer_pool.cc |
| index cd3e0be624008bd500265ee6d8a6e73f584f0577..7cfc949aaf29a13043152f0ee4dcee792ea7de34 100644 |
| --- a/content/browser/renderer_host/media/video_capture_buffer_pool.cc |
| +++ b/content/browser/renderer_host/media/video_capture_buffer_pool.cc |
| @@ -16,99 +16,31 @@ namespace content { |
| const int VideoCaptureBufferPool::kInvalidId = -1; |
| -// A simple holder of a memory-backed buffer and accessors to it. |
| -class SimpleBufferHandle final : public VideoCaptureBufferPool::BufferHandle { |
| - public: |
| - SimpleBufferHandle(void* data, |
| - size_t mapped_size, |
| - base::SharedMemoryHandle handle) |
| - : data_(data), |
| - mapped_size_(mapped_size) |
| -#if defined(OS_POSIX) && !defined(OS_MACOSX) |
| - , |
| - handle_(handle) |
| -#endif |
| - { |
| - } |
| - ~SimpleBufferHandle() override {} |
| - |
| - gfx::Size dimensions() const override { |
| - NOTREACHED(); |
| - return gfx::Size(); |
| - } |
| - size_t mapped_size() const override { return mapped_size_; } |
| - void* data(int plane) override { |
| - DCHECK_EQ(plane, 0); |
| - return data_; |
| - } |
| - ClientBuffer AsClientBuffer(int plane) override { |
| - NOTREACHED(); |
| - return nullptr; |
| - } |
| -#if defined(OS_POSIX) && !defined(OS_MACOSX) |
| - base::FileDescriptor AsPlatformFile() override { |
| - return handle_; |
| - } |
| -#endif |
| - |
| - private: |
| - void* const data_; |
| - const size_t mapped_size_; |
| -#if defined(OS_POSIX) && !defined(OS_MACOSX) |
| - const base::SharedMemoryHandle handle_; |
| -#endif |
| -}; |
| - |
| -// A holder of a GpuMemoryBuffer-backed buffer. Holds weak references to |
| -// GpuMemoryBuffer-backed buffers and provides accessors to their data. |
| -class GpuMemoryBufferBufferHandle final |
| - : public VideoCaptureBufferPool::BufferHandle { |
| - public: |
| - GpuMemoryBufferBufferHandle(const gfx::Size& dimensions, |
| - std::vector< |
| - scoped_ptr<gfx::GpuMemoryBuffer>>* gmbs) |
| - : dimensions_(dimensions), gmbs_(gmbs) { |
| - DCHECK(gmbs); |
| - } |
| - ~GpuMemoryBufferBufferHandle() override {} |
| - |
| - gfx::Size dimensions() const override { return dimensions_; } |
| - size_t mapped_size() const override { return dimensions_.GetArea(); } |
| - void* data(int plane) override { |
| - DCHECK_GE(plane, 0); |
| - DCHECK_LT(plane, static_cast<int>(gmbs_->size())); |
| - DCHECK((*gmbs_)[plane]); |
| - return (*gmbs_)[plane]->memory(0); |
| - } |
| - ClientBuffer AsClientBuffer(int plane) override { |
| - DCHECK_GE(plane, 0); |
| - DCHECK_LT(plane, static_cast<int>(gmbs_->size())); |
| - return (*gmbs_)[plane]->AsClientBuffer(); |
| - } |
| -#if defined(OS_POSIX) && !defined(OS_MACOSX) |
| - base::FileDescriptor AsPlatformFile() override { |
| - NOTREACHED(); |
| - return base::FileDescriptor(); |
| - } |
| -#endif |
| - |
| - private: |
| - const gfx::Size dimensions_; |
| - std::vector<scoped_ptr<gfx::GpuMemoryBuffer>>* const gmbs_; |
| -}; |
| - |
| // Tracker specifics for SharedMemory. |
| class VideoCaptureBufferPool::SharedMemTracker final : public Tracker { |
| public: |
| - SharedMemTracker(); |
| - bool Init(media::VideoPixelFormat format, |
| + SharedMemTracker() : Tracker() {} |
| + |
| + bool Init(const gfx::Size& dimensions, |
| + media::VideoPixelFormat format, |
| media::VideoPixelStorage storage_type, |
| - const gfx::Size& dimensions, |
| - base::Lock* lock) override; |
| + base::Lock* lock) override { |
| + DVLOG(2) << "allocating ShMem of " << dimensions.ToString(); |
| + set_dimensions(dimensions); |
| + // |dimensions| can be 0x0 for trackers that do not require memory backing. |
| + set_max_pixel_count(dimensions.GetArea()); |
| + set_pixel_format(format); |
| + set_storage_type(storage_type); |
| + mapped_size_ = |
| + media::VideoCaptureFormat(dimensions, 0.0f, format, storage_type) |
| + .ImageAllocationSize(); |
| + if (!mapped_size_) |
| + return true; |
| + return shared_memory_.CreateAndMapAnonymous(mapped_size_); |
| + } |
| scoped_ptr<BufferHandle> GetBufferHandle() override { |
| - return make_scoped_ptr(new SimpleBufferHandle( |
| - shared_memory_.memory(), mapped_size_, shared_memory_.handle())); |
| + return make_scoped_ptr(new SharedMemBufferHandle(this)); |
| } |
| bool ShareToProcess(base::ProcessHandle process_handle, |
| base::SharedMemoryHandle* new_handle) override { |
| @@ -122,6 +54,37 @@ class VideoCaptureBufferPool::SharedMemTracker final : public Tracker { |
| } |
| private: |
| + // A simple proxy that implements the BufferHandle interface, providing |
| + // accessors to SharedMemTracker's memory and properties. |
| + class SharedMemBufferHandle : public VideoCaptureBufferPool::BufferHandle { |
| + public: |
| + // |tracker| must outlive SimpleBufferHandle. This is ensured since a |
| + // tracker is pinned until ownership of this SimpleBufferHandle is returned |
| + // to VideoCaptureBufferPool. |
| + explicit SharedMemBufferHandle(SharedMemTracker* tracker) |
| + : tracker_(tracker) {} |
| + ~SharedMemBufferHandle() override {} |
| + |
| + gfx::Size dimensions() const override { return tracker_->dimensions(); } |
| + size_t mapped_size() const override { return tracker_->mapped_size_; } |
| + void* data(int plane) override { |
| + DCHECK_EQ(plane, 0); |
| + return tracker_->shared_memory_.memory(); |
| + } |
| + ClientBuffer AsClientBuffer(int plane) override { |
| + NOTREACHED(); |
| + return nullptr; |
| + } |
| +#if defined(OS_POSIX) && !defined(OS_MACOSX) |
| + base::FileDescriptor AsPlatformFile() override { |
| + return tracker_->shared_memory_.handle(); |
| + } |
| +#endif |
| + |
| + private: |
| + SharedMemTracker* const tracker_; |
| + }; |
| + |
| // The memory created to be shared with renderer processes. |
| base::SharedMemory shared_memory_; |
| size_t mapped_size_; |
| @@ -131,131 +94,134 @@ class VideoCaptureBufferPool::SharedMemTracker final : public Tracker { |
| // associated pixel dimensions. |
| class VideoCaptureBufferPool::GpuMemoryBufferTracker final : public Tracker { |
| public: |
| - GpuMemoryBufferTracker(); |
| - bool Init(media::VideoPixelFormat format, |
| + GpuMemoryBufferTracker() : Tracker() {} |
| + |
| + ~GpuMemoryBufferTracker() override { |
| + for (const auto& gmb : gpu_memory_buffers_) |
| + gmb->Unmap(); |
| + } |
| + |
| + bool Init(const gfx::Size& dimensions, |
| + media::VideoPixelFormat format, |
| media::VideoPixelStorage storage_type, |
| - const gfx::Size& dimensions, |
| - base::Lock* lock) override; |
| - ~GpuMemoryBufferTracker() override; |
| + base::Lock* lock) override { |
| + DVLOG(2) << "allocating GMB for " << dimensions.ToString(); |
| + // BrowserGpuMemoryBufferManager::current() may not be accessed on IO |
| + // Thread. |
| + DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| + DCHECK(BrowserGpuMemoryBufferManager::current()); |
| + // This class is only expected to be called with I420 buffer requests at |
| + // this point. |
| + DCHECK_EQ(format, media::PIXEL_FORMAT_I420); |
| + set_dimensions(dimensions); |
| + set_max_pixel_count(dimensions.GetArea()); |
| + set_pixel_format(format); |
| + set_storage_type(storage_type); |
| + // |dimensions| can be 0x0 for trackers that do not require memory backing. |
| + if (dimensions.GetArea() == 0u) |
| + return true; |
| + |
| + base::AutoUnlock auto_unlock(*lock); |
| + const size_t num_planes = media::VideoFrame::NumPlanes(pixel_format()); |
| + for (size_t i = 0; i < num_planes; ++i) { |
| + const gfx::Size& size = |
| + media::VideoFrame::PlaneSize(pixel_format(), i, dimensions); |
| + gpu_memory_buffers_.push_back( |
| + BrowserGpuMemoryBufferManager::current()->AllocateGpuMemoryBuffer( |
| + size, gfx::BufferFormat::R_8, |
| + gfx::BufferUsage::GPU_READ_CPU_READ_WRITE)); |
| + |
| + DLOG_IF(ERROR, !gpu_memory_buffers_[i]) << "Allocating GpuMemoryBuffer"; |
| + if (!gpu_memory_buffers_[i] || !gpu_memory_buffers_[i]->Map()) |
| + return false; |
| + } |
| + return true; |
| + } |
| scoped_ptr<BufferHandle> GetBufferHandle() override { |
| DCHECK_EQ(gpu_memory_buffers_.size(), |
| media::VideoFrame::NumPlanes(pixel_format())); |
| - return make_scoped_ptr( |
| - new GpuMemoryBufferBufferHandle(dimensions_, &gpu_memory_buffers_)); |
| + return make_scoped_ptr(new GpuMemoryBufferBufferHandle(this)); |
| } |
| + |
| bool ShareToProcess(base::ProcessHandle process_handle, |
| base::SharedMemoryHandle* new_handle) override { |
| NOTREACHED(); |
| return false; |
| } |
| + |
| bool ShareToProcess2(int plane, |
| base::ProcessHandle process_handle, |
| - gfx::GpuMemoryBufferHandle* new_handle) override; |
| - |
| - private: |
| - gfx::Size dimensions_; |
| - // Owned references to GpuMemoryBuffers. |
| - std::vector<scoped_ptr<gfx::GpuMemoryBuffer>> gpu_memory_buffers_; |
| -}; |
| - |
| -VideoCaptureBufferPool::SharedMemTracker::SharedMemTracker() : Tracker() {} |
| - |
| -bool VideoCaptureBufferPool::SharedMemTracker::Init( |
| - media::VideoPixelFormat format, |
| - media::VideoPixelStorage storage_type, |
| - const gfx::Size& dimensions, |
| - base::Lock* lock) { |
| - DVLOG(2) << "allocating ShMem of " << dimensions.ToString(); |
| - set_pixel_format(format); |
| - set_storage_type(storage_type); |
| - // |dimensions| can be 0x0 for trackers that do not require memory backing. |
| - set_pixel_count(dimensions.GetArea()); |
| - mapped_size_ = |
| - media::VideoCaptureFormat(dimensions, 0.0f, format, storage_type) |
| - .ImageAllocationSize(); |
| - if (!mapped_size_) |
| - return true; |
| - return shared_memory_.CreateAndMapAnonymous(mapped_size_); |
| -} |
| - |
| -VideoCaptureBufferPool::GpuMemoryBufferTracker::GpuMemoryBufferTracker() |
| - : Tracker() { |
| -} |
| - |
| -VideoCaptureBufferPool::GpuMemoryBufferTracker::~GpuMemoryBufferTracker() { |
| - for (const auto& gmb : gpu_memory_buffers_) |
| - gmb->Unmap(); |
| -} |
| - |
| -bool VideoCaptureBufferPool::GpuMemoryBufferTracker::Init( |
| - media::VideoPixelFormat format, |
| - media::VideoPixelStorage storage_type, |
| - const gfx::Size& dimensions, |
| - base::Lock* lock) { |
| - DVLOG(2) << "allocating GMB for " << dimensions.ToString(); |
| - // BrowserGpuMemoryBufferManager::current() may not be accessed on IO Thread. |
| - DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| - DCHECK(BrowserGpuMemoryBufferManager::current()); |
| - // This class is only expected to be called with I420 buffer requests at this |
| - // point. |
| - DCHECK_EQ(format, media::PIXEL_FORMAT_I420); |
| - set_pixel_format(format); |
| - set_storage_type(storage_type); |
| - set_pixel_count(dimensions.GetArea()); |
| - // |dimensions| can be 0x0 for trackers that do not require memory backing. |
| - if (dimensions.GetArea() == 0u) |
| + gfx::GpuMemoryBufferHandle* new_handle) override { |
| + DCHECK_LE(plane, static_cast<int>(gpu_memory_buffers_.size())); |
| + |
| + const auto& current_gmb_handle = gpu_memory_buffers_[plane]->GetHandle(); |
| + switch (current_gmb_handle.type) { |
| + case gfx::EMPTY_BUFFER: |
| + NOTREACHED(); |
| + return false; |
| + case gfx::SHARED_MEMORY_BUFFER: { |
| + DCHECK(base::SharedMemory::IsHandleValid(current_gmb_handle.handle)); |
| + base::SharedMemory shared_memory( |
| + base::SharedMemory::DuplicateHandle(current_gmb_handle.handle), |
| + false); |
| + shared_memory.ShareToProcess(process_handle, &new_handle->handle); |
| + DCHECK(base::SharedMemory::IsHandleValid(new_handle->handle)); |
| + new_handle->type = gfx::SHARED_MEMORY_BUFFER; |
| + return true; |
| + } |
| + case gfx::IO_SURFACE_BUFFER: |
| + case gfx::SURFACE_TEXTURE_BUFFER: |
| + case gfx::OZONE_NATIVE_PIXMAP: |
| + *new_handle = current_gmb_handle; |
| + return true; |
| + } |
| + NOTREACHED(); |
| return true; |
| - dimensions_ = dimensions; |
| - |
| - lock->Release(); |
| - const size_t num_planes = media::VideoFrame::NumPlanes(pixel_format()); |
| - for (size_t i = 0; i < num_planes; ++i) { |
| - const gfx::Size& size = |
| - media::VideoFrame::PlaneSize(pixel_format(), i, dimensions); |
| - gpu_memory_buffers_.push_back( |
| - BrowserGpuMemoryBufferManager::current()->AllocateGpuMemoryBuffer( |
| - size, gfx::BufferFormat::R_8, |
| - gfx::BufferUsage::GPU_READ_CPU_READ_WRITE)); |
| - |
| - DLOG_IF(ERROR, !gpu_memory_buffers_[i]) << "Allocating GpuMemoryBuffer"; |
| - if (!gpu_memory_buffers_[i] || !gpu_memory_buffers_[i]->Map()) |
| - return false; |
| } |
| - lock->Acquire(); |
| - return true; |
| -} |
| - |
| -bool VideoCaptureBufferPool::GpuMemoryBufferTracker::ShareToProcess2( |
| - int plane, |
| - base::ProcessHandle process_handle, |
| - gfx::GpuMemoryBufferHandle* new_handle) { |
| - DCHECK_LE(plane, static_cast<int>(gpu_memory_buffers_.size())); |
| - const auto& current_gmb_handle = gpu_memory_buffers_[plane]->GetHandle(); |
| - switch (current_gmb_handle.type) { |
| - case gfx::EMPTY_BUFFER: |
| + private: |
| + // A simple proxy that implements the BufferHandle interface, providing |
| + // accessors to GpuMemoryBufferTracker's memory and properties. |
| + class GpuMemoryBufferBufferHandle |
| + : public VideoCaptureBufferPool::BufferHandle { |
| + public: |
| + // |tracker| must outlive GpuMemoryBufferBufferHandle. This is ensured since |
| + // a tracker is pinned until ownership of this GpuMemoryBufferBufferHandle |
| + // is returned to VideoCaptureBufferPool. |
| + explicit GpuMemoryBufferBufferHandle(GpuMemoryBufferTracker* tracker) |
| + : tracker_(tracker) {} |
| + ~GpuMemoryBufferBufferHandle() override {} |
| + |
| + gfx::Size dimensions() const override { return tracker_->dimensions(); } |
| + size_t mapped_size() const override { |
| + return tracker_->dimensions().GetArea(); |
| + } |
| + void* data(int plane) override { |
| + DCHECK_GE(plane, 0); |
| + DCHECK_LT(plane, static_cast<int>(tracker_->gpu_memory_buffers_.size())); |
| + DCHECK(tracker_->gpu_memory_buffers_[plane]); |
| + return tracker_->gpu_memory_buffers_[plane]->memory(0); |
| + } |
| + ClientBuffer AsClientBuffer(int plane) override { |
| + DCHECK_GE(plane, 0); |
| + DCHECK_LT(plane, static_cast<int>(tracker_->gpu_memory_buffers_.size())); |
| + return tracker_->gpu_memory_buffers_[plane]->AsClientBuffer(); |
| + } |
| +#if defined(OS_POSIX) && !defined(OS_MACOSX) |
| + base::FileDescriptor AsPlatformFile() override { |
| NOTREACHED(); |
| - return false; |
| - case gfx::SHARED_MEMORY_BUFFER: { |
| - DCHECK(base::SharedMemory::IsHandleValid(current_gmb_handle.handle)); |
| - base::SharedMemory shared_memory( |
| - base::SharedMemory::DuplicateHandle(current_gmb_handle.handle), |
| - false); |
| - shared_memory.ShareToProcess(process_handle, &new_handle->handle); |
| - DCHECK(base::SharedMemory::IsHandleValid(new_handle->handle)); |
| - new_handle->type = gfx::SHARED_MEMORY_BUFFER; |
| - return true; |
| + return base::FileDescriptor(); |
| } |
| - case gfx::IO_SURFACE_BUFFER: |
| - case gfx::SURFACE_TEXTURE_BUFFER: |
| - case gfx::OZONE_NATIVE_PIXMAP: |
| - *new_handle = current_gmb_handle; |
| - return true; |
| - } |
| - NOTREACHED(); |
| - return true; |
| -} |
| +#endif |
| + |
| + private: |
| + GpuMemoryBufferTracker* const tracker_; |
| + }; |
| + |
| + // Owned references to GpuMemoryBuffers. |
| + std::vector<scoped_ptr<gfx::GpuMemoryBuffer>> gpu_memory_buffers_; |
| +}; |
| // static |
| scoped_ptr<VideoCaptureBufferPool::Tracker> |
| @@ -275,7 +241,8 @@ VideoCaptureBufferPool::Tracker::~Tracker() {} |
| VideoCaptureBufferPool::VideoCaptureBufferPool(int count) |
| : count_(count), |
| - next_buffer_id_(0) { |
| + next_buffer_id_(0), |
| + last_relinquished_buffer_id_(kInvalidId) { |
| DCHECK_GT(count, 0); |
| } |
| @@ -332,13 +299,12 @@ VideoCaptureBufferPool::GetBufferHandle(int buffer_id) { |
| return tracker->GetBufferHandle(); |
| } |
| -int VideoCaptureBufferPool::ReserveForProducer( |
| - media::VideoPixelFormat format, |
| - media::VideoPixelStorage storage, |
| - const gfx::Size& dimensions, |
| - int* buffer_id_to_drop) { |
| +int VideoCaptureBufferPool::ReserveForProducer(const gfx::Size& dimensions, |
| + media::VideoPixelFormat format, |
| + media::VideoPixelStorage storage, |
| + int* buffer_id_to_drop) { |
| base::AutoLock lock(lock_); |
| - return ReserveForProducerInternal(format, storage, dimensions, |
| + return ReserveForProducerInternal(dimensions, format, storage, |
| buffer_id_to_drop); |
| } |
| @@ -351,6 +317,7 @@ void VideoCaptureBufferPool::RelinquishProducerReservation(int buffer_id) { |
| } |
| DCHECK(tracker->held_by_producer()); |
| tracker->set_held_by_producer(false); |
| + last_relinquished_buffer_id_ = buffer_id; |
| } |
| void VideoCaptureBufferPool::HoldForConsumers( |
| @@ -385,6 +352,34 @@ void VideoCaptureBufferPool::RelinquishConsumerHold(int buffer_id, |
| num_clients); |
| } |
| +int VideoCaptureBufferPool::ResurrectLastForProducer( |
| + const gfx::Size& dimensions, |
| + media::VideoPixelFormat format, |
| + media::VideoPixelStorage storage) { |
| + base::AutoLock lock(lock_); |
| + |
| + // Return early if the last relinquished buffer has been re-used already. |
| + if (last_relinquished_buffer_id_ == kInvalidId) |
| + return kInvalidId; |
| + |
| + // If there are no consumers reading from this buffer, then it's safe to |
| + // provide this buffer back to the producer (because the producer may |
| + // potentially modify the content). Check that the expected dimensions, |
| + // format, and storage match. |
| + TrackerMap::iterator it = trackers_.find(last_relinquished_buffer_id_); |
| + DCHECK(it != trackers_.end()); |
| + DCHECK(!it->second->held_by_producer()); |
| + if (it->second->consumer_hold_count() == 0 && |
| + it->second->dimensions() == dimensions && |
| + it->second->pixel_format() == format && |
| + it->second->storage_type() == storage) { |
| + it->second->set_held_by_producer(true); |
| + return last_relinquished_buffer_id_; |
| + } |
| + |
| + return kInvalidId; |
| +} |
| + |
| double VideoCaptureBufferPool::GetBufferPoolUtilization() const { |
| base::AutoLock lock(lock_); |
| int num_buffers_held = 0; |
| @@ -397,9 +392,9 @@ double VideoCaptureBufferPool::GetBufferPoolUtilization() const { |
| } |
| int VideoCaptureBufferPool::ReserveForProducerInternal( |
| + const gfx::Size& dimensions, |
| media::VideoPixelFormat pixel_format, |
| media::VideoPixelStorage storage_type, |
| - const gfx::Size& dimensions, |
| int* buffer_id_to_drop) { |
| lock_.AssertAcquired(); |
| @@ -408,32 +403,50 @@ int VideoCaptureBufferPool::ReserveForProducerInternal( |
| // largest one that's not big enough, in case we have to reallocate a tracker. |
| *buffer_id_to_drop = kInvalidId; |
| size_t largest_size_in_pixels = 0; |
| + TrackerMap::iterator tracker_of_last_resort = trackers_.end(); |
| TrackerMap::iterator tracker_to_drop = trackers_.end(); |
| for (TrackerMap::iterator it = trackers_.begin(); it != trackers_.end(); |
| ++it) { |
| Tracker* const tracker = it->second; |
| if (!tracker->consumer_hold_count() && !tracker->held_by_producer()) { |
| - if (tracker->pixel_count() >= size_in_pixels && |
| + if (tracker->max_pixel_count() >= size_in_pixels && |
| (tracker->pixel_format() == pixel_format) && |
| (tracker->storage_type() == storage_type)) { |
| + if (it->first == last_relinquished_buffer_id_) { |
| + // This buffer would do just fine, but avoid returning it because the |
| + // client may want to resurrect it. It will be returned perforce if |
| + // the pool has reached it's maximum limit (see code below). |
| + tracker_of_last_resort = it; |
| + continue; |
| + } |
| // Existing tracker is big enough and has correct format. Reuse it. |
| + tracker->set_dimensions(dimensions); |
| tracker->set_held_by_producer(true); |
| return it->first; |
| } |
| - if (tracker->pixel_count() > largest_size_in_pixels) { |
| - largest_size_in_pixels = tracker->pixel_count(); |
| + if (tracker->max_pixel_count() > largest_size_in_pixels) { |
| + largest_size_in_pixels = tracker->max_pixel_count(); |
| tracker_to_drop = it; |
| } |
| } |
| } |
| // Preferably grow the pool by creating a new tracker. If we're at maximum |
| - // size, then reallocate by deleting an existing one instead. |
| + // size, then either use the "last resort" tracker (if any) or reallocate by |
|
emircan
2016/03/25 22:44:24
"then try using |tracker_of_last_resort| or reallo
miu
2016/03/25 23:13:48
Done.
|
| + // deleting an existing one instead. |
| if (trackers_.size() == static_cast<size_t>(count_)) { |
| + if (tracker_of_last_resort != trackers_.end()) { |
| + last_relinquished_buffer_id_ = kInvalidId; |
| + tracker_of_last_resort->second->set_dimensions(dimensions); |
| + tracker_of_last_resort->second->set_held_by_producer(true); |
| + return tracker_of_last_resort->first; |
| + } |
| if (tracker_to_drop == trackers_.end()) { |
| // We're out of space, and can't find an unused tracker to reallocate. |
| return kInvalidId; |
| } |
| + if (tracker_to_drop->first == last_relinquished_buffer_id_) |
| + last_relinquished_buffer_id_ = kInvalidId; |
| *buffer_id_to_drop = tracker_to_drop->first; |
| delete tracker_to_drop->second; |
| trackers_.erase(tracker_to_drop); |
| @@ -445,7 +458,7 @@ int VideoCaptureBufferPool::ReserveForProducerInternal( |
| scoped_ptr<Tracker> tracker = Tracker::CreateTracker(storage_type); |
| // TODO(emircan): We pass the lock here to solve GMB allocation issue, see |
| // crbug.com/545238. |
| - if (!tracker->Init(pixel_format, storage_type, dimensions, &lock_)) { |
| + if (!tracker->Init(dimensions, pixel_format, storage_type, &lock_)) { |
| DLOG(ERROR) << "Error initializing Tracker"; |
| return kInvalidId; |
| } |