1 /*
2 * Copyright (c) 2018-2020, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     encode_tracked_buffer.h
24 //! \brief    Defines the interface for buffer tracker
25 //! \details  The tracker manages the buffers with different type
26 //!
27 
28 #ifndef __ENCODE_BUFFER_TRACKER_H__
29 #define __ENCODE_BUFFER_TRACKER_H__
30 
31 #include "codec_def_common.h"
32 #include "encode_tracked_buffer_queue.h"
33 #include "encode_utils.h"
34 #include "media_class_trace.h"
35 #include "mos_defs.h"
36 #include "mos_defs_specific.h"
37 #include "mos_os.h"
38 #include "mos_os_specific.h"
39 #include <stdint.h>
40 #include <map>
41 #include <memory>
42 #include <vector>
43 
44 #if _MEDIA_RESERVED
45 #include "encode_tracked_buffer_ext.h"
46 #endif
47 
48 namespace encode
49 {
50 // define the buffer types in the tracked list
51 enum class BufferType
52 {
53     mbCodedBuffer,
54     mvDataBuffer,
55     mvTemporalBuffer,
56     ds4xSurface,
57     ds8xSurface,
58     segmentIdStreamOutBuffer,
59     vdencSegIdStreamOutBuffer,
60     bwdAdaptCdfBuffer,
61     postCdefReconSurface,
62     preMbCodedBuffer,
63     preRefSurface,
64     preRawSurface,
65     preDs4xSurface,
66     preDs8xSurface,
67     superResRefScaled,
68     superResRef4xDsScaled,
69     superResRef8xDsScaled,
70     preencRef0,
71     preencRef1,
72     AlignedRawSurface,
73 };
74 
75 struct MapBufferResourceType
76 {
77     BufferType   buffer;
78     ResourceType type;
79 };
80 
81 class EncodeAllocator;
82 class BufferSlot;
83 class TrackedBuffer
84 {
85 public:
86     //!
87     //! \brief  Constructor
88     //! \param  [in] osInterface
89     //!         Pointer to MOS_INTERFACE
90     //! \param  [in] maxRefCnt
91     //!         max reference frame count
92     //! \param  [in] maxNonRefCnt
93     //!         max non-reference frame count
94     //!
95     TrackedBuffer(EncodeAllocator *allocator, uint8_t maxRefCnt, uint8_t maxNonRefCnt);
96 
97     //!
98     //! \brief  Destructor
99     //!
100     virtual ~TrackedBuffer();
101 
102     //!
103     //! \brief  Increase the reference count, default value is 1
104     //! \return uint8_t
105     //!         return current free slot index
106     //!
GetCurrIndex()107     virtual uint8_t GetCurrIndex() { return m_currSlotIndex; }
108 
109     //!
110     //! \brief  Register allocate parameters, it's required when allocate surface
111     //! \param  [in] type
112     //!         BufferType
113     //! \param  [in] param
114     //!         MOS_ALLOC_GFXRES_PARAMS
115     //! \return MOS_STATUS
116     //!         MOS_STATUS_SUCCESS if success, else fail reason
117     //!
118     MOS_STATUS RegisterParam(BufferType type, MOS_ALLOC_GFXRES_PARAMS param);
119 
120     //!
121     //! \brief  Acquire buffer before encoding start for each frame
122     //! \param  [in] refList
123     //!         CODEC_REF_LIST*
124     //! \param  [in] isIdrFrame
125     //!         indicate whether current frame is IDR frame,
126     //!         if true, will reset the buffer tracker status
127     //! \param  [in] lazyRelease
128     //!         whether use lazy method to realse the resources, the default value is false
129     //! \return MOS_STATUS
130     //!         MOS_STATUS_SUCCESS if success, else fail reason
131     //!
132     MOS_STATUS Acquire(CODEC_REF_LIST *refList,
133         bool isIdrFrame,
134         bool lazyRelease = false);
135 
136     //!
137     //! \brief  Release buffers when current frame encoding completed
138     //!         It should be invoked in GetStatusReport
139     //! \param  [in] refList
140     //!         CODEC_REF_LIST*
141     //! \return MOS_STATUS
142     //!         MOS_STATUS_SUCCESS if success, else fail reason
143     //!
144     MOS_STATUS Release(CODEC_REF_LIST *refList);
145 
146     //!
147     //! \brief  It must be invoked when resolution changes, it will release
148     //!         internal buffers on demand
149     //! \return MOS_STATUS
150     //!         MOS_STATUS_SUCCESS if success, else fail reason
151     //!
152     MOS_STATUS OnSizeChange();
153 
154     //!
155     //! \brief  Get Surface from given slot
156     //! \param  [in]type
157     //!         BufferType
158     //! \param  [in]index
159     //!         BufferSlot index
160     //! \return MOS_SURFACE *
161     //!         MOS_SURFACE * if success, else nullptr if the pool is empty
162     //!
163     MOS_SURFACE *GetSurface(BufferType type, uint32_t index);
164 
165     //!
166     //! \brief  Get Buffer from given slot
167     //! \param  [in]type
168     //!         BufferType
169     //! \param  [in]index
170     //!         BufferSlot index
171     //! \return MOS_RESOURCE *
172     //!         MOS_RESOURCE * if success, else nullptr if the pool is empty
173     //!
174     virtual MOS_RESOURCE *GetBuffer(BufferType type, uint32_t index);
175 
176 protected:
177     //!
178     //! \brief  Get Resource type according to the buffer type
179     //! \param  [in]type
180     //!         BufferType
181     //! \return ResourceType
182     //!         return the ResourceType
183     //!
GetResourceType(BufferType buffer)184     ResourceType GetResourceType(BufferType buffer)
185     {
186         for (auto pair : m_mapBufferResourceType)
187         {
188             if (pair.buffer == buffer)
189             {
190                 return pair.type;
191             }
192         }
193 
194         return ResourceType::invalidResource;
195     }
196 
197     //!
198     //! \brief  Reset the unused slots then can use them for other frames
199     //! \param  [in]refList
200     //!         the pointer of reference list
201     //! \return MOS_STATUS
202     //!         MOS_STATUS_SUCCESS if success, else fail reason
203     MOS_STATUS ReleaseUnusedSlots(CODEC_REF_LIST* refList, bool lazyRelease);
204 
205     friend class BufferSlot;
206     //!
207     //! \brief  Get the tracked buffer queue according to the buffer type
208     //! \param  [in]type
209     //!         BufferType
210     //! \return shared_ptr<BufferQueue>
211     //!         shared_ptr<BufferQueue> if success, else nullptr
212     std::shared_ptr<BufferQueue> GetBufferQueue(BufferType type);
213 
214     static constexpr MapBufferResourceType m_mapBufferResourceType[] =
215     {
216         {BufferType::mbCodedBuffer,             ResourceType::bufferResource},
217         {BufferType::mvDataBuffer,              ResourceType::bufferResource},
218         {BufferType::mvTemporalBuffer,          ResourceType::bufferResource},
219         {BufferType::ds4xSurface,               ResourceType::surfaceResource},
220         {BufferType::ds8xSurface,               ResourceType::surfaceResource},
221         {BufferType::segmentIdStreamOutBuffer,  ResourceType::bufferResource},
222         {BufferType::vdencSegIdStreamOutBuffer, ResourceType::bufferResource},
223         {BufferType::bwdAdaptCdfBuffer,         ResourceType::bufferResource},
224         {BufferType::postCdefReconSurface,      ResourceType::surfaceResource},
225         {BufferType::preMbCodedBuffer,          ResourceType::bufferResource},
226         {BufferType::preRefSurface,             ResourceType::surfaceResource},
227         {BufferType::preRawSurface,             ResourceType::surfaceResource},
228         {BufferType::preDs4xSurface,            ResourceType::surfaceResource},
229         {BufferType::preDs8xSurface,            ResourceType::surfaceResource},
230         {BufferType::preencRef0,                ResourceType::bufferResource},
231         {BufferType::preencRef1,                ResourceType::bufferResource},
232         {BufferType::superResRefScaled,         ResourceType::surfaceResource},
233         {BufferType::superResRef4xDsScaled,     ResourceType::surfaceResource},
234         {BufferType::superResRef8xDsScaled,     ResourceType::surfaceResource},
235         {BufferType::AlignedRawSurface,         ResourceType::surfaceResource},
236     };
237 
238     uint8_t m_maxSlotCnt        = 0;     //!< max slot count in the tracked buffer
239     uint8_t m_maxRefSlotCnt     = 0;     //!< max reference slot count in the tracked buffer
240     uint8_t m_maxNonRefSlotCnt  = 0;     //!< max non-reference slot count int he tracked buffer
241     uint8_t m_currSlotIndex     = 0;     //!< current free slot index
242 
243     PMOS_MUTEX                m_mutex;                //!< mutex
244     Condition                 m_condition;            //!< condition
245     EncodeAllocator *         m_allocator = nullptr;  //!< encoder allocator
246     std::vector<BufferSlot *> m_bufferSlots = {};          //!< buffer slots
247 
248     std::map<BufferType, MOS_ALLOC_GFXRES_PARAMS>       m_allocParams = {};  //!< allocate parameters
249     std::map<BufferType, std::shared_ptr<BufferQueue> > m_bufferQueue = {};  //!< buffer queues
250     std::map<BufferType, std::shared_ptr<BufferQueue> > m_oldQueue = {};     //!< old queues for resolution change
251 
252 MEDIA_CLASS_DEFINE_END(encode__TrackedBuffer)
253 };
254 }  // namespace encode
255 #endif  // !__ENCODE_BUFFER_TRACKER_H__
256