1bf215546Sopenharmony_ci/**************************************************************************
2bf215546Sopenharmony_ci *
3bf215546Sopenharmony_ci * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
4bf215546Sopenharmony_ci * Copyright 2014 Advanced Micro Devices, Inc.
5bf215546Sopenharmony_ci * All Rights Reserved.
6bf215546Sopenharmony_ci *
7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
8bf215546Sopenharmony_ci * copy of this software and associated documentation files (the
9bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
10bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
11bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to
12bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
13bf215546Sopenharmony_ci * the following conditions:
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the
16bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
17bf215546Sopenharmony_ci * of the Software.
18bf215546Sopenharmony_ci *
19bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22bf215546Sopenharmony_ci * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
23bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26bf215546Sopenharmony_ci *
27bf215546Sopenharmony_ci **************************************************************************/
28bf215546Sopenharmony_ci
29bf215546Sopenharmony_ci#include "pipe/p_screen.h"
30bf215546Sopenharmony_ci
31bf215546Sopenharmony_ci#include "util/u_video.h"
32bf215546Sopenharmony_ci#include "util/u_memory.h"
33bf215546Sopenharmony_ci
34bf215546Sopenharmony_ci#include "vl/vl_winsys.h"
35bf215546Sopenharmony_ci#include "vl/vl_codec.h"
36bf215546Sopenharmony_ci
37bf215546Sopenharmony_ci#include "va_private.h"
38bf215546Sopenharmony_ci
39bf215546Sopenharmony_ci#include "util/u_handle_table.h"
40bf215546Sopenharmony_ci
41bf215546Sopenharmony_ciDEBUG_GET_ONCE_BOOL_OPTION(mpeg4, "VAAPI_MPEG4_ENABLED", false)
42bf215546Sopenharmony_ci
43bf215546Sopenharmony_ciVAStatus
44bf215546Sopenharmony_civlVaQueryConfigProfiles(VADriverContextP ctx, VAProfile *profile_list, int *num_profiles)
45bf215546Sopenharmony_ci{
46bf215546Sopenharmony_ci   struct pipe_screen *pscreen;
47bf215546Sopenharmony_ci   enum pipe_video_profile p;
48bf215546Sopenharmony_ci   VAProfile vap;
49bf215546Sopenharmony_ci
50bf215546Sopenharmony_ci   if (!ctx)
51bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
52bf215546Sopenharmony_ci
53bf215546Sopenharmony_ci   *num_profiles = 0;
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ci   pscreen = VL_VA_PSCREEN(ctx);
56bf215546Sopenharmony_ci   for (p = PIPE_VIDEO_PROFILE_MPEG2_SIMPLE; p <= PIPE_VIDEO_PROFILE_AV1_MAIN; ++p) {
57bf215546Sopenharmony_ci      if (u_reduce_video_profile(p) == PIPE_VIDEO_FORMAT_MPEG4 && !debug_get_option_mpeg4())
58bf215546Sopenharmony_ci         continue;
59bf215546Sopenharmony_ci
60bf215546Sopenharmony_ci      if (vl_codec_supported(pscreen, p, false) ||
61bf215546Sopenharmony_ci          vl_codec_supported(pscreen, p, true)) {
62bf215546Sopenharmony_ci         vap = PipeToProfile(p);
63bf215546Sopenharmony_ci         if (vap != VAProfileNone)
64bf215546Sopenharmony_ci            profile_list[(*num_profiles)++] = vap;
65bf215546Sopenharmony_ci      }
66bf215546Sopenharmony_ci   }
67bf215546Sopenharmony_ci
68bf215546Sopenharmony_ci   /* Support postprocessing through vl_compositor */
69bf215546Sopenharmony_ci   profile_list[(*num_profiles)++] = VAProfileNone;
70bf215546Sopenharmony_ci
71bf215546Sopenharmony_ci   return VA_STATUS_SUCCESS;
72bf215546Sopenharmony_ci}
73bf215546Sopenharmony_ci
74bf215546Sopenharmony_ciVAStatus
75bf215546Sopenharmony_civlVaQueryConfigEntrypoints(VADriverContextP ctx, VAProfile profile,
76bf215546Sopenharmony_ci                           VAEntrypoint *entrypoint_list, int *num_entrypoints)
77bf215546Sopenharmony_ci{
78bf215546Sopenharmony_ci   struct pipe_screen *pscreen;
79bf215546Sopenharmony_ci   enum pipe_video_profile p;
80bf215546Sopenharmony_ci
81bf215546Sopenharmony_ci   if (!ctx)
82bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
83bf215546Sopenharmony_ci
84bf215546Sopenharmony_ci   *num_entrypoints = 0;
85bf215546Sopenharmony_ci
86bf215546Sopenharmony_ci   if (profile == VAProfileNone) {
87bf215546Sopenharmony_ci      entrypoint_list[(*num_entrypoints)++] = VAEntrypointVideoProc;
88bf215546Sopenharmony_ci      return VA_STATUS_SUCCESS;
89bf215546Sopenharmony_ci   }
90bf215546Sopenharmony_ci
91bf215546Sopenharmony_ci   p = ProfileToPipe(profile);
92bf215546Sopenharmony_ci   if (p == PIPE_VIDEO_PROFILE_UNKNOWN ||
93bf215546Sopenharmony_ci      (u_reduce_video_profile(p) == PIPE_VIDEO_FORMAT_MPEG4 &&
94bf215546Sopenharmony_ci      !debug_get_option_mpeg4()))
95bf215546Sopenharmony_ci      return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
96bf215546Sopenharmony_ci
97bf215546Sopenharmony_ci   pscreen = VL_VA_PSCREEN(ctx);
98bf215546Sopenharmony_ci   if (vl_codec_supported(pscreen, p, false))
99bf215546Sopenharmony_ci      entrypoint_list[(*num_entrypoints)++] = VAEntrypointVLD;
100bf215546Sopenharmony_ci
101bf215546Sopenharmony_ci   if (vl_codec_supported(pscreen, p, true))
102bf215546Sopenharmony_ci      entrypoint_list[(*num_entrypoints)++] = VAEntrypointEncSlice;
103bf215546Sopenharmony_ci
104bf215546Sopenharmony_ci   if (*num_entrypoints == 0)
105bf215546Sopenharmony_ci      return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
106bf215546Sopenharmony_ci
107bf215546Sopenharmony_ci   assert(*num_entrypoints <= ctx->max_entrypoints);
108bf215546Sopenharmony_ci
109bf215546Sopenharmony_ci   return VA_STATUS_SUCCESS;
110bf215546Sopenharmony_ci}
111bf215546Sopenharmony_ci
112bf215546Sopenharmony_ciVAStatus
113bf215546Sopenharmony_civlVaGetConfigAttributes(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint,
114bf215546Sopenharmony_ci                        VAConfigAttrib *attrib_list, int num_attribs)
115bf215546Sopenharmony_ci{
116bf215546Sopenharmony_ci   struct pipe_screen *pscreen;
117bf215546Sopenharmony_ci   int i;
118bf215546Sopenharmony_ci
119bf215546Sopenharmony_ci   if (!ctx)
120bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
121bf215546Sopenharmony_ci
122bf215546Sopenharmony_ci   pscreen = VL_VA_PSCREEN(ctx);
123bf215546Sopenharmony_ci
124bf215546Sopenharmony_ci   for (i = 0; i < num_attribs; ++i) {
125bf215546Sopenharmony_ci      unsigned int value;
126bf215546Sopenharmony_ci      if ((entrypoint == VAEntrypointVLD) &&
127bf215546Sopenharmony_ci          (vl_codec_supported(pscreen, ProfileToPipe(profile), false))) {
128bf215546Sopenharmony_ci         switch (attrib_list[i].type) {
129bf215546Sopenharmony_ci         case VAConfigAttribRTFormat:
130bf215546Sopenharmony_ci            value = VA_RT_FORMAT_YUV420 | VA_RT_FORMAT_YUV422;
131bf215546Sopenharmony_ci            if (pscreen->is_video_format_supported(pscreen, PIPE_FORMAT_P010,
132bf215546Sopenharmony_ci                                                   ProfileToPipe(profile),
133bf215546Sopenharmony_ci                                                   PIPE_VIDEO_ENTRYPOINT_BITSTREAM) ||
134bf215546Sopenharmony_ci                pscreen->is_video_format_supported(pscreen, PIPE_FORMAT_P016,
135bf215546Sopenharmony_ci                                                   ProfileToPipe(profile),
136bf215546Sopenharmony_ci                                                   PIPE_VIDEO_ENTRYPOINT_BITSTREAM))
137bf215546Sopenharmony_ci               value |= VA_RT_FORMAT_YUV420_10BPP;
138bf215546Sopenharmony_ci            break;
139bf215546Sopenharmony_ci         default:
140bf215546Sopenharmony_ci            value = VA_ATTRIB_NOT_SUPPORTED;
141bf215546Sopenharmony_ci            break;
142bf215546Sopenharmony_ci         }
143bf215546Sopenharmony_ci      } else if ((entrypoint == VAEntrypointEncSlice) &&
144bf215546Sopenharmony_ci                 (vl_codec_supported(pscreen, ProfileToPipe(profile), true))) {
145bf215546Sopenharmony_ci         switch (attrib_list[i].type) {
146bf215546Sopenharmony_ci         case VAConfigAttribRTFormat:
147bf215546Sopenharmony_ci            value = VA_RT_FORMAT_YUV420;
148bf215546Sopenharmony_ci            if (pscreen->is_video_format_supported(pscreen, PIPE_FORMAT_P010,
149bf215546Sopenharmony_ci                                                   ProfileToPipe(profile),
150bf215546Sopenharmony_ci                                                   PIPE_VIDEO_ENTRYPOINT_ENCODE) ||
151bf215546Sopenharmony_ci                pscreen->is_video_format_supported(pscreen, PIPE_FORMAT_P016,
152bf215546Sopenharmony_ci                                                   ProfileToPipe(profile),
153bf215546Sopenharmony_ci                                                   PIPE_VIDEO_ENTRYPOINT_ENCODE))
154bf215546Sopenharmony_ci               value |= VA_RT_FORMAT_YUV420_10BPP;
155bf215546Sopenharmony_ci            break;
156bf215546Sopenharmony_ci         case VAConfigAttribRateControl:
157bf215546Sopenharmony_ci            value = VA_RC_CQP | VA_RC_CBR | VA_RC_VBR;
158bf215546Sopenharmony_ci            break;
159bf215546Sopenharmony_ci         case VAConfigAttribEncRateControlExt:
160bf215546Sopenharmony_ci            value = pscreen->get_video_param(pscreen, ProfileToPipe(profile),
161bf215546Sopenharmony_ci                                             PIPE_VIDEO_ENTRYPOINT_ENCODE,
162bf215546Sopenharmony_ci                                             PIPE_VIDEO_CAP_MAX_TEMPORAL_LAYERS);
163bf215546Sopenharmony_ci            if (value > 0) {
164bf215546Sopenharmony_ci               value -= 1;
165bf215546Sopenharmony_ci               value |= (1 << 8);   /* temporal_layer_bitrate_control_flag */
166bf215546Sopenharmony_ci            }
167bf215546Sopenharmony_ci            break;
168bf215546Sopenharmony_ci         case VAConfigAttribEncPackedHeaders:
169bf215546Sopenharmony_ci            value = VA_ENC_PACKED_HEADER_NONE;
170bf215546Sopenharmony_ci            if (u_reduce_video_profile(ProfileToPipe(profile)) == PIPE_VIDEO_FORMAT_HEVC)
171bf215546Sopenharmony_ci               value |= VA_ENC_PACKED_HEADER_SEQUENCE;
172bf215546Sopenharmony_ci            break;
173bf215546Sopenharmony_ci         case VAConfigAttribEncMaxSlices:
174bf215546Sopenharmony_ci         {
175bf215546Sopenharmony_ci            /**
176bf215546Sopenharmony_ci             * \brief Maximum number of slices per frame. Read-only.
177bf215546Sopenharmony_ci             *
178bf215546Sopenharmony_ci             * This attribute determines the maximum number of slices the
179bf215546Sopenharmony_ci             * driver can support to encode a single frame.
180bf215546Sopenharmony_ci             */
181bf215546Sopenharmony_ci            int maxSlicesPerEncodedPic = pscreen->get_video_param(pscreen, ProfileToPipe(profile),
182bf215546Sopenharmony_ci                                             PIPE_VIDEO_ENTRYPOINT_ENCODE,
183bf215546Sopenharmony_ci                                             PIPE_VIDEO_CAP_ENC_MAX_SLICES_PER_FRAME);
184bf215546Sopenharmony_ci            if (maxSlicesPerEncodedPic <= 0)
185bf215546Sopenharmony_ci               value = VA_ATTRIB_NOT_SUPPORTED;
186bf215546Sopenharmony_ci            else
187bf215546Sopenharmony_ci               value = maxSlicesPerEncodedPic;
188bf215546Sopenharmony_ci         } break;
189bf215546Sopenharmony_ci         case VAConfigAttribEncMaxRefFrames:
190bf215546Sopenharmony_ci         {
191bf215546Sopenharmony_ci            int maxL0L1ReferencesPerFrame = pscreen->get_video_param(pscreen, ProfileToPipe(profile),
192bf215546Sopenharmony_ci                                             PIPE_VIDEO_ENTRYPOINT_ENCODE,
193bf215546Sopenharmony_ci                                             PIPE_VIDEO_CAP_ENC_MAX_REFERENCES_PER_FRAME);
194bf215546Sopenharmony_ci            if (maxL0L1ReferencesPerFrame <= 0)
195bf215546Sopenharmony_ci               value = 1;
196bf215546Sopenharmony_ci            else
197bf215546Sopenharmony_ci               value = maxL0L1ReferencesPerFrame;
198bf215546Sopenharmony_ci         } break;
199bf215546Sopenharmony_ci         case VAConfigAttribEncSliceStructure:
200bf215546Sopenharmony_ci         {
201bf215546Sopenharmony_ci            /* The VA enum values match the pipe_video_cap_slice_structure definitions*/
202bf215546Sopenharmony_ci            int supportedSliceStructuresFlagSet = pscreen->get_video_param(pscreen, ProfileToPipe(profile),
203bf215546Sopenharmony_ci                                             PIPE_VIDEO_ENTRYPOINT_ENCODE,
204bf215546Sopenharmony_ci                                             PIPE_VIDEO_CAP_ENC_SLICES_STRUCTURE);
205bf215546Sopenharmony_ci            if (supportedSliceStructuresFlagSet <= 0)
206bf215546Sopenharmony_ci               value = VA_ATTRIB_NOT_SUPPORTED;
207bf215546Sopenharmony_ci            else
208bf215546Sopenharmony_ci               value = supportedSliceStructuresFlagSet;
209bf215546Sopenharmony_ci         } break;
210bf215546Sopenharmony_ci         default:
211bf215546Sopenharmony_ci            value = VA_ATTRIB_NOT_SUPPORTED;
212bf215546Sopenharmony_ci            break;
213bf215546Sopenharmony_ci         }
214bf215546Sopenharmony_ci      } else if (entrypoint == VAEntrypointVideoProc) {
215bf215546Sopenharmony_ci         switch (attrib_list[i].type) {
216bf215546Sopenharmony_ci         case VAConfigAttribRTFormat:
217bf215546Sopenharmony_ci            value = (VA_RT_FORMAT_YUV420 |
218bf215546Sopenharmony_ci                     VA_RT_FORMAT_YUV420_10BPP |
219bf215546Sopenharmony_ci                     VA_RT_FORMAT_RGB32);
220bf215546Sopenharmony_ci            break;
221bf215546Sopenharmony_ci         default:
222bf215546Sopenharmony_ci            value = VA_ATTRIB_NOT_SUPPORTED;
223bf215546Sopenharmony_ci            break;
224bf215546Sopenharmony_ci         }
225bf215546Sopenharmony_ci      } else {
226bf215546Sopenharmony_ci         value = VA_ATTRIB_NOT_SUPPORTED;
227bf215546Sopenharmony_ci      }
228bf215546Sopenharmony_ci      attrib_list[i].value = value;
229bf215546Sopenharmony_ci   }
230bf215546Sopenharmony_ci
231bf215546Sopenharmony_ci   return VA_STATUS_SUCCESS;
232bf215546Sopenharmony_ci}
233bf215546Sopenharmony_ci
234bf215546Sopenharmony_ciVAStatus
235bf215546Sopenharmony_civlVaCreateConfig(VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint,
236bf215546Sopenharmony_ci                 VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id)
237bf215546Sopenharmony_ci{
238bf215546Sopenharmony_ci   vlVaDriver *drv;
239bf215546Sopenharmony_ci   vlVaConfig *config;
240bf215546Sopenharmony_ci   struct pipe_screen *pscreen;
241bf215546Sopenharmony_ci   enum pipe_video_profile p;
242bf215546Sopenharmony_ci   unsigned int supported_rt_formats;
243bf215546Sopenharmony_ci
244bf215546Sopenharmony_ci   if (!ctx)
245bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
246bf215546Sopenharmony_ci
247bf215546Sopenharmony_ci   drv = VL_VA_DRIVER(ctx);
248bf215546Sopenharmony_ci
249bf215546Sopenharmony_ci   if (!drv)
250bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
251bf215546Sopenharmony_ci
252bf215546Sopenharmony_ci   config = CALLOC(1, sizeof(vlVaConfig));
253bf215546Sopenharmony_ci   if (!config)
254bf215546Sopenharmony_ci      return VA_STATUS_ERROR_ALLOCATION_FAILED;
255bf215546Sopenharmony_ci
256bf215546Sopenharmony_ci   if (profile == VAProfileNone) {
257bf215546Sopenharmony_ci      if (entrypoint != VAEntrypointVideoProc) {
258bf215546Sopenharmony_ci         FREE(config);
259bf215546Sopenharmony_ci         return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
260bf215546Sopenharmony_ci      }
261bf215546Sopenharmony_ci
262bf215546Sopenharmony_ci      config->entrypoint = PIPE_VIDEO_ENTRYPOINT_PROCESSING;
263bf215546Sopenharmony_ci      config->profile = PIPE_VIDEO_PROFILE_UNKNOWN;
264bf215546Sopenharmony_ci      supported_rt_formats = VA_RT_FORMAT_YUV420 |
265bf215546Sopenharmony_ci                             VA_RT_FORMAT_YUV420_10BPP |
266bf215546Sopenharmony_ci                             VA_RT_FORMAT_RGB32;
267bf215546Sopenharmony_ci      for (int i = 0; i < num_attribs; i++) {
268bf215546Sopenharmony_ci         if (attrib_list[i].type == VAConfigAttribRTFormat) {
269bf215546Sopenharmony_ci            if (attrib_list[i].value & supported_rt_formats) {
270bf215546Sopenharmony_ci               config->rt_format = attrib_list[i].value;
271bf215546Sopenharmony_ci            } else {
272bf215546Sopenharmony_ci               FREE(config);
273bf215546Sopenharmony_ci               return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
274bf215546Sopenharmony_ci            }
275bf215546Sopenharmony_ci         } else {
276bf215546Sopenharmony_ci            /*other attrib_types are not supported.*/
277bf215546Sopenharmony_ci            FREE(config);
278bf215546Sopenharmony_ci            return VA_STATUS_ERROR_INVALID_VALUE;
279bf215546Sopenharmony_ci         }
280bf215546Sopenharmony_ci      }
281bf215546Sopenharmony_ci
282bf215546Sopenharmony_ci      /* Default value if not specified in the input attributes. */
283bf215546Sopenharmony_ci      if (!config->rt_format)
284bf215546Sopenharmony_ci         config->rt_format = supported_rt_formats;
285bf215546Sopenharmony_ci
286bf215546Sopenharmony_ci      mtx_lock(&drv->mutex);
287bf215546Sopenharmony_ci      *config_id = handle_table_add(drv->htab, config);
288bf215546Sopenharmony_ci      mtx_unlock(&drv->mutex);
289bf215546Sopenharmony_ci      return VA_STATUS_SUCCESS;
290bf215546Sopenharmony_ci   }
291bf215546Sopenharmony_ci
292bf215546Sopenharmony_ci   p = ProfileToPipe(profile);
293bf215546Sopenharmony_ci   if (p == PIPE_VIDEO_PROFILE_UNKNOWN  ||
294bf215546Sopenharmony_ci      (u_reduce_video_profile(p) == PIPE_VIDEO_FORMAT_MPEG4 &&
295bf215546Sopenharmony_ci      !debug_get_option_mpeg4())) {
296bf215546Sopenharmony_ci      FREE(config);
297bf215546Sopenharmony_ci      return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
298bf215546Sopenharmony_ci   }
299bf215546Sopenharmony_ci
300bf215546Sopenharmony_ci   pscreen = VL_VA_PSCREEN(ctx);
301bf215546Sopenharmony_ci
302bf215546Sopenharmony_ci   switch (entrypoint) {
303bf215546Sopenharmony_ci   case VAEntrypointVLD:
304bf215546Sopenharmony_ci      supported_rt_formats = VA_RT_FORMAT_YUV420 | VA_RT_FORMAT_YUV422;
305bf215546Sopenharmony_ci      if (!vl_codec_supported(pscreen, p, false)) {
306bf215546Sopenharmony_ci         FREE(config);
307bf215546Sopenharmony_ci         return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
308bf215546Sopenharmony_ci      }
309bf215546Sopenharmony_ci
310bf215546Sopenharmony_ci      config->entrypoint = PIPE_VIDEO_ENTRYPOINT_BITSTREAM;
311bf215546Sopenharmony_ci      break;
312bf215546Sopenharmony_ci
313bf215546Sopenharmony_ci   case VAEntrypointEncSlice:
314bf215546Sopenharmony_ci      supported_rt_formats = VA_RT_FORMAT_YUV420;
315bf215546Sopenharmony_ci      if (!vl_codec_supported(pscreen, p, true)) {
316bf215546Sopenharmony_ci         FREE(config);
317bf215546Sopenharmony_ci         return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
318bf215546Sopenharmony_ci      }
319bf215546Sopenharmony_ci
320bf215546Sopenharmony_ci      config->entrypoint = PIPE_VIDEO_ENTRYPOINT_ENCODE;
321bf215546Sopenharmony_ci      break;
322bf215546Sopenharmony_ci
323bf215546Sopenharmony_ci   default:
324bf215546Sopenharmony_ci      FREE(config);
325bf215546Sopenharmony_ci      return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
326bf215546Sopenharmony_ci   }
327bf215546Sopenharmony_ci
328bf215546Sopenharmony_ci   config->profile = p;
329bf215546Sopenharmony_ci   if (pscreen->is_video_format_supported(pscreen, PIPE_FORMAT_P010, p,
330bf215546Sopenharmony_ci         config->entrypoint) ||
331bf215546Sopenharmony_ci       pscreen->is_video_format_supported(pscreen, PIPE_FORMAT_P016, p,
332bf215546Sopenharmony_ci         config->entrypoint))
333bf215546Sopenharmony_ci      supported_rt_formats |= VA_RT_FORMAT_YUV420_10BPP;
334bf215546Sopenharmony_ci
335bf215546Sopenharmony_ci   for (int i = 0; i <num_attribs ; i++) {
336bf215546Sopenharmony_ci      if (attrib_list[i].type != VAConfigAttribRTFormat &&
337bf215546Sopenharmony_ci         entrypoint == VAEntrypointVLD ) {
338bf215546Sopenharmony_ci         FREE(config);
339bf215546Sopenharmony_ci         return VA_STATUS_ERROR_INVALID_VALUE;
340bf215546Sopenharmony_ci      }
341bf215546Sopenharmony_ci      if (attrib_list[i].type == VAConfigAttribRateControl) {
342bf215546Sopenharmony_ci         if (attrib_list[i].value == VA_RC_CBR)
343bf215546Sopenharmony_ci            config->rc = PIPE_H2645_ENC_RATE_CONTROL_METHOD_CONSTANT;
344bf215546Sopenharmony_ci         else if (attrib_list[i].value == VA_RC_VBR)
345bf215546Sopenharmony_ci            config->rc = PIPE_H2645_ENC_RATE_CONTROL_METHOD_VARIABLE;
346bf215546Sopenharmony_ci         else if (attrib_list[i].value == VA_RC_CQP)
347bf215546Sopenharmony_ci            config->rc = PIPE_H2645_ENC_RATE_CONTROL_METHOD_DISABLE;
348bf215546Sopenharmony_ci         else {
349bf215546Sopenharmony_ci            FREE(config);
350bf215546Sopenharmony_ci            return VA_STATUS_ERROR_INVALID_VALUE;
351bf215546Sopenharmony_ci         }
352bf215546Sopenharmony_ci      }
353bf215546Sopenharmony_ci      if (attrib_list[i].type == VAConfigAttribRTFormat) {
354bf215546Sopenharmony_ci         if (attrib_list[i].value & supported_rt_formats) {
355bf215546Sopenharmony_ci            config->rt_format = attrib_list[i].value;
356bf215546Sopenharmony_ci         } else {
357bf215546Sopenharmony_ci            FREE(config);
358bf215546Sopenharmony_ci            return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
359bf215546Sopenharmony_ci         }
360bf215546Sopenharmony_ci      }
361bf215546Sopenharmony_ci      if (attrib_list[i].type == VAConfigAttribEncPackedHeaders) {
362bf215546Sopenharmony_ci         if ((attrib_list[i].value > 1) ||
363bf215546Sopenharmony_ci             (attrib_list[i].value &&
364bf215546Sopenharmony_ci               u_reduce_video_profile(ProfileToPipe(profile)) !=
365bf215546Sopenharmony_ci                  PIPE_VIDEO_FORMAT_HEVC) ||
366bf215546Sopenharmony_ci             (config->entrypoint != PIPE_VIDEO_ENTRYPOINT_ENCODE)) {
367bf215546Sopenharmony_ci            FREE(config);
368bf215546Sopenharmony_ci            return VA_STATUS_ERROR_INVALID_VALUE;
369bf215546Sopenharmony_ci         }
370bf215546Sopenharmony_ci      }
371bf215546Sopenharmony_ci   }
372bf215546Sopenharmony_ci
373bf215546Sopenharmony_ci   /* Default value if not specified in the input attributes. */
374bf215546Sopenharmony_ci   if (!config->rt_format)
375bf215546Sopenharmony_ci      config->rt_format = supported_rt_formats;
376bf215546Sopenharmony_ci
377bf215546Sopenharmony_ci   mtx_lock(&drv->mutex);
378bf215546Sopenharmony_ci   *config_id = handle_table_add(drv->htab, config);
379bf215546Sopenharmony_ci   mtx_unlock(&drv->mutex);
380bf215546Sopenharmony_ci
381bf215546Sopenharmony_ci   return VA_STATUS_SUCCESS;
382bf215546Sopenharmony_ci}
383bf215546Sopenharmony_ci
384bf215546Sopenharmony_ciVAStatus
385bf215546Sopenharmony_civlVaDestroyConfig(VADriverContextP ctx, VAConfigID config_id)
386bf215546Sopenharmony_ci{
387bf215546Sopenharmony_ci   vlVaDriver *drv;
388bf215546Sopenharmony_ci   vlVaConfig *config;
389bf215546Sopenharmony_ci
390bf215546Sopenharmony_ci   if (!ctx)
391bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
392bf215546Sopenharmony_ci
393bf215546Sopenharmony_ci   drv = VL_VA_DRIVER(ctx);
394bf215546Sopenharmony_ci
395bf215546Sopenharmony_ci   if (!drv)
396bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
397bf215546Sopenharmony_ci
398bf215546Sopenharmony_ci   mtx_lock(&drv->mutex);
399bf215546Sopenharmony_ci   config = handle_table_get(drv->htab, config_id);
400bf215546Sopenharmony_ci
401bf215546Sopenharmony_ci   if (!config) {
402bf215546Sopenharmony_ci      mtx_unlock(&drv->mutex);
403bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONFIG;
404bf215546Sopenharmony_ci   }
405bf215546Sopenharmony_ci
406bf215546Sopenharmony_ci   FREE(config);
407bf215546Sopenharmony_ci   handle_table_remove(drv->htab, config_id);
408bf215546Sopenharmony_ci   mtx_unlock(&drv->mutex);
409bf215546Sopenharmony_ci
410bf215546Sopenharmony_ci   return VA_STATUS_SUCCESS;
411bf215546Sopenharmony_ci}
412bf215546Sopenharmony_ci
413bf215546Sopenharmony_ciVAStatus
414bf215546Sopenharmony_civlVaQueryConfigAttributes(VADriverContextP ctx, VAConfigID config_id, VAProfile *profile,
415bf215546Sopenharmony_ci                          VAEntrypoint *entrypoint, VAConfigAttrib *attrib_list, int *num_attribs)
416bf215546Sopenharmony_ci{
417bf215546Sopenharmony_ci   vlVaDriver *drv;
418bf215546Sopenharmony_ci   vlVaConfig *config;
419bf215546Sopenharmony_ci
420bf215546Sopenharmony_ci   if (!ctx)
421bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
422bf215546Sopenharmony_ci
423bf215546Sopenharmony_ci   drv = VL_VA_DRIVER(ctx);
424bf215546Sopenharmony_ci
425bf215546Sopenharmony_ci   if (!drv)
426bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONTEXT;
427bf215546Sopenharmony_ci
428bf215546Sopenharmony_ci   mtx_lock(&drv->mutex);
429bf215546Sopenharmony_ci   config = handle_table_get(drv->htab, config_id);
430bf215546Sopenharmony_ci   mtx_unlock(&drv->mutex);
431bf215546Sopenharmony_ci
432bf215546Sopenharmony_ci   if (!config)
433bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONFIG;
434bf215546Sopenharmony_ci
435bf215546Sopenharmony_ci   *profile = PipeToProfile(config->profile);
436bf215546Sopenharmony_ci
437bf215546Sopenharmony_ci   switch (config->entrypoint) {
438bf215546Sopenharmony_ci   case PIPE_VIDEO_ENTRYPOINT_BITSTREAM:
439bf215546Sopenharmony_ci      *entrypoint = VAEntrypointVLD;
440bf215546Sopenharmony_ci      break;
441bf215546Sopenharmony_ci   case PIPE_VIDEO_ENTRYPOINT_ENCODE:
442bf215546Sopenharmony_ci      *entrypoint = VAEntrypointEncSlice;
443bf215546Sopenharmony_ci      break;
444bf215546Sopenharmony_ci   case PIPE_VIDEO_ENTRYPOINT_PROCESSING:
445bf215546Sopenharmony_ci      *entrypoint = VAEntrypointVideoProc;
446bf215546Sopenharmony_ci      break;
447bf215546Sopenharmony_ci   default:
448bf215546Sopenharmony_ci      return VA_STATUS_ERROR_INVALID_CONFIG;
449bf215546Sopenharmony_ci   }
450bf215546Sopenharmony_ci
451bf215546Sopenharmony_ci   *num_attribs = 1;
452bf215546Sopenharmony_ci   attrib_list[0].type = VAConfigAttribRTFormat;
453bf215546Sopenharmony_ci   attrib_list[0].value = config->rt_format;
454bf215546Sopenharmony_ci
455bf215546Sopenharmony_ci   return VA_STATUS_SUCCESS;
456bf215546Sopenharmony_ci}
457