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. 4 5 #ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_BUFFER_POOL_H_ 6 #define CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_BUFFER_POOL_H_ 7 8 #include "base/basictypes.h" 9 #include "base/memory/ref_counted.h" 10 #include "base/memory/scoped_vector.h" 11 #include "base/memory/shared_memory.h" 12 #include "base/process/process.h" 13 #include "base/synchronization/lock.h" 14 #include "content/common/content_export.h" 15 #include "ui/gfx/size.h" 16 17 namespace media { 18 19 class VideoFrame; 20 21 } // namespace media 22 23 namespace content { 24 25 // A thread-safe class that does the bookkeeping and lifetime management for a 26 // pool of shared-memory pixel buffers cycled between an in-process producer 27 // (e.g. a VideoCaptureDevice) and a set of out-of-process consumers. The pool 28 // is intended to be allocated and orchestrated by a VideoCaptureController, but 29 // is designed to outlive the controller if necessary. 30 // 31 // Buffers are identified by an int value called |buffer_id|. Callers may depend 32 // on the buffer IDs being dense in the range [0, count()), so long as the 33 // Allocate() step succeeded. -1 is never a valid ID, and is returned by some 34 // methods to indicate failure. Producers get a buffer by calling 35 // ReserveForProducer(), and may pass on their ownership to the consumer by 36 // calling HoldForConsumers(), or drop the buffer (without further processing) 37 // by calling ReserveForProducer(). Consumers signal that they are done with the 38 // buffer by calling RelinquishConsumerHold(). 39 class CONTENT_EXPORT VideoCaptureBufferPool 40 : public base::RefCountedThreadSafe<VideoCaptureBufferPool> { 41 public: 42 VideoCaptureBufferPool(size_t size, int count); 43 44 // One-time initialization to allocate the shared memory buffers. Returns true 45 // on success. 46 bool Allocate(); 47 48 // One-time (per client/per-buffer) initialization to share a particular 49 // buffer to a process. 50 base::SharedMemoryHandle ShareToProcess(int buffer_id, 51 base::ProcessHandle process_handle); 52 53 // Get the shared memory handle for a particular buffer index. 54 base::SharedMemoryHandle GetHandle(int buffer_id); 55 56 // Get the mapped buffer memory for a particular buffer index. 57 void* GetMemory(int buffer_id); 58 59 // Locate the index of a buffer (if any) that's not in use by the producer or 60 // consumers, and reserve it. The buffer remains reserved (and writable by the 61 // producer) until ownership is transferred either to the consumer via 62 // HoldForConsumers(), or back to the pool with 63 // RelinquishProducerReservation(). 64 int ReserveForProducer(); 65 66 // Indicate that a buffer held for the producer should be returned back to the 67 // pool without passing on to the consumer. This effectively is the opposite 68 // of ReserveForProducer(). 69 void RelinquishProducerReservation(int buffer_id); 70 71 // Transfer a buffer from producer to consumer ownership. 72 // |buffer_id| must be a buffer index previously returned by 73 // ReserveForProducer(), and not already passed to HoldForConsumers(). 74 void HoldForConsumers(int buffer_id, int num_clients); 75 76 // Indicate that one or more consumers are done with a particular buffer. This 77 // effectively is the opposite of HoldForConsumers(). Once the consumers are 78 // done, a buffer is returned to the pool for reuse. 79 void RelinquishConsumerHold(int buffer_id, int num_clients); 80 81 // Detect whether a particular SharedMemoryHandle is exported by a buffer that 82 // belongs to this pool -- that is, whether it was allocated by an earlier 83 // call to ReserveForProducer(). If so, return its buffer_id (a value on the 84 // range [0, count())). If not, return -1, indicating the buffer is not 85 // recognized (it may be a valid frame, but we didn't allocate it). 86 int RecognizeReservedBuffer(base::SharedMemoryHandle maybe_belongs_to_pool); 87 88 // Utility functions to return a buffer wrapped in a useful type. 89 scoped_refptr<media::VideoFrame> ReserveI420VideoFrame(const gfx::Size& size, 90 int rotation); 91 92 int count() const { return count_; } 93 size_t GetMemorySize() const; 94 bool IsAnyBufferHeldForConsumers(); 95 96 private: 97 friend class base::RefCountedThreadSafe<VideoCaptureBufferPool>; 98 99 // Per-buffer state. 100 struct Buffer { 101 Buffer(); 102 103 // The memory created to be shared with renderer processes. 104 base::SharedMemory shared_memory; 105 106 // Rotation in degrees of the buffer. 107 int rotation; 108 109 // Tracks whether this buffer is currently referenced by the producer. 110 bool held_by_producer; 111 112 // Number of consumer processes which hold this shared memory. 113 int consumer_hold_count; 114 }; 115 116 virtual ~VideoCaptureBufferPool(); 117 118 int ReserveForProducerInternal(); 119 120 bool IsAllocated() const; 121 122 // Protects |buffers_| and contents thereof. 123 base::Lock lock_; 124 125 // The buffers, indexed by |buffer_id|. Element 0 is always NULL. 126 ScopedVector<Buffer> buffers_; 127 128 const size_t size_; 129 const int count_; 130 131 DISALLOW_IMPLICIT_CONSTRUCTORS(VideoCaptureBufferPool); 132 }; 133 134 } // namespace content 135 136 #endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_BUFFER_POOL_H_ 137