• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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