| 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..92523756eff74e7dc3b7b6a3ca1076ae47017f0e 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,23 @@ 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;
|
| + }
|
| +
|
| + DCHECK(buffer->held_by_producer);
|
| + *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,71 +107,19 @@ 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;
|
| - for (BufferMap::iterator it = buffers_.begin(); it != buffers_.end(); it++) {
|
| + 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) {
|
| if (buffer->shared_memory.requested_size() >= size) {
|
| @@ -162,35 +127,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(
|
|
|