~ubuntu-branches/ubuntu/vivid/gstreamer-vaapi/vivid

« back to all changes in this revision

Viewing changes to gst-libs/gst/vaapi/gstvaapiutils_h264.c

  • Committer: Package Import Robot
  • Author(s): Vincent Cheng
  • Date: 2014-08-06 23:56:00 UTC
  • mfrom: (0.1.4 sid) (1.1.3)
  • Revision ID: package-import@ubuntu.com-20140806235600-fg1kcmiu67k315q5
Tags: 0.5.9-2
* Remove spurious build-deps: libva-drm1, libavcodec-dev. (Closes: #757283)
* Drop Build-Depends-Indep and build docs unconditionally on all archs.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  gstvaapiutils_h264.c - H.264 related utilities
 
3
 *
 
4
 *  Copyright (C) 2011-2014 Intel Corporation
 
5
 *    Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
 
6
 *
 
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.
 
11
 *
 
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.
 
16
 *
 
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
 
21
 */
 
22
 
 
23
#include "sysdeps.h"
 
24
#include <gst/codecparsers/gsth264parser.h>
 
25
#include "gstvaapiutils_h264_priv.h"
 
26
 
 
27
struct map
 
28
{
 
29
  guint value;
 
30
  const gchar *name;
 
31
};
 
32
 
 
33
/* Profile string map */
 
34
static const struct map gst_vaapi_h264_profile_map[] = {
 
35
/* *INDENT-OFF* */
 
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"          },
 
48
  { 0, NULL }
 
49
/* *INDENT-ON* */
 
50
};
 
51
 
 
52
/* Level string map */
 
53
static const struct map gst_vaapi_h264_level_map[] = {
 
54
/* *INDENT-OFF* */
 
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"   },
 
72
  { 0, NULL }
 
73
/* *INDENT-ON* */
 
74
};
 
75
 
 
76
/* Table A-1 - Level limits */
 
77
/* *INDENT-OFF* */
 
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 },
 
97
  { 0, }
 
98
};
 
99
/* *INDENT-ON* */
 
100
 
 
101
/* Lookup value in map */
 
102
static const struct map *
 
103
map_lookup_value (const struct map *m, guint value)
 
104
{
 
105
  g_return_val_if_fail (m != NULL, NULL);
 
106
 
 
107
  for (; m->name != NULL; m++) {
 
108
    if (m->value == value)
 
109
      return m;
 
110
  }
 
111
  return NULL;
 
112
}
 
113
 
 
114
/* Lookup name in map */
 
115
static const struct map *
 
116
map_lookup_name (const struct map *m, const gchar * name)
 
117
{
 
118
  g_return_val_if_fail (m != NULL, NULL);
 
119
 
 
120
  if (!name)
 
121
    return NULL;
 
122
 
 
123
  for (; m->name != NULL; m++) {
 
124
    if (strcmp (m->name, name) == 0)
 
125
      return m;
 
126
  }
 
127
  return NULL;
 
128
}
 
129
 
 
130
/** Returns a relative score for the supplied GstVaapiProfile */
 
131
guint
 
132
gst_vaapi_utils_h264_get_profile_score (GstVaapiProfile profile)
 
133
{
 
134
  const struct map *const m =
 
135
      map_lookup_value (gst_vaapi_h264_profile_map, profile);
 
136
 
 
137
  return m ? 1 + (m - gst_vaapi_h264_profile_map) : 0;
 
138
}
 
139
 
 
140
/** Returns GstVaapiProfile from H.264 profile_idc value */
 
141
GstVaapiProfile
 
142
gst_vaapi_utils_h264_get_profile (guint8 profile_idc)
 
143
{
 
144
  GstVaapiProfile profile;
 
145
 
 
146
  switch (profile_idc) {
 
147
    case GST_H264_PROFILE_BASELINE:
 
148
      profile = GST_VAAPI_PROFILE_H264_BASELINE;
 
149
      break;
 
150
    case GST_H264_PROFILE_MAIN:
 
151
      profile = GST_VAAPI_PROFILE_H264_MAIN;
 
152
      break;
 
153
    case GST_H264_PROFILE_EXTENDED:
 
154
      profile = GST_VAAPI_PROFILE_H264_EXTENDED;
 
155
      break;
 
156
    case GST_H264_PROFILE_HIGH:
 
157
      profile = GST_VAAPI_PROFILE_H264_HIGH;
 
158
      break;
 
159
    case GST_H264_PROFILE_HIGH10:
 
160
      profile = GST_VAAPI_PROFILE_H264_HIGH10;
 
161
      break;
 
162
    case GST_H264_PROFILE_HIGH_422:
 
163
      profile = GST_VAAPI_PROFILE_H264_HIGH_422;
 
164
      break;
 
165
    case GST_H264_PROFILE_HIGH_444:
 
166
      profile = GST_VAAPI_PROFILE_H264_HIGH_444;
 
167
      break;
 
168
    case GST_H264_PROFILE_SCALABLE_BASELINE:
 
169
      profile = GST_VAAPI_PROFILE_H264_SCALABLE_BASELINE;
 
170
      break;
 
171
    case GST_H264_PROFILE_SCALABLE_HIGH:
 
172
      profile = GST_VAAPI_PROFILE_H264_SCALABLE_HIGH;
 
173
      break;
 
174
    case GST_H264_PROFILE_MULTIVIEW_HIGH:
 
175
      profile = GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH;
 
176
      break;
 
177
    case GST_H264_PROFILE_STEREO_HIGH:
 
178
      profile = GST_VAAPI_PROFILE_H264_STEREO_HIGH;
 
179
      break;
 
180
    default:
 
181
      g_debug ("unsupported profile_idc value");
 
182
      profile = GST_VAAPI_PROFILE_UNKNOWN;
 
183
      break;
 
184
  }
 
185
  return profile;
 
186
}
 
