12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_BUFFER_POOL_H_ 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_BUFFER_POOL_H_ 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 81e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include <map> 91e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/ref_counted.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_vector.h" 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/memory/shared_memory.h" 14a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/process/process.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/synchronization/lock.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/common/content_export.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/size.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace media { 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass VideoFrame; 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace media 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content { 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A thread-safe class that does the bookkeeping and lifetime management for a 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// pool of shared-memory pixel buffers cycled between an in-process producer 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// (e.g. a VideoCaptureDevice) and a set of out-of-process consumers. The pool 301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// is intended to be orchestrated by a VideoCaptureController, but is designed 311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// to outlive the controller if necessary. 321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// 331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Producers get a buffer by calling ReserveForProducer(), and may pass on their 341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// ownership to the consumer by calling HoldForConsumers(), or drop the buffer 351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// (without further processing) by calling RelinquishProducerReservation(). 361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Consumers signal that they are done with the buffer by calling 371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// RelinquishConsumerHold(). 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// Buffers are allocated on demand, but there will never be more than |count| 401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// buffers in existence at any time. Buffers are identified by an int value 411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// called |buffer_id|. -1 (kInvalidId) is never a valid ID, and is returned by 421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// some methods to indicate failure. The active set of buffer ids may change 431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// over the lifetime of the buffer pool, as existing buffers are freed and 441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// reallocated at larger size. When reallocation occurs, new buffer IDs will 451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)// circulate. 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CONTENT_EXPORT VideoCaptureBufferPool 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : public base::RefCountedThreadSafe<VideoCaptureBufferPool> { 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) static const int kInvalidId; 501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) explicit VideoCaptureBufferPool(int count); 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // One-time (per client/per-buffer) initialization to share a particular 531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // buffer to a process. The size of the allocation is returned as 541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // |memory_size|. 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SharedMemoryHandle ShareToProcess(int buffer_id, 561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::ProcessHandle process_handle, 571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) size_t* memory_size); 581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Query the memory parameters of |buffer_id|. Fills in parameters in the 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // pointer arguments, and returns true iff the buffer exists. 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) bool GetBufferInfo(int buffer_id, void** memory, size_t* size); 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Reserve or allocate a buffer of at least |size| bytes and return its id. 641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // This will fail (returning kInvalidId) if the pool already is at its |count| 651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // limit of the number of allocations, and all allocated buffers are in use by 661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // the producer and/or consumers. 671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // 681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // If successful, the reserved buffer remains reserved (and writable by the 69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // producer) until ownership is transferred either to the consumer via 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // HoldForConsumers(), or back to the pool with 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // RelinquishProducerReservation(). 721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // 731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // On occasion, this call will decide to free an old buffer to make room for a 741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // new allocation at a larger size. If so, the ID of the destroyed buffer is 751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // returned via |buffer_id_to_drop|. 761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int ReserveForProducer(size_t size, int* buffer_id_to_drop); 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Indicate that a buffer held for the producer should be returned back to the 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // pool without passing on to the consumer. This effectively is the opposite 80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // of ReserveForProducer(). 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void RelinquishProducerReservation(int buffer_id); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Transfer a buffer from producer to consumer ownership. 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // |buffer_id| must be a buffer index previously returned by 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // ReserveForProducer(), and not already passed to HoldForConsumers(). 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void HoldForConsumers(int buffer_id, int num_clients); 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Indicate that one or more consumers are done with a particular buffer. This 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // effectively is the opposite of HoldForConsumers(). Once the consumers are 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // done, a buffer is returned to the pool for reuse. 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void RelinquishConsumerHold(int buffer_id, int num_clients); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int count() const { return count_; } 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) friend class base::RefCountedThreadSafe<VideoCaptureBufferPool>; 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Per-buffer state. 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct Buffer { 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Buffer(); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The memory created to be shared with renderer processes. 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SharedMemory shared_memory; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Tracks whether this buffer is currently referenced by the producer. 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool held_by_producer; 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Number of consumer processes which hold this shared memory. 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int consumer_hold_count; 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) typedef std::map<int, Buffer*> BufferMap; 1131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~VideoCaptureBufferPool(); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int ReserveForProducerInternal(size_t size, int* buffer_id_to_drop); 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) Buffer* GetBuffer(int buffer_id); 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // The max number of buffers that the pool is allowed to have at any moment. 1211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const int count_; 1221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 1231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Protects everything below it. 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Lock lock_; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // The ID of the next buffer. 1271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) int next_buffer_id_; 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // The buffers, indexed by |buffer_id|. 1301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) BufferMap buffers_; 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_IMPLICIT_CONSTRUCTORS(VideoCaptureBufferPool); 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace content 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // CONTENT_BROWSER_RENDERER_HOST_MEDIA_VIDEO_CAPTURE_BUFFER_POOL_H_ 138