2
* gstvaapiutils_h264.c - H.264 related utilities
4
* Copyright (C) 2011-2014 Intel Corporation
5
* Author: Gwenole Beauchesne <gwenole.beauchesne@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/gsth264parser.h>
25
#include "gstvaapiutils_h264_priv.h"
33
/* Profile string map */
34
static const struct map gst_vaapi_h264_profile_map[] = {
36
{ GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE, "constrained-baseline" },
37
{ GST_VAAPI_PROFILE_H264_BASELINE, "baseline" },
38
{ GST_VAAPI_PROFILE_H264_MAIN, "main" },
39
{ GST_VAAPI_PROFILE_H264_EXTENDED, "extended" },
40
{ GST_VAAPI_PROFILE_H264_HIGH, "high" },
41
{ GST_VAAPI_PROFILE_H264_HIGH10, "high-10" },
42
{ GST_VAAPI_PROFILE_H264_HIGH_422, "high-4:2:2" },
43
{ GST_VAAPI_PROFILE_H264_HIGH_444, "high-4:4:4" },
44
{ GST_VAAPI_PROFILE_H264_SCALABLE_BASELINE, "scalable-baseline" },
45
{ GST_VAAPI_PROFILE_H264_SCALABLE_HIGH, "scalable-high" },
46
{ GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH, "multiview-high" },
47
{ GST_VAAPI_PROFILE_H264_STEREO_HIGH, "stereo-high" },
52
/* Level string map */
53
static const struct map gst_vaapi_h264_level_map[] = {
55
{ GST_VAAPI_LEVEL_H264_L1, "1" },
56
{ GST_VAAPI_LEVEL_H264_L1b, "1b" },
57
{ GST_VAAPI_LEVEL_H264_L1_1, "1.1" },
58
{ GST_VAAPI_LEVEL_H264_L1_2, "1.2" },
59
{ GST_VAAPI_LEVEL_H264_L1_3, "1.3" },
60
{ GST_VAAPI_LEVEL_H264_L2, "2" },
61
{ GST_VAAPI_LEVEL_H264_L2_1, "2.1" },
62
{ GST_VAAPI_LEVEL_H264_L2_2, "2.2" },
63
{ GST_VAAPI_LEVEL_H264_L3, "3" },
64
{ GST_VAAPI_LEVEL_H264_L3_1, "3.1" },
65
{ GST_VAAPI_LEVEL_H264_L3_2, "3.2" },
66
{ GST_VAAPI_LEVEL_H264_L4, "4" },
67
{ GST_VAAPI_LEVEL_H264_L4_1, "4.1" },
68
{ GST_VAAPI_LEVEL_H264_L4_2, "4.2" },
69
{ GST_VAAPI_LEVEL_H264_L5, "5" },
70
{ GST_VAAPI_LEVEL_H264_L5_1, "5.1" },
71
{ GST_VAAPI_LEVEL_H264_L5_2, "5.2" },
76
/* Table A-1 - Level limits */
78
static const GstVaapiH264LevelLimits gst_vaapi_h264_level_limits[] = {
79
/* level idc MaxMBPS MaxFS MaxDpbMbs MaxBR MaxCPB */
80
{ GST_VAAPI_LEVEL_H264_L1, 10, 1485, 99, 396, 64, 175 },
81
{ GST_VAAPI_LEVEL_H264_L1b, 11, 1485, 99, 396, 128, 350 },
82
{ GST_VAAPI_LEVEL_H264_L1_1, 11, 3000, 396, 900, 192, 500 },
83
{ GST_VAAPI_LEVEL_H264_L1_2, 12, 6000, 396, 2376, 384, 1000 },
84
{ GST_VAAPI_LEVEL_H264_L1_3, 13, 11880, 396, 2376, 768, 2000 },
85
{ GST_VAAPI_LEVEL_H264_L2, 20, 11880, 396, 2376, 2000, 2000 },
86
{ GST_VAAPI_LEVEL_H264_L2_1, 21, 19800, 792, 4752, 4000, 4000 },
87
{ GST_VAAPI_LEVEL_H264_L2_2, 22, 20250, 1620, 8100, 4000, 4000 },
88
{ GST_VAAPI_LEVEL_H264_L3, 30, 40500, 1620, 8100, 10000, 10000 },
89
{ GST_VAAPI_LEVEL_H264_L3_1, 31, 108000, 3600, 18000, 14000, 14000 },
90
{ GST_VAAPI_LEVEL_H264_L3_2, 32, 216000, 5120, 20480, 20000, 20000 },
91
{ GST_VAAPI_LEVEL_H264_L4, 40, 245760, 8192, 32768, 20000, 25000 },
92
{ GST_VAAPI_LEVEL_H264_L4_1, 41, 245760, 8192, 32768, 50000, 62500 },
93
{ GST_VAAPI_LEVEL_H264_L4_2, 42, 522240, 8704, 34816, 50000, 62500 },
94
{ GST_VAAPI_LEVEL_H264_L5, 50, 589824, 22080, 110400, 135000, 135000 },
95
{ GST_VAAPI_LEVEL_H264_L5_1, 51, 983040, 36864, 184320, 240000, 240000 },
96
{ GST_VAAPI_LEVEL_H264_L5_2, 52, 2073600, 36864, 184320, 240000, 240000 },
101
/* Lookup value in map */
102
static const struct map *
103
map_lookup_value (const struct map *m, guint value)
105
g_return_val_if_fail (m != NULL, NULL);
107
for (; m->name != NULL; m++) {
108
if (m->value == value)
114
/* Lookup name in map */
115
static const struct map *
116
map_lookup_name (const struct map *m, const gchar * name)
118
g_return_val_if_fail (m != NULL, NULL);
123
for (; m->name != NULL; m++) {
124
if (strcmp (m->name, name) == 0)
130
/** Returns a relative score for the supplied GstVaapiProfile */
132
gst_vaapi_utils_h264_get_profile_score (GstVaapiProfile profile)
134
const struct map *const m =
135
map_lookup_value (gst_vaapi_h264_profile_map, profile);
137
return m ? 1 + (m - gst_vaapi_h264_profile_map) : 0;
140
/** Returns GstVaapiProfile from H.264 profile_idc value */
142
gst_vaapi_utils_h264_get_profile (guint8 profile_idc)
144
GstVaapiProfile profile;
146
switch (profile_idc) {
147
case GST_H264_PROFILE_BASELINE:
148
profile = GST_VAAPI_PROFILE_H264_BASELINE;
150
case GST_H264_PROFILE_MAIN:
151
profile = GST_VAAPI_PROFILE_H264_MAIN;
153
case GST_H264_PROFILE_EXTENDED:
154
profile = GST_VAAPI_PROFILE_H264_EXTENDED;
156
case GST_H264_PROFILE_HIGH:
157
profile = GST_VAAPI_PROFILE_H264_HIGH;
159
case GST_H264_PROFILE_HIGH10:
160
profile = GST_VAAPI_PROFILE_H264_HIGH10;
162
case GST_H264_PROFILE_HIGH_422:
163
profile = GST_VAAPI_PROFILE_H264_HIGH_422;
165
case GST_H264_PROFILE_HIGH_444:
166
profile = GST_VAAPI_PROFILE_H264_HIGH_444;
168
case GST_H264_PROFILE_SCALABLE_BASELINE:
169
profile = GST_VAAPI_PROFILE_H264_SCALABLE_BASELINE;
171
case GST_H264_PROFILE_SCALABLE_HIGH:
172
profile = GST_VAAPI_PROFILE_H264_SCALABLE_HIGH;
174
case GST_H264_PROFILE_MULTIVIEW_HIGH:
175
profile = GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH;
177
case GST_H264_PROFILE_STEREO_HIGH:
178
profile = GST_VAAPI_PROFILE_H264_STEREO_HIGH;
181
g_debug ("unsupported profile_idc value");
182
profile = GST_VAAPI_PROFILE_UNKNOWN;
188
/** Returns H.264 profile_idc value from GstVaapiProfile */
190
gst_vaapi_utils_h264_get_profile_idc (GstVaapiProfile profile)
195
case GST_VAAPI_PROFILE_H264_BASELINE:
196
case GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE:
197
profile_idc = GST_H264_PROFILE_BASELINE;
199
case GST_VAAPI_PROFILE_H264_MAIN:
200
profile_idc = GST_H264_PROFILE_MAIN;
202
case GST_VAAPI_PROFILE_H264_EXTENDED:
203
profile_idc = GST_H264_PROFILE_EXTENDED;
205
case GST_VAAPI_PROFILE_H264_HIGH:
206
profile_idc = GST_H264_PROFILE_HIGH;
208
case GST_VAAPI_PROFILE_H264_HIGH10:
209
profile_idc = GST_H264_PROFILE_HIGH10;
211
case GST_VAAPI_PROFILE_H264_HIGH_422:
212
profile_idc = GST_H264_PROFILE_HIGH_422;
214
case GST_VAAPI_PROFILE_H264_HIGH_444:
215
profile_idc = GST_H264_PROFILE_HIGH_444;
217
case GST_VAAPI_PROFILE_H264_SCALABLE_BASELINE:
218
profile_idc = GST_H264_PROFILE_SCALABLE_BASELINE;
220
case GST_VAAPI_PROFILE_H264_SCALABLE_HIGH:
221
profile_idc = GST_H264_PROFILE_SCALABLE_HIGH;
223
case GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH:
224
profile_idc = GST_H264_PROFILE_MULTIVIEW_HIGH;
226
case GST_VAAPI_PROFILE_H264_STEREO_HIGH:
227
profile_idc = GST_H264_PROFILE_STEREO_HIGH;
230
g_debug ("unsupported GstVaapiProfile value");
237
/** Returns GstVaapiProfile from a string representation */
239
gst_vaapi_utils_h264_get_profile_from_string (const gchar * str)
241
const struct map *const m = map_lookup_name (gst_vaapi_h264_profile_map, str);
243
return m ? (GstVaapiProfile) m->value : GST_VAAPI_PROFILE_UNKNOWN;
246
/** Returns a string representation for the supplied H.264 profile */
248
gst_vaapi_utils_h264_get_profile_string (GstVaapiProfile profile)
250
const struct map *const m =
251
map_lookup_value (gst_vaapi_h264_profile_map, profile);
253
return m ? m->name : NULL;
256
/** Returns GstVaapiLevelH264 from H.264 level_idc value */
258
gst_vaapi_utils_h264_get_level (guint8 level_idc)
260
const GstVaapiH264LevelLimits *llp;
262
// Prefer Level 1.1 over level 1b
263
if (G_UNLIKELY (level_idc == 11))
264
return GST_VAAPI_LEVEL_H264_L1_1;
266
for (llp = gst_vaapi_h264_level_limits; llp->level != 0; llp++) {
267
if (llp->level_idc == level_idc)
270
g_debug ("unsupported level_idc value");
271
return (GstVaapiLevelH264) 0;
274
/** Returns H.264 level_idc value from GstVaapiLevelH264 */
276
gst_vaapi_utils_h264_get_level_idc (GstVaapiLevelH264 level)
278
const GstVaapiH264LevelLimits *const llp =
279
gst_vaapi_utils_h264_get_level_limits (level);
281
return llp ? llp->level_idc : 0;
284
/** Returns GstVaapiLevelH264 from a string representation */
286
gst_vaapi_utils_h264_get_level_from_string (const gchar * str)
288
gint v, level_idc = 0;
293
v = g_ascii_digit_value (str[0]);
302
v = g_ascii_digit_value (str[2]);
303
if (v < 0 || str[3] != '\0')
308
if (level_idc == 10 && str[2] == '\0')
309
return GST_VAAPI_LEVEL_H264_L1b;
314
return gst_vaapi_utils_h264_get_level (level_idc);
317
return (GstVaapiLevelH264) 0;
320
/** Returns a string representation for the supplied H.264 level */
322
gst_vaapi_utils_h264_get_level_string (GstVaapiLevelH264 level)
324
if (level < GST_VAAPI_LEVEL_H264_L1 || level > GST_VAAPI_LEVEL_H264_L5_2)
326
return gst_vaapi_h264_level_map[level - GST_VAAPI_LEVEL_H264_L1].name;
329
/** Returns level limits as specified in Table A-1 of the H.264 standard */
330
const GstVaapiH264LevelLimits *
331
gst_vaapi_utils_h264_get_level_limits (GstVaapiLevelH264 level)
333
if (level < GST_VAAPI_LEVEL_H264_L1 || level > GST_VAAPI_LEVEL_H264_L5_2)
335
return &gst_vaapi_h264_level_limits[level - GST_VAAPI_LEVEL_H264_L1];
338
/** Returns the Table A-1 specification */
339
const GstVaapiH264LevelLimits *
340
gst_vaapi_utils_h264_get_level_limits_table (guint * out_length_ptr)
343
*out_length_ptr = G_N_ELEMENTS (gst_vaapi_h264_level_limits) - 1;
344
return gst_vaapi_h264_level_limits;
347
/** Returns GstVaapiChromaType from H.264 chroma_format_idc value */
349
gst_vaapi_utils_h264_get_chroma_type (guint chroma_format_idc)
351
GstVaapiChromaType chroma_type;
353
switch (chroma_format_idc) {
355
chroma_type = GST_VAAPI_CHROMA_TYPE_YUV400;
358
chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
361
chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422;
364
chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444;
367
g_debug ("unsupported chroma_format_idc value");
368
chroma_type = (GstVaapiChromaType) 0;
374
/** Returns H.264 chroma_format_idc value from GstVaapiChromaType */
376
gst_vaapi_utils_h264_get_chroma_format_idc (GstVaapiChromaType chroma_type)
378
guint chroma_format_idc;
380
switch (chroma_type) {
381
case GST_VAAPI_CHROMA_TYPE_YUV400:
382
chroma_format_idc = 0;
384
case GST_VAAPI_CHROMA_TYPE_YUV420:
385
chroma_format_idc = 1;
387
case GST_VAAPI_CHROMA_TYPE_YUV422:
388
chroma_format_idc = 2;
390
case GST_VAAPI_CHROMA_TYPE_YUV444:
391
chroma_format_idc = 3;
394
g_debug ("unsupported GstVaapiChromaType value");
395
chroma_format_idc = 1;
398
return chroma_format_idc;