1 /*
2 * Copyright (c) 2017, 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 codechal_encode_allocator.cpp
24 //! \brief Resource allocator for all buffer/surface used by encoder
25 //!
26
27 #include "codechal_encode_allocator.h"
28 #include "codechal_encoder_base.h"
29
30 //!
31 //! \enum AllocatorCodec
32 //! \brief Allocator codec
33 //!
34 enum AllocatorCodec
35 {
36 allocatorAVC = 0,
37 allocatorHEVC = 1,
38 allocatorJPEG = 2,
39 allocatorMPEG2 = 3,
40 allocatorVP9 = 4,
41 allocatorVP8 = 5
42 };
43
44 //!
45 //! \enum AllocatorType
46 //! \brief Allocator type
47 //!
48 enum AllocatorType
49 {
50 allocator1D = 0,
51 allocator2D = 1,
52 allocatorBatch = 2
53 };
54
55 //!
56 //! \enum AllocatorFormat
57 //! \brief Allocator format
58 //!
59 enum AllocatorFormat
60 {
61 allocatorLinearBuffer = 0,
62 allocatorBatchBuffer = 1,
63 allocatorSurface = 2
64 };
65
66 //!
67 //! \enum AllocatorTile
68 //! \brief Allocator tile
69 //!
70 enum AllocatorTile
71 {
72 allocatorTileLinear = 0,
73 allocatorTileY = 1,
74 allocatorTileYf = 2,
75 allocatorTileYs = 3
76 };
77
MosToAllocatorCodec(uint32_t codec)78 uint16_t CodechalEncodeAllocator::MosToAllocatorCodec(uint32_t codec)
79 {
80 uint16_t allocCodec = 0;
81
82 if (CODECHAL_AVC == codec)
83 {
84 allocCodec = allocatorAVC;
85 }
86 else if (CODECHAL_HEVC == codec)
87 {
88 allocCodec = allocatorHEVC;
89 }
90 else if (CODECHAL_JPEG == codec)
91 {
92 allocCodec = allocatorJPEG;
93 }
94 else if (CODECHAL_MPEG2 == codec)
95 {
96 allocCodec = allocatorMPEG2;
97 }
98 else if (CODECHAL_VP9 == codec)
99 {
100 allocCodec = allocatorVP9;
101 }
102 else if (CODECHAL_VP8 == codec)
103 {
104 allocCodec = allocatorVP8;
105 }
106
107 return allocCodec;
108 }
109
MosToAllocatorFormat(MOS_FORMAT format)110 uint16_t CodechalEncodeAllocator::MosToAllocatorFormat(MOS_FORMAT format)
111 {
112 uint16_t allocFormat = 0;
113
114 switch (format)
115 {
116 case Format_Buffer :
117 allocFormat = allocatorLinearBuffer;
118 break;
119 case Format_Any :
120 allocFormat = allocatorBatchBuffer;
121 break;
122 case Format_NV12 :
123 case Format_YUY2 :
124 case Format_P208 :
125 case Format_AYUV:
126 case Format_YUYV:
127 case Format_YVYU:
128 case Format_UYVY:
129 case Format_VYUY:
130 case Format_A8R8G8B8:
131 case Format_A8B8G8R8:
132 allocFormat = allocatorSurface;
133 break;
134 default :
135 CODECHAL_ENCODE_ASSERTMESSAGE("Invalid format type = %d", format);
136 break;
137 }
138
139 return allocFormat;
140 }
141
MosToAllocatorTile(MOS_TILE_TYPE type)142 uint16_t CodechalEncodeAllocator::MosToAllocatorTile(MOS_TILE_TYPE type)
143 {
144 uint16_t allocTile = 0;
145
146 if (MOS_TILE_LINEAR == type)
147 {
148 allocTile = allocatorTileLinear;
149 }
150 else if (MOS_TILE_Y == type)
151 {
152 allocTile = allocatorTileY;
153 }
154 else if (MOS_TILE_YF == type)
155 {
156 allocTile = allocatorTileYf;
157 }
158 else
159 {
160 allocTile = allocatorTileYs;
161 }
162
163 return allocTile;
164 }
165
AllocateResource(uint32_t codec,uint32_t width,uint32_t height,ResourceName name,const char * bufName,uint8_t index,bool zeroOnAllocation,MOS_FORMAT format,MOS_TILE_TYPE tile,uint32_t dwMemType)166 void* CodechalEncodeAllocator::AllocateResource(
167 uint32_t codec, uint32_t width, uint32_t height, ResourceName name, const char *bufName,
168 uint8_t index, bool zeroOnAllocation, MOS_FORMAT format, MOS_TILE_TYPE tile, uint32_t dwMemType)
169 {
170 RESOURCE_TAG resTag;
171 MOS_ZeroMemory(&resTag, sizeof(resTag));
172
173 // set buffer name and index
174 resTag.typeID = SetResourceID(codec, name, index);
175
176 resTag.format = MosToAllocatorFormat(format);
177 resTag.tile = MosToAllocatorTile(tile);
178 resTag.zeroOnAllocation = zeroOnAllocation;
179
180 // set type and size info, and allocate buffer
181 void* buffer = nullptr;
182 if (allocatorLinearBuffer == resTag.format)
183 {
184 resTag.size = width;
185 resTag.type = allocator1D;
186 buffer = Allocate1DBuffer(resTag.tag, width, bufName, zeroOnAllocation, dwMemType);
187 }
188 else if (allocatorBatchBuffer == resTag.format)
189 {
190 resTag.size = width;
191 resTag.type = allocatorBatch;
192 buffer = AllocateBatchBuffer(resTag.tag, width, zeroOnAllocation);
193 }
194 else if (allocatorSurface == resTag.format)
195 {
196 resTag.width = (uint16_t)width;
197 resTag.height = (uint16_t)height;
198 resTag.type = allocator2D;
199 buffer = Allocate2DBuffer(resTag.tag, width, height, format, tile, bufName, zeroOnAllocation, dwMemType);
200 }
201 else
202 {
203 CODECHAL_ENCODE_ASSERTMESSAGE("Invalid format type = %d", format);
204 }
205
206 CODECHAL_ENCODE_NORMALMESSAGE("Alloc ID = 0x%x, type = %d, codec = %d, format = %d, tile = %d, zero = %d, width = %d, height = %d, size = %d",
207 resTag.typeID, resTag.type, resTag.codec, resTag.format, resTag.tile, resTag.zeroOnAllocation, resTag.width, resTag.height, resTag.size);
208
209 return buffer;
210 }
211
GetResource(uint32_t codec,ResourceName name,uint8_t index)212 void* CodechalEncodeAllocator::GetResource(uint32_t codec, ResourceName name, uint8_t index)
213 {
214 // find the resource from list
215 return GetResourcePointer(SetResourceID(codec, name, index), matchLevel1);
216 }
217
GetResourceSize(uint32_t codec,ResourceName name,uint8_t index)218 uint32_t CodechalEncodeAllocator::GetResourceSize(uint32_t codec, ResourceName name, uint8_t index)
219 {
220 RESOURCE_TAG resTag;
221 MOS_ZeroMemory(&resTag, sizeof(resTag));
222
223 if ((resTag.tag = GetResourceTag(SetResourceID(codec, name, index), matchLevel1)))
224 {
225 return resTag.size;
226 }
227 else
228 {
229 return 0;
230 }
231 }
232
ReleaseResource(uint32_t codec,ResourceName name,uint8_t index)233 void CodechalEncodeAllocator::ReleaseResource(uint32_t codec, ResourceName name, uint8_t index)
234 {
235 CodechalAllocator::ReleaseResource(SetResourceID(codec, name, index), matchLevel1);
236 }
237
SetResourceID(uint32_t codec,ResourceName name,uint8_t index)238 uint16_t CodechalEncodeAllocator::SetResourceID(uint32_t codec, ResourceName name, uint8_t index)
239 {
240 RESOURCE_TAG resTag;
241 MOS_ZeroMemory(&resTag, sizeof(resTag));
242
243 resTag.typeID = name;
244 resTag.codec = MosToAllocatorCodec(codec);
245 if (IsTrackedBuffer(name) || IsRecycleBuffer(name))
246 {
247 resTag.trackedRecycleBufferIndex = index;
248 }
249 return resTag.typeID;
250 }
251
GetResourceID(uint64_t resourceTag,Match level)252 uint16_t CodechalEncodeAllocator::GetResourceID(uint64_t resourceTag, Match level)
253 {
254 RESOURCE_TAG resTag;
255 MOS_ZeroMemory(&resTag, sizeof(resTag));
256
257 resTag.tag = resourceTag;
258 if (matchLevel0 == level)
259 {
260 // extract codec/name/indx
261 resTag.typeID &= m_bufNameMask;
262
263 // only match name, clear index for tracked/recycled buffer
264 resTag.typeID |= m_bufIndexMask;
265 }
266 else if (matchLevel1 == level)
267 {
268 // extract codec/name/indx
269 resTag.typeID &= m_bufNameMask;
270 }
271 return resTag.typeID;
272 }
273
CodechalEncodeAllocator(CodechalEncoderState * encoder)274 CodechalEncodeAllocator::CodechalEncodeAllocator(CodechalEncoderState* encoder)
275 : CodechalAllocator(encoder->GetOsInterface())
276 {
277 // Initilize interface pointers
278 m_encoder = encoder;
279 }
280
~CodechalEncodeAllocator()281 CodechalEncodeAllocator::~CodechalEncodeAllocator()
282 {
283 }
284