1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_BUFFER_POOL_H_
#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_BUFFER_POOL_H_
#include <map>
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/shared_memory.h"
#include "base/process/process.h"
#include "base/synchronization/lock.h"
#include "content/common/content_export.h"
#include "ui/gfx/geometry/size.h"
namespace media {
class VideoFrame;
} // namespace media
namespace content {
// A thread-safe class that does the bookkeeping and lifetime management for a
// pool of shared-memory pixel buffers cycled between an in-process producer
// (e.g. a VideoCaptureDevice) and a set of out-of-process consumers. The pool
// is intended to be orchestrated by a VideoCaptureController, but is designed
// to outlive the controller if necessary.
//
// Producers get a buffer by calling ReserveForProducer(), and may pass on their
// ownership to the consumer by calling HoldForConsumers(), or drop the buffer
// (without further processing) by calling RelinquishProducerReservation().
// Consumers signal that they are done with the buffer by calling
// RelinquishConsumerHold().
//
// Buffers are allocated on demand, but there will never be more than |count|
// buffers in existence at any time. Buffers are identified by an int value
// called |buffer_id|. -1 (kInvalidId) is never a valid ID, and is returned by
// some methods to indicate failure. The active set of buffer ids may change
// over the lifetime of the buffer pool, as existing buffers are freed and
// reallocated at larger size. When reallocation occurs, new buffer IDs will
// circulate.
class CONTENT_EXPORT VideoCaptureBufferPool
: public base::RefCountedThreadSafe<VideoCaptureBufferPool> {
public:
static const int kInvalidId;
explicit VideoCaptureBufferPool(int count);
// One-time (per client/per-buffer) initialization to share a particular
// buffer to a process. The size of the allocation is returned as
// |memory_size|.
base::SharedMemoryHandle ShareToProcess(int buffer_id,
base::ProcessHandle process_handle,
size_t* memory_size);
// Query the memory parameters of |buffer_id|. Fills in parameters in the
// pointer arguments, and returns true iff the buffer exists.
bool GetBufferInfo(int buffer_id, void** memory, size_t* size);
// Reserve or allocate a buffer of at least |size| bytes and return its id.
// This will fail (returning kInvalidId) if the pool already is at its |count|
// limit of the number of allocations, and all allocated buffers are in use by
// the producer and/or consumers.
//
// If successful, the reserved buffer remains reserved (and writable by the
// producer) until ownership is transferred either to the consumer via
// HoldForConsumers(), or back to the pool with
// RelinquishProducerReservation().
//
// On occasion, this call will decide to free an old buffer to make room for a
// new allocation at a larger size. If so, the ID of the destroyed buffer is
// returned via |buffer_id_to_drop|.
int ReserveForProducer(size_t size, int* buffer_id_to_drop);
// Indicate that a buffer held for the producer should be returned back to the
// pool without passing on to the consumer. This effectively is the opposite
// of ReserveForProducer().
void RelinquishProducerReservation(int buffer_id);
// Transfer a buffer from producer to consumer ownership.
// |buffer_id| must be a buffer index previously returned by
// ReserveForProducer(), and not already passed to HoldForConsumers().
void HoldForConsumers(int buffer_id, int num_clients);
// Indicate that one or more consumers are done with a particular buffer. This
// effectively is the opposite of HoldForConsumers(). Once the consumers are
// done, a buffer is returned to the pool for reuse.
void RelinquishConsumerHold(int buffer_id, int num_clients);
int count() const { return count_; }
private:
friend class base::RefCountedThreadSafe<VideoCaptureBufferPool>;
// Per-buffer state.
struct Buffer {
Buffer();
// The memory created to be shared with renderer processes.
base::SharedMemory shared_memory;
// Tracks whether this buffer is currently referenced by the producer.
bool held_by_producer;
// Number of consumer processes which hold this shared memory.
int consumer_hold_count;
};
typedef std::map<int, Buffer*> BufferMap;
virtual ~VideoCaptureBufferPool();
int ReserveForProducerInternal(size_t size, int* buffer_id_to_drop);
Buffer* GetBuffer(int buffer_id);
// The max number of buffers that the pool is allowed to have at any moment.
const int count_;
// Protects everything below it.
base::Lock lock_;
// The ID of the next buffer.
int next_buffer_id_;
// The buffers, indexed by |buffer_id|.
BufferMap buffers_;
DISALLOW_IMPLICIT_CONSTRUCTORS(VideoCaptureBufferPool);
};
} // namespace content
#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_BUFFER_POOL_H_
|