187
 
 
188
/** Returns H.264 profile_idc value from GstVaapiProfile */
 
189
guint8
 
190
gst_vaapi_utils_h264_get_profile_idc (GstVaapiProfile profile)
 
191
{
 
192
  guint8 profile_idc;
 
193
 
 
194
  switch (profile) {
 
195
    case GST_VAAPI_PROFILE_H264_BASELINE:
 
196
    case GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE:
 
197
      profile_idc = GST_H264_PROFILE_BASELINE;
 
198
      break;
 
199
    case GST_VAAPI_PROFILE_H264_MAIN:
 
200
      profile_idc = GST_H264_PROFILE_MAIN;
 
201
      break;
 
202
    case GST_VAAPI_PROFILE_H264_EXTENDED:
 
203
      profile_idc = GST_H264_PROFILE_EXTENDED;
 
204
      break;
 
205
    case GST_VAAPI_PROFILE_H264_HIGH:
 
206
      profile_idc = GST_H264_PROFILE_HIGH;
 
207
      break;
 
208
    case GST_VAAPI_PROFILE_H264_HIGH10:
 
209
      profile_idc = GST_H264_PROFILE_HIGH10;
 
210
      break;
 
211
    case GST_VAAPI_PROFILE_H264_HIGH_422:
 
212
      profile_idc = GST_H264_PROFILE_HIGH_422;
 
213
      break;
 
214
    case GST_VAAPI_PROFILE_H264_HIGH_444:
 
215
      profile_idc = GST_H264_PROFILE_HIGH_444;
 
216
      break;
 
217
    case GST_VAAPI_PROFILE_H264_SCALABLE_BASELINE:
 
218
      profile_idc = GST_H264_PROFILE_SCALABLE_BASELINE;
 
219
      break;
 
220
    case GST_VAAPI_PROFILE_H264_SCALABLE_HIGH:
 
221
      profile_idc = GST_H264_PROFILE_SCALABLE_HIGH;
 
222
      break;
 
223
    case GST_VAAPI_PROFILE_H264_MULTIVIEW_HIGH:
 
224
      profile_idc = GST_H264_PROFILE_MULTIVIEW_HIGH;
 
225
      break;
 
226
    case GST_VAAPI_PROFILE_H264_STEREO_HIGH:
 
227
      profile_idc = GST_H264_PROFILE_STEREO_HIGH;
 
228
      break;
 
229
    default:
 
230
      g_debug ("unsupported GstVaapiProfile value");
 
231
      profile_idc = 0;
 
232
      break;
 
233
  }
 
234
  return profile_idc;
 
235
}
 
236
 
 
237
/** Returns GstVaapiProfile from a string representation */
 
238
GstVaapiProfile
 
239
gst_vaapi_utils_h264_get_profile_from_string (const gchar * str)
 
240
{
 
241
  const struct map *const m = map_lookup_name (gst_vaapi_h264_profile_map, str);
 
242
 
 
243
  return m ? (GstVaapiProfile) m->value : GST_VAAPI_PROFILE_UNKNOWN;
 
244
}
 
245
 
 
246
/** Returns a string representation for the supplied H.264 profile */
 
247
const gchar *
 
248
gst_vaapi_utils_h264_get_profile_string (GstVaapiProfile profile)
 
249
{
 
250
  const struct map *const m =
 
251
      map_lookup_value (gst_vaapi_h264_profile_map, profile);
 
252
 
 
253
  return m ? m->name : NULL;
 
254
}
 
255
 
 
256
/** Returns GstVaapiLevelH264 from H.264 level_idc value */
 
257
GstVaapiLevelH264
 
258
gst_vaapi_utils_h264_get_level (guint8 level_idc)
 
259
{
 
260
  const GstVaapiH264LevelLimits *llp;
 
261
 
 
262
  // Prefer Level 1.1 over level 1b
 
263
  if (G_UNLIKELY (level_idc == 11))
 
264
    return GST_VAAPI_LEVEL_H264_L1_1;
 
265
 
 
266
  for (llp = gst_vaapi_h264_level_limits; llp->level != 0; llp++) {
 
267
    if (llp->level_idc == level_idc)
 
268
      return llp->level;
 
269
  }
 
270
  g_debug ("unsupported level_idc value");
 
271
  return (GstVaapiLevelH264) 0;
 
272
}
 
273
 
 
274
/** Returns H.264 level_idc value from GstVaapiLevelH264 */
 
