Save errno for logging before potentially overwriting it.
[chromium-blink-merge.git] / content / browser / renderer_host / media / video_capture_buffer_pool.h
blobe839d85538e98e7e328cf67e8bea7571ca51cf71
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_BUFFER_POOL_H_
6 #define CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_BUFFER_POOL_H_
8 #include "base/basictypes.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/scoped_vector.h"
11 #include "base/process.h"
12 #include "base/shared_memory.h"
13 #include "base/synchronization/lock.h"
14 #include "content/common/content_export.h"
15 #include "media/base/video_frame.h"
16 #include "ui/gfx/size.h"
18 namespace content {
20 // A thread-safe class that does the bookkeeping and lifetime management for a
21 // pool of shared-memory pixel buffers cycled between an in-process producer
22 // (e.g. a VideoCaptureDevice) and a set of out-of-process consumers. The pool
23 // is intended to be allocated and orchestrated by a VideoCaptureController, but
24 // is designed to outlive the controller if necessary.
26 // Producers access buffers by means of a VideoFrame container. Producers get
27 // a buffer by calling ReserveForProducer(), and pass on their ownership
28 // of the buffer by calling HoldForConsumers(). Consumers signal that they
29 // are done with the buffer by calling RelinquishConsumerHold().
31 // Buffers are identified by an int value called |buffer_id|. Callers may depend
32 // on the buffer IDs being dense in the range 1 to count(), inclusive, so long
33 // as the Allocate() step succeeded. 0 is never a valid ID, and is returned by
34 // some methods to indicate failure.
35 class CONTENT_EXPORT VideoCaptureBufferPool
36 : public base::RefCountedThreadSafe<VideoCaptureBufferPool> {
37 public:
38 VideoCaptureBufferPool(const gfx::Size& size, int count);
40 // One-time initialization to allocate the shared memory buffers. Returns true
41 // on success.
42 bool Allocate();
44 // One-time (per client/per-buffer) initialization to share a particular
45 // buffer to a process.
46 base::SharedMemoryHandle ShareToProcess(int buffer_id,
47 base::ProcessHandle process_handle);
49 // Locate a buffer (if any) that's not in use by the producer or consumers,
50 // and reserve it as a VideoFrame. The buffer remains reserved (and writable
51 // by the producer) until either the VideoFrame is destroyed, or until
52 // ownership is transferred to the consumer via HoldForConsumers().
54 // The resulting VideoFrames will reference this VideoCaptureBufferPool, and
55 // so the pool will stay alive so long as these VideoFrames do.
57 // |rotation| is used for a clear optimization.
58 scoped_refptr<media::VideoFrame> ReserveForProducer(int rotation);
60 // Transfer a buffer from producer to consumer ownership.
61 // |producer_held_buffer| must be a frame previously returned by
62 // ReserveForProducer(), and not already passed to HoldForConsumers(). The
63 // caller should promptly release all references to |producer_held_buffer|
64 // after calling this method, so that the buffer may be eventually reused once
65 // the consumers finish with it.
66 void HoldForConsumers(
67 const scoped_refptr<media::VideoFrame>& producer_held_buffer,
68 int buffer_id,
69 int num_clients);
71 // Indicate that one or more consumers are done with a particular buffer. This
72 // effectively is the opposite of HoldForConsumers(). Once the consumers are
73 // done, a buffer is returned to the pool for reuse.
74 void RelinquishConsumerHold(int buffer_id, int num_clients);
76 // Detect whether a particular VideoFrame is backed by a buffer that belongs
77 // to this pool -- that is, whether it was allocated by an earlier call to
78 // ReserveForProducer(). If so, return its buffer_id (a value between 1 and
79 // count()). If not, return 0, indicating the buffer is not recognized (it may
80 // be a valid frame, but we didn't allocate it).
81 int RecognizeReservedBuffer(
82 const scoped_refptr<media::VideoFrame>& maybe_belongs_to_pool);
84 int count() const { return count_; }
85 size_t GetMemorySize() const;
86 bool IsAnyBufferHeldForConsumers();
88 private:
89 friend class base::RefCountedThreadSafe<VideoCaptureBufferPool>;
91 // Per-buffer state.
92 struct Buffer {
93 Buffer();
95 // The memory created to be shared with renderer processes.
96 base::SharedMemory shared_memory;
98 // Rotation in degrees of the buffer.
99 int rotation;
101 // Tracks whether this buffer is currently referenced by the producer.
102 bool held_by_producer;
104 // Number of consumer processes which hold this shared memory.
105 int consumer_hold_count;
108 virtual ~VideoCaptureBufferPool();
110 // Callback for VideoFrame destruction.
111 void OnVideoFrameDestroyed(int buffer_id);
113 bool IsAllocated() const;
115 // Protects |buffers_| and contents thereof.
116 base::Lock lock_;
118 // The buffers, indexed by |buffer_id|. Element 0 is always NULL.
119 ScopedVector<Buffer> buffers_;
121 const gfx::Size size_;
122 const int count_;
124 DISALLOW_IMPLICIT_CONSTRUCTORS(VideoCaptureBufferPool);
127 } // namespace content
129 #endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_BUFFER_POOL_H_