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 f583a94adaa638396431ecda7017aa787d99aaa2..c02f983a6dfe0a7def5b21d56efdca5c67248cc7 100644 |
--- a/content/browser/renderer_host/media/video_capture_buffer_pool.cc |
+++ b/content/browser/renderer_host/media/video_capture_buffer_pool.cc |
@@ -10,12 +10,53 @@ |
#include "base/memory/scoped_ptr.h" |
#include "base/stl_util.h" |
#include "media/base/video_frame.h" |
-#include "media/base/video_util.h" |
+ |
+using media::VideoFrame; |
namespace content { |
const int VideoCaptureBufferPool::kInvalidId = -1; |
+// Tracker specifics for SharedMemory. |
+class VideoCaptureBufferPool::SharedMemTracker final : public Tracker { |
+ public: |
+ SharedMemTracker(); |
+ |
+ bool Init(const gfx::Size& dimensions) override; |
+ void* storage() override { return shared_memory_.memory(); } |
+ size_t requested_size() override { return shared_memory_.requested_size(); } |
+ size_t mapped_size() override { return shared_memory_.mapped_size(); } |
+ |
+ bool ShareToProcess(base::ProcessHandle process_handle, |
+ base::SharedMemoryHandle* new_handle) override { |
+ return shared_memory_.ShareToProcess(process_handle, new_handle); |
+ } |
+ |
+ private: |
+ // The memory created to be shared with renderer processes. |
+ base::SharedMemory shared_memory_; |
+}; |
+ |
+VideoCaptureBufferPool::SharedMemTracker::SharedMemTracker() |
+ : Tracker() {} |
+ |
+bool VideoCaptureBufferPool::SharedMemTracker::Init( |
+ const gfx::Size& dimensions) { |
+ // Input |dimensions| can be 0 for buffers that do not require memory backing. |
+ // The allocated size is calculated using VideoFrame methods since this will |
+ // be the abstraction used to wrap the underlying data. |
+ return shared_memory_.CreateAndMapAnonymous( |
+ VideoFrame::AllocationSize(VideoFrame::I420, dimensions)); |
+} |
+ |
+//static |
+scoped_ptr<VideoCaptureBufferPool::Tracker> |
+VideoCaptureBufferPool::Tracker::CreateTracker() { |
+ return make_scoped_ptr(new SharedMemTracker()); |
+} |
+ |
+VideoCaptureBufferPool::Tracker::~Tracker() {} |
+ |
VideoCaptureBufferPool::VideoCaptureBufferPool(int count) |
: count_(count), |
next_buffer_id_(0) { |
@@ -32,65 +73,69 @@ base::SharedMemoryHandle VideoCaptureBufferPool::ShareToProcess( |
size_t* memory_size) { |
base::AutoLock lock(lock_); |
- Buffer* buffer = GetBuffer(buffer_id); |
+ Tracker* buffer = GetBuffer(buffer_id); |
if (!buffer) { |
NOTREACHED() << "Invalid buffer_id."; |
return base::SharedMemory::NULLHandle(); |
} |
base::SharedMemoryHandle remote_handle; |
- buffer->shared_memory.ShareToProcess(process_handle, &remote_handle); |
- *memory_size = buffer->shared_memory.requested_size(); |
- return remote_handle; |
+ if (buffer->ShareToProcess(process_handle, &remote_handle)) { |
+ *memory_size = buffer->mapped_size(); |
+ return remote_handle; |
+ } |
+ DPLOG(ERROR) << "Error mapping Shared Memory."; |
+ return base::SharedMemoryHandle(); |
} |
bool VideoCaptureBufferPool::GetBufferInfo(int buffer_id, |
- void** memory, |
+ void** storage, |
size_t* size) { |
base::AutoLock lock(lock_); |
- Buffer* buffer = GetBuffer(buffer_id); |
+ Tracker* 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(); |
+ DCHECK(buffer->held_by_producer()); |
+ *storage = buffer->storage(); |
+ *size = buffer->mapped_size(); |
return true; |
} |
-int VideoCaptureBufferPool::ReserveForProducer(size_t size, |
- int* buffer_id_to_drop) { |
+int VideoCaptureBufferPool::ReserveForProducer( |
+ const media::VideoCaptureFormat& format, |
+ int* buffer_id_to_drop) { |
base::AutoLock lock(lock_); |
- return ReserveForProducerInternal(size, buffer_id_to_drop); |
+ return ReserveForProducerInternal(format, buffer_id_to_drop); |
} |
void VideoCaptureBufferPool::RelinquishProducerReservation(int buffer_id) { |
base::AutoLock lock(lock_); |
- Buffer* buffer = GetBuffer(buffer_id); |
+ Tracker* buffer = GetBuffer(buffer_id); |
if (!buffer) { |
NOTREACHED() << "Invalid buffer_id."; |
return; |
} |
- DCHECK(buffer->held_by_producer); |
- buffer->held_by_producer = false; |
+ DCHECK(buffer->held_by_producer()); |
+ buffer->set_held_by_producer(false); |
} |
void VideoCaptureBufferPool::HoldForConsumers( |
int buffer_id, |
int num_clients) { |
base::AutoLock lock(lock_); |
- Buffer* buffer = GetBuffer(buffer_id); |
+ Tracker* buffer = GetBuffer(buffer_id); |
if (!buffer) { |
NOTREACHED() << "Invalid buffer_id."; |
return; |
} |
- DCHECK(buffer->held_by_producer); |
- DCHECK(!buffer->consumer_hold_count); |
+ DCHECK(buffer->held_by_producer()); |
+ DCHECK(!buffer->consumer_hold_count()); |
- buffer->consumer_hold_count = num_clients; |
- // Note: |held_by_producer| will stay true until |
+ buffer->set_consumer_hold_count(num_clients); |
+ // Note: |held_by_producer()| will stay true until |
// RelinquishProducerReservation() (usually called by destructor of the object |
// wrapping this buffer, e.g. a media::VideoFrame). |
} |
@@ -98,74 +143,70 @@ void VideoCaptureBufferPool::HoldForConsumers( |
void VideoCaptureBufferPool::RelinquishConsumerHold(int buffer_id, |
int num_clients) { |
base::AutoLock lock(lock_); |
- Buffer* buffer = GetBuffer(buffer_id); |
+ Tracker* buffer = GetBuffer(buffer_id); |
if (!buffer) { |
NOTREACHED() << "Invalid buffer_id."; |
return; |
} |
- DCHECK_GE(buffer->consumer_hold_count, num_clients); |
+ DCHECK_GE(buffer->consumer_hold_count(), num_clients); |
- buffer->consumer_hold_count -= num_clients; |
+ buffer->set_consumer_hold_count(buffer->consumer_hold_count() - num_clients); |
} |
-VideoCaptureBufferPool::Buffer::Buffer() |
- : held_by_producer(false), consumer_hold_count(0) {} |
- |
-int VideoCaptureBufferPool::ReserveForProducerInternal(size_t size, |
- int* buffer_id_to_drop) { |
+int VideoCaptureBufferPool::ReserveForProducerInternal( |
+ const media::VideoCaptureFormat& format, |
+ int* buffer_id_to_drop) { |
lock_.AssertAcquired(); |
+ const size_t size_in_bytes = |
+ VideoFrame::AllocationSize(VideoFrame::I420, format.frame_size); |
miu
2015/04/08 01:20:00
The call to AllocationSize() should use the format
mcasas
2015/04/08 22:07:05
Done.
|
// 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(); |
+ BufferMap::iterator buffer_to_drop = 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) { |
+ Tracker* const buffer = it->second; |
+ if (!buffer->consumer_hold_count() && !buffer->held_by_producer()) { |
+ if (buffer->requested_size() >= size_in_bytes) { |
// Existing buffer is big enough. Reuse it. |
- buffer->held_by_producer = true; |
+ buffer->set_held_by_producer(true); |
return it->first; |
} |
- if (buffer->shared_memory.requested_size() > realloc_size) { |
- realloc_size = buffer->shared_memory.requested_size(); |
- realloc = it; |
+ if (buffer->requested_size() > realloc_size) { |
+ realloc_size = buffer->requested_size(); |
+ buffer_to_drop = it; |
} |
} |
} |
- // Preferentially grow the pool by creating a new buffer. If we're at maximum |
+ // Preferably 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()) { |
+ if (buffer_to_drop == 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); |
+ *buffer_id_to_drop = buffer_to_drop->first; |
+ delete buffer_to_drop->second; |
+ buffers_.erase(buffer_to_drop); |
} |
// 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(); |
+ const int buffer_id = next_buffer_id_++; |
+ scoped_ptr<Tracker> tracker = Tracker::CreateTracker(); |
+ if (!tracker->Init(format.frame_size)) |
+ return kInvalidId; |
+ tracker->set_held_by_producer(true); |
+ buffers_[buffer_id] = tracker.release(); |
+ |
return buffer_id; |
} |
-VideoCaptureBufferPool::Buffer* VideoCaptureBufferPool::GetBuffer( |
+VideoCaptureBufferPool::Tracker* VideoCaptureBufferPool::GetBuffer( |
int buffer_id) { |
- BufferMap::iterator it = buffers_.find(buffer_id); |
- if (it == buffers_.end()) |
- return NULL; |
- return it->second; |
+ BufferMap::const_iterator it = buffers_.find(buffer_id); |
+ return (it == buffers_.end()) ? NULL : it->second; |
} |
} // namespace content |