2 * gstvaapiutils_h265.c - H.265 related utilities
4 * Copyright (C) 2015 Intel Corporation
5 * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1
10 * of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301 USA
24 #include <gst/codecparsers/gsth265parser.h>
25 #include "gstvaapicompat.h"
26 #include "gstvaapiutils_h265_priv.h"
29 #include "gstvaapidebug.h"
37 /* Profile string map */
38 static const struct map gst_vaapi_h265_profile_map[] = {
40 { GST_VAAPI_PROFILE_H265_MAIN, "main" },
41 { GST_VAAPI_PROFILE_H265_MAIN10, "main-10" },
42 { GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE, "main-still-picture" },
43 { GST_VAAPI_PROFILE_H265_MAIN_444, "main-444" },
44 { GST_VAAPI_PROFILE_H265_MAIN_444_10, "main-444-10" },
45 { GST_VAAPI_PROFILE_H265_MAIN_422_10, "main-422-10" },
46 { GST_VAAPI_PROFILE_H265_MAIN12, "main-12" },
47 { GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN, "screen-extended-main" },
48 { GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10, "screen-extended-main-10" },
49 { GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444, "screen-extended-main-444" },
50 { GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444_10, "screen-extended-main-444-10"},
56 static const struct map gst_vaapi_h265_tier_map[] = {
58 { GST_VAAPI_TIER_H265_MAIN, "main" },
59 { GST_VAAPI_TIER_H265_HIGH, "high"},
60 { GST_VAAPI_TIER_H265_UNKNOWN, "unknown"}
64 /* Level string map */
65 static const struct map gst_vaapi_h265_level_map[] = {
67 { GST_VAAPI_LEVEL_H265_L1, "1" },
68 { GST_VAAPI_LEVEL_H265_L2, "2" },
69 { GST_VAAPI_LEVEL_H265_L2_1, "2.1" },
70 { GST_VAAPI_LEVEL_H265_L3, "3" },
71 { GST_VAAPI_LEVEL_H265_L3_1, "3.1" },
72 { GST_VAAPI_LEVEL_H265_L4, "4" },
73 { GST_VAAPI_LEVEL_H265_L4_1, "4.1" },
74 { GST_VAAPI_LEVEL_H265_L5, "5" },
75 { GST_VAAPI_LEVEL_H265_L5_1, "5.1" },
76 { GST_VAAPI_LEVEL_H265_L5_2, "5.2" },
77 { GST_VAAPI_LEVEL_H265_L6, "6" },
78 { GST_VAAPI_LEVEL_H265_L6_1, "6.1" },
79 { GST_VAAPI_LEVEL_H265_L6_2, "6.2" },
84 /* Table A-1 - Level limits */
86 static const GstVaapiH265LevelLimits gst_vaapi_h265_level_limits[] = {
87 /* level idc MaxLumaPs MCPBMt MCPBHt MSlSeg MTR MTC MaxLumaSr MBRMt MBRHt MinCr*/
88 { GST_VAAPI_LEVEL_H265_L1, 30, 36864, 350, 0, 16, 1, 1, 552960, 128, 0, 2},
89 { GST_VAAPI_LEVEL_H265_L2, 60, 122880, 1500, 0, 16, 1, 1, 3686400, 1500, 0, 2},
90 { GST_VAAPI_LEVEL_H265_L2_1, 63, 245760, 3000, 0, 20, 1, 1, 7372800, 3000, 0, 2},
91 { GST_VAAPI_LEVEL_H265_L3, 90, 552960, 6000, 0, 30, 2, 2, 16588800, 6000, 0, 2},
92 { GST_VAAPI_LEVEL_H265_L3_1, 93, 983040, 10000, 0, 40, 3, 3, 33177600, 10000, 0, 2},
93 { GST_VAAPI_LEVEL_H265_L4, 120, 2228224, 12000, 30000, 75, 5, 5, 66846720, 12000, 30000, 4},
94 { GST_VAAPI_LEVEL_H265_L4_1, 123, 2228224, 20000, 50000, 75, 5, 5, 133693440, 20000, 50000, 4},
95 { GST_VAAPI_LEVEL_H265_L5, 150, 8912896, 25000, 100000, 200, 11, 10, 267386880, 25000, 100000, 6},
96 { GST_VAAPI_LEVEL_H265_L5_1, 153, 8912896, 40000, 160000, 200, 11, 10, 534773760, 40000, 160000, 8},
97 { GST_VAAPI_LEVEL_H265_L5_2, 156, 8912896, 60000, 240000, 200, 11, 10, 1069547520, 60000, 240000, 8},
98 { GST_VAAPI_LEVEL_H265_L6, 180, 35651584, 60000, 240000, 600, 22, 20, 1069547520, 60000, 240000, 8},
99 { GST_VAAPI_LEVEL_H265_L6_1, 183, 35651584, 120000, 480000, 600, 22, 20, 2139095040, 120000, 480000, 8},
100 { GST_VAAPI_LEVEL_H265_L6_2, 186, 35651584, 240000, 800000, 600, 22, 20, 4278190080, 240000, 800000, 6},
105 /* Lookup value in map */
106 static const struct map *
107 map_lookup_value (const struct map *m, guint value)
109 g_return_val_if_fail (m != NULL, NULL);
111 for (; m->name != NULL; m++) {
112 if (m->value == value)
118 /* Lookup name in map */
119 static const struct map *
120 map_lookup_name (const struct map *m, const gchar * name)
122 g_return_val_if_fail (m != NULL, NULL);
127 for (; m->name != NULL; m++) {
128 if (strcmp (m->name, name) == 0)
134 /** Returns a relative score for the supplied GstVaapiProfile */
136 gst_vaapi_utils_h265_get_profile_score (GstVaapiProfile profile)
138 const struct map *const m =
139 map_lookup_value (gst_vaapi_h265_profile_map, profile);
141 return m ? 1 + (m - gst_vaapi_h265_profile_map) : 0;
144 /** Returns GstVaapiProfile from H.265 profile_idc value */
146 gst_vaapi_utils_h265_get_profile (GstH265SPS * sps)
148 GstVaapiProfile vaapi_profile;
149 GstH265Profile profile;
151 g_return_val_if_fail (sps != NULL, GST_VAAPI_PROFILE_UNKNOWN);
153 profile = gst_h265_get_profile_from_sps (sps);
155 case GST_H265_PROFILE_MAIN:
156 /* Main Intra, recognize it as MAIN */
157 case GST_H265_PROFILE_MAIN_INTRA:
158 vaapi_profile = GST_VAAPI_PROFILE_H265_MAIN;
160 case GST_H265_PROFILE_MAIN_10:
161 /* Main 10 Intra, recognize it as MAIN10 */
162 case GST_H265_PROFILE_MAIN_10_INTRA:
163 vaapi_profile = GST_VAAPI_PROFILE_H265_MAIN10;
165 case GST_H265_PROFILE_MAIN_12:
166 /* Main 12 Intra, recognize it as MAIN_12 */
167 case GST_H265_PROFILE_MAIN_12_INTRA:
168 vaapi_profile = GST_VAAPI_PROFILE_H265_MAIN12;
170 case GST_H265_PROFILE_MAIN_STILL_PICTURE:
171 vaapi_profile = GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE;
173 case GST_H265_PROFILE_MAIN_422_10:
174 /* Main 422_10 Intra, recognize it as MAIN_422_10 */
175 case GST_H265_PROFILE_MAIN_422_10_INTRA:
176 vaapi_profile = GST_VAAPI_PROFILE_H265_MAIN_422_10;
178 case GST_H265_PROFILE_MAIN_422_12:
179 /* Main 422_12 Intra, recognize it as MAIN_422_12 */
180 case GST_H265_PROFILE_MAIN_422_12_INTRA:
181 vaapi_profile = GST_VAAPI_PROFILE_H265_MAIN_422_12;
183 case GST_H265_PROFILE_MAIN_444:
184 /* Main 444 Intra, recognize it as MAIN_444 */
185 case GST_H265_PROFILE_MAIN_444_INTRA:
186 vaapi_profile = GST_VAAPI_PROFILE_H265_MAIN_444;
188 case GST_H265_PROFILE_MAIN_444_10:
189 /* Main 444_10 Intra, recognize it as MAIN_444_10 */
190 case GST_H265_PROFILE_MAIN_444_10_INTRA:
191 vaapi_profile = GST_VAAPI_PROFILE_H265_MAIN_444_10;
193 case GST_H265_PROFILE_MAIN_444_12:
194 /* Main 444_12 Intra, recognize it as MAIN_444_12 */
195 case GST_H265_PROFILE_MAIN_444_12_INTRA:
196 vaapi_profile = GST_VAAPI_PROFILE_H265_MAIN_444_12;
198 case GST_H265_PROFILE_SCREEN_EXTENDED_MAIN:
199 vaapi_profile = GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN;
201 case GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_10:
202 vaapi_profile = GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10;
204 case GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444:
205 vaapi_profile = GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444;
207 case GST_H265_PROFILE_SCREEN_EXTENDED_MAIN_444_10:
208 vaapi_profile = GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444_10;
211 GST_DEBUG ("unsupported profile_idc value");
212 vaapi_profile = GST_VAAPI_PROFILE_UNKNOWN;
215 return vaapi_profile;
218 /** Returns H.265 profile_idc value from GstVaapiProfile */
220 gst_vaapi_utils_h265_get_profile_idc (GstVaapiProfile profile)
225 case GST_VAAPI_PROFILE_H265_MAIN:
226 profile_idc = GST_H265_PROFILE_IDC_MAIN;
228 case GST_VAAPI_PROFILE_H265_MAIN10:
229 profile_idc = GST_H265_PROFILE_IDC_MAIN_10;
231 case GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE:
232 profile_idc = GST_H265_PROFILE_IDC_MAIN_STILL_PICTURE;
234 case GST_VAAPI_PROFILE_H265_MAIN_422_10:
236 case GST_VAAPI_PROFILE_H265_MAIN_444:
238 case GST_VAAPI_PROFILE_H265_MAIN_444_10:
240 case GST_VAAPI_PROFILE_H265_MAIN12:
241 profile_idc = GST_H265_PROFILE_IDC_FORMAT_RANGE_EXTENSION;
243 case GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN:
245 case GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_10:
247 case GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444:
249 case GST_VAAPI_PROFILE_H265_SCREEN_EXTENDED_MAIN_444_10:
250 profile_idc = GST_H265_PROFILE_IDC_SCREEN_CONTENT_CODING;
253 GST_DEBUG ("unsupported GstVaapiProfile value");
260 /** Returns GstVaapiProfile from a string representation */
262 gst_vaapi_utils_h265_get_profile_from_string (const gchar * str)
264 const struct map *const m = map_lookup_name (gst_vaapi_h265_profile_map, str);
266 return m ? (GstVaapiProfile) m->value : GST_VAAPI_PROFILE_UNKNOWN;
269 /** Returns a string representation for the supplied H.265 profile */
271 gst_vaapi_utils_h265_get_profile_string (GstVaapiProfile profile)
273 const struct map *const m =
274 map_lookup_value (gst_vaapi_h265_profile_map, profile);
276 return m ? m->name : NULL;
279 /** Returns GstVaapiLevelH265 from H.265 level_idc value */
281 gst_vaapi_utils_h265_get_level (guint8 level_idc)
283 const GstVaapiH265LevelLimits *llp;
285 for (llp = gst_vaapi_h265_level_limits; llp->level != 0; llp++) {
286 if (llp->level_idc == level_idc)
289 GST_DEBUG ("unsupported level_idc value");
290 return (GstVaapiLevelH265) 0;
293 /** Returns H.265 level_idc value from GstVaapiLevelH265 */
295 gst_vaapi_utils_h265_get_level_idc (GstVaapiLevelH265 level)
297 const GstVaapiH265LevelLimits *const llp =
298 gst_vaapi_utils_h265_get_level_limits (level);
300 return llp ? llp->level_idc : 0;
303 /** Returns GstVaapiLevelH265 from a string representation */
305 gst_vaapi_utils_h265_get_level_from_string (const gchar * str)
307 gint v, level_idc = 0;
312 v = g_ascii_digit_value (str[0]);
321 v = g_ascii_digit_value (str[2]);
322 if (v < 0 || str[3] != '\0')
329 return gst_vaapi_utils_h265_get_level (level_idc);
332 return (GstVaapiLevelH265) 0;
335 /** Returns a string representation for the supplied H.265 level */
337 gst_vaapi_utils_h265_get_level_string (GstVaapiLevelH265 level)
339 if (level < GST_VAAPI_LEVEL_H265_L1 || level > GST_VAAPI_LEVEL_H265_L6_2)
341 return gst_vaapi_h265_level_map[level - GST_VAAPI_LEVEL_H265_L1].name;
344 /** Returns level limits as specified in Table A-1 of the H.265 standard */
345 const GstVaapiH265LevelLimits *
346 gst_vaapi_utils_h265_get_level_limits (GstVaapiLevelH265 level)
348 if (level < GST_VAAPI_LEVEL_H265_L1 || level > GST_VAAPI_LEVEL_H265_L6_2)
350 return &gst_vaapi_h265_level_limits[level - GST_VAAPI_LEVEL_H265_L1];
353 /** Returns the Table A-1 & A-2 specification */
354 const GstVaapiH265LevelLimits *
355 gst_vaapi_utils_h265_get_level_limits_table (guint * out_length_ptr)
358 *out_length_ptr = G_N_ELEMENTS (gst_vaapi_h265_level_limits) - 1;
359 return gst_vaapi_h265_level_limits;
362 /** Returns GstVaapiChromaType from H.265 chroma_format_idc value */
364 gst_vaapi_utils_h265_get_chroma_type (guint chroma_format_idc,
365 guint luma_bit_depth, guint chroma_bit_depth)
367 GstVaapiChromaType chroma_type = (GstVaapiChromaType) 0;
370 if (luma_bit_depth < 8 || chroma_bit_depth < 8 ||
371 luma_bit_depth > 16 || chroma_bit_depth > 16) {
372 GST_WARNING ("invalid luma_bit_depth or chroma_bit_depth value");
376 depth = MAX (luma_bit_depth, chroma_bit_depth);
378 switch (chroma_format_idc) {
380 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV400;
384 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
385 else if (depth > 8 && depth <= 10)
386 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420_10BPP;
387 else if (depth > 10 && depth <= 12)
388 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420_12BPP;
392 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422;
393 else if (depth > 8 && depth <= 10)
394 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422_10BPP;
395 else if (depth > 10 && depth <= 12)
396 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422_12BPP;
400 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444;
401 else if (depth > 8 && depth <= 10)
402 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444_10BPP;
403 else if (depth > 10 && depth <= 12)
404 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444_12BPP;
410 if (chroma_type == (GstVaapiChromaType) 0)
411 GST_DEBUG ("unsupported chroma_format_idc value");
416 /** Returns H.265 chroma_format_idc value from GstVaapiChromaType */
418 gst_vaapi_utils_h265_get_chroma_format_idc (GstVaapiChromaType chroma_type)
420 guint chroma_format_idc;
422 switch (chroma_type) {
423 case GST_VAAPI_CHROMA_TYPE_YUV400:
424 chroma_format_idc = 0;
426 case GST_VAAPI_CHROMA_TYPE_YUV420:
427 case GST_VAAPI_CHROMA_TYPE_YUV420_10BPP:
428 case GST_VAAPI_CHROMA_TYPE_YUV420_12BPP:
429 chroma_format_idc = 1;
431 case GST_VAAPI_CHROMA_TYPE_YUV422:
432 case GST_VAAPI_CHROMA_TYPE_YUV422_10BPP:
433 case GST_VAAPI_CHROMA_TYPE_YUV422_12BPP:
434 chroma_format_idc = 2;
436 case GST_VAAPI_CHROMA_TYPE_YUV444:
437 case GST_VAAPI_CHROMA_TYPE_YUV444_10BPP:
438 case GST_VAAPI_CHROMA_TYPE_YUV444_12BPP:
439 chroma_format_idc = 3;
442 GST_DEBUG ("unsupported GstVaapiChromaType value");
443 chroma_format_idc = 1;
446 return chroma_format_idc;
449 /** Returns GstVaapiTierH265 from a string representation */
451 gst_vaapi_utils_h265_get_tier_from_string (const gchar * str)
453 const struct map *const m = map_lookup_name (gst_vaapi_h265_tier_map, str);
455 return m ? (GstVaapiTierH265) m->value : GST_VAAPI_TIER_H265_UNKNOWN;
458 /** Returns a string representation for the supplied H.265 tier */
460 gst_vaapi_utils_h265_get_tier_string (GstVaapiTierH265 tier)
462 const struct map *const m = map_lookup_value (gst_vaapi_h265_tier_map, tier);
464 return m ? m->name : NULL;