kodi
VideoBuffer.h
1 /*
2  * Copyright (C) 2005-2018 Team Kodi
3  * This file is part of Kodi - https://kodi.tv
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  * See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "threads/CriticalSection.h"
12 #include <atomic>
13 #include <deque>
14 #include <list>
15 #include <map>
16 #include <memory>
17 #include <string>
18 #include <vector>
19 
20 extern "C" {
21 #include <libavutil/pixfmt.h>
22 }
23 
24 struct YuvImage
25 {
26  static const int MAX_PLANES = 3;
27 
28  uint8_t* plane[MAX_PLANES];
29  int planesize[MAX_PLANES];
30  int stride[MAX_PLANES];
31  unsigned int width;
32  unsigned int height;
33  unsigned int cshift_x; // this is the chroma shift used
34  unsigned int cshift_y;
35  unsigned int bpp; // bytes per pixel
36 };
37 
38 //-----------------------------------------------------------------------------
39 //
40 //-----------------------------------------------------------------------------
41 
42 #define BUFFER_STATE_DECODER 0x01;
43 #define BUFFER_STATE_RENDER 0x02;
44 
45 class CVideoBuffer;
46 class IVideoBufferPool;
48 
49 typedef void (CVideoBufferManager::*ReadyToDispose)(IVideoBufferPool *pool);
50 
51 class IVideoBufferPool : public std::enable_shared_from_this<IVideoBufferPool>
52 {
53 public:
54  virtual ~IVideoBufferPool() = default;
55 
56  // get a free buffer from the pool, sets ref count to 1
57  virtual CVideoBuffer* Get() = 0;
58 
59  // called by buffer when ref count goes to zero
60  virtual void Return(int id) = 0;
61 
62  // required if pool is registered with BufferManager BM call configure
63  // as soon as it knows parameters: pixFmx, size
64  virtual void Configure(AVPixelFormat format, int size) {}
65 
66  // required if pool is registered with BufferManager
67  virtual bool IsConfigured() { return false; }
68 
69  // required if pool is registered with BufferManager
70  // called before Get() to check if buffer pool is suitable
71  virtual bool IsCompatible(AVPixelFormat format, int size) { return false; }
72 
73  // callback when BM releases buffer pool. i.e. before a new codec is created
74  // clients can register a new pool on this callback
75  virtual void Released(CVideoBufferManager& videoBufferManager) {}
76 
77  // called by BM when buffer is discarded
78  // pool calls back when all buffers are back home
79  virtual void Discard(CVideoBufferManager* bm, ReadyToDispose cb) { (bm->*cb)(this); }
80 
81  // call on Get() before returning buffer to caller
82  std::shared_ptr<IVideoBufferPool> GetPtr() { return shared_from_this(); }
83 };
84 
86 {
87 public:
88  CVideoBuffer() = delete;
89  virtual ~CVideoBuffer() = default;
90  void Acquire();
91  void Acquire(std::shared_ptr<IVideoBufferPool> pool);
92  void Release();
93  int GetId() const { return m_id; }
94 
95  virtual AVPixelFormat GetFormat();
96  virtual uint8_t* GetMemPtr() { return nullptr; }
97  virtual void GetPlanes(uint8_t* (&planes)[YuvImage::MAX_PLANES]) {}
98  virtual void GetStrides(int (&strides)[YuvImage::MAX_PLANES]) {}
99  virtual void SetPixelFormat(const AVPixelFormat pixFormat) {}
100  virtual void SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES]) {}
101  virtual void SetDimensions(int width,
102  int height,
103  const int (&strides)[YuvImage::MAX_PLANES],
104  const int (&planeOffsets)[YuvImage::MAX_PLANES])
105  {
106  }
107 
108  static bool CopyPicture(YuvImage* pDst, YuvImage *pSrc);
109  static bool CopyNV12Picture(YuvImage* pDst, YuvImage *pSrc);
110  static bool CopyYUV422PackedPicture(YuvImage* pDst, YuvImage *pSrc);
111 
112 protected:
113  explicit CVideoBuffer(int id);
114  AVPixelFormat m_pixFormat = AV_PIX_FMT_NONE;
115  std::atomic_int m_refCount;
116  int m_id;
117  std::shared_ptr<IVideoBufferPool> m_pool;
118 };
119 
121 {
122 public:
123  CVideoBufferSysMem(IVideoBufferPool &pool, int id, AVPixelFormat format, int size);
124  ~CVideoBufferSysMem() override;
125  uint8_t* GetMemPtr() override;
126  void GetPlanes(uint8_t*(&planes)[YuvImage::MAX_PLANES]) override;
127  void GetStrides(int(&strides)[YuvImage::MAX_PLANES]) override;
128  void SetPixelFormat(const AVPixelFormat pixFormat) override;
129  void SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES]) override;
130  void SetDimensions(int width, int height, const int (&strides)[YuvImage::MAX_PLANES], const int (&planeOffsets)[YuvImage::MAX_PLANES]) override;
131  bool Alloc();
132 
133 protected:
134  int m_width = 0;
135  int m_height = 0;
136  int m_size = 0;
137  uint8_t *m_data = nullptr;
138  YuvImage m_image;
139 };
140 
141 //-----------------------------------------------------------------------------
142 //
143 //-----------------------------------------------------------------------------
144 
146 {
147 public:
148  ~CVideoBufferPoolSysMem() override;
149  CVideoBuffer* Get() override;
150  void Return(int id) override;
151  void Configure(AVPixelFormat format, int size) override;
152  bool IsConfigured() override;
153  bool IsCompatible(AVPixelFormat format, int size) override;
154  void Discard(CVideoBufferManager *bm, ReadyToDispose cb) override;
155 
156  static std::shared_ptr<IVideoBufferPool> CreatePool();
157 
158 protected:
159  int m_width = 0;
160  int m_height = 0;
161  int m_size = 0;
162  AVPixelFormat m_pixFormat = AV_PIX_FMT_NONE;
163  bool m_configured = false;
164  CCriticalSection m_critSection;
165  CVideoBufferManager *m_bm = nullptr;
166  ReadyToDispose m_cbDispose;
167 
168  std::vector<CVideoBufferSysMem*> m_all;
169  std::deque<int> m_used;
170  std::deque<int> m_free;
171 };
172 
173 //-----------------------------------------------------------------------------
174 //
175 //-----------------------------------------------------------------------------
176 
177 typedef std::shared_ptr<IVideoBufferPool> (*CreatePoolFunc)();
178 
180 {
181 public:
183  void RegisterPool(const std::shared_ptr<IVideoBufferPool>& pool);
184  void RegisterPoolFactory(const std::string& id, CreatePoolFunc createFunc);
185  void ReleasePools();
186  void ReleasePool(IVideoBufferPool *pool);
187  CVideoBuffer* Get(AVPixelFormat format, int size, IVideoBufferPool **pPool);
188  void ReadyForDisposal(IVideoBufferPool *pool);
189 
190 protected:
191  CCriticalSection m_critSection;
192  std::list<std::shared_ptr<IVideoBufferPool>> m_pools;
193  std::list<std::shared_ptr<IVideoBufferPool>> m_discardedPools;
194  std::map<std::string, CreatePoolFunc> m_poolFactories;
195 
196 private:
197  CVideoBufferManager (const CVideoBufferManager&) = delete;
198  CVideoBufferManager& operator= (const CVideoBufferManager&) = delete;
199 };
Definition: VideoBuffer.h:85
Definition: VideoBuffer.h:120
Definition: VideoBuffer.h:179
Definition: VideoBuffer.h:24
Definition: VideoBuffer.h:51
Definition: VideoBuffer.h:145