275
guint8
 
276
gst_vaapi_utils_h264_get_level_idc (GstVaapiLevelH264 level)
 
277
{
 
278
  const GstVaapiH264LevelLimits *const llp =
 
279
      gst_vaapi_utils_h264_get_level_limits (level);
 
280
 
 
281
  return llp ? llp->level_idc : 0;
 
282
}
 
283
 
 
284
/** Returns GstVaapiLevelH264 from a string representation */
 
285
GstVaapiLevelH264
 
286
gst_vaapi_utils_h264_get_level_from_string (const gchar * str)
 
287
{
 
288
  gint v, level_idc = 0;
 
289
 
 
290
  if (!str || !str[0])
 
291
    goto not_found;
 
292
 
 
293
  v = g_ascii_digit_value (str[0]);
 
294
  if (v < 0)
 
295
    goto not_found;
 
296
  level_idc = v * 10;
 
297
 
 
298
  switch (str[1]) {
 
299
    case '\0':
 
300
      break;
 
301
    case '.':
 
302
      v = g_ascii_digit_value (str[2]);
 
303
      if (v < 0 || str[3] != '\0')
 
304
        goto not_found;
 
305
      level_idc += v;
 
306
      break;
 
307
    case 'b':
 
308
      if (level_idc == 10 && str[2] == '\0')
 
309
        return GST_VAAPI_LEVEL_H264_L1b;
 
310
      // fall-trough
 
311
    default:
 
312
      goto not_found;
 
313
  }
 
314
  return gst_vaapi_utils_h264_get_level (level_idc);
 
315
 
 
316
not_found:
 
317
  return (GstVaapiLevelH264) 0;
 
318
}
 
319
 
 
320
/** Returns a string representation for the supplied H.264 level */
 
321
const gchar *
 
322
gst_vaapi_utils_h264_get_level_string (GstVaapiLevelH264 level)
 
323
{
 
324
  if (level < GST_VAAPI_LEVEL_H264_L1 || level > GST_VAAPI_LEVEL_H264_L5_2)
 
325
    return NULL;
 
326
  return gst_vaapi_h264_level_map[level - GST_VAAPI_LEVEL_H264_L1].name;
 
327
}
 
328
 
 
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)
 
332
{
 
333
  if (level < GST_VAAPI_LEVEL_H264_L1 || level > GST_VAAPI_LEVEL_H264_L5_2)
 
334
    return NULL;
 
335
  return &gst_vaapi_h264_level_limits[level - GST_VAAPI_LEVEL_H264_L1];
 
336
}
 
337
 
 
338
/** Returns the Table A-1 specification */
 
339
const GstVaapiH264LevelLimits *
 
340
gst_vaapi_utils_h264_get_level_limits_table (guint * out_length_ptr)
 
341
{
 
342
  if (out_length_ptr)
 
343
    *out_length_ptr = G_N_ELEMENTS (gst_vaapi_h264_level_limits) - 1;
 
344
  return gst_vaapi_h264_level_limits;
 
345
}
 
346
 
 
347
/** Returns GstVaapiChromaType from H.264 chroma_format_idc value */
 
348
GstVaapiChromaType
 
349
gst_vaapi_utils_h264_get_chroma_type (guint chroma_format_idc)
 
350
{
 
351
  GstVaapiChromaType chroma_type;
 
352
 
 
353
  switch (chroma_format_idc) {
 
354
    case 0:
 
355
      chroma_type = GST_VAAPI_CHROMA_TYPE_YUV400;
 
356
      break;
 
357
    case 1:
 
358
      chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
 
359
      break;
 
360
    case 2:
 
361
      chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422;
 
362
      break;
 
363
    case 3:
 
364
      chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444;
 
365
      break;
 
366
    default:
 
367
      g_debug ("unsupported chroma_format_idc value");
 
368
      chroma_type = (GstVaapiChromaType) 0;
 
369
      break;
 
370
  }
 
371
  return chroma_type;
 
372
}
 
373
 
 
374
/** Returns H.264 chroma_format_idc value from GstVaapiChromaType */
 
375
guint
 
376
gst_vaapi_utils_h264_get_chroma_format_idc (GstVaapiChromaType chroma_type)
 
377
{
 
378
  guint chroma_format_idc;
 
379
 
 
380
  switch (chroma_type) {
 
381
    case GST_VAAPI_CHROMA_TYPE_YUV400:
 
382
      chroma_format_idc = 0;
 
383
      break;
 
384
    case GST_VAAPI_CHROMA_TYPE_YUV420:
 
385
      chroma_format_idc = 1;
 
386
      break;
 
387
    case GST_VAAPI_CHROMA_TYPE_YUV422:
 
388
      chroma_format_idc = 2;
 
389
      break;
 
390
    case GST_VAAPI_CHROMA_TYPE_YUV444:
 
391
      chroma_format_idc = 3;
 
392
      break;
 
393
    default:
 
394
      g_debug ("unsupported GstVaapiChromaType value");
 
395
      chroma_format_idc = 1;
 
396
      break;
 
397
  }
 
398
  return chroma_format_idc;
 
399
}