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/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_
|