1 /* Gstreamer
2 * Copyright (C) <2011> Intel Corporation
3 * Copyright (C) <2011> Collabora Ltd.
4 * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
5 *
6 * Some bits C-c,C-v'ed and s/4/3 from h264parse and videoparsers/h264parse.c:
7 * Copyright (C) <2010> Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
8 * Copyright (C) <2010> Collabora Multimedia
9 * Copyright (C) <2010> Nokia Corporation
10 *
11 * (C) 2005 Michal Benes <michal.benes@itonis.tv>
12 * (C) 2008 Wim Taymans <wim.taymans@gmail.com>
13 *
14 * This library is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU Library General Public
16 * License as published by the Free Software Foundation; either
17 * version 2 of the License, or (at your option) any later version.
18 *
19 * This library is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * Library General Public License for more details.
23 *
24 * You should have received a copy of the GNU Library General Public
25 * License along with this library; if not, write to the
26 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
27 * Boston, MA 02110-1301, USA.
28 */
29
30 /**
31 * SECTION:gsth264parser
32 * @title: GstH264Parser
33 * @short_description: Convenience library for h264 video
34 * bitstream parsing.
35 *
36 * It offers bitstream parsing in both AVC (length-prefixed) and Annex B
37 * (0x000001 start code prefix) format. To identify a NAL unit in a bitstream
38 * and parse its headers, first call:
39 *
40 * * #gst_h264_parser_identify_nalu to identify a NAL unit in an Annex B type bitstream
41 *
42 * * #gst_h264_parser_identify_nalu_avc to identify a NAL unit in an AVC type bitstream
43 *
44 * The following functions are then available for parsing the structure of the
45 * #GstH264NalUnit, depending on the #GstH264NalUnitType:
46 *
47 * * From #GST_H264_NAL_SLICE to #GST_H264_NAL_SLICE_IDR: #gst_h264_parser_parse_slice_hdr
48 *
49 * * #GST_H264_NAL_SEI: #gst_h264_parser_parse_sei
50 *
51 * * #GST_H264_NAL_SPS: #gst_h264_parser_parse_sps
52 *
53 * * #GST_H264_NAL_PPS: #gst_h264_parser_parse_pps
54 *
55 * * Any other: #gst_h264_parser_parse_nal
56 *
57 * One of these functions *must* be called on every NAL unit in the bitstream,
58 * in order to keep the internal structures of the #GstH264NalParser up to
59 * date. It is legal to call #gst_h264_parser_parse_nal on NAL units of any
60 * type, if no special parsing of the current NAL unit is required by the
61 * application.
62 *
63 * For more details about the structures, look at the ITU-T H.264 and ISO/IEC 14496-10 – MPEG-4
64 * Part 10 specifications, available at:
65 *
66 * * ITU-T H.264: http://www.itu.int/rec/T-REC-H.264
67 *
68 * * ISO/IEC 14496-10: http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=56538
69 *
70 */
71
72 #ifdef HAVE_CONFIG_H
73 # include "config.h"
74 #endif
75
76 #include "nalutils.h"
77 #include "gsth264parser.h"
78
79 #include <gst/base/gstbytereader.h>
80 #include <gst/base/gstbitreader.h>
81 #include <string.h>
82
83 #ifndef GST_DISABLE_GST_DEBUG
84 #define GST_CAT_DEFAULT gst_h264_debug_category_get()
85 static GstDebugCategory *
gst_h264_debug_category_get(void)86 gst_h264_debug_category_get (void)
87 {
88 static gsize cat_gonce = 0;
89
90 if (g_once_init_enter (&cat_gonce)) {
91 GstDebugCategory *cat = NULL;
92
93 GST_DEBUG_CATEGORY_INIT (cat, "codecparsers_h264", 0, "h264 parse library");
94
95 g_once_init_leave (&cat_gonce, (gsize) cat);
96 }
97
98 return (GstDebugCategory *) cat_gonce;
99 }
100 #endif /* GST_DISABLE_GST_DEBUG */
101
102 /**** Default scaling_lists according to Table 7-2 *****/
103 static const guint8 default_4x4_intra[16] = {
104 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32,
105 32, 37, 37, 42
106 };
107
108 static const guint8 default_4x4_inter[16] = {
109 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27,
110 27, 30, 30, 34
111 };
112
113 static const guint8 default_8x8_intra[64] = {
114 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18,
115 18, 18, 18, 23, 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27,
116 27, 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31, 31, 33,
117 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42
118 };
119
120 static const guint8 default_8x8_inter[64] = {
121 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19,
122 19, 19, 19, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24,
123 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 28,
124 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35
125 };
126
127 static const guint8 zigzag_8x8[64] = {
128 0, 1, 8, 16, 9, 2, 3, 10,
129 17, 24, 32, 25, 18, 11, 4, 5,
130 12, 19, 26, 33, 40, 48, 41, 34,
131 27, 20, 13, 6, 7, 14, 21, 28,
132 35, 42, 49, 56, 57, 50, 43, 36,
133 29, 22, 15, 23, 30, 37, 44, 51,
134 58, 59, 52, 45, 38, 31, 39, 46,
135 53, 60, 61, 54, 47, 55, 62, 63
136 };
137
138 static const guint8 zigzag_4x4[16] = {
139 0, 1, 4, 8,
140 5, 2, 3, 6,
141 9, 12, 13, 10,
142 7, 11, 14, 15,
143 };
144
145 typedef struct
146 {
147 guint par_n, par_d;
148 } PAR;
149
150 /* Table E-1 - Meaning of sample aspect ratio indicator (1..16) */
151 static const PAR aspect_ratios[17] = {
152 {0, 0},
153 {1, 1},
154 {12, 11},
155 {10, 11},
156 {16, 11},
157 {40, 33},
158 {24, 11},
159 {20, 11},
160 {32, 11},
161 {80, 33},
162 {18, 11},
163 {15, 11},
164 {64, 33},
165 {160, 99},
166 {4, 3},
167 {3, 2},
168 {2, 1}
169 };
170
171 /***** Utils ****/
172 #define EXTENDED_SAR 255
173
174 static GstH264SPS *
gst_h264_parser_get_sps(GstH264NalParser * nalparser,guint8 sps_id)175 gst_h264_parser_get_sps (GstH264NalParser * nalparser, guint8 sps_id)
176 {
177 GstH264SPS *sps;
178
179 sps = &nalparser->sps[sps_id];
180
181 if (sps->valid)
182 return sps;
183
184 return NULL;
185 }
186
187 static GstH264PPS *
gst_h264_parser_get_pps(GstH264NalParser * nalparser,guint8 pps_id)188 gst_h264_parser_get_pps (GstH264NalParser * nalparser, guint8 pps_id)
189 {
190 GstH264PPS *pps;
191
192 pps = &nalparser->pps[pps_id];
193
194 if (pps->valid)
195 return pps;
196
197 return NULL;
198 }
199
200 static gboolean
gst_h264_parse_nalu_header(GstH264NalUnit * nalu)201 gst_h264_parse_nalu_header (GstH264NalUnit * nalu)
202 {
203 guint8 *data = nalu->data + nalu->offset;
204 guint8 svc_extension_flag;
205 GstBitReader br;
206
207 if (nalu->size < 1)
208 return FALSE;
209
210 nalu->type = (data[0] & 0x1f);
211 nalu->ref_idc = (data[0] & 0x60) >> 5;
212 nalu->idr_pic_flag = (nalu->type == 5 ? 1 : 0);
213 nalu->header_bytes = 1;
214
215 nalu->extension_type = GST_H264_NAL_EXTENSION_NONE;
216
217 switch (nalu->type) {
218 case GST_H264_NAL_PREFIX_UNIT:
219 case GST_H264_NAL_SLICE_EXT:
220 if (nalu->size < 4)
221 return FALSE;
222 gst_bit_reader_init (&br, nalu->data + nalu->offset + nalu->header_bytes,
223 nalu->size - nalu->header_bytes);
224
225 svc_extension_flag = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
226 if (svc_extension_flag) { /* SVC */
227
228 nalu->extension_type = GST_H264_NAL_EXTENSION_SVC;
229
230 } else { /* MVC */
231 GstH264NalUnitExtensionMVC *const mvc = &nalu->extension.mvc;
232
233 nalu->extension_type = GST_H264_NAL_EXTENSION_MVC;
234 mvc->non_idr_flag = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
235 mvc->priority_id = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
236 mvc->view_id = gst_bit_reader_get_bits_uint16_unchecked (&br, 10);
237 mvc->temporal_id = gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
238 mvc->anchor_pic_flag = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
239 mvc->inter_view_flag = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
240
241 /* Update IdrPicFlag (H.7.4.1.1) */
242 nalu->idr_pic_flag = !mvc->non_idr_flag;
243 }
244 nalu->header_bytes += 3;
245 break;
246 default:
247 break;
248 }
249
250 GST_DEBUG ("Nal type %u, ref_idc %u", nalu->type, nalu->ref_idc);
251 return TRUE;
252 }
253
254 /*
255 * gst_h264_pps_copy:
256 * @dst_pps: The destination #GstH264PPS to copy into
257 * @src_pps: The source #GstH264PPS to copy from
258 *
259 * Copies @src_pps into @dst_pps.
260 *
261 * Returns: %TRUE if everything went fine, %FALSE otherwise
262 */
263 static gboolean
gst_h264_pps_copy(GstH264PPS * dst_pps,const GstH264PPS * src_pps)264 gst_h264_pps_copy (GstH264PPS * dst_pps, const GstH264PPS * src_pps)
265 {
266 g_return_val_if_fail (dst_pps != NULL, FALSE);
267 g_return_val_if_fail (src_pps != NULL, FALSE);
268
269 gst_h264_pps_clear (dst_pps);
270
271 *dst_pps = *src_pps;
272
273 if (src_pps->slice_group_id)
274 dst_pps->slice_group_id = g_memdup2 (src_pps->slice_group_id,
275 src_pps->pic_size_in_map_units_minus1 + 1);
276
277 return TRUE;
278 }
279
280 /* Copy MVC-specific data for subset SPS header */
281 static gboolean
gst_h264_sps_mvc_copy(GstH264SPS * dst_sps,const GstH264SPS * src_sps)282 gst_h264_sps_mvc_copy (GstH264SPS * dst_sps, const GstH264SPS * src_sps)
283 {
284 GstH264SPSExtMVC *const dst_mvc = &dst_sps->extension.mvc;
285 const GstH264SPSExtMVC *const src_mvc = &src_sps->extension.mvc;
286 guint i, j, k;
287
288 g_assert (dst_sps->extension_type == GST_H264_NAL_EXTENSION_MVC);
289
290 dst_mvc->num_views_minus1 = src_mvc->num_views_minus1;
291 dst_mvc->view = g_new0 (GstH264SPSExtMVCView, dst_mvc->num_views_minus1 + 1);
292 if (!dst_mvc->view)
293 return FALSE;
294
295 dst_mvc->view[0].view_id = src_mvc->view[0].view_id;
296
297 for (i = 1; i <= dst_mvc->num_views_minus1; i++) {
298 GstH264SPSExtMVCView *const dst_view = &dst_mvc->view[i];
299 const GstH264SPSExtMVCView *const src_view = &src_mvc->view[i];
300
301 dst_view->view_id = src_view->view_id;
302
303 dst_view->num_anchor_refs_l0 = src_view->num_anchor_refs_l0;
304 for (j = 0; j < dst_view->num_anchor_refs_l0; j++)
305 dst_view->anchor_ref_l0[j] = src_view->anchor_ref_l0[j];
306
307 dst_view->num_anchor_refs_l1 = src_view->num_anchor_refs_l1;
308 for (j = 0; j < dst_view->num_anchor_refs_l1; j++)
309 dst_view->anchor_ref_l1[j] = src_view->anchor_ref_l1[j];
310
311 dst_view->num_non_anchor_refs_l0 = src_view->num_non_anchor_refs_l0;
312 for (j = 0; j < dst_view->num_non_anchor_refs_l0; j++)
313 dst_view->non_anchor_ref_l0[j] = src_view->non_anchor_ref_l0[j];
314
315 dst_view->num_non_anchor_refs_l1 = src_view->num_non_anchor_refs_l1;
316 for (j = 0; j < dst_view->num_non_anchor_refs_l1; j++)
317 dst_view->non_anchor_ref_l1[j] = src_view->non_anchor_ref_l1[j];
318 }
319
320 dst_mvc->num_level_values_signalled_minus1 =
321 src_mvc->num_level_values_signalled_minus1;
322 dst_mvc->level_value = g_new0 (GstH264SPSExtMVCLevelValue,
323 dst_mvc->num_level_values_signalled_minus1 + 1);
324 if (!dst_mvc->level_value)
325 return FALSE;
326
327 for (i = 0; i <= dst_mvc->num_level_values_signalled_minus1; i++) {
328 GstH264SPSExtMVCLevelValue *const dst_value = &dst_mvc->level_value[i];
329 const GstH264SPSExtMVCLevelValue *const src_value =
330 &src_mvc->level_value[i];
331
332 dst_value->level_idc = src_value->level_idc;
333
334 dst_value->num_applicable_ops_minus1 = src_value->num_applicable_ops_minus1;
335 dst_value->applicable_op = g_new0 (GstH264SPSExtMVCLevelValueOp,
336 dst_value->num_applicable_ops_minus1 + 1);
337 if (!dst_value->applicable_op)
338 return FALSE;
339
340 for (j = 0; j <= dst_value->num_applicable_ops_minus1; j++) {
341 GstH264SPSExtMVCLevelValueOp *const dst_op = &dst_value->applicable_op[j];
342 const GstH264SPSExtMVCLevelValueOp *const src_op =
343 &src_value->applicable_op[j];
344
345 dst_op->temporal_id = src_op->temporal_id;
346 dst_op->num_target_views_minus1 = src_op->num_target_views_minus1;
347 dst_op->target_view_id =
348 g_new (guint16, dst_op->num_target_views_minus1 + 1);
349 if (!dst_op->target_view_id)
350 return FALSE;
351
352 for (k = 0; k <= dst_op->num_target_views_minus1; k++)
353 dst_op->target_view_id[k] = src_op->target_view_id[k];
354 dst_op->num_views_minus1 = src_op->num_views_minus1;
355 }
356 }
357 return TRUE;
358 }
359
360 /*
361 * gst_h264_sps_copy:
362 * @dst_sps: The destination #GstH264SPS to copy into
363 * @src_sps: The source #GstH264SPS to copy from
364 *
365 * Copies @src_sps into @dst_sps.
366 *
367 * Returns: %TRUE if everything went fine, %FALSE otherwise
368 */
369 static gboolean
gst_h264_sps_copy(GstH264SPS * dst_sps,const GstH264SPS * src_sps)370 gst_h264_sps_copy (GstH264SPS * dst_sps, const GstH264SPS * src_sps)
371 {
372 g_return_val_if_fail (dst_sps != NULL, FALSE);
373 g_return_val_if_fail (src_sps != NULL, FALSE);
374
375 gst_h264_sps_clear (dst_sps);
376
377 *dst_sps = *src_sps;
378
379 switch (dst_sps->extension_type) {
380 case GST_H264_NAL_EXTENSION_MVC:
381 if (!gst_h264_sps_mvc_copy (dst_sps, src_sps))
382 return FALSE;
383 break;
384 }
385 return TRUE;
386 }
387
388 /****** Parsing functions *****/
389
390 static gboolean
gst_h264_parse_hrd_parameters(GstH264HRDParams * hrd,NalReader * nr)391 gst_h264_parse_hrd_parameters (GstH264HRDParams * hrd, NalReader * nr)
392 {
393 guint sched_sel_idx;
394
395 GST_DEBUG ("parsing \"HRD Parameters\"");
396
397 READ_UE_MAX (nr, hrd->cpb_cnt_minus1, 31);
398 READ_UINT8 (nr, hrd->bit_rate_scale, 4);
399 READ_UINT8 (nr, hrd->cpb_size_scale, 4);
400
401 for (sched_sel_idx = 0; sched_sel_idx <= hrd->cpb_cnt_minus1; sched_sel_idx++) {
402 READ_UE (nr, hrd->bit_rate_value_minus1[sched_sel_idx]);
403 READ_UE (nr, hrd->cpb_size_value_minus1[sched_sel_idx]);
404 READ_UINT8 (nr, hrd->cbr_flag[sched_sel_idx], 1);
405 }
406
407 READ_UINT8 (nr, hrd->initial_cpb_removal_delay_length_minus1, 5);
408 READ_UINT8 (nr, hrd->cpb_removal_delay_length_minus1, 5);
409 READ_UINT8 (nr, hrd->dpb_output_delay_length_minus1, 5);
410 READ_UINT8 (nr, hrd->time_offset_length, 5);
411
412 return TRUE;
413
414 error:
415 GST_WARNING ("error parsing \"HRD Parameters\"");
416 return FALSE;
417 }
418
419 static gboolean
gst_h264_parse_vui_parameters(GstH264SPS * sps,NalReader * nr)420 gst_h264_parse_vui_parameters (GstH264SPS * sps, NalReader * nr)
421 {
422 GstH264VUIParams *vui = &sps->vui_parameters;
423
424 GST_DEBUG ("parsing \"VUI Parameters\"");
425
426 /* set default values for fields that might not be present in the bitstream
427 and have valid defaults */
428 vui->video_format = 5;
429 vui->colour_primaries = 2;
430 vui->transfer_characteristics = 2;
431 vui->matrix_coefficients = 2;
432
433 READ_UINT8 (nr, vui->aspect_ratio_info_present_flag, 1);
434 if (vui->aspect_ratio_info_present_flag) {
435 READ_UINT8 (nr, vui->aspect_ratio_idc, 8);
436 if (vui->aspect_ratio_idc == EXTENDED_SAR) {
437 READ_UINT16 (nr, vui->sar_width, 16);
438 READ_UINT16 (nr, vui->sar_height, 16);
439 vui->par_n = vui->sar_width;
440 vui->par_d = vui->sar_height;
441 } else if (vui->aspect_ratio_idc <= 16) {
442 vui->par_n = aspect_ratios[vui->aspect_ratio_idc].par_n;
443 vui->par_d = aspect_ratios[vui->aspect_ratio_idc].par_d;
444 }
445 }
446
447 READ_UINT8 (nr, vui->overscan_info_present_flag, 1);
448 if (vui->overscan_info_present_flag)
449 READ_UINT8 (nr, vui->overscan_appropriate_flag, 1);
450
451 READ_UINT8 (nr, vui->video_signal_type_present_flag, 1);
452 if (vui->video_signal_type_present_flag) {
453
454 READ_UINT8 (nr, vui->video_format, 3);
455 READ_UINT8 (nr, vui->video_full_range_flag, 1);
456 READ_UINT8 (nr, vui->colour_description_present_flag, 1);
457 if (vui->colour_description_present_flag) {
458 READ_UINT8 (nr, vui->colour_primaries, 8);
459 READ_UINT8 (nr, vui->transfer_characteristics, 8);
460 READ_UINT8 (nr, vui->matrix_coefficients, 8);
461 }
462 }
463
464 READ_UINT8 (nr, vui->chroma_loc_info_present_flag, 1);
465 if (vui->chroma_loc_info_present_flag) {
466 READ_UE_MAX (nr, vui->chroma_sample_loc_type_top_field, 5);
467 READ_UE_MAX (nr, vui->chroma_sample_loc_type_bottom_field, 5);
468 }
469
470 READ_UINT8 (nr, vui->timing_info_present_flag, 1);
471 if (vui->timing_info_present_flag) {
472 READ_UINT32 (nr, vui->num_units_in_tick, 32);
473 if (vui->num_units_in_tick == 0)
474 GST_WARNING ("num_units_in_tick = 0 detected in stream "
475 "(incompliant to H.264 E.2.1).");
476
477 READ_UINT32 (nr, vui->time_scale, 32);
478 if (vui->time_scale == 0)
479 GST_WARNING ("time_scale = 0 detected in stream "
480 "(incompliant to H.264 E.2.1).");
481
482 READ_UINT8 (nr, vui->fixed_frame_rate_flag, 1);
483 }
484
485 READ_UINT8 (nr, vui->nal_hrd_parameters_present_flag, 1);
486 if (vui->nal_hrd_parameters_present_flag) {
487 if (!gst_h264_parse_hrd_parameters (&vui->nal_hrd_parameters, nr))
488 goto error;
489 }
490
491 READ_UINT8 (nr, vui->vcl_hrd_parameters_present_flag, 1);
492 if (vui->vcl_hrd_parameters_present_flag) {
493 if (!gst_h264_parse_hrd_parameters (&vui->vcl_hrd_parameters, nr))
494 goto error;
495 }
496
497 if (vui->nal_hrd_parameters_present_flag ||
498 vui->vcl_hrd_parameters_present_flag)
499 READ_UINT8 (nr, vui->low_delay_hrd_flag, 1);
500
501 READ_UINT8 (nr, vui->pic_struct_present_flag, 1);
502 READ_UINT8 (nr, vui->bitstream_restriction_flag, 1);
503 if (vui->bitstream_restriction_flag) {
504 READ_UINT8 (nr, vui->motion_vectors_over_pic_boundaries_flag, 1);
505 READ_UE (nr, vui->max_bytes_per_pic_denom);
506 READ_UE_MAX (nr, vui->max_bits_per_mb_denom, 16);
507 READ_UE_MAX (nr, vui->log2_max_mv_length_horizontal, 16);
508 READ_UE_MAX (nr, vui->log2_max_mv_length_vertical, 16);
509 READ_UE (nr, vui->num_reorder_frames);
510 READ_UE (nr, vui->max_dec_frame_buffering);
511 }
512
513 return TRUE;
514
515 error:
516 GST_WARNING ("error parsing \"VUI Parameters\"");
517 return FALSE;
518 }
519
520 static gboolean
gst_h264_parser_parse_scaling_list(NalReader * nr,guint8 scaling_lists_4x4[6][16],guint8 scaling_lists_8x8[6][64],const guint8 fallback_4x4_inter[16],const guint8 fallback_4x4_intra[16],const guint8 fallback_8x8_inter[64],const guint8 fallback_8x8_intra[64],guint8 n_lists)521 gst_h264_parser_parse_scaling_list (NalReader * nr,
522 guint8 scaling_lists_4x4[6][16], guint8 scaling_lists_8x8[6][64],
523 const guint8 fallback_4x4_inter[16], const guint8 fallback_4x4_intra[16],
524 const guint8 fallback_8x8_inter[64], const guint8 fallback_8x8_intra[64],
525 guint8 n_lists)
526 {
527 guint i;
528
529 static const guint8 *default_lists[12] = {
530 default_4x4_intra, default_4x4_intra, default_4x4_intra,
531 default_4x4_inter, default_4x4_inter, default_4x4_inter,
532 default_8x8_intra, default_8x8_inter,
533 default_8x8_intra, default_8x8_inter,
534 default_8x8_intra, default_8x8_inter
535 };
536
537 GST_DEBUG ("parsing scaling lists");
538
539 for (i = 0; i < 12; i++) {
540 gboolean use_default = FALSE;
541
542 if (i < n_lists) {
543 guint8 scaling_list_present_flag;
544
545 READ_UINT8 (nr, scaling_list_present_flag, 1);
546 if (scaling_list_present_flag) {
547 guint8 *scaling_list;
548 guint size;
549 guint j;
550 guint8 last_scale, next_scale;
551
552 if (i < 6) {
553 scaling_list = scaling_lists_4x4[i];
554 size = 16;
555 } else {
556 scaling_list = scaling_lists_8x8[i - 6];
557 size = 64;
558 }
559
560 last_scale = 8;
561 next_scale = 8;
562 for (j = 0; j < size; j++) {
563 if (next_scale != 0) {
564 gint32 delta_scale;
565
566 READ_SE (nr, delta_scale);
567 next_scale = (last_scale + delta_scale) & 0xff;
568 }
569 if (j == 0 && next_scale == 0) {
570 /* Use default scaling lists (7.4.2.1.1.1) */
571 memcpy (scaling_list, default_lists[i], size);
572 break;
573 }
574 last_scale = scaling_list[j] =
575 (next_scale == 0) ? last_scale : next_scale;
576 }
577 } else
578 use_default = TRUE;
579 } else
580 use_default = TRUE;
581
582 if (use_default) {
583 switch (i) {
584 case 0:
585 memcpy (scaling_lists_4x4[0], fallback_4x4_intra, 16);
586 break;
587 case 1:
588 memcpy (scaling_lists_4x4[1], scaling_lists_4x4[0], 16);
589 break;
590 case 2:
591 memcpy (scaling_lists_4x4[2], scaling_lists_4x4[1], 16);
592 break;
593 case 3:
594 memcpy (scaling_lists_4x4[3], fallback_4x4_inter, 16);
595 break;
596 case 4:
597 memcpy (scaling_lists_4x4[4], scaling_lists_4x4[3], 16);
598 break;
599 case 5:
600 memcpy (scaling_lists_4x4[5], scaling_lists_4x4[4], 16);
601 break;
602 case 6:
603 memcpy (scaling_lists_8x8[0], fallback_8x8_intra, 64);
604 break;
605 case 7:
606 memcpy (scaling_lists_8x8[1], fallback_8x8_inter, 64);
607 break;
608 case 8:
609 memcpy (scaling_lists_8x8[2], scaling_lists_8x8[0], 64);
610 break;
611 case 9:
612 memcpy (scaling_lists_8x8[3], scaling_lists_8x8[1], 64);
613 break;
614 case 10:
615 memcpy (scaling_lists_8x8[4], scaling_lists_8x8[2], 64);
616 break;
617 case 11:
618 memcpy (scaling_lists_8x8[5], scaling_lists_8x8[3], 64);
619 break;
620
621 default:
622 break;
623 }
624 }
625 }
626
627 return TRUE;
628
629 error:
630 GST_WARNING ("error parsing scaling lists");
631 return FALSE;
632 }
633
634 static gboolean
slice_parse_ref_pic_list_modification_1(GstH264SliceHdr * slice,NalReader * nr,guint list,gboolean is_mvc)635 slice_parse_ref_pic_list_modification_1 (GstH264SliceHdr * slice,
636 NalReader * nr, guint list, gboolean is_mvc)
637 {
638 GstH264RefPicListModification *entries;
639 guint8 *ref_pic_list_modification_flag, *n_ref_pic_list_modification;
640 guint32 modification_of_pic_nums_idc;
641 gsize max_entries;
642 guint i = 0;
643
644 if (list == 0) {
645 entries = slice->ref_pic_list_modification_l0;
646 max_entries = G_N_ELEMENTS (slice->ref_pic_list_modification_l0);
647 ref_pic_list_modification_flag = &slice->ref_pic_list_modification_flag_l0;
648 n_ref_pic_list_modification = &slice->n_ref_pic_list_modification_l0;
649 } else {
650 entries = slice->ref_pic_list_modification_l1;
651 max_entries = G_N_ELEMENTS (slice->ref_pic_list_modification_l1);
652 ref_pic_list_modification_flag = &slice->ref_pic_list_modification_flag_l1;
653 n_ref_pic_list_modification = &slice->n_ref_pic_list_modification_l1;
654 }
655
656 READ_UINT8 (nr, *ref_pic_list_modification_flag, 1);
657 if (*ref_pic_list_modification_flag) {
658 while (1) {
659 READ_UE (nr, modification_of_pic_nums_idc);
660 if (modification_of_pic_nums_idc == 0 ||
661 modification_of_pic_nums_idc == 1) {
662 READ_UE_MAX (nr, entries[i].value.abs_diff_pic_num_minus1,
663 slice->max_pic_num - 1);
664 } else if (modification_of_pic_nums_idc == 2) {
665 READ_UE (nr, entries[i].value.long_term_pic_num);
666 } else if (is_mvc && (modification_of_pic_nums_idc == 4 ||
667 modification_of_pic_nums_idc == 5)) {
668 READ_UE (nr, entries[i].value.abs_diff_view_idx_minus1);
669 }
670 entries[i++].modification_of_pic_nums_idc = modification_of_pic_nums_idc;
671 if (modification_of_pic_nums_idc == 3)
672 break;
673 if (i >= max_entries)
674 goto error;
675 }
676 }
677 *n_ref_pic_list_modification = i;
678 return TRUE;
679
680 error:
681 GST_WARNING ("error parsing \"Reference picture list %u modification\"",
682 list);
683 return FALSE;
684 }
685
686 static gboolean
slice_parse_ref_pic_list_modification(GstH264SliceHdr * slice,NalReader * nr,gboolean is_mvc)687 slice_parse_ref_pic_list_modification (GstH264SliceHdr * slice, NalReader * nr,
688 gboolean is_mvc)
689 {
690 if (!GST_H264_IS_I_SLICE (slice) && !GST_H264_IS_SI_SLICE (slice)) {
691 if (!slice_parse_ref_pic_list_modification_1 (slice, nr, 0, is_mvc))
692 return FALSE;
693 }
694
695 if (GST_H264_IS_B_SLICE (slice)) {
696 if (!slice_parse_ref_pic_list_modification_1 (slice, nr, 1, is_mvc))
697 return FALSE;
698 }
699 return TRUE;
700 }
701
702 static gboolean
gst_h264_slice_parse_dec_ref_pic_marking(GstH264SliceHdr * slice,GstH264NalUnit * nalu,NalReader * nr)703 gst_h264_slice_parse_dec_ref_pic_marking (GstH264SliceHdr * slice,
704 GstH264NalUnit * nalu, NalReader * nr)
705 {
706 GstH264DecRefPicMarking *dec_ref_pic_m;
707 guint start_pos, start_epb;
708
709 GST_DEBUG ("parsing \"Decoded reference picture marking\"");
710
711 start_pos = nal_reader_get_pos (nr);
712 start_epb = nal_reader_get_epb_count (nr);
713
714 dec_ref_pic_m = &slice->dec_ref_pic_marking;
715
716 if (nalu->idr_pic_flag) {
717 READ_UINT8 (nr, dec_ref_pic_m->no_output_of_prior_pics_flag, 1);
718 READ_UINT8 (nr, dec_ref_pic_m->long_term_reference_flag, 1);
719 } else {
720 READ_UINT8 (nr, dec_ref_pic_m->adaptive_ref_pic_marking_mode_flag, 1);
721 if (dec_ref_pic_m->adaptive_ref_pic_marking_mode_flag) {
722 guint32 mem_mgmt_ctrl_op;
723 GstH264RefPicMarking *refpicmarking;
724
725 dec_ref_pic_m->n_ref_pic_marking = 0;
726 while (1) {
727 READ_UE_MAX (nr, mem_mgmt_ctrl_op, 6);
728 if (mem_mgmt_ctrl_op == 0)
729 break;
730
731 if (dec_ref_pic_m->n_ref_pic_marking >=
732 G_N_ELEMENTS (dec_ref_pic_m->ref_pic_marking))
733 goto error;
734
735 refpicmarking =
736 &dec_ref_pic_m->ref_pic_marking[dec_ref_pic_m->n_ref_pic_marking];
737
738 refpicmarking->memory_management_control_operation = mem_mgmt_ctrl_op;
739
740 if (mem_mgmt_ctrl_op == 1 || mem_mgmt_ctrl_op == 3)
741 READ_UE (nr, refpicmarking->difference_of_pic_nums_minus1);
742
743 if (mem_mgmt_ctrl_op == 2)
744 READ_UE (nr, refpicmarking->long_term_pic_num);
745
746 if (mem_mgmt_ctrl_op == 3 || mem_mgmt_ctrl_op == 6)
747 READ_UE (nr, refpicmarking->long_term_frame_idx);
748
749 if (mem_mgmt_ctrl_op == 4)
750 READ_UE (nr, refpicmarking->max_long_term_frame_idx_plus1);
751
752 dec_ref_pic_m->n_ref_pic_marking++;
753 }
754 }
755 }
756
757 dec_ref_pic_m->bit_size = (nal_reader_get_pos (nr) - start_pos) -
758 (8 * (nal_reader_get_epb_count (nr) - start_epb));
759
760 return TRUE;
761
762 error:
763 GST_WARNING ("error parsing \"Decoded reference picture marking\"");
764 return FALSE;
765 }
766
767 static gboolean
gst_h264_slice_parse_pred_weight_table(GstH264SliceHdr * slice,NalReader * nr,guint8 chroma_array_type)768 gst_h264_slice_parse_pred_weight_table (GstH264SliceHdr * slice,
769 NalReader * nr, guint8 chroma_array_type)
770 {
771 GstH264PredWeightTable *p;
772 gint16 default_luma_weight, default_chroma_weight;
773 gint i;
774
775 GST_DEBUG ("parsing \"Prediction weight table\"");
776
777 p = &slice->pred_weight_table;
778
779 READ_UE_MAX (nr, p->luma_log2_weight_denom, 7);
780 /* set default values */
781 default_luma_weight = 1 << p->luma_log2_weight_denom;
782 for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++)
783 p->luma_weight_l0[i] = default_luma_weight;
784 if (GST_H264_IS_B_SLICE (slice)) {
785 for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++)
786 p->luma_weight_l1[i] = default_luma_weight;
787 }
788
789 if (chroma_array_type != 0) {
790 READ_UE_MAX (nr, p->chroma_log2_weight_denom, 7);
791 /* set default values */
792 default_chroma_weight = 1 << p->chroma_log2_weight_denom;
793 for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++) {
794 p->chroma_weight_l0[i][0] = default_chroma_weight;
795 p->chroma_weight_l0[i][1] = default_chroma_weight;
796 }
797 if (GST_H264_IS_B_SLICE (slice)) {
798 for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++) {
799 p->chroma_weight_l1[i][0] = default_chroma_weight;
800 p->chroma_weight_l1[i][1] = default_chroma_weight;
801 }
802 }
803 }
804
805 for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++) {
806 guint8 luma_weight_l0_flag;
807
808 READ_UINT8 (nr, luma_weight_l0_flag, 1);
809 if (luma_weight_l0_flag) {
810 READ_SE_ALLOWED (nr, p->luma_weight_l0[i], -128, 127);
811 READ_SE_ALLOWED (nr, p->luma_offset_l0[i], -128, 127);
812 }
813 if (chroma_array_type != 0) {
814 guint8 chroma_weight_l0_flag;
815 gint j;
816
817 READ_UINT8 (nr, chroma_weight_l0_flag, 1);
818 if (chroma_weight_l0_flag) {
819 for (j = 0; j < 2; j++) {
820 READ_SE_ALLOWED (nr, p->chroma_weight_l0[i][j], -128, 127);
821 READ_SE_ALLOWED (nr, p->chroma_offset_l0[i][j], -128, 127);
822 }
823 }
824 }
825 }
826
827 if (GST_H264_IS_B_SLICE (slice)) {
828 for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++) {
829 guint8 luma_weight_l1_flag;
830
831 READ_UINT8 (nr, luma_weight_l1_flag, 1);
832 if (luma_weight_l1_flag) {
833 READ_SE_ALLOWED (nr, p->luma_weight_l1[i], -128, 127);
834 READ_SE_ALLOWED (nr, p->luma_offset_l1[i], -128, 127);
835 }
836 if (chroma_array_type != 0) {
837 guint8 chroma_weight_l1_flag;
838 gint j;
839
840 READ_UINT8 (nr, chroma_weight_l1_flag, 1);
841 if (chroma_weight_l1_flag) {
842 for (j = 0; j < 2; j++) {
843 READ_SE_ALLOWED (nr, p->chroma_weight_l1[i][j], -128, 127);
844 READ_SE_ALLOWED (nr, p->chroma_offset_l1[i][j], -128, 127);
845 }
846 }
847 }
848 }
849 }
850
851 return TRUE;
852
853 error:
854 GST_WARNING ("error parsing \"Prediction weight table\"");
855 return FALSE;
856 }
857
858 static GstH264ParserResult
gst_h264_parser_parse_buffering_period(GstH264NalParser * nalparser,GstH264BufferingPeriod * per,NalReader * nr)859 gst_h264_parser_parse_buffering_period (GstH264NalParser * nalparser,
860 GstH264BufferingPeriod * per, NalReader * nr)
861 {
862 GstH264SPS *sps;
863 guint8 sps_id;
864
865 GST_DEBUG ("parsing \"Buffering period\"");
866
867 READ_UE_MAX (nr, sps_id, GST_H264_MAX_SPS_COUNT - 1);
868 sps = gst_h264_parser_get_sps (nalparser, sps_id);
869 if (!sps) {
870 GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
871 sps_id);
872 return GST_H264_PARSER_BROKEN_LINK;
873 }
874 per->sps = sps;
875
876 if (sps->vui_parameters_present_flag) {
877 GstH264VUIParams *vui = &sps->vui_parameters;
878
879 if (vui->nal_hrd_parameters_present_flag) {
880 GstH264HRDParams *hrd = &vui->nal_hrd_parameters;
881 const guint8 nbits = hrd->initial_cpb_removal_delay_length_minus1 + 1;
882 guint8 sched_sel_idx;
883
884 for (sched_sel_idx = 0; sched_sel_idx <= hrd->cpb_cnt_minus1;
885 sched_sel_idx++) {
886 READ_UINT32 (nr, per->nal_initial_cpb_removal_delay[sched_sel_idx],
887 nbits);
888 READ_UINT32 (nr,
889 per->nal_initial_cpb_removal_delay_offset[sched_sel_idx], nbits);
890 }
891 }
892
893 if (vui->vcl_hrd_parameters_present_flag) {
894 GstH264HRDParams *hrd = &vui->vcl_hrd_parameters;
895 const guint8 nbits = hrd->initial_cpb_removal_delay_length_minus1 + 1;
896 guint8 sched_sel_idx;
897
898 for (sched_sel_idx = 0; sched_sel_idx <= hrd->cpb_cnt_minus1;
899 sched_sel_idx++) {
900 READ_UINT32 (nr, per->vcl_initial_cpb_removal_delay[sched_sel_idx],
901 nbits);
902 READ_UINT32 (nr,
903 per->vcl_initial_cpb_removal_delay_offset[sched_sel_idx], nbits);
904 }
905 }
906 }
907
908 return GST_H264_PARSER_OK;
909
910 error:
911 GST_WARNING ("error parsing \"Buffering period\"");
912 return GST_H264_PARSER_ERROR;
913 }
914
915 static gboolean
gst_h264_parse_clock_timestamp(GstH264ClockTimestamp * tim,guint8 time_offset_length,NalReader * nr)916 gst_h264_parse_clock_timestamp (GstH264ClockTimestamp * tim,
917 guint8 time_offset_length, NalReader * nr)
918 {
919 GST_DEBUG ("parsing \"Clock timestamp\"");
920
921 /* default values */
922 tim->time_offset = 0;
923
924 READ_UINT8 (nr, tim->ct_type, 2);
925 READ_UINT8 (nr, tim->nuit_field_based_flag, 1);
926 READ_UINT8 (nr, tim->counting_type, 5);
927 READ_UINT8 (nr, tim->full_timestamp_flag, 1);
928 READ_UINT8 (nr, tim->discontinuity_flag, 1);
929 READ_UINT8 (nr, tim->cnt_dropped_flag, 1);
930 READ_UINT8 (nr, tim->n_frames, 8);
931
932 if (tim->full_timestamp_flag) {
933 tim->seconds_flag = TRUE;
934 READ_UINT8 (nr, tim->seconds_value, 6);
935
936 tim->minutes_flag = TRUE;
937 READ_UINT8 (nr, tim->minutes_value, 6);
938
939 tim->hours_flag = TRUE;
940 READ_UINT8 (nr, tim->hours_value, 5);
941 } else {
942 READ_UINT8 (nr, tim->seconds_flag, 1);
943 if (tim->seconds_flag) {
944 READ_UINT8 (nr, tim->seconds_value, 6);
945 READ_UINT8 (nr, tim->minutes_flag, 1);
946 if (tim->minutes_flag) {
947 READ_UINT8 (nr, tim->minutes_value, 6);
948 READ_UINT8 (nr, tim->hours_flag, 1);
949 if (tim->hours_flag)
950 READ_UINT8 (nr, tim->hours_value, 5);
951 }
952 }
953 }
954
955 if (time_offset_length > 0)
956 READ_UINT32 (nr, tim->time_offset, time_offset_length);
957
958 return TRUE;
959
960 error:
961 GST_WARNING ("error parsing \"Clock timestamp\"");
962 return FALSE;
963 }
964
965 static GstH264ParserResult
gst_h264_parser_parse_pic_timing(GstH264NalParser * nalparser,GstH264PicTiming * tim,NalReader * nr)966 gst_h264_parser_parse_pic_timing (GstH264NalParser * nalparser,
967 GstH264PicTiming * tim, NalReader * nr)
968 {
969 GstH264ParserResult error = GST_H264_PARSER_ERROR;
970
971 GST_DEBUG ("parsing \"Picture timing\"");
972 if (!nalparser->last_sps || !nalparser->last_sps->valid) {
973 GST_WARNING ("didn't get the associated sequence parameter set for the "
974 "current access unit");
975 error = GST_H264_PARSER_BROKEN_LINK;
976 goto error;
977 }
978
979 if (nalparser->last_sps->vui_parameters_present_flag) {
980 GstH264VUIParams *vui = &nalparser->last_sps->vui_parameters;
981 GstH264HRDParams *hrd = NULL;
982
983 if (vui->nal_hrd_parameters_present_flag) {
984 hrd = &vui->nal_hrd_parameters;
985 } else if (vui->vcl_hrd_parameters_present_flag) {
986 hrd = &vui->vcl_hrd_parameters;
987 }
988
989 tim->CpbDpbDelaysPresentFlag = ! !hrd;
990 tim->pic_struct_present_flag = vui->pic_struct_present_flag;
991
992 if (tim->CpbDpbDelaysPresentFlag) {
993 tim->cpb_removal_delay_length_minus1 =
994 hrd->cpb_removal_delay_length_minus1;
995 tim->dpb_output_delay_length_minus1 = hrd->dpb_output_delay_length_minus1;
996
997 READ_UINT32 (nr, tim->cpb_removal_delay,
998 tim->cpb_removal_delay_length_minus1 + 1);
999 READ_UINT32 (nr, tim->dpb_output_delay,
1000 tim->dpb_output_delay_length_minus1 + 1);
1001 }
1002
1003 if (tim->pic_struct_present_flag) {
1004 const guint8 num_clock_ts_table[9] = {
1005 1, 1, 1, 2, 2, 3, 3, 2, 3
1006 };
1007 guint8 num_clock_num_ts;
1008 guint i;
1009
1010 READ_UINT8 (nr, tim->pic_struct, 4);
1011 CHECK_ALLOWED ((gint8) tim->pic_struct, 0, 8);
1012
1013 tim->time_offset_length = 24;
1014 if (hrd)
1015 tim->time_offset_length = hrd->time_offset_length;
1016
1017 num_clock_num_ts = num_clock_ts_table[tim->pic_struct];
1018 for (i = 0; i < num_clock_num_ts; i++) {
1019 READ_UINT8 (nr, tim->clock_timestamp_flag[i], 1);
1020 if (tim->clock_timestamp_flag[i]) {
1021 if (!gst_h264_parse_clock_timestamp (&tim->clock_timestamp[i],
1022 tim->time_offset_length, nr))
1023 goto error;
1024 }
1025 }
1026 }
1027 }
1028
1029 if (!tim->CpbDpbDelaysPresentFlag && !tim->pic_struct_present_flag) {
1030 GST_WARNING
1031 ("Invalid pic_timing SEI NAL with neither CpbDpbDelays nor pic_struct");
1032 return GST_H264_PARSER_BROKEN_DATA;
1033 }
1034
1035 return GST_H264_PARSER_OK;
1036
1037 error:
1038 GST_WARNING ("error parsing \"Picture timing\"");
1039 return error;
1040 }
1041
1042 static GstH264ParserResult
gst_h264_parser_parse_registered_user_data(GstH264NalParser * nalparser,GstH264RegisteredUserData * rud,NalReader * nr,guint payload_size)1043 gst_h264_parser_parse_registered_user_data (GstH264NalParser * nalparser,
1044 GstH264RegisteredUserData * rud, NalReader * nr, guint payload_size)
1045 {
1046 guint8 *data = NULL;
1047 guint i;
1048
1049 rud->data = NULL;
1050 rud->size = 0;
1051
1052 if (payload_size < 2) {
1053 GST_WARNING ("Too small payload size %d", payload_size);
1054 return GST_H264_PARSER_BROKEN_DATA;
1055 }
1056
1057 READ_UINT8 (nr, rud->country_code, 8);
1058 --payload_size;
1059
1060 if (rud->country_code == 0xFF) {
1061 READ_UINT8 (nr, rud->country_code_extension, 8);
1062 --payload_size;
1063 } else {
1064 rud->country_code_extension = 0;
1065 }
1066
1067 if (payload_size < 1) {
1068 GST_WARNING ("No more remaining payload data to store");
1069 return GST_H264_PARSER_BROKEN_DATA;
1070 }
1071
1072 data = g_malloc (payload_size);
1073 for (i = 0; i < payload_size; ++i) {
1074 READ_UINT8 (nr, data[i], 8);
1075 }
1076
1077 GST_MEMDUMP ("SEI user data", data, payload_size);
1078
1079 rud->data = data;
1080 rud->size = payload_size;
1081 return GST_H264_PARSER_OK;
1082
1083 error:
1084 {
1085 GST_WARNING ("error parsing \"Registered User Data\"");
1086 g_free (data);
1087 return GST_H264_PARSER_ERROR;
1088 }
1089 }
1090
1091 static GstH264ParserResult
gst_h264_parser_parse_recovery_point(GstH264NalParser * nalparser,GstH264RecoveryPoint * rp,NalReader * nr)1092 gst_h264_parser_parse_recovery_point (GstH264NalParser * nalparser,
1093 GstH264RecoveryPoint * rp, NalReader * nr)
1094 {
1095 GstH264SPS *const sps = nalparser->last_sps;
1096
1097 GST_DEBUG ("parsing \"Recovery point\"");
1098 if (!sps || !sps->valid) {
1099 GST_WARNING ("didn't get the associated sequence parameter set for the "
1100 "current access unit");
1101 goto error;
1102 }
1103
1104 READ_UE_MAX (nr, rp->recovery_frame_cnt, sps->max_frame_num - 1);
1105 READ_UINT8 (nr, rp->exact_match_flag, 1);
1106 READ_UINT8 (nr, rp->broken_link_flag, 1);
1107 READ_UINT8 (nr, rp->changing_slice_group_idc, 2);
1108
1109 return GST_H264_PARSER_OK;
1110
1111 error:
1112 GST_WARNING ("error parsing \"Recovery point\"");
1113 return GST_H264_PARSER_ERROR;
1114 }
1115
1116 /* Parse SEI stereo_video_info() message */
1117 static GstH264ParserResult
gst_h264_parser_parse_stereo_video_info(GstH264NalParser * nalparser,GstH264StereoVideoInfo * info,NalReader * nr)1118 gst_h264_parser_parse_stereo_video_info (GstH264NalParser * nalparser,
1119 GstH264StereoVideoInfo * info, NalReader * nr)
1120 {
1121 GST_DEBUG ("parsing \"Stereo Video info\"");
1122
1123 READ_UINT8 (nr, info->field_views_flag, 1);
1124 if (info->field_views_flag) {
1125 READ_UINT8 (nr, info->top_field_is_left_view_flag, 1);
1126 } else {
1127 READ_UINT8 (nr, info->current_frame_is_left_view_flag, 1);
1128 READ_UINT8 (nr, info->next_frame_is_second_view_flag, 1);
1129 }
1130 READ_UINT8 (nr, info->left_view_self_contained_flag, 1);
1131 READ_UINT8 (nr, info->right_view_self_contained_flag, 1);
1132
1133 return GST_H264_PARSER_OK;
1134
1135 error:
1136 GST_WARNING ("error parsing \"Stereo Video info\"");
1137 return GST_H264_PARSER_ERROR;
1138 }
1139
1140 /* Parse SEI frame_packing_arrangement() message */
1141 static GstH264ParserResult
gst_h264_parser_parse_frame_packing(GstH264NalParser * nalparser,GstH264FramePacking * frame_packing,NalReader * nr,guint payload_size)1142 gst_h264_parser_parse_frame_packing (GstH264NalParser * nalparser,
1143 GstH264FramePacking * frame_packing, NalReader * nr, guint payload_size)
1144 {
1145 guint8 frame_packing_extension_flag;
1146 guint start_pos;
1147
1148 GST_DEBUG ("parsing \"Frame Packing Arrangement\"");
1149
1150 start_pos = nal_reader_get_pos (nr);
1151 READ_UE (nr, frame_packing->frame_packing_id);
1152 READ_UINT8 (nr, frame_packing->frame_packing_cancel_flag, 1);
1153
1154 if (!frame_packing->frame_packing_cancel_flag) {
1155 READ_UINT8 (nr, frame_packing->frame_packing_type, 7);
1156 READ_UINT8 (nr, frame_packing->quincunx_sampling_flag, 1);
1157 READ_UINT8 (nr, frame_packing->content_interpretation_type, 6);
1158 READ_UINT8 (nr, frame_packing->spatial_flipping_flag, 1);
1159 READ_UINT8 (nr, frame_packing->frame0_flipped_flag, 1);
1160 READ_UINT8 (nr, frame_packing->field_views_flag, 1);
1161 READ_UINT8 (nr, frame_packing->current_frame_is_frame0_flag, 1);
1162 READ_UINT8 (nr, frame_packing->frame0_self_contained_flag, 1);
1163 READ_UINT8 (nr, frame_packing->frame1_self_contained_flag, 1);
1164
1165 if (!frame_packing->quincunx_sampling_flag &&
1166 frame_packing->frame_packing_type !=
1167 GST_H264_FRAME_PACKING_TEMPORAL_INTERLEAVING) {
1168 READ_UINT8 (nr, frame_packing->frame0_grid_position_x, 4);
1169 READ_UINT8 (nr, frame_packing->frame0_grid_position_y, 4);
1170 READ_UINT8 (nr, frame_packing->frame1_grid_position_x, 4);
1171 READ_UINT8 (nr, frame_packing->frame1_grid_position_y, 4);
1172 }
1173
1174 /* Skip frame_packing_arrangement_reserved_byte */
1175 if (!nal_reader_skip (nr, 8))
1176 goto error;
1177
1178 READ_UE_MAX (nr, frame_packing->frame_packing_repetition_period, 16384);
1179 }
1180
1181 READ_UINT8 (nr, frame_packing_extension_flag, 1);
1182
1183 /* All data that follows within a frame packing arrangement SEI message
1184 after the value 1 for frame_packing_arrangement_extension_flag shall
1185 be ignored (D.2.25) */
1186 if (frame_packing_extension_flag) {
1187 nal_reader_skip_long (nr,
1188 payload_size - (nal_reader_get_pos (nr) - start_pos));
1189 }
1190
1191 return GST_H264_PARSER_OK;
1192
1193 error:
1194 GST_WARNING ("error parsing \"Frame Packing Arrangement\"");
1195 return GST_H264_PARSER_ERROR;
1196 }
1197
1198 static GstH264ParserResult
gst_h264_parser_parse_mastering_display_colour_volume(GstH264NalParser * parser,GstH264MasteringDisplayColourVolume * mdcv,NalReader * nr)1199 gst_h264_parser_parse_mastering_display_colour_volume (GstH264NalParser *
1200 parser, GstH264MasteringDisplayColourVolume * mdcv, NalReader * nr)
1201 {
1202 guint i;
1203
1204 GST_DEBUG ("parsing \"Mastering display colour volume\"");
1205
1206 for (i = 0; i < 3; i++) {
1207 READ_UINT16 (nr, mdcv->display_primaries_x[i], 16);
1208 READ_UINT16 (nr, mdcv->display_primaries_y[i], 16);
1209 }
1210
1211 READ_UINT16 (nr, mdcv->white_point_x, 16);
1212 READ_UINT16 (nr, mdcv->white_point_y, 16);
1213 READ_UINT32 (nr, mdcv->max_display_mastering_luminance, 32);
1214 READ_UINT32 (nr, mdcv->min_display_mastering_luminance, 32);
1215
1216 return GST_H264_PARSER_OK;
1217
1218 error:
1219 GST_WARNING ("error parsing \"Mastering display colour volume\"");
1220 return GST_H264_PARSER_ERROR;
1221 }
1222
1223 static GstH264ParserResult
gst_h264_parser_parse_content_light_level_info(GstH264NalParser * parser,GstH264ContentLightLevel * cll,NalReader * nr)1224 gst_h264_parser_parse_content_light_level_info (GstH264NalParser * parser,
1225 GstH264ContentLightLevel * cll, NalReader * nr)
1226 {
1227 GST_DEBUG ("parsing \"Content light level\"");
1228
1229 READ_UINT16 (nr, cll->max_content_light_level, 16);
1230 READ_UINT16 (nr, cll->max_pic_average_light_level, 16);
1231
1232 return GST_H264_PARSER_OK;
1233
1234 error:
1235 GST_WARNING ("error parsing \"Content light level\"");
1236 return GST_H264_PARSER_ERROR;
1237 }
1238
1239 static GstH264ParserResult
gst_h264_parser_parse_sei_unhandled_payload(GstH264NalParser * parser,GstH264SEIUnhandledPayload * payload,NalReader * nr,guint payload_type,guint payload_size)1240 gst_h264_parser_parse_sei_unhandled_payload (GstH264NalParser * parser,
1241 GstH264SEIUnhandledPayload * payload, NalReader * nr, guint payload_type,
1242 guint payload_size)
1243 {
1244 guint8 *data = NULL;
1245 gint i;
1246
1247 payload->payloadType = payload_type;
1248
1249 data = g_malloc0 (payload_size);
1250 for (i = 0; i < payload_size; ++i) {
1251 READ_UINT8 (nr, data[i], 8);
1252 }
1253
1254 payload->size = payload_size;
1255 payload->data = data;
1256
1257 return GST_H264_PARSER_OK;
1258
1259 error:
1260 GST_WARNING ("error parsing \"Unhandled payload\"");
1261 g_free (data);
1262
1263 return GST_H264_PARSER_ERROR;
1264 }
1265
1266 static GstH264ParserResult
gst_h264_parser_parse_sei_message(GstH264NalParser * nalparser,NalReader * nr,GstH264SEIMessage * sei)1267 gst_h264_parser_parse_sei_message (GstH264NalParser * nalparser,
1268 NalReader * nr, GstH264SEIMessage * sei)
1269 {
1270 guint32 payloadSize;
1271 guint8 payload_type_byte, payload_size_byte;
1272 guint remaining, payload_size, next;
1273 GstH264ParserResult res;
1274
1275 GST_DEBUG ("parsing \"SEI message\"");
1276
1277 memset (sei, 0, sizeof (*sei));
1278
1279 do {
1280 READ_UINT8 (nr, payload_type_byte, 8);
1281 sei->payloadType += payload_type_byte;
1282 } while (payload_type_byte == 0xff);
1283
1284 payloadSize = 0;
1285 do {
1286 READ_UINT8 (nr, payload_size_byte, 8);
1287 payloadSize += payload_size_byte;
1288 }
1289 while (payload_size_byte == 0xff);
1290
1291 remaining = nal_reader_get_remaining (nr);
1292 payload_size = payloadSize * 8 < remaining ? payloadSize * 8 : remaining;
1293 next = nal_reader_get_pos (nr) + payload_size;
1294
1295 GST_DEBUG ("SEI message received: payloadType %u, payloadSize = %u bits",
1296 sei->payloadType, payload_size);
1297
1298 switch (sei->payloadType) {
1299 case GST_H264_SEI_BUF_PERIOD:
1300 /* size not set; might depend on emulation_prevention_three_byte */
1301 res = gst_h264_parser_parse_buffering_period (nalparser,
1302 &sei->payload.buffering_period, nr);
1303 break;
1304 case GST_H264_SEI_PIC_TIMING:
1305 /* size not set; might depend on emulation_prevention_three_byte */
1306 res = gst_h264_parser_parse_pic_timing (nalparser,
1307 &sei->payload.pic_timing, nr);
1308 break;
1309 case GST_H264_SEI_REGISTERED_USER_DATA:
1310 res = gst_h264_parser_parse_registered_user_data (nalparser,
1311 &sei->payload.registered_user_data, nr, payload_size >> 3);
1312 break;
1313 case GST_H264_SEI_RECOVERY_POINT:
1314 res = gst_h264_parser_parse_recovery_point (nalparser,
1315 &sei->payload.recovery_point, nr);
1316 break;
1317 case GST_H264_SEI_STEREO_VIDEO_INFO:
1318 res = gst_h264_parser_parse_stereo_video_info (nalparser,
1319 &sei->payload.stereo_video_info, nr);
1320 break;
1321 case GST_H264_SEI_FRAME_PACKING:
1322 res = gst_h264_parser_parse_frame_packing (nalparser,
1323 &sei->payload.frame_packing, nr, payload_size);
1324 break;
1325 case GST_H264_SEI_MASTERING_DISPLAY_COLOUR_VOLUME:
1326 res = gst_h264_parser_parse_mastering_display_colour_volume (nalparser,
1327 &sei->payload.mastering_display_colour_volume, nr);
1328 break;
1329 case GST_H264_SEI_CONTENT_LIGHT_LEVEL:
1330 res = gst_h264_parser_parse_content_light_level_info (nalparser,
1331 &sei->payload.content_light_level, nr);
1332 break;
1333 default:
1334 res = gst_h264_parser_parse_sei_unhandled_payload (nalparser,
1335 &sei->payload.unhandled_payload, nr, sei->payloadType,
1336 payload_size >> 3);
1337 sei->payloadType = GST_H264_SEI_UNHANDLED_PAYLOAD;
1338 break;
1339 }
1340
1341 /* When SEI message doesn't end at byte boundary,
1342 * check remaining bits fit the specification.
1343 */
1344 if (!nal_reader_is_byte_aligned (nr)) {
1345 guint8 bit_equal_to_one;
1346 READ_UINT8 (nr, bit_equal_to_one, 1);
1347 if (!bit_equal_to_one)
1348 GST_WARNING ("Bit non equal to one.");
1349
1350 while (!nal_reader_is_byte_aligned (nr)) {
1351 guint8 bit_equal_to_zero;
1352 READ_UINT8 (nr, bit_equal_to_zero, 1);
1353 if (bit_equal_to_zero)
1354 GST_WARNING ("Bit non equal to zero.");
1355 }
1356 }
1357
1358 /* Always make sure all the advertised SEI bits
1359 * were consumed during parsing */
1360 if (next > nal_reader_get_pos (nr)) {
1361 GST_LOG ("Skipping %u unused SEI bits", next - nal_reader_get_pos (nr));
1362
1363 if (!nal_reader_skip_long (nr, next - nal_reader_get_pos (nr)))
1364 goto error;
1365 }
1366
1367 return res;
1368
1369 error:
1370 GST_WARNING ("error parsing \"Sei message\"");
1371 return GST_H264_PARSER_ERROR;
1372 }
1373
1374 /******** API *************/
1375
1376 /**
1377 * gst_h264_nal_parser_new:
1378 *
1379 * Creates a new #GstH264NalParser. It should be freed with
1380 * gst_h264_nal_parser_free after use.
1381 *
1382 * Returns: a new #GstH264NalParser
1383 */
1384 GstH264NalParser *
gst_h264_nal_parser_new(void)1385 gst_h264_nal_parser_new (void)
1386 {
1387 GstH264NalParser *nalparser;
1388
1389 nalparser = g_slice_new0 (GstH264NalParser);
1390
1391 return nalparser;
1392 }
1393
1394 /**
1395 * gst_h264_nal_parser_free:
1396 * @nalparser: the #GstH264NalParser to free
1397 *
1398 * Frees @nalparser and sets it to %NULL
1399 */
1400 void
gst_h264_nal_parser_free(GstH264NalParser * nalparser)1401 gst_h264_nal_parser_free (GstH264NalParser * nalparser)
1402 {
1403 guint i;
1404
1405 for (i = 0; i < GST_H264_MAX_SPS_COUNT; i++)
1406 gst_h264_sps_clear (&nalparser->sps[i]);
1407 for (i = 0; i < GST_H264_MAX_PPS_COUNT; i++)
1408 gst_h264_pps_clear (&nalparser->pps[i]);
1409 g_slice_free (GstH264NalParser, nalparser);
1410
1411 nalparser = NULL;
1412 }
1413
1414 /**
1415 * gst_h264_parser_identify_nalu_unchecked:
1416 * @nalparser: a #GstH264NalParser
1417 * @data: The data to parse
1418 * @offset: the offset from which to parse @data
1419 * @size: the size of @data
1420 * @nalu: The #GstH264NalUnit where to store parsed nal headers
1421 *
1422 * Parses @data and fills @nalu from the next nalu data from @data.
1423 *
1424 * This differs from @gst_h264_parser_identify_nalu in that it doesn't
1425 * check whether the packet is complete or not.
1426 *
1427 * Note: Only use this function if you already know the provided @data
1428 * is a complete NALU, else use @gst_h264_parser_identify_nalu.
1429 *
1430 * Returns: a #GstH264ParserResult
1431 */
1432 GstH264ParserResult
gst_h264_parser_identify_nalu_unchecked(GstH264NalParser * nalparser,const guint8 * data,guint offset,gsize size,GstH264NalUnit * nalu)1433 gst_h264_parser_identify_nalu_unchecked (GstH264NalParser * nalparser,
1434 const guint8 * data, guint offset, gsize size, GstH264NalUnit * nalu)
1435 {
1436 gint off1;
1437
1438 memset (nalu, 0, sizeof (*nalu));
1439
1440 if (size < offset + 4) {
1441 GST_DEBUG ("Can't parse, buffer has too small size %" G_GSIZE_FORMAT
1442 ", offset %u", size, offset);
1443 return GST_H264_PARSER_ERROR;
1444 }
1445
1446 off1 = scan_for_start_codes (data + offset, size - offset);
1447
1448 if (off1 < 0) {
1449 GST_DEBUG ("No start code prefix in this buffer");
1450 return GST_H264_PARSER_NO_NAL;
1451 }
1452
1453 nalu->sc_offset = offset + off1;
1454
1455 /* sc might have 2 or 3 0-bytes */
1456 if (nalu->sc_offset > 0 && data[nalu->sc_offset - 1] == 00)
1457 nalu->sc_offset--;
1458
1459 nalu->offset = offset + off1 + 3;
1460 nalu->data = (guint8 *) data;
1461 nalu->size = size - nalu->offset;
1462
1463 if (!gst_h264_parse_nalu_header (nalu)) {
1464 GST_WARNING ("error parsing \"NAL unit header\"");
1465 nalu->size = 0;
1466 return GST_H264_PARSER_BROKEN_DATA;
1467 }
1468
1469 nalu->valid = TRUE;
1470
1471 if (nalu->type == GST_H264_NAL_SEQ_END ||
1472 nalu->type == GST_H264_NAL_STREAM_END) {
1473 GST_DEBUG ("end-of-seq or end-of-stream nal found");
1474 nalu->size = 1;
1475 return GST_H264_PARSER_OK;
1476 }
1477
1478 return GST_H264_PARSER_OK;
1479 }
1480
1481 /**
1482 * gst_h264_parser_identify_nalu:
1483 * @nalparser: a #GstH264NalParser
1484 * @data: The data to parse, containing an Annex B coded NAL unit
1485 * @offset: the offset in @data from which to parse the NAL unit
1486 * @size: the size of @data
1487 * @nalu: The #GstH264NalUnit to store the identified NAL unit in
1488 *
1489 * Parses the headers of an Annex B coded NAL unit from @data and puts the
1490 * result into @nalu.
1491 *
1492 * Returns: a #GstH264ParserResult
1493 */
1494 GstH264ParserResult
gst_h264_parser_identify_nalu(GstH264NalParser * nalparser,const guint8 * data,guint offset,gsize size,GstH264NalUnit * nalu)1495 gst_h264_parser_identify_nalu (GstH264NalParser * nalparser,
1496 const guint8 * data, guint offset, gsize size, GstH264NalUnit * nalu)
1497 {
1498 GstH264ParserResult res;
1499 gint off2;
1500
1501 res =
1502 gst_h264_parser_identify_nalu_unchecked (nalparser, data, offset, size,
1503 nalu);
1504
1505 if (res != GST_H264_PARSER_OK)
1506 goto beach;
1507
1508 /* The two NALs are exactly 1 byte size and are placed at the end of an AU,
1509 * there is no need to wait for the following */
1510 if (nalu->type == GST_H264_NAL_SEQ_END ||
1511 nalu->type == GST_H264_NAL_STREAM_END)
1512 goto beach;
1513
1514 off2 = scan_for_start_codes (data + nalu->offset, size - nalu->offset);
1515 if (off2 < 0) {
1516 GST_DEBUG ("Nal start %d, No end found", nalu->offset);
1517
1518 return GST_H264_PARSER_NO_NAL_END;
1519 }
1520
1521 /* Mini performance improvement:
1522 * We could have a way to store how many 0s were skipped to avoid
1523 * parsing them again on the next NAL */
1524 while (off2 > 0 && data[nalu->offset + off2 - 1] == 00)
1525 off2--;
1526
1527 nalu->size = off2;
1528 if (nalu->size < 2)
1529 return GST_H264_PARSER_BROKEN_DATA;
1530
1531 GST_DEBUG ("Complete nal found. Off: %d, Size: %d", nalu->offset, nalu->size);
1532
1533 beach:
1534 return res;
1535 }
1536
1537
1538 /**
1539 * gst_h264_parser_identify_nalu_avc:
1540 * @nalparser: a #GstH264NalParser
1541 * @data: The data to parse, containing an AVC coded NAL unit
1542 * @offset: the offset in @data from which to parse the NAL unit
1543 * @size: the size of @data
1544 * @nal_length_size: the size in bytes of the AVC nal length prefix.
1545 * @nalu: The #GstH264NalUnit to store the identified NAL unit in
1546 *
1547 * Parses the headers of an AVC coded NAL unit from @data and puts the result
1548 * into @nalu.
1549 *
1550 * Returns: a #GstH264ParserResult
1551 */
1552 GstH264ParserResult
gst_h264_parser_identify_nalu_avc(GstH264NalParser * nalparser,const guint8 * data,guint offset,gsize size,guint8 nal_length_size,GstH264NalUnit * nalu)1553 gst_h264_parser_identify_nalu_avc (GstH264NalParser * nalparser,
1554 const guint8 * data, guint offset, gsize size, guint8 nal_length_size,
1555 GstH264NalUnit * nalu)
1556 {
1557 GstBitReader br;
1558
1559 memset (nalu, 0, sizeof (*nalu));
1560
1561 /* Would overflow guint below otherwise: the callers needs to ensure that
1562 * this never happens */
1563 if (offset > G_MAXUINT32 - nal_length_size) {
1564 GST_WARNING ("offset + nal_length_size overflow");
1565 nalu->size = 0;
1566 return GST_H264_PARSER_BROKEN_DATA;
1567 }
1568
1569 if (size < offset + nal_length_size) {
1570 GST_DEBUG ("Can't parse, buffer has too small size %" G_GSIZE_FORMAT
1571 ", offset %u", size, offset);
1572 return GST_H264_PARSER_ERROR;
1573 }
1574
1575 size = size - offset;
1576 gst_bit_reader_init (&br, data + offset, size);
1577
1578 nalu->size = gst_bit_reader_get_bits_uint32_unchecked (&br,
1579 nal_length_size * 8);
1580 nalu->sc_offset = offset;
1581 nalu->offset = offset + nal_length_size;
1582
1583 if (nalu->size > G_MAXUINT32 - nal_length_size) {
1584 GST_WARNING ("NALU size + nal_length_size overflow");
1585 nalu->size = 0;
1586 return GST_H264_PARSER_BROKEN_DATA;
1587 }
1588
1589 if (size < (gsize) nalu->size + nal_length_size) {
1590 nalu->size = 0;
1591
1592 return GST_H264_PARSER_NO_NAL_END;
1593 }
1594
1595 nalu->data = (guint8 *) data;
1596
1597 if (!gst_h264_parse_nalu_header (nalu)) {
1598 GST_WARNING ("error parsing \"NAL unit header\"");
1599 nalu->size = 0;
1600 return GST_H264_PARSER_BROKEN_DATA;
1601 }
1602
1603 nalu->valid = TRUE;
1604
1605 return GST_H264_PARSER_OK;
1606 }
1607
1608 /**
1609 * gst_h264_parser_parse_nal:
1610 * @nalparser: a #GstH264NalParser
1611 * @nalu: The #GstH264NalUnit to parse
1612 *
1613 * This function should be called in the case one doesn't need to
1614 * parse a specific structure. It is necessary to do so to make
1615 * sure @nalparser is up to date.
1616 *
1617 * Returns: a #GstH264ParserResult
1618 */
1619 GstH264ParserResult
gst_h264_parser_parse_nal(GstH264NalParser * nalparser,GstH264NalUnit * nalu)1620 gst_h264_parser_parse_nal (GstH264NalParser * nalparser, GstH264NalUnit * nalu)
1621 {
1622 GstH264SPS sps;
1623 GstH264PPS pps;
1624
1625 switch (nalu->type) {
1626 case GST_H264_NAL_SPS:
1627 return gst_h264_parser_parse_sps (nalparser, nalu, &sps);
1628 break;
1629 case GST_H264_NAL_PPS:
1630 return gst_h264_parser_parse_pps (nalparser, nalu, &pps);
1631 }
1632
1633 return GST_H264_PARSER_OK;
1634 }
1635
1636 /**
1637 * gst_h264_parser_parse_sps:
1638 * @nalparser: a #GstH264NalParser
1639 * @nalu: The #GST_H264_NAL_SPS #GstH264NalUnit to parse
1640 * @sps: The #GstH264SPS to fill.
1641 *
1642 * Parses @nalu containing a Sequence Parameter Set, and fills @sps.
1643 *
1644 * Returns: a #GstH264ParserResult
1645 */
1646 GstH264ParserResult
gst_h264_parser_parse_sps(GstH264NalParser * nalparser,GstH264NalUnit * nalu,GstH264SPS * sps)1647 gst_h264_parser_parse_sps (GstH264NalParser * nalparser, GstH264NalUnit * nalu,
1648 GstH264SPS * sps)
1649 {
1650 GstH264ParserResult res = gst_h264_parse_sps (nalu, sps);
1651
1652 if (res == GST_H264_PARSER_OK) {
1653 GST_DEBUG ("adding sequence parameter set with id: %d to array", sps->id);
1654
1655 if (!gst_h264_sps_copy (&nalparser->sps[sps->id], sps))
1656 return GST_H264_PARSER_ERROR;
1657 nalparser->last_sps = &nalparser->sps[sps->id];
1658 }
1659 return res;
1660 }
1661
1662 /* Parse seq_parameter_set_data() */
1663 static gboolean
gst_h264_parse_sps_data(NalReader * nr,GstH264SPS * sps)1664 gst_h264_parse_sps_data (NalReader * nr, GstH264SPS * sps)
1665 {
1666 gint width, height;
1667 guint subwc[] = { 1, 2, 2, 1 };
1668 guint subhc[] = { 1, 2, 1, 1 };
1669
1670 memset (sps, 0, sizeof (*sps));
1671
1672 /* set default values for fields that might not be present in the bitstream
1673 and have valid defaults */
1674 sps->extension_type = GST_H264_NAL_EXTENSION_NONE;
1675 sps->chroma_format_idc = 1;
1676 memset (sps->scaling_lists_4x4, 16, 96);
1677 memset (sps->scaling_lists_8x8, 16, 384);
1678
1679 READ_UINT8 (nr, sps->profile_idc, 8);
1680 READ_UINT8 (nr, sps->constraint_set0_flag, 1);
1681 READ_UINT8 (nr, sps->constraint_set1_flag, 1);
1682 READ_UINT8 (nr, sps->constraint_set2_flag, 1);
1683 READ_UINT8 (nr, sps->constraint_set3_flag, 1);
1684 READ_UINT8 (nr, sps->constraint_set4_flag, 1);
1685 READ_UINT8 (nr, sps->constraint_set5_flag, 1);
1686
1687 /* skip reserved_zero_2bits */
1688 if (!nal_reader_skip (nr, 2))
1689 goto error;
1690
1691 READ_UINT8 (nr, sps->level_idc, 8);
1692
1693 READ_UE_MAX (nr, sps->id, GST_H264_MAX_SPS_COUNT - 1);
1694
1695 if (sps->profile_idc == 100 || sps->profile_idc == 110 ||
1696 sps->profile_idc == 122 || sps->profile_idc == 244 ||
1697 sps->profile_idc == 44 || sps->profile_idc == 83 ||
1698 sps->profile_idc == 86 || sps->profile_idc == 118 ||
1699 sps->profile_idc == 128 || sps->profile_idc == 138 ||
1700 sps->profile_idc == 139 || sps->profile_idc == 134 ||
1701 sps->profile_idc == 135) {
1702 READ_UE_MAX (nr, sps->chroma_format_idc, 3);
1703 if (sps->chroma_format_idc == 3)
1704 READ_UINT8 (nr, sps->separate_colour_plane_flag, 1);
1705
1706 READ_UE_MAX (nr, sps->bit_depth_luma_minus8, 6);
1707 READ_UE_MAX (nr, sps->bit_depth_chroma_minus8, 6);
1708 READ_UINT8 (nr, sps->qpprime_y_zero_transform_bypass_flag, 1);
1709
1710 READ_UINT8 (nr, sps->scaling_matrix_present_flag, 1);
1711 if (sps->scaling_matrix_present_flag) {
1712 guint8 n_lists;
1713
1714 n_lists = (sps->chroma_format_idc != 3) ? 8 : 12;
1715 if (!gst_h264_parser_parse_scaling_list (nr,
1716 sps->scaling_lists_4x4, sps->scaling_lists_8x8,
1717 default_4x4_inter, default_4x4_intra,
1718 default_8x8_inter, default_8x8_intra, n_lists))
1719 goto error;
1720 }
1721 }
1722
1723 READ_UE_MAX (nr, sps->log2_max_frame_num_minus4, 12);
1724
1725 sps->max_frame_num = 1 << (sps->log2_max_frame_num_minus4 + 4);
1726
1727 READ_UE_MAX (nr, sps->pic_order_cnt_type, 2);
1728 if (sps->pic_order_cnt_type == 0) {
1729 READ_UE_MAX (nr, sps->log2_max_pic_order_cnt_lsb_minus4, 12);
1730 } else if (sps->pic_order_cnt_type == 1) {
1731 guint i;
1732
1733 READ_UINT8 (nr, sps->delta_pic_order_always_zero_flag, 1);
1734 READ_SE (nr, sps->offset_for_non_ref_pic);
1735 READ_SE (nr, sps->offset_for_top_to_bottom_field);
1736 READ_UE_MAX (nr, sps->num_ref_frames_in_pic_order_cnt_cycle, 255);
1737
1738 for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++)
1739 READ_SE (nr, sps->offset_for_ref_frame[i]);
1740 }
1741
1742 READ_UE (nr, sps->num_ref_frames);
1743 READ_UINT8 (nr, sps->gaps_in_frame_num_value_allowed_flag, 1);
1744 READ_UE (nr, sps->pic_width_in_mbs_minus1);
1745 READ_UE (nr, sps->pic_height_in_map_units_minus1);
1746 READ_UINT8 (nr, sps->frame_mbs_only_flag, 1);
1747
1748 if (!sps->frame_mbs_only_flag)
1749 READ_UINT8 (nr, sps->mb_adaptive_frame_field_flag, 1);
1750
1751 READ_UINT8 (nr, sps->direct_8x8_inference_flag, 1);
1752 READ_UINT8 (nr, sps->frame_cropping_flag, 1);
1753 if (sps->frame_cropping_flag) {
1754 READ_UE (nr, sps->frame_crop_left_offset);
1755 READ_UE (nr, sps->frame_crop_right_offset);
1756 READ_UE (nr, sps->frame_crop_top_offset);
1757 READ_UE (nr, sps->frame_crop_bottom_offset);
1758 }
1759
1760 READ_UINT8 (nr, sps->vui_parameters_present_flag, 1);
1761 if (sps->vui_parameters_present_flag)
1762 if (!gst_h264_parse_vui_parameters (sps, nr))
1763 goto error;
1764
1765 /* calculate ChromaArrayType */
1766 if (!sps->separate_colour_plane_flag)
1767 sps->chroma_array_type = sps->chroma_format_idc;
1768
1769 /* Calculate width and height */
1770 width = (sps->pic_width_in_mbs_minus1 + 1);
1771 width *= 16;
1772 height = (sps->pic_height_in_map_units_minus1 + 1);
1773 height *= 16 * (2 - sps->frame_mbs_only_flag);
1774 GST_LOG ("initial width=%d, height=%d", width, height);
1775 if (width < 0 || height < 0) {
1776 GST_WARNING ("invalid width/height in SPS");
1777 goto error;
1778 }
1779
1780 sps->width = width;
1781 sps->height = height;
1782
1783 if (sps->frame_cropping_flag) {
1784 const guint crop_unit_x = subwc[sps->chroma_format_idc];
1785 const guint crop_unit_y =
1786 subhc[sps->chroma_format_idc] * (2 - sps->frame_mbs_only_flag);
1787
1788 width -= (sps->frame_crop_left_offset + sps->frame_crop_right_offset)
1789 * crop_unit_x;
1790 height -= (sps->frame_crop_top_offset + sps->frame_crop_bottom_offset)
1791 * crop_unit_y;
1792
1793 sps->crop_rect_width = width;
1794 sps->crop_rect_height = height;
1795 sps->crop_rect_x = sps->frame_crop_left_offset * crop_unit_x;
1796 sps->crop_rect_y = sps->frame_crop_top_offset * crop_unit_y;
1797
1798 GST_LOG ("crop_rectangle x=%u y=%u width=%u, height=%u", sps->crop_rect_x,
1799 sps->crop_rect_y, width, height);
1800 }
1801
1802 sps->fps_num_removed = 0;
1803 sps->fps_den_removed = 1;
1804
1805 return TRUE;
1806
1807 error:
1808 return FALSE;
1809 }
1810
1811 /* Parse subset_seq_parameter_set() data for MVC */
1812 static gboolean
gst_h264_parse_sps_mvc_data(NalReader * nr,GstH264SPS * sps)1813 gst_h264_parse_sps_mvc_data (NalReader * nr, GstH264SPS * sps)
1814 {
1815 GstH264SPSExtMVC *const mvc = &sps->extension.mvc;
1816 guint8 bit_equal_to_one;
1817 guint i, j, k;
1818
1819 READ_UINT8 (nr, bit_equal_to_one, 1);
1820 if (!bit_equal_to_one)
1821 return FALSE;
1822
1823 sps->extension_type = GST_H264_NAL_EXTENSION_MVC;
1824
1825 READ_UE_MAX (nr, mvc->num_views_minus1, GST_H264_MAX_VIEW_COUNT - 1);
1826
1827 mvc->view = g_new0 (GstH264SPSExtMVCView, mvc->num_views_minus1 + 1);
1828 if (!mvc->view)
1829 goto error_allocation_failed;
1830
1831 for (i = 0; i <= mvc->num_views_minus1; i++)
1832 READ_UE_MAX (nr, mvc->view[i].view_id, GST_H264_MAX_VIEW_ID);
1833
1834 for (i = 1; i <= mvc->num_views_minus1; i++) {
1835 /* for RefPicList0 */
1836 READ_UE_MAX (nr, mvc->view[i].num_anchor_refs_l0, 15);
1837 for (j = 0; j < mvc->view[i].num_anchor_refs_l0; j++) {
1838 READ_UE_MAX (nr, mvc->view[i].anchor_ref_l0[j], GST_H264_MAX_VIEW_ID);
1839 }
1840
1841 /* for RefPicList1 */
1842 READ_UE_MAX (nr, mvc->view[i].num_anchor_refs_l1, 15);
1843 for (j = 0; j < mvc->view[i].num_anchor_refs_l1; j++) {
1844 READ_UE_MAX (nr, mvc->view[i].anchor_ref_l1[j], GST_H264_MAX_VIEW_ID);
1845 }
1846 }
1847
1848 for (i = 1; i <= mvc->num_views_minus1; i++) {
1849 /* for RefPicList0 */
1850 READ_UE_MAX (nr, mvc->view[i].num_non_anchor_refs_l0, 15);
1851 for (j = 0; j < mvc->view[i].num_non_anchor_refs_l0; j++) {
1852 READ_UE_MAX (nr, mvc->view[i].non_anchor_ref_l0[j], GST_H264_MAX_VIEW_ID);
1853 }
1854
1855 /* for RefPicList1 */
1856 READ_UE_MAX (nr, mvc->view[i].num_non_anchor_refs_l1, 15);
1857 for (j = 0; j < mvc->view[i].num_non_anchor_refs_l1; j++) {
1858 READ_UE_MAX (nr, mvc->view[i].non_anchor_ref_l1[j], GST_H264_MAX_VIEW_ID);
1859 }
1860 }
1861
1862 READ_UE_MAX (nr, mvc->num_level_values_signalled_minus1, 63);
1863
1864 mvc->level_value =
1865 g_new0 (GstH264SPSExtMVCLevelValue,
1866 mvc->num_level_values_signalled_minus1 + 1);
1867 if (!mvc->level_value)
1868 goto error_allocation_failed;
1869
1870 for (i = 0; i <= mvc->num_level_values_signalled_minus1; i++) {
1871 GstH264SPSExtMVCLevelValue *const level_value = &mvc->level_value[i];
1872
1873 READ_UINT8 (nr, level_value->level_idc, 8);
1874
1875 READ_UE_MAX (nr, level_value->num_applicable_ops_minus1, 1023);
1876 level_value->applicable_op =
1877 g_new0 (GstH264SPSExtMVCLevelValueOp,
1878 level_value->num_applicable_ops_minus1 + 1);
1879 if (!level_value->applicable_op)
1880 goto error_allocation_failed;
1881
1882 for (j = 0; j <= level_value->num_applicable_ops_minus1; j++) {
1883 GstH264SPSExtMVCLevelValueOp *const op = &level_value->applicable_op[j];
1884
1885 READ_UINT8 (nr, op->temporal_id, 3);
1886
1887 READ_UE_MAX (nr, op->num_target_views_minus1, 1023);
1888 op->target_view_id = g_new (guint16, op->num_target_views_minus1 + 1);
1889 if (!op->target_view_id)
1890 goto error_allocation_failed;
1891
1892 for (k = 0; k <= op->num_target_views_minus1; k++)
1893 READ_UE_MAX (nr, op->target_view_id[k], GST_H264_MAX_VIEW_ID);
1894 READ_UE_MAX (nr, op->num_views_minus1, 1023);
1895 }
1896 }
1897 return TRUE;
1898
1899 error_allocation_failed:
1900 GST_WARNING ("failed to allocate memory");
1901 gst_h264_sps_clear (sps);
1902 return FALSE;
1903
1904 error:
1905 gst_h264_sps_clear (sps);
1906 return FALSE;
1907 }
1908
1909 /**
1910 * gst_h264_parse_sps:
1911 * @nalu: The #GST_H264_NAL_SPS #GstH264NalUnit to parse
1912 * @sps: The #GstH264SPS to fill.
1913 *
1914 * Parses @data, and fills the @sps structure.
1915 *
1916 * Returns: a #GstH264ParserResult
1917 */
1918 GstH264ParserResult
gst_h264_parse_sps(GstH264NalUnit * nalu,GstH264SPS * sps)1919 gst_h264_parse_sps (GstH264NalUnit * nalu, GstH264SPS * sps)
1920 {
1921 NalReader nr;
1922
1923 GST_DEBUG ("parsing SPS");
1924
1925 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
1926 nalu->size - nalu->header_bytes);
1927
1928 if (!gst_h264_parse_sps_data (&nr, sps))
1929 goto error;
1930
1931 sps->valid = TRUE;
1932
1933 return GST_H264_PARSER_OK;
1934
1935 error:
1936 GST_WARNING ("error parsing \"Sequence parameter set\"");
1937 sps->valid = FALSE;
1938 return GST_H264_PARSER_ERROR;
1939 }
1940
1941 /**
1942 * gst_h264_parser_parse_subset_sps:
1943 * @nalparser: a #GstH264NalParser
1944 * @nalu: The #GST_H264_NAL_SUBSET_SPS #GstH264NalUnit to parse
1945 * @sps: The #GstH264SPS to fill.
1946 *
1947 * Parses @data, and fills in the @sps structure.
1948 *
1949 * This function fully parses @data and allocates all the necessary
1950 * data structures needed for MVC extensions. The resulting @sps
1951 * structure shall be deallocated with gst_h264_sps_clear() when it is
1952 * no longer needed.
1953 *
1954 * Note: if the caller doesn't need any of the MVC-specific data, then
1955 * gst_h264_parser_parse_sps() is more efficient because those extra
1956 * syntax elements are not parsed and no extra memory is allocated.
1957 *
1958 * Returns: a #GstH264ParserResult
1959 *
1960 * Since: 1.6
1961 */
1962 GstH264ParserResult
gst_h264_parser_parse_subset_sps(GstH264NalParser * nalparser,GstH264NalUnit * nalu,GstH264SPS * sps)1963 gst_h264_parser_parse_subset_sps (GstH264NalParser * nalparser,
1964 GstH264NalUnit * nalu, GstH264SPS * sps)
1965 {
1966 GstH264ParserResult res;
1967
1968 res = gst_h264_parse_subset_sps (nalu, sps);
1969 if (res == GST_H264_PARSER_OK) {
1970 GST_DEBUG ("adding sequence parameter set with id: %d to array", sps->id);
1971
1972 if (!gst_h264_sps_copy (&nalparser->sps[sps->id], sps)) {
1973 gst_h264_sps_clear (sps);
1974 return GST_H264_PARSER_ERROR;
1975 }
1976 nalparser->last_sps = &nalparser->sps[sps->id];
1977 }
1978 return res;
1979 }
1980
1981 /**
1982 * gst_h264_parse_subset_sps:
1983 * @nalu: The #GST_H264_NAL_SUBSET_SPS #GstH264NalUnit to parse
1984 * @sps: The #GstH264SPS to fill.
1985 *
1986 * Parses @data, and fills in the @sps structure.
1987 *
1988 * This function fully parses @data and allocates all the necessary
1989 * data structures needed for MVC extensions. The resulting @sps
1990 * structure shall be deallocated with gst_h264_sps_clear() when it is
1991 * no longer needed.
1992 *
1993 * Note: if the caller doesn't need any of the MVC-specific data, then
1994 * gst_h264_parser_parse_sps() is more efficient because those extra
1995 * syntax elements are not parsed and no extra memory is allocated.
1996 *
1997 * Returns: a #GstH264ParserResult
1998 *
1999 * Since: 1.6
2000 */
2001 GstH264ParserResult
gst_h264_parse_subset_sps(GstH264NalUnit * nalu,GstH264SPS * sps)2002 gst_h264_parse_subset_sps (GstH264NalUnit * nalu, GstH264SPS * sps)
2003 {
2004 NalReader nr;
2005
2006 GST_DEBUG ("parsing Subset SPS");
2007
2008 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
2009 nalu->size - nalu->header_bytes);
2010
2011 if (!gst_h264_parse_sps_data (&nr, sps))
2012 goto error;
2013
2014 if (sps->profile_idc == GST_H264_PROFILE_MULTIVIEW_HIGH ||
2015 sps->profile_idc == GST_H264_PROFILE_STEREO_HIGH) {
2016 if (!gst_h264_parse_sps_mvc_data (&nr, sps))
2017 goto error;
2018 }
2019
2020 sps->valid = TRUE;
2021 return GST_H264_PARSER_OK;
2022
2023 error:
2024 GST_WARNING ("error parsing \"Subset sequence parameter set\"");
2025 gst_h264_sps_clear (sps);
2026 sps->valid = FALSE;
2027 return GST_H264_PARSER_ERROR;
2028 }
2029
2030 /**
2031 * gst_h264_parse_pps:
2032 * @nalparser: a #GstH264NalParser
2033 * @nalu: The #GST_H264_NAL_PPS #GstH264NalUnit to parse
2034 * @pps: The #GstH264PPS to fill.
2035 *
2036 * Parses @data, and fills the @pps structure.
2037 *
2038 * The resulting @pps data structure shall be deallocated with the
2039 * gst_h264_pps_clear() function when it is no longer needed, or prior
2040 * to parsing a new PPS NAL unit.
2041 *
2042 * Returns: a #GstH264ParserResult
2043 */
2044 GstH264ParserResult
gst_h264_parse_pps(GstH264NalParser * nalparser,GstH264NalUnit * nalu,GstH264PPS * pps)2045 gst_h264_parse_pps (GstH264NalParser * nalparser, GstH264NalUnit * nalu,
2046 GstH264PPS * pps)
2047 {
2048 NalReader nr;
2049 GstH264SPS *sps;
2050 gint sps_id;
2051 gint qp_bd_offset;
2052
2053 GST_DEBUG ("parsing PPS");
2054
2055 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
2056 nalu->size - nalu->header_bytes);
2057
2058 memset (pps, 0, sizeof (*pps));
2059
2060 READ_UE_MAX (&nr, pps->id, GST_H264_MAX_PPS_COUNT - 1);
2061 READ_UE_MAX (&nr, sps_id, GST_H264_MAX_SPS_COUNT - 1);
2062
2063 sps = gst_h264_parser_get_sps (nalparser, sps_id);
2064 if (!sps) {
2065 GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
2066 sps_id);
2067 return GST_H264_PARSER_BROKEN_LINK;
2068 }
2069 pps->sequence = sps;
2070 qp_bd_offset = 6 * (sps->bit_depth_luma_minus8 +
2071 sps->separate_colour_plane_flag);
2072
2073 /* set default values for fields that might not be present in the bitstream
2074 and have valid defaults */
2075 memcpy (&pps->scaling_lists_4x4, &sps->scaling_lists_4x4, 96);
2076 memcpy (&pps->scaling_lists_8x8, &sps->scaling_lists_8x8, 384);
2077
2078 READ_UINT8 (&nr, pps->entropy_coding_mode_flag, 1);
2079 READ_UINT8 (&nr, pps->pic_order_present_flag, 1);
2080 READ_UE_MAX (&nr, pps->num_slice_groups_minus1, 7);
2081 if (pps->num_slice_groups_minus1 > 0) {
2082 READ_UE_MAX (&nr, pps->slice_group_map_type, 6);
2083
2084 if (pps->slice_group_map_type == 0) {
2085 gint i;
2086
2087 for (i = 0; i <= pps->num_slice_groups_minus1; i++)
2088 READ_UE (&nr, pps->run_length_minus1[i]);
2089 } else if (pps->slice_group_map_type == 2) {
2090 gint i;
2091
2092 for (i = 0; i < pps->num_slice_groups_minus1; i++) {
2093 READ_UE (&nr, pps->top_left[i]);
2094 READ_UE (&nr, pps->bottom_right[i]);
2095 }
2096 } else if (pps->slice_group_map_type >= 3 && pps->slice_group_map_type <= 5) {
2097 READ_UINT8 (&nr, pps->slice_group_change_direction_flag, 1);
2098 READ_UE (&nr, pps->slice_group_change_rate_minus1);
2099 } else if (pps->slice_group_map_type == 6) {
2100 gint bits;
2101 gint i;
2102
2103 READ_UE (&nr, pps->pic_size_in_map_units_minus1);
2104 bits = g_bit_storage (pps->num_slice_groups_minus1);
2105
2106 pps->slice_group_id =
2107 g_new (guint8, pps->pic_size_in_map_units_minus1 + 1);
2108 for (i = 0; i <= pps->pic_size_in_map_units_minus1; i++)
2109 READ_UINT8 (&nr, pps->slice_group_id[i], bits);
2110 }
2111 }
2112
2113 READ_UE_MAX (&nr, pps->num_ref_idx_l0_active_minus1, 31);
2114 READ_UE_MAX (&nr, pps->num_ref_idx_l1_active_minus1, 31);
2115 READ_UINT8 (&nr, pps->weighted_pred_flag, 1);
2116 READ_UINT8 (&nr, pps->weighted_bipred_idc, 2);
2117 READ_SE_ALLOWED (&nr, pps->pic_init_qp_minus26, -(26 + qp_bd_offset), 25);
2118 READ_SE_ALLOWED (&nr, pps->pic_init_qs_minus26, -26, 25);
2119 READ_SE_ALLOWED (&nr, pps->chroma_qp_index_offset, -12, 12);
2120 pps->second_chroma_qp_index_offset = pps->chroma_qp_index_offset;
2121 READ_UINT8 (&nr, pps->deblocking_filter_control_present_flag, 1);
2122 READ_UINT8 (&nr, pps->constrained_intra_pred_flag, 1);
2123 READ_UINT8 (&nr, pps->redundant_pic_cnt_present_flag, 1);
2124
2125 if (!nal_reader_has_more_data (&nr))
2126 goto done;
2127
2128 READ_UINT8 (&nr, pps->transform_8x8_mode_flag, 1);
2129
2130 READ_UINT8 (&nr, pps->pic_scaling_matrix_present_flag, 1);
2131 if (pps->pic_scaling_matrix_present_flag) {
2132 guint8 n_lists;
2133
2134 n_lists = 6 + ((sps->chroma_format_idc != 3) ? 2 : 6) *
2135 pps->transform_8x8_mode_flag;
2136
2137 if (sps->scaling_matrix_present_flag) {
2138 if (!gst_h264_parser_parse_scaling_list (&nr,
2139 pps->scaling_lists_4x4, pps->scaling_lists_8x8,
2140 sps->scaling_lists_4x4[3], sps->scaling_lists_4x4[0],
2141 sps->scaling_lists_8x8[3], sps->scaling_lists_8x8[0], n_lists))
2142 goto error;
2143 } else {
2144 if (!gst_h264_parser_parse_scaling_list (&nr,
2145 pps->scaling_lists_4x4, pps->scaling_lists_8x8,
2146 default_4x4_inter, default_4x4_intra,
2147 default_8x8_inter, default_8x8_intra, n_lists))
2148 goto error;
2149 }
2150 }
2151
2152 READ_SE_ALLOWED (&nr, pps->second_chroma_qp_index_offset, -12, 12);
2153
2154 done:
2155 pps->valid = TRUE;
2156 return GST_H264_PARSER_OK;
2157
2158 error:
2159 GST_WARNING ("error parsing \"Picture parameter set\"");
2160 pps->valid = FALSE;
2161 gst_h264_pps_clear (pps);
2162 return GST_H264_PARSER_ERROR;
2163 }
2164
2165 /**
2166 * gst_h264_parser_parse_pps:
2167 * @nalparser: a #GstH264NalParser
2168 * @nalu: The #GST_H264_NAL_PPS #GstH264NalUnit to parse
2169 * @pps: The #GstH264PPS to fill.
2170 *
2171 * Parses @nalu containing a Picture Parameter Set, and fills @pps.
2172 *
2173 * The resulting @pps data structure must be deallocated by the caller using
2174 * gst_h264_pps_clear().
2175 *
2176 * Returns: a #GstH264ParserResult
2177 */
2178 GstH264ParserResult
gst_h264_parser_parse_pps(GstH264NalParser * nalparser,GstH264NalUnit * nalu,GstH264PPS * pps)2179 gst_h264_parser_parse_pps (GstH264NalParser * nalparser,
2180 GstH264NalUnit * nalu, GstH264PPS * pps)
2181 {
2182 GstH264ParserResult res = gst_h264_parse_pps (nalparser, nalu, pps);
2183
2184 if (res == GST_H264_PARSER_OK) {
2185 GST_DEBUG ("adding picture parameter set with id: %d to array", pps->id);
2186
2187 if (!gst_h264_pps_copy (&nalparser->pps[pps->id], pps))
2188 return GST_H264_PARSER_ERROR;
2189 nalparser->last_pps = &nalparser->pps[pps->id];
2190 }
2191
2192 return res;
2193 }
2194
2195 /**
2196 * gst_h264_pps_clear:
2197 * @pps: The #GstH264PPS to free
2198 *
2199 * Clears all @pps internal resources.
2200 *
2201 * Since: 1.4
2202 */
2203 void
gst_h264_pps_clear(GstH264PPS * pps)2204 gst_h264_pps_clear (GstH264PPS * pps)
2205 {
2206 g_return_if_fail (pps != NULL);
2207
2208 g_free (pps->slice_group_id);
2209 pps->slice_group_id = NULL;
2210 }
2211
2212 /**
2213 * gst_h264_parser_parse_slice_hdr:
2214 * @nalparser: a #GstH264NalParser
2215 * @nalu: The #GST_H264_NAL_SLICE to #GST_H264_NAL_SLICE_IDR #GstH264NalUnit to parse
2216 * @slice: The #GstH264SliceHdr to fill.
2217 * @parse_pred_weight_table: Whether to parse the pred_weight_table or not
2218 * @parse_dec_ref_pic_marking: Whether to parse the dec_ref_pic_marking or not
2219 *
2220 * Parses @nalu containing a coded slice, and fills @slice.
2221 *
2222 * Returns: a #GstH264ParserResult
2223 */
2224 GstH264ParserResult
gst_h264_parser_parse_slice_hdr(GstH264NalParser * nalparser,GstH264NalUnit * nalu,GstH264SliceHdr * slice,gboolean parse_pred_weight_table,gboolean parse_dec_ref_pic_marking)2225 gst_h264_parser_parse_slice_hdr (GstH264NalParser * nalparser,
2226 GstH264NalUnit * nalu, GstH264SliceHdr * slice,
2227 gboolean parse_pred_weight_table, gboolean parse_dec_ref_pic_marking)
2228 {
2229 NalReader nr;
2230 gint pps_id;
2231 GstH264PPS *pps;
2232 GstH264SPS *sps;
2233 guint start_pos, start_epb;
2234
2235 memset (slice, 0, sizeof (*slice));
2236
2237 if (!nalu->size) {
2238 GST_DEBUG ("Invalid Nal Unit");
2239 return GST_H264_PARSER_ERROR;
2240 }
2241
2242 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
2243 nalu->size - nalu->header_bytes);
2244
2245 READ_UE (&nr, slice->first_mb_in_slice);
2246 READ_UE (&nr, slice->type);
2247
2248 GST_DEBUG ("parsing \"Slice header\", slice type %u", slice->type);
2249
2250 READ_UE_MAX (&nr, pps_id, GST_H264_MAX_PPS_COUNT - 1);
2251 pps = gst_h264_parser_get_pps (nalparser, pps_id);
2252
2253 if (!pps) {
2254 GST_WARNING ("couldn't find associated picture parameter set with id: %d",
2255 pps_id);
2256
2257 return GST_H264_PARSER_BROKEN_LINK;
2258 }
2259
2260 slice->pps = pps;
2261 sps = pps->sequence;
2262 if (!sps) {
2263 GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
2264 pps->id);
2265 return GST_H264_PARSER_BROKEN_LINK;
2266 }
2267
2268 /* Check we can actually parse this slice (AVC, MVC headers only) */
2269 if (sps->extension_type && sps->extension_type != GST_H264_NAL_EXTENSION_MVC) {
2270 GST_WARNING ("failed to parse unsupported slice header");
2271 return GST_H264_PARSER_BROKEN_DATA;
2272 }
2273
2274 /* set default values for fields that might not be present in the bitstream
2275 and have valid defaults */
2276 if (GST_H264_IS_I_SLICE (slice)) {
2277 slice->num_ref_idx_l0_active_minus1 = 0;
2278 slice->num_ref_idx_l1_active_minus1 = 0;
2279 } else {
2280 slice->num_ref_idx_l0_active_minus1 = pps->num_ref_idx_l0_active_minus1;
2281
2282 if (GST_H264_IS_B_SLICE (slice))
2283 slice->num_ref_idx_l1_active_minus1 = pps->num_ref_idx_l1_active_minus1;
2284 else
2285 slice->num_ref_idx_l1_active_minus1 = 0;
2286 }
2287
2288 if (sps->separate_colour_plane_flag)
2289 READ_UINT8 (&nr, slice->colour_plane_id, 2);
2290
2291 READ_UINT16 (&nr, slice->frame_num, sps->log2_max_frame_num_minus4 + 4);
2292
2293 if (!sps->frame_mbs_only_flag) {
2294 READ_UINT8 (&nr, slice->field_pic_flag, 1);
2295 if (slice->field_pic_flag)
2296 READ_UINT8 (&nr, slice->bottom_field_flag, 1);
2297 }
2298
2299 /* calculate MaxPicNum */
2300 if (slice->field_pic_flag)
2301 slice->max_pic_num = 2 * sps->max_frame_num;
2302 else
2303 slice->max_pic_num = sps->max_frame_num;
2304
2305 if (nalu->idr_pic_flag)
2306 READ_UE_MAX (&nr, slice->idr_pic_id, G_MAXUINT16);
2307
2308 start_pos = nal_reader_get_pos (&nr);
2309 start_epb = nal_reader_get_epb_count (&nr);
2310
2311 if (sps->pic_order_cnt_type == 0) {
2312 READ_UINT16 (&nr, slice->pic_order_cnt_lsb,
2313 sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
2314
2315 if (pps->pic_order_present_flag && !slice->field_pic_flag)
2316 READ_SE (&nr, slice->delta_pic_order_cnt_bottom);
2317 }
2318
2319 if (sps->pic_order_cnt_type == 1 && !sps->delta_pic_order_always_zero_flag) {
2320 READ_SE (&nr, slice->delta_pic_order_cnt[0]);
2321 if (pps->pic_order_present_flag && !slice->field_pic_flag)
2322 READ_SE (&nr, slice->delta_pic_order_cnt[1]);
2323 }
2324
2325 slice->pic_order_cnt_bit_size = (nal_reader_get_pos (&nr) - start_pos) -
2326 (8 * (nal_reader_get_epb_count (&nr) - start_epb));
2327
2328 if (pps->redundant_pic_cnt_present_flag)
2329 READ_UE_MAX (&nr, slice->redundant_pic_cnt, G_MAXINT8);
2330
2331 if (GST_H264_IS_B_SLICE (slice))
2332 READ_UINT8 (&nr, slice->direct_spatial_mv_pred_flag, 1);
2333
2334 if (GST_H264_IS_P_SLICE (slice) || GST_H264_IS_SP_SLICE (slice) ||
2335 GST_H264_IS_B_SLICE (slice)) {
2336 READ_UINT8 (&nr, slice->num_ref_idx_active_override_flag, 1);
2337 if (slice->num_ref_idx_active_override_flag) {
2338 READ_UE_MAX (&nr, slice->num_ref_idx_l0_active_minus1, 31);
2339
2340 if (GST_H264_IS_B_SLICE (slice))
2341 READ_UE_MAX (&nr, slice->num_ref_idx_l1_active_minus1, 31);
2342 }
2343 }
2344
2345 if (!slice_parse_ref_pic_list_modification (slice, &nr,
2346 GST_H264_IS_MVC_NALU (nalu)))
2347 goto error;
2348
2349 if ((pps->weighted_pred_flag && (GST_H264_IS_P_SLICE (slice)
2350 || GST_H264_IS_SP_SLICE (slice)))
2351 || (pps->weighted_bipred_idc == 1 && GST_H264_IS_B_SLICE (slice))) {
2352 if (!gst_h264_slice_parse_pred_weight_table (slice, &nr,
2353 sps->chroma_array_type))
2354 goto error;
2355 }
2356
2357 if (nalu->ref_idc != 0) {
2358 if (!gst_h264_slice_parse_dec_ref_pic_marking (slice, nalu, &nr))
2359 goto error;
2360 }
2361
2362 if (pps->entropy_coding_mode_flag && !GST_H264_IS_I_SLICE (slice) &&
2363 !GST_H264_IS_SI_SLICE (slice))
2364 READ_UE_MAX (&nr, slice->cabac_init_idc, 2);
2365
2366 READ_SE_ALLOWED (&nr, slice->slice_qp_delta, -87, 77);
2367
2368 if (GST_H264_IS_SP_SLICE (slice) || GST_H264_IS_SI_SLICE (slice)) {
2369 if (GST_H264_IS_SP_SLICE (slice))
2370 READ_UINT8 (&nr, slice->sp_for_switch_flag, 1);
2371 READ_SE_ALLOWED (&nr, slice->slice_qs_delta, -51, 51);
2372 }
2373
2374 if (pps->deblocking_filter_control_present_flag) {
2375 READ_UE_MAX (&nr, slice->disable_deblocking_filter_idc, 2);
2376 if (slice->disable_deblocking_filter_idc != 1) {
2377 READ_SE_ALLOWED (&nr, slice->slice_alpha_c0_offset_div2, -6, 6);
2378 READ_SE_ALLOWED (&nr, slice->slice_beta_offset_div2, -6, 6);
2379 }
2380 }
2381
2382 if (pps->num_slice_groups_minus1 > 0 &&
2383 pps->slice_group_map_type >= 3 && pps->slice_group_map_type <= 5) {
2384 /* Ceil(Log2(PicSizeInMapUnits / SliceGroupChangeRate + 1)) [7-33] */
2385 guint32 PicWidthInMbs = sps->pic_width_in_mbs_minus1 + 1;
2386 guint32 PicHeightInMapUnits = sps->pic_height_in_map_units_minus1 + 1;
2387 guint32 PicSizeInMapUnits = PicWidthInMbs * PicHeightInMapUnits;
2388 guint32 SliceGroupChangeRate = pps->slice_group_change_rate_minus1 + 1;
2389 const guint n = ceil_log2 (PicSizeInMapUnits / SliceGroupChangeRate + 1);
2390 READ_UINT16 (&nr, slice->slice_group_change_cycle, n);
2391 }
2392
2393 slice->header_size = nal_reader_get_pos (&nr);
2394 slice->n_emulation_prevention_bytes = nal_reader_get_epb_count (&nr);
2395
2396 return GST_H264_PARSER_OK;
2397
2398 error:
2399 GST_WARNING ("error parsing \"Slice header\"");
2400 return GST_H264_PARSER_ERROR;
2401 }
2402
2403 /* Free MVC-specific data from subset SPS header */
2404 static void
gst_h264_sps_mvc_clear(GstH264SPS * sps)2405 gst_h264_sps_mvc_clear (GstH264SPS * sps)
2406 {
2407 GstH264SPSExtMVC *const mvc = &sps->extension.mvc;
2408 guint i, j;
2409
2410 g_assert (sps->extension_type == GST_H264_NAL_EXTENSION_MVC);
2411
2412 g_free (mvc->view);
2413 mvc->view = NULL;
2414
2415 for (i = 0; i <= mvc->num_level_values_signalled_minus1; i++) {
2416 GstH264SPSExtMVCLevelValue *const level_value = &mvc->level_value[i];
2417
2418 for (j = 0; j <= level_value->num_applicable_ops_minus1; j++) {
2419 g_free (level_value->applicable_op[j].target_view_id);
2420 level_value->applicable_op[j].target_view_id = NULL;
2421 }
2422 g_free (level_value->applicable_op);
2423 level_value->applicable_op = NULL;
2424 }
2425 g_free (mvc->level_value);
2426 mvc->level_value = NULL;
2427
2428 /* All meaningful MVC info are now gone, just pretend to be a
2429 * standard AVC struct now */
2430 sps->extension_type = GST_H264_NAL_EXTENSION_NONE;
2431 }
2432
2433 /**
2434 * gst_h264_sps_clear:
2435 * @sps: The #GstH264SPS to free
2436 *
2437 * Clears all @sps internal resources.
2438 *
2439 * Since: 1.6
2440 */
2441 void
gst_h264_sps_clear(GstH264SPS * sps)2442 gst_h264_sps_clear (GstH264SPS * sps)
2443 {
2444 g_return_if_fail (sps != NULL);
2445
2446 switch (sps->extension_type) {
2447 case GST_H264_NAL_EXTENSION_MVC:
2448 gst_h264_sps_mvc_clear (sps);
2449 break;
2450 }
2451 }
2452
2453 /**
2454 * gst_h264_sei_clear:
2455 * sei: The #GstH264SEIMessage to clear
2456 *
2457 * Frees allocated data in @sei if any.
2458 *
2459 * Since: 1.18
2460 */
2461 void
gst_h264_sei_clear(GstH264SEIMessage * sei)2462 gst_h264_sei_clear (GstH264SEIMessage * sei)
2463 {
2464 switch (sei->payloadType) {
2465 case GST_H264_SEI_REGISTERED_USER_DATA:{
2466 GstH264RegisteredUserData *rud = &sei->payload.registered_user_data;
2467
2468 g_free ((guint8 *) rud->data);
2469 rud->data = NULL;
2470 break;
2471 }
2472 case GST_H264_SEI_UNHANDLED_PAYLOAD:{
2473 GstH264SEIUnhandledPayload *payload = &sei->payload.unhandled_payload;
2474
2475 g_free (payload->data);
2476 payload->data = NULL;
2477 payload->size = 0;
2478 break;
2479 }
2480 default:
2481 break;
2482 }
2483 }
2484
2485 /**
2486 * gst_h264_parser_parse_sei:
2487 * @nalparser: a #GstH264NalParser
2488 * @nalu: The #GST_H264_NAL_SEI #GstH264NalUnit to parse
2489 * @messages: The GArray of #GstH264SEIMessage to fill. The caller must free it when done.
2490 *
2491 * Parses @nalu containing one or more Supplementary Enhancement Information messages,
2492 * and allocates and fills the @messages array.
2493 *
2494 * Returns: a #GstH264ParserResult
2495 */
2496 GstH264ParserResult
gst_h264_parser_parse_sei(GstH264NalParser * nalparser,GstH264NalUnit * nalu,GArray ** messages)2497 gst_h264_parser_parse_sei (GstH264NalParser * nalparser, GstH264NalUnit * nalu,
2498 GArray ** messages)
2499 {
2500 NalReader nr;
2501 GstH264SEIMessage sei;
2502 GstH264ParserResult res;
2503
2504 GST_DEBUG ("parsing SEI nal");
2505 nal_reader_init (&nr, nalu->data + nalu->offset + nalu->header_bytes,
2506 nalu->size - nalu->header_bytes);
2507 *messages = g_array_new (FALSE, FALSE, sizeof (GstH264SEIMessage));
2508 g_array_set_clear_func (*messages, (GDestroyNotify) gst_h264_sei_clear);
2509
2510 do {
2511 res = gst_h264_parser_parse_sei_message (nalparser, &nr, &sei);
2512 if (res == GST_H264_PARSER_OK)
2513 g_array_append_val (*messages, sei);
2514 else
2515 break;
2516 } while (nal_reader_has_more_data (&nr));
2517
2518 return res;
2519 }
2520
2521 /**
2522 * gst_h264_parser_update_sps:
2523 * @nalparser: a #GstH264NalParser
2524 * @sps: (transfer none): a #GstH264SPS.
2525 *
2526 * Replace internal Sequence Parameter Set struct corresponding to id of @sps
2527 * with @sps. @nalparser will mark @sps as last parsed sps.
2528 *
2529 * Returns: a #GstH264ParserResult
2530 *
2531 * Since: 1.18
2532 */
2533 GstH264ParserResult
gst_h264_parser_update_sps(GstH264NalParser * nalparser,GstH264SPS * sps)2534 gst_h264_parser_update_sps (GstH264NalParser * nalparser, GstH264SPS * sps)
2535 {
2536 g_return_val_if_fail (nalparser != NULL, GST_H264_PARSER_ERROR);
2537 g_return_val_if_fail (sps != NULL, GST_H264_PARSER_ERROR);
2538 g_return_val_if_fail (sps->id >= 0 && sps->id < GST_H264_MAX_SPS_COUNT,
2539 GST_H264_PARSER_ERROR);
2540
2541 if (!sps->valid) {
2542 GST_WARNING ("Cannot update with invalid SPS");
2543 return GST_H264_PARSER_ERROR;
2544 }
2545
2546 GST_DEBUG ("Updating sequence parameter set with id: %d", sps->id);
2547
2548 if (!gst_h264_sps_copy (&nalparser->sps[sps->id], sps))
2549 return GST_H264_PARSER_ERROR;
2550
2551 nalparser->last_sps = &nalparser->sps[sps->id];
2552
2553 return GST_H264_PARSER_OK;
2554 }
2555
2556 /**
2557 * gst_h264_parser_update_pps:
2558 * @nalparser: a #GstH264NalParser
2559 * @pps: (transfer none): a #GstH264PPS.
2560 *
2561 * Replace internal Picture Parameter Set struct corresponding to id of @pps
2562 * with @pps. @nalparser will mark @pps as last parsed pps.
2563 *
2564 * Returns: a #GstH264ParserResult
2565 *
2566 * Since: 1.18
2567 */
2568 GstH264ParserResult
gst_h264_parser_update_pps(GstH264NalParser * nalparser,GstH264PPS * pps)2569 gst_h264_parser_update_pps (GstH264NalParser * nalparser, GstH264PPS * pps)
2570 {
2571 GstH264SPS *sps;
2572
2573 g_return_val_if_fail (nalparser != NULL, GST_H264_PARSER_ERROR);
2574 g_return_val_if_fail (pps != NULL, GST_H264_PARSER_ERROR);
2575 g_return_val_if_fail (pps->id >= 0 && pps->id < GST_H264_MAX_PPS_COUNT,
2576 GST_H264_PARSER_ERROR);
2577
2578 if (!pps->valid) {
2579 GST_WARNING ("Cannot update with invalid PPS");
2580 return GST_H264_PARSER_ERROR;
2581 }
2582
2583 if (!pps->sequence) {
2584 GST_WARNING ("No linked SPS struct");
2585 return GST_H264_PARSER_BROKEN_LINK;
2586 }
2587
2588 sps = gst_h264_parser_get_sps (nalparser, pps->sequence->id);
2589 if (!sps || sps != pps->sequence) {
2590 GST_WARNING ("Linked SPS is not identical to internal SPS");
2591 return GST_H264_PARSER_BROKEN_LINK;
2592 }
2593
2594 GST_DEBUG ("Updating picture parameter set with id: %d", pps->id);
2595
2596 if (!gst_h264_pps_copy (&nalparser->pps[pps->id], pps))
2597 return GST_H264_PARSER_ERROR;
2598
2599 nalparser->last_pps = &nalparser->pps[pps->id];
2600
2601 return GST_H264_PARSER_OK;
2602 }
2603
2604 /**
2605 * gst_h264_quant_matrix_8x8_get_zigzag_from_raster:
2606 * @out_quant: (out): The resulting quantization matrix
2607 * @quant: The source quantization matrix
2608 *
2609 * Converts quantization matrix @quant from raster scan order to
2610 * zigzag scan order and store the resulting factors into @out_quant.
2611 *
2612 * Note: it is an error to pass the same table in both @quant and
2613 * @out_quant arguments.
2614 *
2615 * Since: 1.4
2616 */
2617 void
gst_h264_quant_matrix_8x8_get_zigzag_from_raster(guint8 out_quant[64],const guint8 quant[64])2618 gst_h264_quant_matrix_8x8_get_zigzag_from_raster (guint8 out_quant[64],
2619 const guint8 quant[64])
2620 {
2621 guint i;
2622
2623 g_return_if_fail (out_quant != quant);
2624
2625 for (i = 0; i < 64; i++)
2626 out_quant[i] = quant[zigzag_8x8[i]];
2627 }
2628
2629 /**
2630 * gst_h264_quant_matrix_8x8_get_raster_from_zigzag:
2631 * @out_quant: (out): The resulting quantization matrix
2632 * @quant: The source quantization matrix
2633 *
2634 * Converts quantization matrix @quant from zigzag scan order to
2635 * raster scan order and store the resulting factors into @out_quant.
2636 *
2637 * Note: it is an error to pass the same table in both @quant and
2638 * @out_quant arguments.
2639 *
2640 * Since: 1.4
2641 */
2642 void
gst_h264_quant_matrix_8x8_get_raster_from_zigzag(guint8 out_quant[64],const guint8 quant[64])2643 gst_h264_quant_matrix_8x8_get_raster_from_zigzag (guint8 out_quant[64],
2644 const guint8 quant[64])
2645 {
2646 guint i;
2647
2648 g_return_if_fail (out_quant != quant);
2649
2650 for (i = 0; i < 64; i++)
2651 out_quant[zigzag_8x8[i]] = quant[i];
2652 }
2653
2654 /**
2655 * gst_h264_quant_matrix_4x4_get_zigzag_from_raster:
2656 * @out_quant: (out): The resulting quantization matrix
2657 * @quant: The source quantization matrix
2658 *
2659 * Converts quantization matrix @quant from raster scan order to
2660 * zigzag scan order and store the resulting factors into @out_quant.
2661 *
2662 * Note: it is an error to pass the same table in both @quant and
2663 * @out_quant arguments.
2664 *
2665 * Since: 1.4
2666 */
2667 void
gst_h264_quant_matrix_4x4_get_zigzag_from_raster(guint8 out_quant[16],const guint8 quant[16])2668 gst_h264_quant_matrix_4x4_get_zigzag_from_raster (guint8 out_quant[16],
2669 const guint8 quant[16])
2670 {
2671 guint i;
2672
2673 g_return_if_fail (out_quant != quant);
2674
2675 for (i = 0; i < 16; i++)
2676 out_quant[i] = quant[zigzag_4x4[i]];
2677 }
2678
2679 /**
2680 * gst_h264_quant_matrix_4x4_get_raster_from_zigzag:
2681 * @out_quant: (out): The resulting quantization matrix
2682 * @quant: The source quantization matrix
2683 *
2684 * Converts quantization matrix @quant from zigzag scan order to
2685 * raster scan order and store the resulting factors into @out_quant.
2686 *
2687 * Note: it is an error to pass the same table in both @quant and
2688 * @out_quant arguments.
2689 *
2690 * Since: 1.4
2691 */
2692 void
gst_h264_quant_matrix_4x4_get_raster_from_zigzag(guint8 out_quant[16],const guint8 quant[16])2693 gst_h264_quant_matrix_4x4_get_raster_from_zigzag (guint8 out_quant[16],
2694 const guint8 quant[16])
2695 {
2696 guint i;
2697
2698 g_return_if_fail (out_quant != quant);
2699
2700 for (i = 0; i < 16; i++)
2701 out_quant[zigzag_4x4[i]] = quant[i];
2702 }
2703
2704 /**
2705 * gst_h264_video_calculate_framerate:
2706 * @sps: Current Sequence Parameter Set
2707 * @field_pic_flag: Current @field_pic_flag, obtained from latest slice header
2708 * @pic_struct: @pic_struct value if available, 0 otherwise
2709 * @fps_num: (out): The resulting fps numerator
2710 * @fps_den: (out): The resulting fps denominator
2711 *
2712 * Calculate framerate of a video sequence using @sps VUI information,
2713 * @field_pic_flag from a slice header and @pic_struct from #GstH264PicTiming SEI
2714 * message.
2715 *
2716 * If framerate is variable or can't be determined, @fps_num will be set to 0
2717 * and @fps_den to 1.
2718 */
2719 void
gst_h264_video_calculate_framerate(const GstH264SPS * sps,guint field_pic_flag,guint pic_struct,gint * fps_num,gint * fps_den)2720 gst_h264_video_calculate_framerate (const GstH264SPS * sps,
2721 guint field_pic_flag, guint pic_struct, gint * fps_num, gint * fps_den)
2722 {
2723 gint num = 0;
2724 gint den = 1;
2725
2726 /* To calculate framerate, we use this formula:
2727 * time_scale 1 1
2728 * fps = ----------------- x --------------- x ------------------------
2729 * num_units_in_tick DeltaTfiDivisor (field_pic_flag ? 2 : 1)
2730 *
2731 * See H264 specification E2.1 for more details.
2732 */
2733
2734 if (sps) {
2735 if (sps->vui_parameters_present_flag) {
2736 const GstH264VUIParams *vui = &sps->vui_parameters;
2737 if (vui->timing_info_present_flag) {
2738 int delta_tfi_divisor = 1;
2739 num = vui->time_scale;
2740 den = vui->num_units_in_tick;
2741
2742 if (vui->pic_struct_present_flag) {
2743 switch (pic_struct) {
2744 case 1:
2745 case 2:
2746 delta_tfi_divisor = 1;
2747 break;
2748 case 0:
2749 case 3:
2750 case 4:
2751 delta_tfi_divisor = 2;
2752 break;
2753 case 5:
2754 case 6:
2755 delta_tfi_divisor = 3;
2756 break;
2757 case 7:
2758 delta_tfi_divisor = 4;
2759 break;
2760 case 8:
2761 delta_tfi_divisor = 6;
2762 break;
2763 }
2764 } else {
2765 delta_tfi_divisor = field_pic_flag ? 1 : 2;
2766 }
2767 den *= delta_tfi_divisor;
2768
2769 /* Picture is two fields ? */
2770 den *= (field_pic_flag ? 2 : 1);
2771 }
2772 }
2773 }
2774
2775 *fps_num = num;
2776 *fps_den = den;
2777 }
2778
2779 static gboolean
gst_h264_write_sei_registered_user_data(NalWriter * nw,GstH264RegisteredUserData * rud)2780 gst_h264_write_sei_registered_user_data (NalWriter * nw,
2781 GstH264RegisteredUserData * rud)
2782 {
2783 WRITE_UINT8 (nw, rud->country_code, 8);
2784 if (rud->country_code == 0xff)
2785 WRITE_UINT8 (nw, rud->country_code_extension, 8);
2786
2787 WRITE_BYTES (nw, rud->data, rud->size);
2788
2789 return TRUE;
2790
2791 error:
2792 return FALSE;
2793 }
2794
2795 static gboolean
gst_h264_write_sei_frame_packing(NalWriter * nw,GstH264FramePacking * frame_packing)2796 gst_h264_write_sei_frame_packing (NalWriter * nw,
2797 GstH264FramePacking * frame_packing)
2798 {
2799 WRITE_UE (nw, frame_packing->frame_packing_id);
2800 WRITE_UINT8 (nw, frame_packing->frame_packing_cancel_flag, 1);
2801
2802 if (!frame_packing->frame_packing_cancel_flag) {
2803 WRITE_UINT8 (nw, frame_packing->frame_packing_type, 7);
2804 WRITE_UINT8 (nw, frame_packing->quincunx_sampling_flag, 1);
2805 WRITE_UINT8 (nw, frame_packing->content_interpretation_type, 6);
2806 WRITE_UINT8 (nw, frame_packing->spatial_flipping_flag, 1);
2807 WRITE_UINT8 (nw, frame_packing->frame0_flipped_flag, 1);
2808 WRITE_UINT8 (nw, frame_packing->field_views_flag, 1);
2809 WRITE_UINT8 (nw, frame_packing->current_frame_is_frame0_flag, 1);
2810 WRITE_UINT8 (nw, frame_packing->frame0_self_contained_flag, 1);
2811 WRITE_UINT8 (nw, frame_packing->frame1_self_contained_flag, 1);
2812
2813 if (!frame_packing->quincunx_sampling_flag &&
2814 frame_packing->frame_packing_type !=
2815 GST_H264_FRAME_PACKING_TEMPORAL_INTERLEAVING) {
2816 WRITE_UINT8 (nw, frame_packing->frame0_grid_position_x, 4);
2817 WRITE_UINT8 (nw, frame_packing->frame0_grid_position_y, 4);
2818 WRITE_UINT8 (nw, frame_packing->frame1_grid_position_x, 4);
2819 WRITE_UINT8 (nw, frame_packing->frame1_grid_position_y, 4);
2820 }
2821
2822 /* frame_packing_arrangement_reserved_byte */
2823 WRITE_UINT8 (nw, 0, 8);
2824 WRITE_UE (nw, frame_packing->frame_packing_repetition_period);
2825 }
2826
2827 /* frame_packing_arrangement_extension_flag */
2828 WRITE_UINT8 (nw, 0, 1);
2829
2830 return TRUE;
2831
2832 error:
2833 return FALSE;
2834 }
2835
2836 static gboolean
gst_h264_write_sei_mastering_display_colour_volume(NalWriter * nw,GstH264MasteringDisplayColourVolume * mdcv)2837 gst_h264_write_sei_mastering_display_colour_volume (NalWriter * nw,
2838 GstH264MasteringDisplayColourVolume * mdcv)
2839 {
2840 gint i;
2841
2842 for (i = 0; i < 3; i++) {
2843 WRITE_UINT16 (nw, mdcv->display_primaries_x[i], 16);
2844 WRITE_UINT16 (nw, mdcv->display_primaries_y[i], 16);
2845 }
2846
2847 WRITE_UINT16 (nw, mdcv->white_point_x, 16);
2848 WRITE_UINT16 (nw, mdcv->white_point_y, 16);
2849 WRITE_UINT32 (nw, mdcv->max_display_mastering_luminance, 32);
2850 WRITE_UINT32 (nw, mdcv->min_display_mastering_luminance, 32);
2851
2852 return TRUE;
2853
2854 error:
2855 return FALSE;
2856 }
2857
2858 static gboolean
gst_h264_write_sei_content_light_level_info(NalWriter * nw,GstH264ContentLightLevel * cll)2859 gst_h264_write_sei_content_light_level_info (NalWriter * nw,
2860 GstH264ContentLightLevel * cll)
2861 {
2862 WRITE_UINT16 (nw, cll->max_content_light_level, 16);
2863 WRITE_UINT16 (nw, cll->max_pic_average_light_level, 16);
2864
2865 return TRUE;
2866
2867 error:
2868 return FALSE;
2869 }
2870
2871 static gboolean
gst_h264_write_sei_pic_timing(NalWriter * nw,GstH264PicTiming * tim)2872 gst_h264_write_sei_pic_timing (NalWriter * nw, GstH264PicTiming * tim)
2873 {
2874 if (tim->CpbDpbDelaysPresentFlag) {
2875 WRITE_UINT32 (nw, tim->cpb_removal_delay,
2876 tim->cpb_removal_delay_length_minus1 + 1);
2877 WRITE_UINT32 (nw, tim->dpb_output_delay,
2878 tim->dpb_output_delay_length_minus1 + 1);
2879 }
2880
2881 if (tim->pic_struct_present_flag) {
2882 const guint8 num_clock_ts_table[9] = {
2883 1, 1, 1, 2, 2, 3, 3, 2, 3
2884 };
2885 guint8 num_clock_num_ts;
2886 guint i;
2887
2888 WRITE_UINT8 (nw, tim->pic_struct, 4);
2889
2890 num_clock_num_ts = num_clock_ts_table[tim->pic_struct];
2891 for (i = 0; i < num_clock_num_ts; i++) {
2892 WRITE_UINT8 (nw, tim->clock_timestamp_flag[i], 1);
2893 if (tim->clock_timestamp_flag[i]) {
2894 GstH264ClockTimestamp *timestamp = &tim->clock_timestamp[i];
2895
2896 WRITE_UINT8 (nw, timestamp->ct_type, 2);
2897 WRITE_UINT8 (nw, timestamp->nuit_field_based_flag, 1);
2898 WRITE_UINT8 (nw, timestamp->counting_type, 5);
2899 WRITE_UINT8 (nw, timestamp->full_timestamp_flag, 1);
2900 WRITE_UINT8 (nw, timestamp->discontinuity_flag, 1);
2901 WRITE_UINT8 (nw, timestamp->cnt_dropped_flag, 1);
2902 WRITE_UINT8 (nw, timestamp->n_frames, 8);
2903
2904 if (timestamp->full_timestamp_flag) {
2905 WRITE_UINT8 (nw, timestamp->seconds_value, 6);
2906 WRITE_UINT8 (nw, timestamp->minutes_value, 6);
2907 WRITE_UINT8 (nw, timestamp->hours_value, 5);
2908 } else {
2909 WRITE_UINT8 (nw, timestamp->seconds_flag, 1);
2910 if (timestamp->seconds_flag) {
2911 WRITE_UINT8 (nw, timestamp->seconds_value, 6);
2912 WRITE_UINT8 (nw, timestamp->minutes_flag, 1);
2913 if (timestamp->minutes_flag) {
2914 WRITE_UINT8 (nw, timestamp->minutes_value, 6);
2915 WRITE_UINT8 (nw, timestamp->hours_flag, 1);
2916 if (timestamp->hours_flag)
2917 WRITE_UINT8 (nw, timestamp->hours_value, 5);
2918 }
2919 }
2920 }
2921
2922 if (tim->time_offset_length > 0) {
2923 WRITE_UINT32 (nw, timestamp->time_offset, tim->time_offset_length);
2924 }
2925 }
2926 }
2927 }
2928
2929 return TRUE;
2930
2931 error:
2932 return FALSE;
2933 }
2934
2935 static GstMemory *
gst_h264_create_sei_memory_internal(guint8 nal_prefix_size,gboolean packetized,GArray * messages)2936 gst_h264_create_sei_memory_internal (guint8 nal_prefix_size,
2937 gboolean packetized, GArray * messages)
2938 {
2939 NalWriter nw;
2940 gint i;
2941 gboolean have_written_data = FALSE;
2942
2943 nal_writer_init (&nw, nal_prefix_size, packetized);
2944
2945 if (messages->len == 0)
2946 goto error;
2947
2948 GST_DEBUG ("Create SEI nal from array, len: %d", messages->len);
2949
2950 /* nal header */
2951 /* forbidden_zero_bit */
2952 WRITE_UINT8 (&nw, 0, 1);
2953 /* nal_ref_idc, zero for sei nalu */
2954 WRITE_UINT8 (&nw, 0, 2);
2955 /* nal_unit_type */
2956 WRITE_UINT8 (&nw, GST_H264_NAL_SEI, 5);
2957
2958 for (i = 0; i < messages->len; i++) {
2959 GstH264SEIMessage *msg = &g_array_index (messages, GstH264SEIMessage, i);
2960 guint32 payload_size_data = 0;
2961 guint32 payload_size_in_bits = 0;
2962 guint32 payload_type_data = msg->payloadType;
2963 gboolean need_align = FALSE;
2964
2965 switch (payload_type_data) {
2966 case GST_H264_SEI_REGISTERED_USER_DATA:{
2967 GstH264RegisteredUserData *rud = &msg->payload.registered_user_data;
2968
2969 /* itu_t_t35_country_code: 8 bits */
2970 payload_size_data = 1;
2971 if (rud->country_code == 0xff) {
2972 /* itu_t_t35_country_code_extension_byte */
2973 payload_size_data++;
2974 }
2975
2976 payload_size_data += rud->size;
2977 break;
2978 }
2979 case GST_H264_SEI_FRAME_PACKING:{
2980 GstH264FramePacking *frame_packing = &msg->payload.frame_packing;
2981 guint leading_zeros, rest;
2982
2983 /* frame_packing_arrangement_id: exp-golomb bits */
2984 count_exp_golomb_bits (frame_packing->frame_packing_id,
2985 &leading_zeros, &rest);
2986 payload_size_in_bits = leading_zeros + rest;
2987
2988 /* frame_packing_arrangement_cancel_flag: 1 bit */
2989 payload_size_in_bits++;
2990 if (!frame_packing->frame_packing_cancel_flag) {
2991 /* frame_packing_arrangement_type: 7 bits
2992 * quincunx_sampling_flag: 1 bit
2993 * content_interpretation_type: 6 bit
2994 * spatial_flipping_flag: 1 bit
2995 * frame0_flipped_flag: 1 bit
2996 * field_views_flag: 1 bit
2997 * current_frame_is_frame0_flag: 1 bit
2998 * frame0_self_contained_flag: 1 bit
2999 * frame1_self_contained_flag: 1 bit
3000 */
3001 payload_size_in_bits += 20;
3002
3003 if (!frame_packing->quincunx_sampling_flag &&
3004 frame_packing->frame_packing_type !=
3005 GST_H264_FRAME_PACKING_TEMPORAL_INTERLEAVING) {
3006 /* frame0_grid_position_x: 4bits
3007 * frame0_grid_position_y: 4bits
3008 * frame1_grid_position_x: 4bits
3009 * frame1_grid_position_y: 4bits
3010 */
3011 payload_size_in_bits += 16;
3012 }
3013
3014 /* frame_packing_arrangement_reserved_byte: 8 bits */
3015 payload_size_in_bits += 8;
3016
3017 /* frame_packing_arrangement_repetition_period: exp-golomb bits */
3018 count_exp_golomb_bits (frame_packing->frame_packing_repetition_period,
3019 &leading_zeros, &rest);
3020 payload_size_in_bits += (leading_zeros + rest);
3021 }
3022 /* frame_packing_arrangement_extension_flag: 1 bit */
3023 payload_size_in_bits++;
3024
3025 payload_size_data = payload_size_in_bits >> 3;
3026
3027 if ((payload_size_in_bits & 0x7) != 0) {
3028 GST_INFO ("Bits for Frame Packing SEI is not byte aligned");
3029 payload_size_data++;
3030 need_align = TRUE;
3031 }
3032 break;
3033 }
3034 case GST_H264_SEI_MASTERING_DISPLAY_COLOUR_VOLUME:
3035 /* x, y 16 bits per RGB channel
3036 * x, y 16 bits white point
3037 * max, min luminance 32 bits
3038 *
3039 * (2 * 2 * 3) + (2 * 2) + (4 * 2) = 24 bytes
3040 */
3041 payload_size_data = 24;
3042 break;
3043 case GST_H264_SEI_CONTENT_LIGHT_LEVEL:
3044 /* maxCLL and maxFALL per 16 bits
3045 *
3046 * 2 * 2 = 4 bytes
3047 */
3048 payload_size_data = 4;
3049 break;
3050 case GST_H264_SEI_PIC_TIMING:{
3051 GstH264PicTiming *tim = &msg->payload.pic_timing;
3052 const guint8 num_clock_ts_table[9] = {
3053 1, 1, 1, 2, 2, 3, 3, 2, 3
3054 };
3055 guint8 num_clock_num_ts;
3056 guint i;
3057
3058 if (!tim->CpbDpbDelaysPresentFlag && !tim->pic_struct_present_flag) {
3059 GST_WARNING
3060 ("Both CpbDpbDelaysPresentFlag and pic_struct_present_flag are zero");
3061 break;
3062 }
3063
3064 if (tim->CpbDpbDelaysPresentFlag) {
3065 payload_size_in_bits = tim->cpb_removal_delay_length_minus1 + 1;
3066 payload_size_in_bits += tim->dpb_output_delay_length_minus1 + 1;
3067 }
3068
3069 if (tim->pic_struct_present_flag) {
3070 /* pic_struct: 4bits */
3071 payload_size_in_bits += 4;
3072
3073 num_clock_num_ts = num_clock_ts_table[tim->pic_struct];
3074 for (i = 0; i < num_clock_num_ts; i++) {
3075 /* clock_timestamp_flag: 1bit */
3076 payload_size_in_bits++;
3077
3078 if (tim->clock_timestamp_flag[i]) {
3079 GstH264ClockTimestamp *timestamp = &tim->clock_timestamp[i];
3080
3081 /* ct_type: 2bits
3082 * nuit_field_based_flag: 1bit
3083 * counting_type: 5bits
3084 * full_timestamp_flag: 1bit
3085 * discontinuity_flag: 1bit
3086 * cnt_dropped_flag: 1bit
3087 * n_frames: 8bits
3088 */
3089 payload_size_in_bits += 19;
3090 if (timestamp->full_timestamp_flag) {
3091 /* seconds_value: 6bits
3092 * minutes_value: 6bits
3093 * hours_value: 5bits
3094 */
3095 payload_size_in_bits += 17;
3096 } else {
3097 /* seconds_flag: 1bit */
3098 payload_size_in_bits++;
3099
3100 if (timestamp->seconds_flag) {
3101 /* seconds_value: 6bits
3102 * minutes_flag: 1bit
3103 */
3104 payload_size_in_bits += 7;
3105 if (timestamp->minutes_flag) {
3106 /* minutes_value: 6bits
3107 * hours_flag: 1bits
3108 */
3109 payload_size_in_bits += 7;
3110 if (timestamp->hours_flag) {
3111 /* hours_value: 5bits */
3112 payload_size_in_bits += 5;
3113 }
3114 }
3115 }
3116 }
3117
3118 /* time_offset_length bits */
3119 payload_size_in_bits += tim->time_offset_length;
3120 }
3121 }
3122 }
3123
3124 payload_size_data = payload_size_in_bits >> 3;
3125
3126 if ((payload_size_in_bits & 0x7) != 0) {
3127 GST_INFO ("Bits for Picture Timing SEI is not byte aligned");
3128 payload_size_data++;
3129 need_align = TRUE;
3130 }
3131 break;
3132 }
3133 default:
3134 break;
3135 }
3136
3137 if (payload_size_data == 0) {
3138 GST_FIXME ("Unsupported SEI type %d", msg->payloadType);
3139 continue;
3140 }
3141
3142 /* write payload type bytes */
3143 while (payload_type_data >= 0xff) {
3144 WRITE_UINT8 (&nw, 0xff, 8);
3145 payload_type_data -= 0xff;
3146 }
3147 WRITE_UINT8 (&nw, payload_type_data, 8);
3148
3149 /* write payload size bytes */
3150 while (payload_size_data >= 0xff) {
3151 WRITE_UINT8 (&nw, 0xff, 8);
3152 payload_size_data -= 0xff;
3153 }
3154 WRITE_UINT8 (&nw, payload_size_data, 8);
3155
3156 switch (msg->payloadType) {
3157 case GST_H264_SEI_REGISTERED_USER_DATA:
3158 GST_DEBUG ("Writing \"Registered user data\"");
3159 if (!gst_h264_write_sei_registered_user_data (&nw,
3160 &msg->payload.registered_user_data)) {
3161 GST_WARNING ("Failed to write \"Registered user data\"");
3162 goto error;
3163 }
3164 have_written_data = TRUE;
3165 break;
3166 case GST_H264_SEI_FRAME_PACKING:
3167 GST_DEBUG ("Writing \"Frame packing\"");
3168 if (!gst_h264_write_sei_frame_packing (&nw,
3169 &msg->payload.frame_packing)) {
3170 GST_WARNING ("Failed to write \"Frame packing\"");
3171 goto error;
3172 }
3173 have_written_data = TRUE;
3174 break;
3175 case GST_H264_SEI_MASTERING_DISPLAY_COLOUR_VOLUME:
3176 GST_DEBUG ("Writing \"Mastering display colour volume\"");
3177 if (!gst_h264_write_sei_mastering_display_colour_volume (&nw,
3178 &msg->payload.mastering_display_colour_volume)) {
3179 GST_WARNING ("Failed to write \"Mastering display colour volume\"");
3180 goto error;
3181 }
3182 have_written_data = TRUE;
3183 break;
3184 case GST_H264_SEI_CONTENT_LIGHT_LEVEL:
3185 GST_DEBUG ("Writing \"Content light level\"");
3186 if (!gst_h264_write_sei_content_light_level_info (&nw,
3187 &msg->payload.content_light_level)) {
3188 GST_WARNING ("Failed to write \"Content light level\"");
3189 goto error;
3190 }
3191 have_written_data = TRUE;
3192 break;
3193 case GST_H264_SEI_PIC_TIMING:
3194 GST_DEBUG ("Writing \"Picture timing\"");
3195 if (!gst_h264_write_sei_pic_timing (&nw, &msg->payload.pic_timing)) {
3196 GST_WARNING ("Failed to write \"Picture timing\"");
3197 goto error;
3198 }
3199 have_written_data = TRUE;
3200 break;
3201 default:
3202 break;
3203 }
3204
3205 if (need_align && !nal_writer_do_rbsp_trailing_bits (&nw)) {
3206 GST_WARNING ("Cannot insert traling bits");
3207 goto error;
3208 }
3209 }
3210
3211 if (!have_written_data) {
3212 GST_WARNING ("No written sei data");
3213 goto error;
3214 }
3215
3216 if (!nal_writer_do_rbsp_trailing_bits (&nw)) {
3217 GST_WARNING ("Failed to insert rbsp trailing bits");
3218 goto error;
3219 }
3220
3221 return nal_writer_reset_and_get_memory (&nw);
3222
3223 error:
3224 nal_writer_reset (&nw);
3225
3226 return NULL;
3227 }
3228
3229 /**
3230 * gst_h264_create_sei_memory:
3231 * @start_code_prefix_length: a length of start code prefix, must be 3 or 4
3232 * @messages: (transfer none): a GArray of #GstH264SEIMessage
3233 *
3234 * Creates raw byte-stream format (a.k.a Annex B type) SEI nal unit data
3235 * from @messages
3236 *
3237 * Returns: a #GstMemory containing a SEI nal unit
3238 *
3239 * Since: 1.18
3240 */
3241 GstMemory *
gst_h264_create_sei_memory(guint8 start_code_prefix_length,GArray * messages)3242 gst_h264_create_sei_memory (guint8 start_code_prefix_length, GArray * messages)
3243 {
3244 g_return_val_if_fail (start_code_prefix_length == 3
3245 || start_code_prefix_length == 4, NULL);
3246 g_return_val_if_fail (messages != NULL, NULL);
3247 g_return_val_if_fail (messages->len > 0, NULL);
3248
3249 return gst_h264_create_sei_memory_internal (start_code_prefix_length,
3250 FALSE, messages);
3251 }
3252
3253 /**
3254 * gst_h264_create_sei_memory_avc:
3255 * @nal_length_size: a size of nal length field, allowed range is [1, 4]
3256 * @messages: (transfer none): a GArray of #GstH264SEIMessage
3257 *
3258 * Creates raw packetized format SEI nal unit data from @messages
3259 *
3260 * Returns: a #GstMemory containing a SEI nal unit
3261 *
3262 * Since: 1.18
3263 */
3264 GstMemory *
gst_h264_create_sei_memory_avc(guint8 nal_length_size,GArray * messages)3265 gst_h264_create_sei_memory_avc (guint8 nal_length_size, GArray * messages)
3266 {
3267 g_return_val_if_fail (nal_length_size > 0 && nal_length_size < 5, NULL);
3268 g_return_val_if_fail (messages != NULL, NULL);
3269 g_return_val_if_fail (messages->len > 0, NULL);
3270
3271 return gst_h264_create_sei_memory_internal (nal_length_size, TRUE, messages);
3272 }
3273
3274 static GstBuffer *
gst_h264_parser_insert_sei_internal(GstH264NalParser * nalparser,guint8 nal_prefix_size,gboolean packetized,GstBuffer * au,GstMemory * sei)3275 gst_h264_parser_insert_sei_internal (GstH264NalParser * nalparser,
3276 guint8 nal_prefix_size, gboolean packetized, GstBuffer * au,
3277 GstMemory * sei)
3278 {
3279 GstH264NalUnit nalu;
3280 GstMapInfo info;
3281 GstH264ParserResult pres;
3282 guint offset = 0;
3283 GstBuffer *new_buffer = NULL;
3284
3285 if (!gst_buffer_map (au, &info, GST_MAP_READ)) {
3286 GST_ERROR ("Cannot map au buffer");
3287 return NULL;
3288 }
3289
3290 /* Find the offset of the first slice */
3291 do {
3292 if (packetized) {
3293 pres = gst_h264_parser_identify_nalu_avc (nalparser,
3294 info.data, offset, info.size, nal_prefix_size, &nalu);
3295 } else {
3296 pres = gst_h264_parser_identify_nalu (nalparser,
3297 info.data, offset, info.size, &nalu);
3298 }
3299
3300 if (pres != GST_H264_PARSER_OK && pres != GST_H264_PARSER_NO_NAL_END) {
3301 GST_DEBUG ("Failed to identify nal unit, ret: %d", pres);
3302 gst_buffer_unmap (au, &info);
3303
3304 return NULL;
3305 }
3306
3307 if ((nalu.type >= GST_H264_NAL_SLICE && nalu.type <= GST_H264_NAL_SLICE_IDR)
3308 || (nalu.type >= GST_H264_NAL_SLICE_AUX
3309 && nalu.type <= GST_H264_NAL_SLICE_DEPTH)) {
3310 GST_DEBUG ("Found slice nal type %d at offset %d",
3311 nalu.type, nalu.sc_offset);
3312 break;
3313 }
3314
3315 offset = nalu.offset + nalu.size;
3316 } while (pres == GST_H264_PARSER_OK);
3317 gst_buffer_unmap (au, &info);
3318
3319 /* found the best position now, create new buffer */
3320 new_buffer = gst_buffer_new ();
3321
3322 /* copy all metadata */
3323 if (!gst_buffer_copy_into (new_buffer, au, GST_BUFFER_COPY_METADATA, 0, -1)) {
3324 GST_ERROR ("Failed to copy metadata into new buffer");
3325 gst_clear_buffer (&new_buffer);
3326 goto out;
3327 }
3328
3329 /* copy non-slice nal */
3330 if (nalu.sc_offset > 0) {
3331 if (!gst_buffer_copy_into (new_buffer, au,
3332 GST_BUFFER_COPY_MEMORY, 0, nalu.sc_offset)) {
3333 GST_ERROR ("Failed to copy buffer");
3334 gst_clear_buffer (&new_buffer);
3335 goto out;
3336 }
3337 }
3338
3339 /* insert sei */
3340 gst_buffer_append_memory (new_buffer, gst_memory_ref (sei));
3341
3342 /* copy the rest */
3343 if (!gst_buffer_copy_into (new_buffer, au,
3344 GST_BUFFER_COPY_MEMORY, nalu.sc_offset, -1)) {
3345 GST_ERROR ("Failed to copy buffer");
3346 gst_clear_buffer (&new_buffer);
3347 goto out;
3348 }
3349
3350 out:
3351 return new_buffer;
3352 }
3353
3354 /**
3355 * gst_h264_parser_insert_sei:
3356 * @nalparser: a #GstH264NalParser
3357 * @au: (transfer none): a #GstBuffer containing AU data
3358 * @sei: (transfer none): a #GstMemory containing a SEI nal
3359 *
3360 * Copy @au into new #GstBuffer and insert @sei into the #GstBuffer.
3361 * The validation for completeness of @au and @sei is caller's responsibility.
3362 * Both @au and @sei must be byte-stream formatted
3363 *
3364 * Returns: (nullable): a SEI inserted #GstBuffer or %NULL
3365 * if cannot figure out proper position to insert a @sei
3366 *
3367 * Since: 1.18
3368 */
3369 GstBuffer *
gst_h264_parser_insert_sei(GstH264NalParser * nalparser,GstBuffer * au,GstMemory * sei)3370 gst_h264_parser_insert_sei (GstH264NalParser * nalparser, GstBuffer * au,
3371 GstMemory * sei)
3372 {
3373 g_return_val_if_fail (nalparser != NULL, NULL);
3374 g_return_val_if_fail (GST_IS_BUFFER (au), NULL);
3375 g_return_val_if_fail (sei != NULL, NULL);
3376
3377 /* the size of start code prefix (3 or 4) is not matter since it will be
3378 * scanned */
3379 return gst_h264_parser_insert_sei_internal (nalparser, 4, FALSE, au, sei);
3380 }
3381
3382 /**
3383 * gst_h264_parser_insert_sei_avc:
3384 * @nalparser: a #GstH264NalParser
3385 * @nal_length_size: a size of nal length field, allowed range is [1, 4]
3386 * @au: (transfer none): a #GstBuffer containing AU data
3387 * @sei: (transfer none): a #GstMemory containing a SEI nal
3388 *
3389 * Copy @au into new #GstBuffer and insert @sei into the #GstBuffer.
3390 * The validation for completeness of @au and @sei is caller's responsibility.
3391 * Nal prefix type of both @au and @sei must be packetized, and
3392 * also the size of nal length field must be identical to @nal_length_size
3393 *
3394 * Returns: (nullable): a SEI inserted #GstBuffer or %NULL
3395 * if cannot figure out proper position to insert a @sei
3396 *
3397 * Since: 1.18
3398 */
3399 GstBuffer *
gst_h264_parser_insert_sei_avc(GstH264NalParser * nalparser,guint8 nal_length_size,GstBuffer * au,GstMemory * sei)3400 gst_h264_parser_insert_sei_avc (GstH264NalParser * nalparser,
3401 guint8 nal_length_size, GstBuffer * au, GstMemory * sei)
3402 {
3403 g_return_val_if_fail (nalparser != NULL, NULL);
3404 g_return_val_if_fail (nal_length_size > 0 && nal_length_size < 5, NULL);
3405 g_return_val_if_fail (GST_IS_BUFFER (au), NULL);
3406 g_return_val_if_fail (sei != NULL, NULL);
3407
3408 /* the size of start code prefix (3 or 4) is not matter since it will be
3409 * scanned */
3410 return gst_h264_parser_insert_sei_internal (nalparser, nal_length_size, TRUE,
3411 au, sei);
3412 }
3413