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