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 f6486a5405128c6006329a2462a794fbf7c4a38c..a4f6d041b78d77488997bbf465ba29dfc5a0d34a 100644 |
| --- a/content/browser/renderer_host/media/video_capture_buffer_pool.cc |
| +++ b/content/browser/renderer_host/media/video_capture_buffer_pool.cc |
| @@ -42,6 +42,22 @@ base::SharedMemoryHandle VideoCaptureBufferPool::ShareToProcess( |
| return remote_handle; |
| } |
| +bool VideoCaptureBufferPool::GetBufferInfo(int buffer_id, |
| + void** memory, |
| + size_t* size) { |
| + base::AutoLock lock(lock_); |
| + |
| + Buffer* buffer = GetBuffer(buffer_id); |
| + if (!buffer) { |
| + NOTREACHED() << "Invalid buffer_id."; |
| + return false; |
| + } |
|
ncarter (slow)
2013/11/12 21:14:22
Should probably add a DCHECK here that the buffer
sheu
2013/11/18 22:42:11
Done.
|
| + |
| + *memory = buffer->shared_memory.memory(); |
| + *size = buffer->shared_memory.mapped_size(); |
| + return true; |
| +} |
| + |
| int VideoCaptureBufferPool::ReserveForProducer(size_t size, |
| int* buffer_id_to_drop) { |
| base::AutoLock lock(lock_); |
| @@ -90,70 +106,18 @@ void VideoCaptureBufferPool::RelinquishConsumerHold(int buffer_id, |
| buffer->consumer_hold_count -= num_clients; |
| } |
| -int VideoCaptureBufferPool::RecognizeReservedBuffer( |
| - base::SharedMemoryHandle maybe_belongs_to_pool) { |
| - base::AutoLock lock(lock_); |
| - for (BufferMap::iterator it = buffers_.begin(); it != buffers_.end(); it++) { |
| - if (it->second->shared_memory.handle() == maybe_belongs_to_pool) { |
| - DCHECK(it->second->held_by_producer); |
| - return it->first; |
| - } |
| - } |
| - return kInvalidId; // Buffer is not from our pool. |
| -} |
| - |
| -scoped_refptr<media::VideoFrame> VideoCaptureBufferPool::ReserveI420VideoFrame( |
| - const gfx::Size& size, |
| - int rotation, |
| - int* buffer_id_to_drop) { |
| - base::AutoLock lock(lock_); |
| - |
| - size_t frame_bytes = |
| - media::VideoFrame::AllocationSize(media::VideoFrame::I420, size); |
| - |
| - int buffer_id = ReserveForProducerInternal(frame_bytes, buffer_id_to_drop); |
| - if (buffer_id == kInvalidId) |
| - return NULL; |
| - |
| - base::Closure disposal_handler = base::Bind( |
| - &VideoCaptureBufferPool::RelinquishProducerReservation, |
| - this, |
| - buffer_id); |
| - |
| - Buffer* buffer = GetBuffer(buffer_id); |
| - // Wrap the buffer in a VideoFrame container. |
| - scoped_refptr<media::VideoFrame> frame = |
| - media::VideoFrame::WrapExternalSharedMemory( |
| - media::VideoFrame::I420, |
| - size, |
| - gfx::Rect(size), |
| - size, |
| - static_cast<uint8*>(buffer->shared_memory.memory()), |
| - frame_bytes, |
| - buffer->shared_memory.handle(), |
| - base::TimeDelta(), |
| - disposal_handler); |
| - |
| - if (buffer->rotation != rotation) { |
| - // TODO(jiayl): Generalize the |rotation| mechanism. |
| - media::FillYUV(frame.get(), 0, 128, 128); |
| - buffer->rotation = rotation; |
| - } |
| - |
| - return frame; |
| -} |
| - |
| VideoCaptureBufferPool::Buffer::Buffer() |
| - : rotation(0), |
| - held_by_producer(false), |
| - consumer_hold_count(0) {} |
| + : held_by_producer(false), consumer_hold_count(0) {} |
| int VideoCaptureBufferPool::ReserveForProducerInternal(size_t size, |
| int* buffer_id_to_drop) { |
| lock_.AssertAcquired(); |
| - // Look for a buffer that's allocated, big enough, and not in use. |
| + // Look for a buffer that's allocated, big enough, and not in use. Track the |
| + // largest one that's not big enough, in case we have to reallocate a buffer. |
| *buffer_id_to_drop = kInvalidId; |
| + size_t realloc_size = 0; |
| + BufferMap::iterator realloc = buffers_.end(); |
| for (BufferMap::iterator it = buffers_.begin(); it != buffers_.end(); it++) { |
| Buffer* buffer = it->second; |
| if (!buffer->consumer_hold_count && !buffer->held_by_producer) { |
| @@ -162,35 +126,36 @@ int VideoCaptureBufferPool::ReserveForProducerInternal(size_t size, |
| buffer->held_by_producer = true; |
| return it->first; |
| } |
| + if (buffer->shared_memory.requested_size() > realloc_size) { |
| + realloc_size = buffer->shared_memory.requested_size(); |
| + realloc = it; |
| + } |
| } |
| } |
| - // Look for a buffer that's not in use, that we can reallocate. |
| - for (BufferMap::iterator it = buffers_.begin(); it != buffers_.end(); it++) { |
| - Buffer* buffer = it->second; |
| - if (!buffer->consumer_hold_count && !buffer->held_by_producer) { |
| - // Existing buffer is too small. Free it so we can allocate a new one |
| - // after the loop. |
| - *buffer_id_to_drop = it->first; |
| - buffers_.erase(it); |
| - delete buffer; |
| - break; |
| + // Preferentially grow the pool by creating a new buffer. If we're at maximum |
| + // size, then reallocate by deleting an existing one instead. |
| + if (buffers_.size() == static_cast<size_t>(count_)) { |
| + if (realloc == buffers_.end()) { |
| + // We're out of space, and can't find an unused buffer to reallocate. |
| + return kInvalidId; |
| } |
| + *buffer_id_to_drop = realloc->first; |
| + delete realloc->second; |
| + buffers_.erase(realloc); |
| } |
| - // If possible, grow the pool by creating a new buffer. |
| - if (static_cast<int>(buffers_.size()) < count_) { |
| - int buffer_id = next_buffer_id_++; |
| - scoped_ptr<Buffer> buffer(new Buffer()); |
| + // Create the new buffer. |
| + int buffer_id = next_buffer_id_++; |
| + scoped_ptr<Buffer> buffer(new Buffer()); |
| + if (size) { |
| + // |size| can be 0 for buffers that do not require memory backing. |
| if (!buffer->shared_memory.CreateAndMapAnonymous(size)) |
| return kInvalidId; |
| - buffer->held_by_producer = true; |
| - buffers_[buffer_id] = buffer.release(); |
| - return buffer_id; |
| } |
| - |
| - // The pool is at its size limit, and all buffers are in use. |
| - return kInvalidId; |
| + buffer->held_by_producer = true; |
| + buffers_[buffer_id] = buffer.release(); |
| + return buffer_id; |
| } |
| VideoCaptureBufferPool::Buffer* VideoCaptureBufferPool::GetBuffer( |