documentation: fixed a heap o' typos
[platform/upstream/gstreamer.git] / gst / videoparsers / gsth264parse.c
1 /* GStreamer H.264 Parser
2  * Copyright (C) <2010> Collabora ltd
3  * Copyright (C) <2010> Nokia Corporation
4  * Copyright (C) <2011> Intel Corporation
5  *
6  * Copyright (C) <2010> Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
7  * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #  include "config.h"
27 #endif
28
29 #include <gst/base/base.h>
30 #include <gst/pbutils/pbutils.h>
31 #include <gst/video/video.h>
32 #include "gsth264parse.h"
33
34 #include <string.h>
35
36 GST_DEBUG_CATEGORY (h264_parse_debug);
37 #define GST_CAT_DEFAULT h264_parse_debug
38
39 #define DEFAULT_CONFIG_INTERVAL      (0)
40
41 enum
42 {
43   PROP_0,
44   PROP_CONFIG_INTERVAL
45 };
46
47 enum
48 {
49   GST_H264_PARSE_FORMAT_NONE,
50   GST_H264_PARSE_FORMAT_AVC,
51   GST_H264_PARSE_FORMAT_BYTE,
52   GST_H264_PARSE_FORMAT_AVC3
53 };
54
55 enum
56 {
57   GST_H264_PARSE_ALIGN_NONE = 0,
58   GST_H264_PARSE_ALIGN_NAL,
59   GST_H264_PARSE_ALIGN_AU
60 };
61
62 enum
63 {
64   GST_H264_PARSE_STATE_GOT_SPS = 1 << 0,
65   GST_H264_PARSE_STATE_GOT_PPS = 1 << 1,
66   GST_H264_PARSE_STATE_GOT_SLICE = 1 << 2,
67
68   GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS = (GST_H264_PARSE_STATE_GOT_SPS |
69       GST_H264_PARSE_STATE_GOT_PPS),
70   GST_H264_PARSE_STATE_VALID_PICTURE =
71       (GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS |
72       GST_H264_PARSE_STATE_GOT_SLICE)
73 };
74
75 #define GST_H264_PARSE_STATE_VALID(parse, expected_state) \
76   (((parse)->state & (expected_state)) == (expected_state))
77
78 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
79     GST_PAD_SINK,
80     GST_PAD_ALWAYS,
81     GST_STATIC_CAPS ("video/x-h264"));
82
83 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
84     GST_PAD_SRC,
85     GST_PAD_ALWAYS,
86     GST_STATIC_CAPS ("video/x-h264, parsed = (boolean) true, "
87         "stream-format=(string) { avc, avc3, byte-stream }, "
88         "alignment=(string) { au, nal }"));
89
90 #define parent_class gst_h264_parse_parent_class
91 G_DEFINE_TYPE (GstH264Parse, gst_h264_parse, GST_TYPE_BASE_PARSE);
92
93 static void gst_h264_parse_finalize (GObject * object);
94
95 static gboolean gst_h264_parse_start (GstBaseParse * parse);
96 static gboolean gst_h264_parse_stop (GstBaseParse * parse);
97 static GstFlowReturn gst_h264_parse_handle_frame (GstBaseParse * parse,
98     GstBaseParseFrame * frame, gint * skipsize);
99 static GstFlowReturn gst_h264_parse_parse_frame (GstBaseParse * parse,
100     GstBaseParseFrame * frame);
101 static GstFlowReturn gst_h264_parse_pre_push_frame (GstBaseParse * parse,
102     GstBaseParseFrame * frame);
103
104 static void gst_h264_parse_set_property (GObject * object, guint prop_id,
105     const GValue * value, GParamSpec * pspec);
106 static void gst_h264_parse_get_property (GObject * object, guint prop_id,
107     GValue * value, GParamSpec * pspec);
108
109 static gboolean gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps);
110 static GstCaps *gst_h264_parse_get_caps (GstBaseParse * parse,
111     GstCaps * filter);
112 static gboolean gst_h264_parse_event (GstBaseParse * parse, GstEvent * event);
113 static gboolean gst_h264_parse_src_event (GstBaseParse * parse,
114     GstEvent * event);
115 static void gst_h264_parse_update_src_caps (GstH264Parse * h264parse,
116     GstCaps * caps);
117
118 static void
119 gst_h264_parse_class_init (GstH264ParseClass * klass)
120 {
121   GObjectClass *gobject_class = (GObjectClass *) klass;
122   GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
123   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
124
125   GST_DEBUG_CATEGORY_INIT (h264_parse_debug, "h264parse", 0, "h264 parser");
126
127   gobject_class->finalize = gst_h264_parse_finalize;
128   gobject_class->set_property = gst_h264_parse_set_property;
129   gobject_class->get_property = gst_h264_parse_get_property;
130
131   g_object_class_install_property (gobject_class, PROP_CONFIG_INTERVAL,
132       g_param_spec_int ("config-interval",
133           "SPS PPS Send Interval",
134           "Send SPS and PPS Insertion Interval in seconds (sprop parameter sets "
135           "will be multiplexed in the data stream when detected.) "
136           "(0 = disabled, -1 = send with every IDR frame)",
137           -1, 3600, DEFAULT_CONFIG_INTERVAL,
138           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
139
140   /* Override BaseParse vfuncs */
141   parse_class->start = GST_DEBUG_FUNCPTR (gst_h264_parse_start);
142   parse_class->stop = GST_DEBUG_FUNCPTR (gst_h264_parse_stop);
143   parse_class->handle_frame = GST_DEBUG_FUNCPTR (gst_h264_parse_handle_frame);
144   parse_class->pre_push_frame =
145       GST_DEBUG_FUNCPTR (gst_h264_parse_pre_push_frame);
146   parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_h264_parse_set_caps);
147   parse_class->get_sink_caps = GST_DEBUG_FUNCPTR (gst_h264_parse_get_caps);
148   parse_class->sink_event = GST_DEBUG_FUNCPTR (gst_h264_parse_event);
149   parse_class->src_event = GST_DEBUG_FUNCPTR (gst_h264_parse_src_event);
150
151   gst_element_class_add_static_pad_template (gstelement_class, &srctemplate);
152   gst_element_class_add_static_pad_template (gstelement_class, &sinktemplate);
153
154   gst_element_class_set_static_metadata (gstelement_class, "H.264 parser",
155       "Codec/Parser/Converter/Video",
156       "Parses H.264 streams",
157       "Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>");
158 }
159
160 static void
161 gst_h264_parse_init (GstH264Parse * h264parse)
162 {
163   h264parse->frame_out = gst_adapter_new ();
164   gst_base_parse_set_pts_interpolation (GST_BASE_PARSE (h264parse), FALSE);
165   GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (h264parse));
166   GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (h264parse));
167
168   h264parse->aud_needed = TRUE;
169   h264parse->aud_insert = TRUE;
170 }
171
172
173 static void
174 gst_h264_parse_finalize (GObject * object)
175 {
176   GstH264Parse *h264parse = GST_H264_PARSE (object);
177
178   g_object_unref (h264parse->frame_out);
179
180   G_OBJECT_CLASS (parent_class)->finalize (object);
181 }
182
183 static void
184 gst_h264_parse_reset_frame (GstH264Parse * h264parse)
185 {
186   GST_DEBUG_OBJECT (h264parse, "reset frame");
187
188   /* done parsing; reset state */
189   h264parse->current_off = -1;
190
191   h264parse->picture_start = FALSE;
192   h264parse->update_caps = FALSE;
193   h264parse->idr_pos = -1;
194   h264parse->sei_pos = -1;
195   h264parse->keyframe = FALSE;
196   h264parse->predicted = FALSE;
197   h264parse->bidirectional = FALSE;
198   h264parse->header = FALSE;
199   h264parse->frame_start = FALSE;
200   h264parse->aud_insert = TRUE;
201   h264parse->have_sps_in_frame = FALSE;
202   h264parse->have_pps_in_frame = FALSE;
203   gst_adapter_clear (h264parse->frame_out);
204 }
205
206 static void
207 gst_h264_parse_reset_stream_info (GstH264Parse * h264parse)
208 {
209   gint i;
210
211   h264parse->width = 0;
212   h264parse->height = 0;
213   h264parse->fps_num = 0;
214   h264parse->fps_den = 0;
215   h264parse->upstream_par_n = -1;
216   h264parse->upstream_par_d = -1;
217   h264parse->parsed_par_n = 0;
218   h264parse->parsed_par_d = 0;
219   h264parse->parsed_colorimetry.range = GST_VIDEO_COLOR_RANGE_UNKNOWN;
220   h264parse->parsed_colorimetry.matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
221   h264parse->parsed_colorimetry.transfer = GST_VIDEO_TRANSFER_UNKNOWN;
222   h264parse->parsed_colorimetry.primaries = GST_VIDEO_COLOR_PRIMARIES_UNKNOWN;
223
224   h264parse->have_pps = FALSE;
225   h264parse->have_sps = FALSE;
226
227   h264parse->multiview_mode = GST_VIDEO_MULTIVIEW_MODE_NONE;
228   h264parse->multiview_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE;
229   h264parse->first_in_bundle = TRUE;
230
231   h264parse->align = GST_H264_PARSE_ALIGN_NONE;
232   h264parse->format = GST_H264_PARSE_FORMAT_NONE;
233
234   h264parse->transform = FALSE;
235   h264parse->nal_length_size = 4;
236   h264parse->packetized = FALSE;
237   h264parse->push_codec = FALSE;
238
239   gst_buffer_replace (&h264parse->codec_data, NULL);
240   gst_buffer_replace (&h264parse->codec_data_in, NULL);
241
242   gst_h264_parse_reset_frame (h264parse);
243
244   for (i = 0; i < GST_H264_MAX_SPS_COUNT; i++)
245     gst_buffer_replace (&h264parse->sps_nals[i], NULL);
246   for (i = 0; i < GST_H264_MAX_PPS_COUNT; i++)
247     gst_buffer_replace (&h264parse->pps_nals[i], NULL);
248 }
249
250 static void
251 gst_h264_parse_reset (GstH264Parse * h264parse)
252 {
253   h264parse->last_report = GST_CLOCK_TIME_NONE;
254
255   h264parse->dts = GST_CLOCK_TIME_NONE;
256   h264parse->ts_trn_nb = GST_CLOCK_TIME_NONE;
257   h264parse->do_ts = TRUE;
258
259   h264parse->sent_codec_tag = FALSE;
260
261   h264parse->pending_key_unit_ts = GST_CLOCK_TIME_NONE;
262   gst_event_replace (&h264parse->force_key_unit_event, NULL);
263
264   h264parse->discont = FALSE;
265   h264parse->discard_bidirectional = FALSE;
266
267   gst_h264_parse_reset_stream_info (h264parse);
268 }
269
270 static gboolean
271 gst_h264_parse_start (GstBaseParse * parse)
272 {
273   GstH264Parse *h264parse = GST_H264_PARSE (parse);
274
275   GST_DEBUG_OBJECT (parse, "start");
276   gst_h264_parse_reset (h264parse);
277
278   h264parse->nalparser = gst_h264_nal_parser_new ();
279
280   h264parse->state = 0;
281   h264parse->dts = GST_CLOCK_TIME_NONE;
282   h264parse->ts_trn_nb = GST_CLOCK_TIME_NONE;
283   h264parse->sei_pic_struct_pres_flag = FALSE;
284   h264parse->sei_pic_struct = 0;
285   h264parse->field_pic_flag = 0;
286
287   gst_base_parse_set_min_frame_size (parse, 4);
288
289   return TRUE;
290 }
291
292 static gboolean
293 gst_h264_parse_stop (GstBaseParse * parse)
294 {
295   GstH264Parse *h264parse = GST_H264_PARSE (parse);
296
297   GST_DEBUG_OBJECT (parse, "stop");
298   gst_h264_parse_reset (h264parse);
299
300   gst_h264_nal_parser_free (h264parse->nalparser);
301
302   return TRUE;
303 }
304
305 static const gchar *
306 gst_h264_parse_get_string (GstH264Parse * parse, gboolean format, gint code)
307 {
308   if (format) {
309     switch (code) {
310       case GST_H264_PARSE_FORMAT_AVC:
311         return "avc";
312       case GST_H264_PARSE_FORMAT_BYTE:
313         return "byte-stream";
314       case GST_H264_PARSE_FORMAT_AVC3:
315         return "avc3";
316       default:
317         return "none";
318     }
319   } else {
320     switch (code) {
321       case GST_H264_PARSE_ALIGN_NAL:
322         return "nal";
323       case GST_H264_PARSE_ALIGN_AU:
324         return "au";
325       default:
326         return "none";
327     }
328   }
329 }
330
331 static void
332 gst_h264_parse_format_from_caps (GstCaps * caps, guint * format, guint * align)
333 {
334   if (format)
335     *format = GST_H264_PARSE_FORMAT_NONE;
336
337   if (align)
338     *align = GST_H264_PARSE_ALIGN_NONE;
339
340   g_return_if_fail (gst_caps_is_fixed (caps));
341
342   GST_DEBUG ("parsing caps: %" GST_PTR_FORMAT, caps);
343
344   if (caps && gst_caps_get_size (caps) > 0) {
345     GstStructure *s = gst_caps_get_structure (caps, 0);
346     const gchar *str = NULL;
347
348     if (format) {
349       if ((str = gst_structure_get_string (s, "stream-format"))) {
350         if (strcmp (str, "avc") == 0)
351           *format = GST_H264_PARSE_FORMAT_AVC;
352         else if (strcmp (str, "byte-stream") == 0)
353           *format = GST_H264_PARSE_FORMAT_BYTE;
354         else if (strcmp (str, "avc3") == 0)
355           *format = GST_H264_PARSE_FORMAT_AVC3;
356       }
357     }
358
359     if (align) {
360       if ((str = gst_structure_get_string (s, "alignment"))) {
361         if (strcmp (str, "au") == 0)
362           *align = GST_H264_PARSE_ALIGN_AU;
363         else if (strcmp (str, "nal") == 0)
364           *align = GST_H264_PARSE_ALIGN_NAL;
365       }
366     }
367   }
368 }
369
370 /* check downstream caps to configure format and alignment */
371 static void
372 gst_h264_parse_negotiate (GstH264Parse * h264parse, gint in_format,
373     GstCaps * in_caps)
374 {
375   GstCaps *caps;
376   guint format = h264parse->format;
377   guint align = h264parse->align;
378
379   g_return_if_fail ((in_caps == NULL) || gst_caps_is_fixed (in_caps));
380
381   caps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (h264parse));
382   GST_DEBUG_OBJECT (h264parse, "allowed caps: %" GST_PTR_FORMAT, caps);
383
384   /* concentrate on leading structure, since decodebin parser
385    * capsfilter always includes parser template caps */
386   if (caps) {
387     caps = gst_caps_truncate (caps);
388     GST_DEBUG_OBJECT (h264parse, "negotiating with caps: %" GST_PTR_FORMAT,
389         caps);
390   }
391
392   h264parse->can_passthrough = FALSE;
393
394   if (in_caps && caps) {
395     if (gst_caps_can_intersect (in_caps, caps)) {
396       GST_DEBUG_OBJECT (h264parse, "downstream accepts upstream caps");
397       gst_h264_parse_format_from_caps (in_caps, &format, &align);
398       gst_caps_unref (caps);
399       caps = NULL;
400       h264parse->can_passthrough = TRUE;
401     }
402   }
403
404   /* FIXME We could fail the negotiation immediately if caps are empty */
405   if (caps && !gst_caps_is_empty (caps)) {
406     /* fixate to avoid ambiguity with lists when parsing */
407     caps = gst_caps_fixate (caps);
408     gst_h264_parse_format_from_caps (caps, &format, &align);
409   }
410
411   /* default */
412   if (!format)
413     format = GST_H264_PARSE_FORMAT_BYTE;
414   if (!align)
415     align = GST_H264_PARSE_ALIGN_AU;
416
417   GST_DEBUG_OBJECT (h264parse, "selected format %s, alignment %s",
418       gst_h264_parse_get_string (h264parse, TRUE, format),
419       gst_h264_parse_get_string (h264parse, FALSE, align));
420
421   h264parse->format = format;
422   h264parse->align = align;
423
424   h264parse->transform = in_format != h264parse->format ||
425       align == GST_H264_PARSE_ALIGN_AU;
426
427   if (caps)
428     gst_caps_unref (caps);
429 }
430
431 static GstBuffer *
432 gst_h264_parse_wrap_nal (GstH264Parse * h264parse, guint format, guint8 * data,
433     guint size)
434 {
435   GstBuffer *buf;
436   guint nl = h264parse->nal_length_size;
437   guint32 tmp;
438
439   GST_DEBUG_OBJECT (h264parse, "nal length %d", size);
440
441   buf = gst_buffer_new_allocate (NULL, 4 + size, NULL);
442   if (format == GST_H264_PARSE_FORMAT_AVC
443       || format == GST_H264_PARSE_FORMAT_AVC3) {
444     tmp = GUINT32_TO_BE (size << (32 - 8 * nl));
445   } else {
446     /* HACK: nl should always be 4 here, otherwise this won't work. 
447      * There are legit cases where nl in avc stream is 2, but byte-stream
448      * SC is still always 4 bytes. */
449     nl = 4;
450     tmp = GUINT32_TO_BE (1);
451   }
452
453   gst_buffer_fill (buf, 0, &tmp, sizeof (guint32));
454   gst_buffer_fill (buf, nl, data, size);
455   gst_buffer_set_size (buf, size + nl);
456
457   return buf;
458 }
459
460 static void
461 gst_h264_parser_store_nal (GstH264Parse * h264parse, guint id,
462     GstH264NalUnitType naltype, GstH264NalUnit * nalu)
463 {
464   GstBuffer *buf, **store;
465   guint size = nalu->size, store_size;
466
467   if (naltype == GST_H264_NAL_SPS || naltype == GST_H264_NAL_SUBSET_SPS) {
468     store_size = GST_H264_MAX_SPS_COUNT;
469     store = h264parse->sps_nals;
470     GST_DEBUG_OBJECT (h264parse, "storing sps %u", id);
471   } else if (naltype == GST_H264_NAL_PPS) {
472     store_size = GST_H264_MAX_PPS_COUNT;
473     store = h264parse->pps_nals;
474     GST_DEBUG_OBJECT (h264parse, "storing pps %u", id);
475   } else
476     return;
477
478   if (id >= store_size) {
479     GST_DEBUG_OBJECT (h264parse, "unable to store nal, id out-of-range %d", id);
480     return;
481   }
482
483   buf = gst_buffer_new_allocate (NULL, size, NULL);
484   gst_buffer_fill (buf, 0, nalu->data + nalu->offset, size);
485
486   /* Indicate that buffer contain a header needed for decoding */
487   if (naltype == GST_H264_NAL_SPS || naltype == GST_H264_NAL_PPS)
488     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_HEADER);
489
490   if (store[id])
491     gst_buffer_unref (store[id]);
492
493   store[id] = buf;
494 }
495
496 #ifndef GST_DISABLE_GST_DEBUG
497 static const gchar *nal_names[] = {
498   "Unknown",
499   "Slice",
500   "Slice DPA",
501   "Slice DPB",
502   "Slice DPC",
503   "Slice IDR",
504   "SEI",
505   "SPS",
506   "PPS",
507   "AU delimiter",
508   "Sequence End",
509   "Stream End",
510   "Filler Data",
511   "SPS extension",
512   "Prefix",
513   "SPS Subset",
514   "Depth Parameter Set",
515   "Reserved", "Reserved",
516   "Slice Aux Unpartitioned",
517   "Slice Extension",
518   "Slice Depth/3D-AVC Extension"
519 };
520
521 static const gchar *
522 _nal_name (GstH264NalUnitType nal_type)
523 {
524   if (nal_type <= GST_H264_NAL_SLICE_DEPTH)
525     return nal_names[nal_type];
526   return "Invalid";
527 }
528 #endif
529
530 static void
531 gst_h264_parse_process_sei_user_data (GstH264Parse * h264parse,
532     GstH264RegisteredUserData * rud)
533 {
534   guint16 provider_code;
535   GstByteReader br;
536   GstVideoParseUtilsField field = GST_VIDEO_PARSE_UTILS_FIELD_1;
537
538   /* only US country code is currently supported */
539   switch (rud->country_code) {
540     case ITU_T_T35_COUNTRY_CODE_US:
541       break;
542     default:
543       GST_LOG_OBJECT (h264parse, "Unsupported country code %d",
544           rud->country_code);
545       return;
546   }
547
548   if (rud->data == NULL || rud->size < 2)
549     return;
550
551   gst_byte_reader_init (&br, rud->data, rud->size);
552
553   provider_code = gst_byte_reader_get_uint16_be_unchecked (&br);
554
555   if (h264parse->sei_pic_struct ==
556       (guint8) GST_H264_SEI_PIC_STRUCT_BOTTOM_FIELD)
557     field = GST_VIDEO_PARSE_UTILS_FIELD_2;
558   gst_video_parse_user_data ((GstElement *) h264parse, &h264parse->user_data,
559       &br, field, provider_code);
560
561 }
562
563 static void
564 gst_h264_parse_process_sei (GstH264Parse * h264parse, GstH264NalUnit * nalu)
565 {
566   GstH264SEIMessage sei;
567   GstH264NalParser *nalparser = h264parse->nalparser;
568   GstH264ParserResult pres;
569   GArray *messages;
570   guint i;
571
572   pres = gst_h264_parser_parse_sei (nalparser, nalu, &messages);
573   if (pres != GST_H264_PARSER_OK)
574     GST_WARNING_OBJECT (h264parse, "failed to parse one or more SEI message");
575
576   /* Even if pres != GST_H264_PARSER_OK, some message could have been parsed and
577    * stored in messages.
578    */
579   for (i = 0; i < messages->len; i++) {
580     sei = g_array_index (messages, GstH264SEIMessage, i);
581     switch (sei.payloadType) {
582       case GST_H264_SEI_PIC_TIMING:
583       {
584         guint j;
585         h264parse->sei_pic_struct_pres_flag =
586             sei.payload.pic_timing.pic_struct_present_flag;
587         h264parse->sei_cpb_removal_delay =
588             sei.payload.pic_timing.cpb_removal_delay;
589         if (h264parse->sei_pic_struct_pres_flag) {
590           h264parse->sei_pic_struct = sei.payload.pic_timing.pic_struct;
591         }
592
593         h264parse->num_clock_timestamp = 0;
594
595         for (j = 0; j < 3; j++) {
596           if (sei.payload.pic_timing.clock_timestamp_flag[j]) {
597             memcpy (&h264parse->clock_timestamp[h264parse->
598                     num_clock_timestamp++],
599                 &sei.payload.pic_timing.clock_timestamp[j],
600                 sizeof (GstH264ClockTimestamp));
601           }
602         }
603
604         GST_LOG_OBJECT (h264parse, "pic timing updated");
605         break;
606       }
607       case GST_H264_SEI_REGISTERED_USER_DATA:
608         gst_h264_parse_process_sei_user_data (h264parse,
609             &sei.payload.registered_user_data);
610         break;
611       case GST_H264_SEI_BUF_PERIOD:
612         if (h264parse->ts_trn_nb == GST_CLOCK_TIME_NONE ||
613             h264parse->dts == GST_CLOCK_TIME_NONE)
614           h264parse->ts_trn_nb = 0;
615         else
616           h264parse->ts_trn_nb = h264parse->dts;
617
618         GST_LOG_OBJECT (h264parse,
619             "new buffering period; ts_trn_nb updated: %" GST_TIME_FORMAT,
620             GST_TIME_ARGS (h264parse->ts_trn_nb));
621         break;
622
623         /* Additional messages that are not innerly useful to the
624          * element but for debugging purposes */
625       case GST_H264_SEI_RECOVERY_POINT:
626         GST_LOG_OBJECT (h264parse, "recovery point found: %u %u %u %u",
627             sei.payload.recovery_point.recovery_frame_cnt,
628             sei.payload.recovery_point.exact_match_flag,
629             sei.payload.recovery_point.broken_link_flag,
630             sei.payload.recovery_point.changing_slice_group_idc);
631         h264parse->keyframe = TRUE;
632         break;
633
634         /* Additional messages that are not innerly useful to the
635          * element but for debugging purposes */
636       case GST_H264_SEI_STEREO_VIDEO_INFO:{
637         GstVideoMultiviewMode mview_mode = GST_VIDEO_MULTIVIEW_MODE_NONE;
638         GstVideoMultiviewFlags mview_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE;
639
640         GST_LOG_OBJECT (h264parse, "Stereo video information %u %u %u %u %u %u",
641             sei.payload.stereo_video_info.field_views_flag,
642             sei.payload.stereo_video_info.top_field_is_left_view_flag,
643             sei.payload.stereo_video_info.current_frame_is_left_view_flag,
644             sei.payload.stereo_video_info.next_frame_is_second_view_flag,
645             sei.payload.stereo_video_info.left_view_self_contained_flag,
646             sei.payload.stereo_video_info.right_view_self_contained_flag);
647
648         if (sei.payload.stereo_video_info.field_views_flag) {
649           mview_mode = GST_VIDEO_MULTIVIEW_MODE_ROW_INTERLEAVED;
650           if (!sei.payload.stereo_video_info.top_field_is_left_view_flag)
651             mview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
652         } else {
653           mview_mode = GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
654           if (sei.payload.stereo_video_info.next_frame_is_second_view_flag) {
655             /* Mark current frame as first in bundle */
656             h264parse->first_in_bundle = TRUE;
657             if (!sei.payload.stereo_video_info.current_frame_is_left_view_flag)
658               mview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
659           }
660         }
661         if (mview_mode != h264parse->multiview_mode ||
662             mview_flags != h264parse->multiview_flags) {
663           h264parse->multiview_mode = mview_mode;
664           h264parse->multiview_flags = mview_flags;
665           /* output caps need to be changed */
666           gst_h264_parse_update_src_caps (h264parse, NULL);
667         }
668         break;
669       }
670       case GST_H264_SEI_FRAME_PACKING:{
671         GstVideoMultiviewMode mview_mode = GST_VIDEO_MULTIVIEW_MODE_NONE;
672         GstVideoMultiviewFlags mview_flags = GST_VIDEO_MULTIVIEW_FLAGS_NONE;
673
674         GST_LOG_OBJECT (h264parse,
675             "frame packing arrangement message: id %u cancelled %u "
676             "type %u quincunx %u content_interpretation %d flip %u "
677             "right_first %u field_views %u is_frame0 %u",
678             sei.payload.frame_packing.frame_packing_id,
679             sei.payload.frame_packing.frame_packing_cancel_flag,
680             sei.payload.frame_packing.frame_packing_type,
681             sei.payload.frame_packing.quincunx_sampling_flag,
682             sei.payload.frame_packing.content_interpretation_type,
683             sei.payload.frame_packing.spatial_flipping_flag,
684             sei.payload.frame_packing.frame0_flipped_flag,
685             sei.payload.frame_packing.field_views_flag,
686             sei.payload.frame_packing.current_frame_is_frame0_flag);
687
688         /* Only IDs from 0->255 and 512->2^31-1 are valid. Ignore others */
689         if ((sei.payload.frame_packing.frame_packing_id >= 256 &&
690                 sei.payload.frame_packing.frame_packing_id < 512) ||
691             (sei.payload.frame_packing.frame_packing_id >= (1U << 31)))
692           break;                /* ignore */
693
694         if (!sei.payload.frame_packing.frame_packing_cancel_flag) {
695           /* Cancel flag sets things back to no-info */
696
697           if (sei.payload.frame_packing.content_interpretation_type == 2)
698             mview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST;
699
700           switch (sei.payload.frame_packing.frame_packing_type) {
701             case 0:
702               mview_mode = GST_VIDEO_MULTIVIEW_MODE_CHECKERBOARD;
703               break;
704             case 1:
705               mview_mode = GST_VIDEO_MULTIVIEW_MODE_COLUMN_INTERLEAVED;
706               break;
707             case 2:
708               mview_mode = GST_VIDEO_MULTIVIEW_MODE_ROW_INTERLEAVED;
709               break;
710             case 3:
711               if (sei.payload.frame_packing.quincunx_sampling_flag)
712                 mview_mode = GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE_QUINCUNX;
713               else
714                 mview_mode = GST_VIDEO_MULTIVIEW_MODE_SIDE_BY_SIDE;
715               if (sei.payload.frame_packing.spatial_flipping_flag) {
716                 /* One of the views is flopped. */
717                 if (sei.payload.frame_packing.frame0_flipped_flag !=
718                     ! !(mview_flags &
719                         GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST))
720                   /* the left view is flopped */
721                   mview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_LEFT_FLOPPED;
722                 else
723                   mview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_FLOPPED;
724               }
725               break;
726             case 4:
727               mview_mode = GST_VIDEO_MULTIVIEW_MODE_TOP_BOTTOM;
728               if (sei.payload.frame_packing.spatial_flipping_flag) {
729                 /* One of the views is flipped, */
730                 if (sei.payload.frame_packing.frame0_flipped_flag !=
731                     ! !(mview_flags &
732                         GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_VIEW_FIRST))
733                   /* the left view is flipped */
734                   mview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_LEFT_FLIPPED;
735                 else
736                   mview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_RIGHT_FLIPPED;
737               }
738               break;
739             case 5:
740               if (sei.payload.frame_packing.content_interpretation_type == 0)
741                 mview_mode = GST_VIDEO_MULTIVIEW_MODE_MULTIVIEW_FRAME_BY_FRAME;
742               else
743                 mview_mode = GST_VIDEO_MULTIVIEW_MODE_FRAME_BY_FRAME;
744               break;
745             default:
746               GST_DEBUG_OBJECT (h264parse, "Invalid frame packing type %u",
747                   sei.payload.frame_packing.frame_packing_type);
748               break;
749           }
750         }
751
752         if (mview_mode != h264parse->multiview_mode ||
753             mview_flags != h264parse->multiview_flags) {
754           h264parse->multiview_mode = mview_mode;
755           h264parse->multiview_flags = mview_flags;
756           /* output caps need to be changed */
757           gst_h264_parse_update_src_caps (h264parse, NULL);
758         }
759         break;
760       }
761     }
762   }
763   g_array_free (messages, TRUE);
764 }
765
766 /* caller guarantees 2 bytes of nal payload */
767 static gboolean
768 gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu)
769 {
770   guint nal_type;
771   GstH264PPS pps = { 0, };
772   GstH264SPS sps = { 0, };
773   GstH264NalParser *nalparser = h264parse->nalparser;
774   GstH264ParserResult pres;
775
776   /* nothing to do for broken input */
777   if (G_UNLIKELY (nalu->size < 2)) {
778     GST_DEBUG_OBJECT (h264parse, "not processing nal size %u", nalu->size);
779     return TRUE;
780   }
781
782   /* we have a peek as well */
783   nal_type = nalu->type;
784
785   GST_DEBUG_OBJECT (h264parse, "processing nal of type %u %s, size %u",
786       nal_type, _nal_name (nal_type), nalu->size);
787
788   switch (nal_type) {
789     case GST_H264_NAL_SUBSET_SPS:
790       if (!GST_H264_PARSE_STATE_VALID (h264parse, GST_H264_PARSE_STATE_GOT_SPS))
791         return FALSE;
792       pres = gst_h264_parser_parse_subset_sps (nalparser, nalu, &sps);
793       goto process_sps;
794
795     case GST_H264_NAL_SPS:
796       /* reset state, everything else is obsolete */
797       h264parse->state = 0;
798       pres = gst_h264_parser_parse_sps (nalparser, nalu, &sps);
799
800     process_sps:
801       /* arranged for a fallback sps.id, so use that one and only warn */
802       if (pres != GST_H264_PARSER_OK) {
803         GST_WARNING_OBJECT (h264parse, "failed to parse SPS:");
804         h264parse->state |= GST_H264_PARSE_STATE_GOT_SPS;
805         h264parse->header = TRUE;
806         return FALSE;
807       }
808
809       GST_DEBUG_OBJECT (h264parse, "triggering src caps check");
810       h264parse->update_caps = TRUE;
811       h264parse->have_sps = TRUE;
812       h264parse->have_sps_in_frame = TRUE;
813       if (h264parse->push_codec && h264parse->have_pps) {
814         /* SPS and PPS found in stream before the first pre_push_frame, no need
815          * to forcibly push at start */
816         GST_INFO_OBJECT (h264parse, "have SPS/PPS in stream");
817         h264parse->push_codec = FALSE;
818         h264parse->have_sps = FALSE;
819         h264parse->have_pps = FALSE;
820       }
821
822       gst_h264_parser_store_nal (h264parse, sps.id, nal_type, nalu);
823       gst_h264_sps_clear (&sps);
824       h264parse->state |= GST_H264_PARSE_STATE_GOT_SPS;
825       h264parse->header = TRUE;
826       break;
827     case GST_H264_NAL_PPS:
828       /* expected state: got-sps */
829       h264parse->state &= GST_H264_PARSE_STATE_GOT_SPS;
830       if (!GST_H264_PARSE_STATE_VALID (h264parse, GST_H264_PARSE_STATE_GOT_SPS))
831         return FALSE;
832
833       pres = gst_h264_parser_parse_pps (nalparser, nalu, &pps);
834       /* arranged for a fallback pps.id, so use that one and only warn */
835       if (pres != GST_H264_PARSER_OK) {
836         GST_WARNING_OBJECT (h264parse, "failed to parse PPS:");
837         if (pres != GST_H264_PARSER_BROKEN_LINK)
838           return FALSE;
839       }
840
841       /* parameters might have changed, force caps check */
842       if (!h264parse->have_pps) {
843         GST_DEBUG_OBJECT (h264parse, "triggering src caps check");
844         h264parse->update_caps = TRUE;
845       }
846       h264parse->have_pps = TRUE;
847       h264parse->have_pps_in_frame = TRUE;
848       if (h264parse->push_codec && h264parse->have_sps) {
849         /* SPS and PPS found in stream before the first pre_push_frame, no need
850          * to forcibly push at start */
851         GST_INFO_OBJECT (h264parse, "have SPS/PPS in stream");
852         h264parse->push_codec = FALSE;
853         h264parse->have_sps = FALSE;
854         h264parse->have_pps = FALSE;
855       }
856
857       gst_h264_parser_store_nal (h264parse, pps.id, nal_type, nalu);
858       gst_h264_pps_clear (&pps);
859       h264parse->state |= GST_H264_PARSE_STATE_GOT_PPS;
860       h264parse->header = TRUE;
861       break;
862     case GST_H264_NAL_SEI:
863       /* expected state: got-sps */
864       if (!GST_H264_PARSE_STATE_VALID (h264parse, GST_H264_PARSE_STATE_GOT_SPS))
865         return FALSE;
866
867       h264parse->header = TRUE;
868       gst_h264_parse_process_sei (h264parse, nalu);
869       /* mark SEI pos */
870       if (h264parse->sei_pos == -1) {
871         if (h264parse->transform)
872           h264parse->sei_pos = gst_adapter_available (h264parse->frame_out);
873         else
874           h264parse->sei_pos = nalu->sc_offset;
875         GST_DEBUG_OBJECT (h264parse, "marking SEI in frame at offset %d",
876             h264parse->sei_pos);
877       }
878       break;
879
880     case GST_H264_NAL_SLICE:
881     case GST_H264_NAL_SLICE_DPA:
882     case GST_H264_NAL_SLICE_DPB:
883     case GST_H264_NAL_SLICE_DPC:
884     case GST_H264_NAL_SLICE_IDR:
885     case GST_H264_NAL_SLICE_EXT:
886       /* expected state: got-sps|got-pps (valid picture headers) */
887       h264parse->state &= GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS;
888       if (!GST_H264_PARSE_STATE_VALID (h264parse,
889               GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS))
890         return FALSE;
891
892       /* don't need to parse the whole slice (header) here */
893       if (*(nalu->data + nalu->offset + nalu->header_bytes) & 0x80) {
894         /* means first_mb_in_slice == 0 */
895         /* real frame data */
896         GST_DEBUG_OBJECT (h264parse, "first_mb_in_slice = 0");
897         h264parse->frame_start = TRUE;
898       }
899       GST_DEBUG_OBJECT (h264parse, "frame start: %i", h264parse->frame_start);
900       if (nal_type == GST_H264_NAL_SLICE_EXT && !GST_H264_IS_MVC_NALU (nalu))
901         break;
902       {
903         GstH264SliceHdr slice;
904
905         pres = gst_h264_parser_parse_slice_hdr (nalparser, nalu, &slice,
906             FALSE, FALSE);
907         GST_DEBUG_OBJECT (h264parse,
908             "parse result %d, first MB: %u, slice type: %u",
909             pres, slice.first_mb_in_slice, slice.type);
910         if (pres == GST_H264_PARSER_OK) {
911           if (GST_H264_IS_I_SLICE (&slice) || GST_H264_IS_SI_SLICE (&slice))
912             h264parse->keyframe = TRUE;
913           else if (GST_H264_IS_P_SLICE (&slice)
914               || GST_H264_IS_SP_SLICE (&slice))
915             h264parse->predicted = TRUE;
916           else if (GST_H264_IS_B_SLICE (&slice))
917             h264parse->bidirectional = TRUE;
918
919           h264parse->state |= GST_H264_PARSE_STATE_GOT_SLICE;
920           h264parse->field_pic_flag = slice.field_pic_flag;
921         }
922       }
923       if (G_LIKELY (nal_type != GST_H264_NAL_SLICE_IDR &&
924               !h264parse->push_codec))
925         break;
926       /* if we need to sneak codec NALs into the stream,
927        * this is a good place, so fake it as IDR
928        * (which should be at start anyway) */
929       /* mark where config needs to go if interval expired */
930       /* mind replacement buffer if applicable */
931       if (h264parse->idr_pos == -1) {
932         if (h264parse->transform)
933           h264parse->idr_pos = gst_adapter_available (h264parse->frame_out);
934         else
935           h264parse->idr_pos = nalu->sc_offset;
936         GST_DEBUG_OBJECT (h264parse, "marking IDR in frame at offset %d",
937             h264parse->idr_pos);
938       }
939       /* if SEI precedes (faked) IDR, then we have to insert config there */
940       if (h264parse->sei_pos >= 0 && h264parse->idr_pos > h264parse->sei_pos) {
941         h264parse->idr_pos = h264parse->sei_pos;
942         GST_DEBUG_OBJECT (h264parse, "moved IDR mark to SEI position %d",
943             h264parse->idr_pos);
944       }
945       break;
946     case GST_H264_NAL_AU_DELIMITER:
947       /* Just accumulate AU Delimiter, whether it's before SPS or not */
948       pres = gst_h264_parser_parse_nal (nalparser, nalu);
949       if (pres != GST_H264_PARSER_OK)
950         return FALSE;
951       h264parse->aud_insert = FALSE;
952       break;
953     default:
954       /* drop anything before the initial SPS */
955       if (!GST_H264_PARSE_STATE_VALID (h264parse, GST_H264_PARSE_STATE_GOT_SPS))
956         return FALSE;
957
958       pres = gst_h264_parser_parse_nal (nalparser, nalu);
959       if (pres != GST_H264_PARSER_OK)
960         return FALSE;
961       break;
962   }
963
964   /* if AVC output needed, collect properly prefixed nal in adapter,
965    * and use that to replace outgoing buffer data later on */
966   if (h264parse->transform) {
967     GstBuffer *buf;
968
969     GST_LOG_OBJECT (h264parse, "collecting NAL in AVC frame");
970     buf = gst_h264_parse_wrap_nal (h264parse, h264parse->format,
971         nalu->data + nalu->offset, nalu->size);
972     gst_adapter_push (h264parse->frame_out, buf);
973   }
974   return TRUE;
975 }
976
977 /* caller guarantees at least 2 bytes of nal payload for each nal
978  * returns TRUE if next_nal indicates that nal terminates an AU */
979 static inline gboolean
980 gst_h264_parse_collect_nal (GstH264Parse * h264parse, const guint8 * data,
981     guint size, GstH264NalUnit * nalu)
982 {
983   gboolean complete;
984   GstH264ParserResult parse_res;
985   GstH264NalUnitType nal_type = nalu->type;
986   GstH264NalUnit nnalu;
987
988   GST_DEBUG_OBJECT (h264parse, "parsing collected nal");
989   parse_res = gst_h264_parser_identify_nalu_unchecked (h264parse->nalparser,
990       data, nalu->offset + nalu->size, size, &nnalu);
991
992   if (parse_res != GST_H264_PARSER_OK)
993     return FALSE;
994
995   /* determine if AU complete */
996   GST_LOG_OBJECT (h264parse, "nal type: %d %s", nal_type, _nal_name (nal_type));
997   /* coded slice NAL starts a picture,
998    * i.e. other types become aggregated in front of it */
999   h264parse->picture_start |= (nal_type == GST_H264_NAL_SLICE ||
1000       nal_type == GST_H264_NAL_SLICE_DPA || nal_type == GST_H264_NAL_SLICE_IDR);
1001
1002   /* consider a coded slices (IDR or not) to start a picture,
1003    * (so ending the previous one) if first_mb_in_slice == 0
1004    * (non-0 is part of previous one) */
1005   /* NOTE this is not entirely according to Access Unit specs in 7.4.1.2.4,
1006    * but in practice it works in sane cases, needs not much parsing,
1007    * and also works with broken frame_num in NAL
1008    * (where spec-wise would fail) */
1009   nal_type = nnalu.type;
1010   complete = h264parse->picture_start && ((nal_type >= GST_H264_NAL_SEI &&
1011           nal_type <= GST_H264_NAL_AU_DELIMITER) ||
1012       (nal_type >= 14 && nal_type <= 18));
1013
1014   GST_LOG_OBJECT (h264parse, "next nal type: %d %s", nal_type,
1015       _nal_name (nal_type));
1016   /* first_mb_in_slice == 0 considered start of frame */
1017   if (nnalu.size > nnalu.header_bytes)
1018     complete |= h264parse->picture_start && (nal_type == GST_H264_NAL_SLICE
1019         || nal_type == GST_H264_NAL_SLICE_DPA
1020         || nal_type == GST_H264_NAL_SLICE_IDR) &&
1021         (nnalu.data[nnalu.offset + nnalu.header_bytes] & 0x80);
1022
1023   GST_LOG_OBJECT (h264parse, "au complete: %d", complete);
1024
1025   return complete;
1026 }
1027
1028 static guint8 au_delim[6] = {
1029   0x00, 0x00, 0x00, 0x01,       /* nal prefix */
1030   0x09,                         /* nal unit type = access unit delimiter */
1031   0xf0                          /* allow any slice type */
1032 };
1033
1034 static GstFlowReturn
1035 gst_h264_parse_handle_frame_packetized (GstBaseParse * parse,
1036     GstBaseParseFrame * frame)
1037 {
1038   GstH264Parse *h264parse = GST_H264_PARSE (parse);
1039   GstBuffer *buffer = frame->buffer;
1040   GstFlowReturn ret = GST_FLOW_OK;
1041   GstH264ParserResult parse_res;
1042   GstH264NalUnit nalu;
1043   const guint nl = h264parse->nal_length_size;
1044   GstMapInfo map;
1045   gint left;
1046
1047   if (nl < 1 || nl > 4) {
1048     GST_DEBUG_OBJECT (h264parse, "insufficient data to split input");
1049     return GST_FLOW_NOT_NEGOTIATED;
1050   }
1051
1052   /* need to save buffer from invalidation upon _finish_frame */
1053   if (h264parse->split_packetized)
1054     buffer = gst_buffer_copy (frame->buffer);
1055
1056   gst_buffer_map (buffer, &map, GST_MAP_READ);
1057
1058   left = map.size;
1059
1060   GST_LOG_OBJECT (h264parse,
1061       "processing packet buffer of size %" G_GSIZE_FORMAT, map.size);
1062
1063   parse_res = gst_h264_parser_identify_nalu_avc (h264parse->nalparser,
1064       map.data, 0, map.size, nl, &nalu);
1065
1066   while (parse_res == GST_H264_PARSER_OK) {
1067     GST_DEBUG_OBJECT (h264parse, "AVC nal offset %d", nalu.offset + nalu.size);
1068
1069     /* either way, have a look at it */
1070     gst_h264_parse_process_nal (h264parse, &nalu);
1071
1072     /* dispatch per NALU if needed */
1073     if (h264parse->split_packetized) {
1074       GstBaseParseFrame tmp_frame;
1075
1076       gst_base_parse_frame_init (&tmp_frame);
1077       tmp_frame.flags |= frame->flags;
1078       tmp_frame.offset = frame->offset;
1079       tmp_frame.overhead = frame->overhead;
1080       tmp_frame.buffer = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL,
1081           nalu.offset, nalu.size);
1082
1083       /* note we don't need to come up with a sub-buffer, since
1084        * subsequent code only considers input buffer's metadata.
1085        * Real data is either taken from input by baseclass or
1086        * a replacement output buffer is provided anyway. */
1087       gst_h264_parse_parse_frame (parse, &tmp_frame);
1088       ret = gst_base_parse_finish_frame (parse, &tmp_frame, nl + nalu.size);
1089       left -= nl + nalu.size;
1090     }
1091
1092     parse_res = gst_h264_parser_identify_nalu_avc (h264parse->nalparser,
1093         map.data, nalu.offset + nalu.size, map.size, nl, &nalu);
1094   }
1095
1096   gst_buffer_unmap (buffer, &map);
1097
1098   if (!h264parse->split_packetized) {
1099     gst_h264_parse_parse_frame (parse, frame);
1100     ret = gst_base_parse_finish_frame (parse, frame, map.size);
1101   } else {
1102     gst_buffer_unref (buffer);
1103     if (G_UNLIKELY (left)) {
1104       /* should not be happening for nice AVC */
1105       GST_WARNING_OBJECT (parse, "skipping leftover AVC data %d", left);
1106       frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
1107       ret = gst_base_parse_finish_frame (parse, frame, map.size);
1108     }
1109   }
1110
1111   if (parse_res == GST_H264_PARSER_NO_NAL_END ||
1112       parse_res == GST_H264_PARSER_BROKEN_DATA) {
1113
1114     if (h264parse->split_packetized) {
1115       GST_ELEMENT_ERROR (h264parse, STREAM, FAILED, (NULL),
1116           ("invalid AVC input data"));
1117
1118       return GST_FLOW_ERROR;
1119     } else {
1120       /* do not meddle to much in this case */
1121       GST_DEBUG_OBJECT (h264parse, "parsing packet failed");
1122     }
1123   }
1124
1125   return ret;
1126 }
1127
1128 static GstFlowReturn
1129 gst_h264_parse_handle_frame (GstBaseParse * parse,
1130     GstBaseParseFrame * frame, gint * skipsize)
1131 {
1132   GstH264Parse *h264parse = GST_H264_PARSE (parse);
1133   GstBuffer *buffer = frame->buffer;
1134   GstMapInfo map;
1135   guint8 *data;
1136   gsize size;
1137   gint current_off = 0;
1138   gboolean drain, nonext;
1139   GstH264NalParser *nalparser = h264parse->nalparser;
1140   GstH264NalUnit nalu;
1141   GstH264ParserResult pres;
1142   gint framesize;
1143   GstFlowReturn ret;
1144   gboolean au_complete;
1145
1146   if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (frame->buffer,
1147               GST_BUFFER_FLAG_DISCONT))) {
1148     h264parse->discont = TRUE;
1149   }
1150
1151   /* delegate in packetized case, no skipping should be needed */
1152   if (h264parse->packetized)
1153     return gst_h264_parse_handle_frame_packetized (parse, frame);
1154
1155   gst_buffer_map (buffer, &map, GST_MAP_READ);
1156   data = map.data;
1157   size = map.size;
1158
1159   /* expect at least 3 bytes start_code, and 1 bytes NALU header.
1160    * the length of the NALU payload can be zero.
1161    * (e.g. EOS/EOB placed at the end of an AU.) */
1162   if (G_UNLIKELY (size < 4)) {
1163     gst_buffer_unmap (buffer, &map);
1164     *skipsize = 1;
1165     return GST_FLOW_OK;
1166   }
1167
1168   /* need to configure aggregation */
1169   if (G_UNLIKELY (h264parse->format == GST_H264_PARSE_FORMAT_NONE))
1170     gst_h264_parse_negotiate (h264parse, GST_H264_PARSE_FORMAT_BYTE, NULL);
1171
1172   /* avoid stale cached parsing state */
1173   if (frame->flags & GST_BASE_PARSE_FRAME_FLAG_NEW_FRAME) {
1174     GST_LOG_OBJECT (h264parse, "parsing new frame");
1175     gst_h264_parse_reset_frame (h264parse);
1176   } else {
1177     GST_LOG_OBJECT (h264parse, "resuming frame parsing");
1178   }
1179
1180   /* Always consume the entire input buffer when in_align == ALIGN_AU */
1181   drain = GST_BASE_PARSE_DRAINING (parse)
1182       || h264parse->in_align == GST_H264_PARSE_ALIGN_AU;
1183   nonext = FALSE;
1184
1185   current_off = h264parse->current_off;
1186   if (current_off < 0)
1187     current_off = 0;
1188   g_assert (current_off < size);
1189   GST_DEBUG_OBJECT (h264parse, "last parse position %d", current_off);
1190
1191   /* check for initial skip */
1192   if (h264parse->current_off == -1) {
1193     pres =
1194         gst_h264_parser_identify_nalu_unchecked (nalparser, data, current_off,
1195         size, &nalu);
1196     switch (pres) {
1197       case GST_H264_PARSER_OK:
1198         if (nalu.sc_offset > 0) {
1199           int i;
1200           gboolean is_filler_data = TRUE;
1201           /* Handle filler data */
1202           for (i = 0; i < nalu.sc_offset; i++) {
1203             if (data[i] != 0x00) {
1204               is_filler_data = FALSE;
1205               break;
1206             }
1207           }
1208           if (is_filler_data) {
1209             GST_DEBUG_OBJECT (parse, "Dropping filler data %d", nalu.sc_offset);
1210             frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
1211             gst_buffer_unmap (buffer, &map);
1212             ret = gst_base_parse_finish_frame (parse, frame, nalu.sc_offset);
1213             goto drop;
1214           }
1215           *skipsize = nalu.sc_offset;
1216           goto skip;
1217         }
1218         break;
1219       case GST_H264_PARSER_NO_NAL:
1220         *skipsize = size - 3;
1221         goto skip;
1222         break;
1223       default:
1224         /* should not really occur either */
1225         GST_ELEMENT_ERROR (h264parse, STREAM, FORMAT,
1226             ("Error parsing H.264 stream"), ("Invalid H.264 stream"));
1227         goto invalid_stream;
1228     }
1229   }
1230
1231   while (TRUE) {
1232     pres =
1233         gst_h264_parser_identify_nalu (nalparser, data, current_off, size,
1234         &nalu);
1235
1236     switch (pres) {
1237       case GST_H264_PARSER_OK:
1238         GST_DEBUG_OBJECT (h264parse, "complete nal (offset, size): (%u, %u) ",
1239             nalu.offset, nalu.size);
1240         break;
1241       case GST_H264_PARSER_NO_NAL_END:
1242         GST_DEBUG_OBJECT (h264parse, "not a complete nal found at offset %u",
1243             nalu.offset);
1244         /* if draining, accept it as complete nal */
1245         if (drain) {
1246           nonext = TRUE;
1247           nalu.size = size - nalu.offset;
1248           GST_DEBUG_OBJECT (h264parse, "draining, accepting with size %u",
1249               nalu.size);
1250           /* if it's not too short at least */
1251           if (nalu.size < 2)
1252             goto broken;
1253           break;
1254         }
1255         /* otherwise need more */
1256         goto more;
1257       case GST_H264_PARSER_BROKEN_LINK:
1258         GST_ELEMENT_ERROR (h264parse, STREAM, FORMAT,
1259             ("Error parsing H.264 stream"),
1260             ("The link to structure needed for the parsing couldn't be found"));
1261         goto invalid_stream;
1262       case GST_H264_PARSER_ERROR:
1263         /* should not really occur either */
1264         GST_ELEMENT_ERROR (h264parse, STREAM, FORMAT,
1265             ("Error parsing H.264 stream"), ("Invalid H.264 stream"));
1266         goto invalid_stream;
1267       case GST_H264_PARSER_NO_NAL:
1268         GST_ELEMENT_ERROR (h264parse, STREAM, FORMAT,
1269             ("Error parsing H.264 stream"), ("No H.264 NAL unit found"));
1270         goto invalid_stream;
1271       case GST_H264_PARSER_BROKEN_DATA:
1272         GST_WARNING_OBJECT (h264parse, "input stream is corrupt; "
1273             "it contains a NAL unit of length %u", nalu.size);
1274       broken:
1275         /* broken nal at start -> arrange to skip it,
1276          * otherwise have it terminate current au
1277          * (and so it will be skipped on next frame round) */
1278         GST_ELEMENT_WARNING (h264parse, STREAM, DECODE,
1279             (NULL), ("Broken bit stream"));
1280         if (current_off == 0) {
1281           GST_DEBUG_OBJECT (h264parse, "skipping broken nal");
1282           *skipsize = nalu.offset;
1283           h264parse->aud_needed = TRUE;
1284           goto skip;
1285         } else {
1286           GST_DEBUG_OBJECT (h264parse, "terminating au");
1287           nalu.size = 0;
1288           nalu.offset = nalu.sc_offset;
1289           goto end;
1290         }
1291         break;
1292       default:
1293         g_assert_not_reached ();
1294         break;
1295     }
1296
1297     GST_DEBUG_OBJECT (h264parse, "%p complete nal found. Off: %u, Size: %u",
1298         data, nalu.offset, nalu.size);
1299
1300     if (!nonext) {
1301       /* expect at least 3 bytes start_code, and 1 bytes NALU header.
1302        * the length of the NALU payload can be zero.
1303        * (e.g. EOS/EOB placed at the end of an AU.) */
1304       if (nalu.offset + nalu.size + 3 + 1 > size) {
1305         GST_DEBUG_OBJECT (h264parse, "not enough data for next NALU");
1306         if (drain) {
1307           GST_DEBUG_OBJECT (h264parse, "but draining anyway");
1308           nonext = TRUE;
1309         } else {
1310           goto more;
1311         }
1312       }
1313     }
1314
1315     if (!gst_h264_parse_process_nal (h264parse, &nalu)) {
1316       GST_WARNING_OBJECT (h264parse,
1317           "broken/invalid nal Type: %d %s, Size: %u will be dropped",
1318           nalu.type, _nal_name (nalu.type), nalu.size);
1319       *skipsize = nalu.size;
1320       h264parse->aud_needed = TRUE;
1321       goto skip;
1322     }
1323
1324     /* Judge whether or not to insert AU Delimiter in case of byte-stream
1325      * If we're in the middle of au, we don't need to insert aud.
1326      * Otherwise, we honor the result in gst_h264_parse_process_nal.
1327      * Note that this should be done until draining if it's happening.
1328      */
1329     if (h264parse->align == GST_H264_PARSE_ALIGN_NAL && !h264parse->aud_needed)
1330       h264parse->aud_insert = FALSE;
1331
1332     if (nonext)
1333       break;
1334
1335     /* if no next nal, we know it's complete here */
1336     au_complete = gst_h264_parse_collect_nal (h264parse, data, size, &nalu);
1337
1338     if (h264parse->align == GST_H264_PARSE_ALIGN_NAL) {
1339       h264parse->aud_needed = au_complete;
1340       break;
1341     }
1342
1343     if (au_complete)
1344       break;
1345
1346     GST_DEBUG_OBJECT (h264parse, "Looking for more");
1347     current_off = nalu.offset + nalu.size;
1348   }
1349
1350 end:
1351   framesize = nalu.offset + nalu.size;
1352
1353   gst_buffer_unmap (buffer, &map);
1354
1355   gst_h264_parse_parse_frame (parse, frame);
1356
1357   return gst_base_parse_finish_frame (parse, frame, framesize);
1358
1359 more:
1360   *skipsize = 0;
1361
1362   /* Restart parsing from here next time */
1363   if (current_off > 0)
1364     h264parse->current_off = current_off;
1365
1366   /* Fall-through. */
1367 out:
1368   gst_buffer_unmap (buffer, &map);
1369   return GST_FLOW_OK;
1370
1371 drop:
1372   GST_DEBUG_OBJECT (h264parse, "Dropped data");
1373   return ret;
1374
1375 skip:
1376   GST_DEBUG_OBJECT (h264parse, "skipping %d", *skipsize);
1377   /* If we are collecting access units, we need to preserve the initial
1378    * config headers (SPS, PPS et al.) and only reset the frame if another
1379    * slice NAL was received. This means that broken pictures are discarded */
1380   if (h264parse->align != GST_H264_PARSE_ALIGN_AU ||
1381       !(h264parse->state & GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS) ||
1382       (h264parse->state & GST_H264_PARSE_STATE_GOT_SLICE))
1383     gst_h264_parse_reset_frame (h264parse);
1384   goto out;
1385
1386 invalid_stream:
1387   gst_buffer_unmap (buffer, &map);
1388   return GST_FLOW_ERROR;
1389 }
1390
1391 /* byte together avc codec data based on collected pps and sps so far */
1392 static GstBuffer *
1393 gst_h264_parse_make_codec_data (GstH264Parse * h264parse)
1394 {
1395   GstBuffer *buf, *nal;
1396   gint i, sps_size = 0, pps_size = 0, num_sps = 0, num_pps = 0;
1397   guint8 profile_idc = 0, profile_comp = 0, level_idc = 0;
1398   gboolean found = FALSE;
1399   GstMapInfo map;
1400   guint8 *data;
1401   gint nl;
1402
1403   /* only nal payload in stored nals */
1404
1405   for (i = 0; i < GST_H264_MAX_SPS_COUNT; i++) {
1406     if ((nal = h264parse->sps_nals[i])) {
1407       gsize size = gst_buffer_get_size (nal);
1408       num_sps++;
1409       /* size bytes also count */
1410       sps_size += size + 2;
1411       if (size >= 4) {
1412         guint8 tmp[3];
1413         found = TRUE;
1414         gst_buffer_extract (nal, 1, tmp, 3);
1415         profile_idc = tmp[0];
1416         profile_comp = tmp[1];
1417         level_idc = tmp[2];
1418       }
1419     }
1420   }
1421   for (i = 0; i < GST_H264_MAX_PPS_COUNT; i++) {
1422     if ((nal = h264parse->pps_nals[i])) {
1423       num_pps++;
1424       /* size bytes also count */
1425       pps_size += gst_buffer_get_size (nal) + 2;
1426     }
1427   }
1428
1429   /* AVC3 has SPS/PPS inside the stream, not in the codec_data */
1430   if (h264parse->format == GST_H264_PARSE_FORMAT_AVC3) {
1431     num_sps = sps_size = 0;
1432     num_pps = pps_size = 0;
1433   }
1434
1435   GST_DEBUG_OBJECT (h264parse,
1436       "constructing codec_data: num_sps=%d, num_pps=%d", num_sps, num_pps);
1437
1438   if (!found || (0 == num_pps
1439           && GST_H264_PARSE_FORMAT_AVC3 != h264parse->format))
1440     return NULL;
1441
1442   buf = gst_buffer_new_allocate (NULL, 5 + 1 + sps_size + 1 + pps_size, NULL);
1443   gst_buffer_map (buf, &map, GST_MAP_WRITE);
1444   data = map.data;
1445   nl = h264parse->nal_length_size;
1446
1447   data[0] = 1;                  /* AVC Decoder Configuration Record ver. 1 */
1448   data[1] = profile_idc;        /* profile_idc                             */
1449   data[2] = profile_comp;       /* profile_compability                     */
1450   data[3] = level_idc;          /* level_idc                               */
1451   data[4] = 0xfc | (nl - 1);    /* nal_length_size_minus1                  */
1452   data[5] = 0xe0 | num_sps;     /* number of SPSs */
1453
1454   data += 6;
1455   if (h264parse->format != GST_H264_PARSE_FORMAT_AVC3) {
1456     for (i = 0; i < GST_H264_MAX_SPS_COUNT; i++) {
1457       if ((nal = h264parse->sps_nals[i])) {
1458         gsize nal_size = gst_buffer_get_size (nal);
1459         GST_WRITE_UINT16_BE (data, nal_size);
1460         gst_buffer_extract (nal, 0, data + 2, nal_size);
1461         data += 2 + nal_size;
1462       }
1463     }
1464   }
1465
1466   data[0] = num_pps;
1467   data++;
1468   if (h264parse->format != GST_H264_PARSE_FORMAT_AVC3) {
1469     for (i = 0; i < GST_H264_MAX_PPS_COUNT; i++) {
1470       if ((nal = h264parse->pps_nals[i])) {
1471         gsize nal_size = gst_buffer_get_size (nal);
1472         GST_WRITE_UINT16_BE (data, nal_size);
1473         gst_buffer_extract (nal, 0, data + 2, nal_size);
1474         data += 2 + nal_size;
1475       }
1476     }
1477   }
1478
1479   gst_buffer_unmap (buf, &map);
1480
1481   return buf;
1482 }
1483
1484 static void
1485 gst_h264_parse_get_par (GstH264Parse * h264parse, gint * num, gint * den)
1486 {
1487   if (h264parse->upstream_par_n != -1 && h264parse->upstream_par_d != -1) {
1488     *num = h264parse->upstream_par_n;
1489     *den = h264parse->upstream_par_d;
1490   } else {
1491     *num = h264parse->parsed_par_n;
1492     *den = h264parse->parsed_par_d;
1493   }
1494 }
1495
1496 static GstCaps *
1497 get_compatible_profile_caps (GstH264SPS * sps)
1498 {
1499   GstCaps *caps = NULL;
1500   const gchar **profiles = NULL;
1501   gint i;
1502   GValue compat_profiles = G_VALUE_INIT;
1503   g_value_init (&compat_profiles, GST_TYPE_LIST);
1504
1505   switch (sps->profile_idc) {
1506     case GST_H264_PROFILE_EXTENDED:
1507       if (sps->constraint_set0_flag) {  /* A.2.1 */
1508         if (sps->constraint_set1_flag) {
1509           static const gchar *profile_array[] =
1510               { "constrained-baseline", "baseline", "main", "high",
1511             "high-10", "high-4:2:2", "high-4:4:4", NULL
1512           };
1513           profiles = profile_array;
1514         } else {
1515           static const gchar *profile_array[] = { "baseline", NULL };
1516           profiles = profile_array;
1517         }
1518       } else if (sps->constraint_set1_flag) {   /* A.2.2 */
1519         static const gchar *profile_array[] =
1520             { "main", "high", "high-10", "high-4:2:2", "high-4:4:4", NULL };
1521         profiles = profile_array;
1522       }
1523       break;
1524     case GST_H264_PROFILE_BASELINE:
1525       if (sps->constraint_set1_flag) {  /* A.2.1 */
1526         static const gchar *profile_array[] =
1527             { "baseline", "main", "high", "high-10", "high-4:2:2",
1528           "high-4:4:4", NULL
1529         };
1530         profiles = profile_array;
1531       } else {
1532         static const gchar *profile_array[] = { "extended", NULL };
1533         profiles = profile_array;
1534       }
1535       break;
1536     case GST_H264_PROFILE_MAIN:
1537     {
1538       static const gchar *profile_array[] =
1539           { "high", "high-10", "high-4:2:2", "high-4:4:4", NULL };
1540       profiles = profile_array;
1541     }
1542       break;
1543     case GST_H264_PROFILE_HIGH:
1544       if (sps->constraint_set1_flag) {
1545         static const gchar *profile_array[] =
1546             { "main", "high-10", "high-4:2:2", "high-4:4:4", NULL };
1547         profiles = profile_array;
1548       } else {
1549         static const gchar *profile_array[] =
1550             { "high-10", "high-4:2:2", "high-4:4:4", NULL };
1551         profiles = profile_array;
1552       }
1553       break;
1554     case GST_H264_PROFILE_HIGH10:
1555       if (sps->constraint_set1_flag) {
1556         static const gchar *profile_array[] =
1557             { "main", "high", "high-4:2:2", "high-4:4:4", NULL };
1558         profiles = profile_array;
1559       } else {
1560         if (sps->constraint_set3_flag) {        /* A.2.8 */
1561           static const gchar *profile_array[] =
1562               { "high-10", "high-4:2:2", "high-4:4:4", "high-4:2:2-intra",
1563             "high-4:4:4-intra", NULL
1564           };
1565           profiles = profile_array;
1566         } else {
1567           static const gchar *profile_array[] =
1568               { "high-4:2:2", "high-4:4:4", NULL };
1569           profiles = profile_array;
1570         }
1571       }
1572       break;
1573     case GST_H264_PROFILE_HIGH_422:
1574       if (sps->constraint_set1_flag) {
1575         static const gchar *profile_array[] =
1576             { "main", "high", "high-10", "high-4:4:4", NULL };
1577         profiles = profile_array;
1578       } else {
1579         if (sps->constraint_set3_flag) {        /* A.2.9 */
1580           static const gchar *profile_array[] =
1581               { "high-4:2:2", "high-4:4:4", "high-4:4:4-intra", NULL };
1582           profiles = profile_array;
1583         } else {
1584           static const gchar *profile_array[] = { "high-4:4:4", NULL };
1585           profiles = profile_array;
1586         }
1587       }
1588       break;
1589     case GST_H264_PROFILE_HIGH_444:
1590       if (sps->constraint_set1_flag) {
1591         static const gchar *profile_array[] =
1592             { "main", "high", "high-10", "high-4:2:2", NULL };
1593         profiles = profile_array;
1594       } else if (sps->constraint_set3_flag) {   /* A.2.10 */
1595         static const gchar *profile_array[] = { "high-4:4:4", NULL };
1596         profiles = profile_array;
1597       }
1598       break;
1599     case GST_H264_PROFILE_MULTIVIEW_HIGH:
1600       if (sps->extension_type == GST_H264_NAL_EXTENSION_MVC
1601           && sps->extension.mvc.num_views_minus1 == 1) {
1602         static const gchar *profile_array[] =
1603             { "stereo-high", "multiview-high", NULL };
1604         profiles = profile_array;
1605       } else {
1606         static const gchar *profile_array[] = { "multiview-high", NULL };
1607         profiles = profile_array;
1608       }
1609       break;
1610     default:
1611       break;
1612   }
1613
1614   if (profiles) {
1615     GValue value = G_VALUE_INIT;
1616     caps = gst_caps_new_empty_simple ("video/x-h264");
1617     for (i = 0; profiles[i]; i++) {
1618       g_value_init (&value, G_TYPE_STRING);
1619       g_value_set_string (&value, profiles[i]);
1620       gst_value_list_append_value (&compat_profiles, &value);
1621       g_value_unset (&value);
1622     }
1623     gst_caps_set_value (caps, "profile", &compat_profiles);
1624     g_value_unset (&compat_profiles);
1625   }
1626
1627   return caps;
1628 }
1629
1630 /* if downstream didn't support the exact profile indicated in sps header,
1631  * check for the compatible profiles also */
1632 static void
1633 ensure_caps_profile (GstH264Parse * h264parse, GstCaps * caps, GstH264SPS * sps)
1634 {
1635   GstCaps *peer_caps, *compat_caps;
1636
1637   peer_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (h264parse));
1638   if (!peer_caps || !gst_caps_can_intersect (caps, peer_caps)) {
1639     GstCaps *filter_caps = gst_caps_new_empty_simple ("video/x-h264");
1640
1641     if (peer_caps)
1642       gst_caps_unref (peer_caps);
1643     peer_caps =
1644         gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (h264parse),
1645         filter_caps);
1646
1647     gst_caps_unref (filter_caps);
1648   }
1649
1650   if (peer_caps && !gst_caps_can_intersect (caps, peer_caps)) {
1651     GstStructure *structure;
1652
1653     compat_caps = get_compatible_profile_caps (sps);
1654     if (compat_caps != NULL) {
1655       GstCaps *res_caps = NULL;
1656
1657       res_caps = gst_caps_intersect (peer_caps, compat_caps);
1658
1659       if (res_caps && !gst_caps_is_empty (res_caps)) {
1660         const gchar *profile_str = NULL;
1661
1662         res_caps = gst_caps_fixate (res_caps);
1663         structure = gst_caps_get_structure (res_caps, 0);
1664         profile_str = gst_structure_get_string (structure, "profile");
1665         if (profile_str) {
1666           gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile_str,
1667               NULL);
1668           GST_DEBUG_OBJECT (h264parse,
1669               "Setting compatible profile %s to the caps", profile_str);
1670         }
1671       }
1672       if (res_caps)
1673         gst_caps_unref (res_caps);
1674       gst_caps_unref (compat_caps);
1675     }
1676   }
1677   if (peer_caps)
1678     gst_caps_unref (peer_caps);
1679 }
1680
1681 static const gchar *
1682 digit_to_string (guint digit)
1683 {
1684   static const char itoa[][2] = {
1685     "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"
1686   };
1687
1688   if (G_LIKELY (digit < 10))
1689     return itoa[digit];
1690   else
1691     return NULL;
1692 }
1693
1694 static const gchar *
1695 get_profile_string (GstH264SPS * sps)
1696 {
1697   const gchar *profile = NULL;
1698
1699   switch (sps->profile_idc) {
1700     case 66:
1701       if (sps->constraint_set1_flag)
1702         profile = "constrained-baseline";
1703       else
1704         profile = "baseline";
1705       break;
1706     case 77:
1707       profile = "main";
1708       break;
1709     case 88:
1710       profile = "extended";
1711       break;
1712     case 100:
1713       if (sps->constraint_set4_flag) {
1714         if (sps->constraint_set5_flag)
1715           profile = "constrained-high";
1716         else
1717           profile = "progressive-high";
1718       } else
1719         profile = "high";
1720       break;
1721     case 110:
1722       if (sps->constraint_set3_flag)
1723         profile = "high-10-intra";
1724       else if (sps->constraint_set4_flag)
1725         profile = "progressive-high-10";
1726       else
1727         profile = "high-10";
1728       break;
1729     case 122:
1730       if (sps->constraint_set3_flag)
1731         profile = "high-4:2:2-intra";
1732       else
1733         profile = "high-4:2:2";
1734       break;
1735     case 244:
1736       if (sps->constraint_set3_flag)
1737         profile = "high-4:4:4-intra";
1738       else
1739         profile = "high-4:4:4";
1740       break;
1741     case 44:
1742       profile = "cavlc-4:4:4-intra";
1743       break;
1744     case 118:
1745       profile = "multiview-high";
1746       break;
1747     case 128:
1748       profile = "stereo-high";
1749       break;
1750     case 83:
1751       if (sps->constraint_set5_flag)
1752         profile = "scalable-constrained-baseline";
1753       else
1754         profile = "scalable-baseline";
1755       break;
1756     case 86:
1757       if (sps->constraint_set3_flag)
1758         profile = "scalable-high-intra";
1759       else if (sps->constraint_set5_flag)
1760         profile = "scalable-constrained-high";
1761       else
1762         profile = "scalable-high";
1763       break;
1764     default:
1765       return NULL;
1766   }
1767
1768   return profile;
1769 }
1770
1771 static const gchar *
1772 get_level_string (GstH264SPS * sps)
1773 {
1774   if (sps->level_idc == 0)
1775     return NULL;
1776   else if ((sps->level_idc == 11 && sps->constraint_set3_flag)
1777       || sps->level_idc == 9)
1778     return "1b";
1779   else if (sps->level_idc % 10 == 0)
1780     return digit_to_string (sps->level_idc / 10);
1781   else {
1782     switch (sps->level_idc) {
1783       case 11:
1784         return "1.1";
1785       case 12:
1786         return "1.2";
1787       case 13:
1788         return "1.3";
1789       case 21:
1790         return "2.1";
1791       case 22:
1792         return "2.2";
1793       case 31:
1794         return "3.1";
1795       case 32:
1796         return "3.2";
1797       case 41:
1798         return "4.1";
1799       case 42:
1800         return "4.2";
1801       case 51:
1802         return "5.1";
1803       case 52:
1804         return "5.2";
1805       default:
1806         return NULL;
1807     }
1808   }
1809 }
1810
1811 static void
1812 gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps)
1813 {
1814   GstH264SPS *sps;
1815   GstCaps *sink_caps, *src_caps;
1816   gboolean modified = FALSE;
1817   GstBuffer *buf = NULL;
1818   GstStructure *s = NULL;
1819
1820   if (G_UNLIKELY (!gst_pad_has_current_caps (GST_BASE_PARSE_SRC_PAD
1821               (h264parse))))
1822     modified = TRUE;
1823   else if (G_UNLIKELY (!h264parse->update_caps))
1824     return;
1825
1826   /* if this is being called from the first _setcaps call, caps on the sinkpad
1827    * aren't set yet and so they need to be passed as an argument */
1828   if (caps)
1829     sink_caps = gst_caps_ref (caps);
1830   else
1831     sink_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (h264parse));
1832
1833   /* carry over input caps as much as possible; override with our own stuff */
1834   if (!sink_caps)
1835     sink_caps = gst_caps_new_empty_simple ("video/x-h264");
1836   else
1837     s = gst_caps_get_structure (sink_caps, 0);
1838
1839   sps = h264parse->nalparser->last_sps;
1840   GST_DEBUG_OBJECT (h264parse, "sps: %p", sps);
1841
1842   /* only codec-data for nice-and-clean au aligned packetized avc format */
1843   if ((h264parse->format == GST_H264_PARSE_FORMAT_AVC
1844           || h264parse->format == GST_H264_PARSE_FORMAT_AVC3)
1845       && h264parse->align == GST_H264_PARSE_ALIGN_AU) {
1846     buf = gst_h264_parse_make_codec_data (h264parse);
1847     if (buf && h264parse->codec_data) {
1848       GstMapInfo map;
1849
1850       gst_buffer_map (buf, &map, GST_MAP_READ);
1851       if (map.size != gst_buffer_get_size (h264parse->codec_data) ||
1852           gst_buffer_memcmp (h264parse->codec_data, 0, map.data, map.size))
1853         modified = TRUE;
1854
1855       gst_buffer_unmap (buf, &map);
1856     } else {
1857       if (!buf && h264parse->codec_data_in)
1858         buf = gst_buffer_ref (h264parse->codec_data_in);
1859       modified = TRUE;
1860     }
1861   }
1862
1863   caps = NULL;
1864   if (G_UNLIKELY (!sps)) {
1865     caps = gst_caps_copy (sink_caps);
1866   } else {
1867     gint crop_width, crop_height;
1868     gint fps_num, fps_den;
1869     gint par_n, par_d;
1870     GstH264VUIParams *vui = &sps->vui_parameters;
1871     gchar *colorimetry = NULL;
1872
1873     if (sps->frame_cropping_flag) {
1874       crop_width = sps->crop_rect_width;
1875       crop_height = sps->crop_rect_height;
1876     } else {
1877       crop_width = sps->width;
1878       crop_height = sps->height;
1879     }
1880
1881     if (G_UNLIKELY (h264parse->width != crop_width ||
1882             h264parse->height != crop_height)) {
1883       GST_INFO_OBJECT (h264parse, "resolution changed %dx%d",
1884           crop_width, crop_height);
1885       h264parse->width = crop_width;
1886       h264parse->height = crop_height;
1887       modified = TRUE;
1888     }
1889
1890     /* 0/1 is set as the default in the codec parser, we will set
1891      * it in case we have no info */
1892     gst_h264_video_calculate_framerate (sps, h264parse->field_pic_flag,
1893         h264parse->sei_pic_struct, &fps_num, &fps_den);
1894     if (G_UNLIKELY (h264parse->fps_num != fps_num
1895             || h264parse->fps_den != fps_den)) {
1896       GST_DEBUG_OBJECT (h264parse, "framerate changed %d/%d", fps_num, fps_den);
1897       h264parse->fps_num = fps_num;
1898       h264parse->fps_den = fps_den;
1899       modified = TRUE;
1900     }
1901
1902     if (vui->aspect_ratio_info_present_flag) {
1903       if (G_UNLIKELY ((h264parse->parsed_par_n != vui->par_n)
1904               || (h264parse->parsed_par_d != vui->par_d))) {
1905         h264parse->parsed_par_n = vui->par_n;
1906         h264parse->parsed_par_d = vui->par_d;
1907         GST_INFO_OBJECT (h264parse, "pixel aspect ratio has been changed %d/%d",
1908             h264parse->parsed_par_n, h264parse->parsed_par_d);
1909         modified = TRUE;
1910       }
1911     }
1912
1913     if (vui->video_signal_type_present_flag &&
1914         vui->colour_description_present_flag) {
1915       GstVideoColorimetry ci = { 0, };
1916       gchar *old_colorimetry = NULL;
1917
1918       if (vui->video_full_range_flag)
1919         ci.range = GST_VIDEO_COLOR_RANGE_0_255;
1920       else
1921         ci.range = GST_VIDEO_COLOR_RANGE_16_235;
1922
1923       ci.matrix = gst_video_color_matrix_from_iso (vui->matrix_coefficients);
1924       ci.transfer =
1925           gst_video_color_transfer_from_iso (vui->transfer_characteristics);
1926       ci.primaries = gst_video_color_primaries_from_iso (vui->colour_primaries);
1927
1928       old_colorimetry =
1929           gst_video_colorimetry_to_string (&h264parse->parsed_colorimetry);
1930       colorimetry = gst_video_colorimetry_to_string (&ci);
1931
1932       if (colorimetry && g_strcmp0 (old_colorimetry, colorimetry)) {
1933         GST_INFO_OBJECT (h264parse,
1934             "colorimetry has been changed from %s to %s",
1935             GST_STR_NULL (old_colorimetry), colorimetry);
1936         h264parse->parsed_colorimetry = ci;
1937         modified = TRUE;
1938       }
1939
1940       g_free (old_colorimetry);
1941     }
1942
1943     if (G_UNLIKELY (modified || h264parse->update_caps)) {
1944       GstVideoInterlaceMode imode = GST_VIDEO_INTERLACE_MODE_PROGRESSIVE;
1945       gint width, height;
1946       GstClockTime latency;
1947
1948       const gchar *caps_mview_mode = NULL;
1949       GstVideoMultiviewMode mview_mode = h264parse->multiview_mode;
1950       GstVideoMultiviewFlags mview_flags = h264parse->multiview_flags;
1951       const gchar *chroma_format = NULL;
1952       guint bit_depth_chroma;
1953
1954       fps_num = h264parse->fps_num;
1955       fps_den = h264parse->fps_den;
1956
1957       caps = gst_caps_copy (sink_caps);
1958
1959       /* sps should give this but upstream overrides */
1960       if (s && gst_structure_has_field (s, "width"))
1961         gst_structure_get_int (s, "width", &width);
1962       else
1963         width = h264parse->width;
1964
1965       if (s && gst_structure_has_field (s, "height"))
1966         gst_structure_get_int (s, "height", &height);
1967       else
1968         height = h264parse->height;
1969
1970       if (s == NULL ||
1971           !gst_structure_get_fraction (s, "pixel-aspect-ratio", &par_n,
1972               &par_d)) {
1973         gst_h264_parse_get_par (h264parse, &par_n, &par_d);
1974         if (par_n != 0 && par_d != 0) {
1975           GST_INFO_OBJECT (h264parse, "PAR %d/%d", par_n, par_d);
1976           gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
1977               par_n, par_d, NULL);
1978         } else {
1979           /* Assume par_n/par_d of 1/1 for calcs below, but don't set into caps */
1980           par_n = par_d = 1;
1981         }
1982       }
1983
1984       /* Pass through or set output stereo/multiview config */
1985       if (s && gst_structure_has_field (s, "multiview-mode")) {
1986         caps_mview_mode = gst_structure_get_string (s, "multiview-mode");
1987         gst_structure_get_flagset (s, "multiview-flags",
1988             (guint *) & mview_flags, NULL);
1989       } else if (mview_mode != GST_VIDEO_MULTIVIEW_MODE_NONE) {
1990         if (gst_video_multiview_guess_half_aspect (mview_mode,
1991                 width, height, par_n, par_d)) {
1992           mview_flags |= GST_VIDEO_MULTIVIEW_FLAGS_HALF_ASPECT;
1993         }
1994
1995         caps_mview_mode = gst_video_multiview_mode_to_caps_string (mview_mode);
1996         gst_caps_set_simple (caps, "multiview-mode", G_TYPE_STRING,
1997             caps_mview_mode, "multiview-flags",
1998             GST_TYPE_VIDEO_MULTIVIEW_FLAGSET, mview_flags,
1999             GST_FLAG_SET_MASK_EXACT, NULL);
2000       }
2001
2002       gst_caps_set_simple (caps, "width", G_TYPE_INT, width,
2003           "height", G_TYPE_INT, height, NULL);
2004
2005       /* upstream overrides */
2006       if (s && gst_structure_has_field (s, "framerate")) {
2007         gst_structure_get_fraction (s, "framerate", &fps_num, &fps_den);
2008       }
2009
2010       /* but not necessarily or reliably this */
2011       if (fps_den > 0) {
2012         GstStructure *s2;
2013         gst_caps_set_simple (caps, "framerate",
2014             GST_TYPE_FRACTION, fps_num, fps_den, NULL);
2015         s2 = gst_caps_get_structure (caps, 0);
2016         gst_structure_get_fraction (s2, "framerate", &h264parse->parsed_fps_n,
2017             &h264parse->parsed_fps_d);
2018         gst_base_parse_set_frame_rate (GST_BASE_PARSE (h264parse), fps_num,
2019             fps_den, 0, 0);
2020         if (fps_num > 0) {
2021           latency = gst_util_uint64_scale (GST_SECOND, fps_den, fps_num);
2022           gst_base_parse_set_latency (GST_BASE_PARSE (h264parse), latency,
2023               latency);
2024         }
2025
2026       }
2027
2028       /* upstream overrides or uses sps info */
2029       if (s && gst_structure_has_field (s, "interlace-mode"))
2030         imode =
2031             gst_video_interlace_mode_from_string (gst_structure_get_string (s,
2032                 "interlace-mode"));
2033       else if (sps->frame_mbs_only_flag == 0)
2034         imode = GST_VIDEO_INTERLACE_MODE_MIXED;
2035
2036       gst_caps_set_simple (caps, "interlace-mode", G_TYPE_STRING,
2037           gst_video_interlace_mode_to_string (imode), NULL);
2038
2039       bit_depth_chroma = sps->bit_depth_chroma_minus8 + 8;
2040
2041       switch (sps->chroma_format_idc) {
2042         case 0:
2043           chroma_format = "4:0:0";
2044           bit_depth_chroma = 0;
2045           break;
2046         case 1:
2047           chroma_format = "4:2:0";
2048           break;
2049         case 2:
2050           chroma_format = "4:2:2";
2051           break;
2052         case 3:
2053           chroma_format = "4:4:4";
2054           break;
2055         default:
2056           break;
2057       }
2058
2059       if (chroma_format)
2060         gst_caps_set_simple (caps,
2061             "chroma-format", G_TYPE_STRING, chroma_format,
2062             "bit-depth-luma", G_TYPE_UINT, sps->bit_depth_luma_minus8 + 8,
2063             "bit-depth-chroma", G_TYPE_UINT, bit_depth_chroma, NULL);
2064
2065       if (colorimetry && (!s || !gst_structure_has_field (s, "colorimetry"))) {
2066         gst_caps_set_simple (caps, "colorimetry", G_TYPE_STRING, colorimetry,
2067             NULL);
2068       }
2069     }
2070
2071     g_free (colorimetry);
2072   }
2073
2074   if (caps) {
2075     gst_caps_set_simple (caps, "parsed", G_TYPE_BOOLEAN, TRUE,
2076         "stream-format", G_TYPE_STRING,
2077         gst_h264_parse_get_string (h264parse, TRUE, h264parse->format),
2078         "alignment", G_TYPE_STRING,
2079         gst_h264_parse_get_string (h264parse, FALSE, h264parse->align), NULL);
2080
2081     /* set profile and level in caps */
2082     if (sps) {
2083       const gchar *profile, *level;
2084
2085       profile = get_profile_string (sps);
2086       if (profile != NULL)
2087         gst_caps_set_simple (caps, "profile", G_TYPE_STRING, profile, NULL);
2088
2089       level = get_level_string (sps);
2090       if (level != NULL)
2091         gst_caps_set_simple (caps, "level", G_TYPE_STRING, level, NULL);
2092
2093       /* relax the profile constraint to find a suitable decoder */
2094       ensure_caps_profile (h264parse, caps, sps);
2095     }
2096
2097     src_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (h264parse));
2098
2099     if (src_caps) {
2100       /* use codec data from old caps for comparison; we don't want to resend caps
2101          if everything is same except codec data; */
2102       if (gst_structure_has_field (gst_caps_get_structure (src_caps, 0),
2103               "codec_data")) {
2104         gst_caps_set_value (caps, "codec_data",
2105             gst_structure_get_value (gst_caps_get_structure (src_caps, 0),
2106                 "codec_data"));
2107       } else if (!buf) {
2108         GstStructure *s;
2109         /* remove any left-over codec-data hanging around */
2110         s = gst_caps_get_structure (caps, 0);
2111         gst_structure_remove_field (s, "codec_data");
2112       }
2113     }
2114
2115     if (!(src_caps && gst_caps_is_strictly_equal (src_caps, caps))) {
2116       /* update codec data to new value */
2117       if (buf) {
2118         gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
2119         gst_buffer_replace (&h264parse->codec_data, buf);
2120         gst_buffer_unref (buf);
2121         buf = NULL;
2122       } else {
2123         GstStructure *s;
2124         /* remove any left-over codec-data hanging around */
2125         s = gst_caps_get_structure (caps, 0);
2126         gst_structure_remove_field (s, "codec_data");
2127         gst_buffer_replace (&h264parse->codec_data, NULL);
2128       }
2129
2130       gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (h264parse), caps);
2131     }
2132
2133     if (src_caps)
2134       gst_caps_unref (src_caps);
2135     gst_caps_unref (caps);
2136   }
2137
2138   gst_caps_unref (sink_caps);
2139   if (buf)
2140     gst_buffer_unref (buf);
2141 }
2142
2143 static void
2144 gst_h264_parse_get_timestamp (GstH264Parse * h264parse,
2145     GstClockTime * out_ts, GstClockTime * out_dur, gboolean frame)
2146 {
2147   GstH264SPS *sps = h264parse->nalparser->last_sps;
2148   GstClockTime upstream;
2149   gint duration = 1;
2150
2151   g_return_if_fail (out_dur != NULL);
2152   g_return_if_fail (out_ts != NULL);
2153
2154   upstream = *out_ts;
2155   GST_LOG_OBJECT (h264parse, "Upstream ts %" GST_TIME_FORMAT,
2156       GST_TIME_ARGS (upstream));
2157
2158   if (!frame) {
2159     GST_LOG_OBJECT (h264parse, "no frame data ->  0 duration");
2160     *out_dur = 0;
2161     goto exit;
2162   } else {
2163     *out_ts = upstream;
2164   }
2165
2166   if (!sps) {
2167     GST_DEBUG_OBJECT (h264parse, "referred SPS invalid");
2168     goto exit;
2169   } else if (!sps->vui_parameters_present_flag) {
2170     GST_DEBUG_OBJECT (h264parse,
2171         "unable to compute timestamp: VUI not present");
2172     goto exit;
2173   } else if (!sps->vui_parameters.timing_info_present_flag) {
2174     GST_DEBUG_OBJECT (h264parse,
2175         "unable to compute timestamp: timing info not present");
2176     goto exit;
2177   } else if (sps->vui_parameters.time_scale == 0) {
2178     GST_DEBUG_OBJECT (h264parse,
2179         "unable to compute timestamp: time_scale = 0 "
2180         "(this is forbidden in spec; bitstream probably contains error)");
2181     goto exit;
2182   }
2183
2184   if (h264parse->sei_pic_struct_pres_flag &&
2185       h264parse->sei_pic_struct != (guint8) - 1) {
2186     /* Note that when h264parse->sei_pic_struct == -1 (unspecified), there
2187      * are ways to infer its value. This is related to computing the
2188      * TopFieldOrderCnt and BottomFieldOrderCnt, which looks
2189      * complicated and thus not implemented for the time being. Yet
2190      * the value we have here is correct for many applications
2191      */
2192     switch (h264parse->sei_pic_struct) {
2193       case GST_H264_SEI_PIC_STRUCT_TOP_FIELD:
2194       case GST_H264_SEI_PIC_STRUCT_BOTTOM_FIELD:
2195         duration = 1;
2196         break;
2197       case GST_H264_SEI_PIC_STRUCT_FRAME:
2198       case GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM:
2199       case GST_H264_SEI_PIC_STRUCT_BOTTOM_TOP:
2200         duration = 2;
2201         break;
2202       case GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
2203       case GST_H264_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
2204         duration = 3;
2205         break;
2206       case GST_H264_SEI_PIC_STRUCT_FRAME_DOUBLING:
2207         duration = 4;
2208         break;
2209       case GST_H264_SEI_PIC_STRUCT_FRAME_TRIPLING:
2210         duration = 6;
2211         break;
2212       default:
2213         GST_DEBUG_OBJECT (h264parse,
2214             "h264parse->sei_pic_struct of unknown value %d. Not parsed",
2215             h264parse->sei_pic_struct);
2216         break;
2217     }
2218   } else {
2219     duration = h264parse->field_pic_flag ? 1 : 2;
2220   }
2221
2222   GST_LOG_OBJECT (h264parse, "frame tick duration %d", duration);
2223
2224   /*
2225    * h264parse.264 C.1.2 Timing of coded picture removal (equivalent to DTS):
2226    * Tr,n(0) = initial_cpb_removal_delay[ SchedSelIdx ] / 90000
2227    * Tr,n(n) = Tr,n(nb) + Tc * cpb_removal_delay(n)
2228    * where
2229    * Tc = num_units_in_tick / time_scale
2230    */
2231
2232   if (h264parse->ts_trn_nb != GST_CLOCK_TIME_NONE) {
2233     GST_LOG_OBJECT (h264parse, "buffering based ts");
2234     /* buffering period is present */
2235     if (upstream != GST_CLOCK_TIME_NONE) {
2236       /* If upstream timestamp is valid, we respect it and adjust current
2237        * reference point */
2238       h264parse->ts_trn_nb = upstream -
2239           (GstClockTime) gst_util_uint64_scale
2240           (h264parse->sei_cpb_removal_delay * GST_SECOND,
2241           sps->vui_parameters.num_units_in_tick,
2242           sps->vui_parameters.time_scale);
2243     } else {
2244       /* If no upstream timestamp is given, we write in new timestamp */
2245       upstream = h264parse->dts = h264parse->ts_trn_nb +
2246           (GstClockTime) gst_util_uint64_scale
2247           (h264parse->sei_cpb_removal_delay * GST_SECOND,
2248           sps->vui_parameters.num_units_in_tick,
2249           sps->vui_parameters.time_scale);
2250     }
2251   } else {
2252     GstClockTime dur;
2253
2254     GST_LOG_OBJECT (h264parse, "duration based ts");
2255     /* naive method: no removal delay specified
2256      * track upstream timestamp and provide best guess frame duration */
2257     dur = gst_util_uint64_scale (duration * GST_SECOND,
2258         sps->vui_parameters.num_units_in_tick, sps->vui_parameters.time_scale);
2259     /* sanity check */
2260     if (dur < GST_MSECOND) {
2261       GST_DEBUG_OBJECT (h264parse, "discarding dur %" GST_TIME_FORMAT,
2262           GST_TIME_ARGS (dur));
2263     } else {
2264       *out_dur = dur;
2265     }
2266   }
2267
2268 exit:
2269   if (GST_CLOCK_TIME_IS_VALID (upstream))
2270     *out_ts = h264parse->dts = upstream;
2271
2272   if (GST_CLOCK_TIME_IS_VALID (*out_dur) &&
2273       GST_CLOCK_TIME_IS_VALID (h264parse->dts))
2274     h264parse->dts += *out_dur;
2275 }
2276
2277 static GstFlowReturn
2278 gst_h264_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
2279 {
2280   GstH264Parse *h264parse;
2281   GstBuffer *buffer;
2282   guint av;
2283
2284   h264parse = GST_H264_PARSE (parse);
2285   buffer = frame->buffer;
2286
2287   gst_h264_parse_update_src_caps (h264parse, NULL);
2288
2289   /* don't mess with timestamps if provided by upstream,
2290    * particularly since our ts not that good they handle seeking etc */
2291   if (h264parse->do_ts)
2292     gst_h264_parse_get_timestamp (h264parse,
2293         &GST_BUFFER_TIMESTAMP (buffer), &GST_BUFFER_DURATION (buffer),
2294         h264parse->frame_start);
2295
2296   if (h264parse->keyframe)
2297     GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2298   else
2299     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2300
2301   if (h264parse->discard_bidirectional && h264parse->bidirectional)
2302     goto discard;
2303
2304   if (h264parse->header)
2305     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_HEADER);
2306   else
2307     GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_HEADER);
2308
2309   if (h264parse->discont) {
2310     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
2311     h264parse->discont = FALSE;
2312   }
2313
2314   /* replace with transformed AVC output if applicable */
2315   av = gst_adapter_available (h264parse->frame_out);
2316   if (av) {
2317     GstBuffer *buf;
2318
2319     buf = gst_adapter_take_buffer (h264parse->frame_out, av);
2320     gst_buffer_copy_into (buf, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
2321     gst_buffer_replace (&frame->out_buffer, buf);
2322     gst_buffer_unref (buf);
2323   }
2324
2325 done:
2326   return GST_FLOW_OK;
2327
2328 discard:
2329   GST_DEBUG_OBJECT (h264parse, "Discarding bidirectional frame");
2330   frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
2331   gst_h264_parse_reset_frame (h264parse);
2332   goto done;
2333 }
2334
2335 /* sends a codec NAL downstream, decorating and transforming as needed.
2336  * No ownership is taken of @nal */
2337 static GstFlowReturn
2338 gst_h264_parse_push_codec_buffer (GstH264Parse * h264parse,
2339     GstBuffer * nal, GstClockTime ts)
2340 {
2341   GstMapInfo map;
2342
2343   gst_buffer_map (nal, &map, GST_MAP_READ);
2344   nal = gst_h264_parse_wrap_nal (h264parse, h264parse->format,
2345       map.data, map.size);
2346   gst_buffer_unmap (nal, &map);
2347
2348   GST_BUFFER_TIMESTAMP (nal) = ts;
2349   GST_BUFFER_DURATION (nal) = 0;
2350
2351   return gst_pad_push (GST_BASE_PARSE_SRC_PAD (h264parse), nal);
2352 }
2353
2354 static GstEvent *
2355 check_pending_key_unit_event (GstEvent * pending_event,
2356     GstSegment * segment, GstClockTime timestamp, guint flags,
2357     GstClockTime pending_key_unit_ts)
2358 {
2359   GstClockTime running_time, stream_time;
2360   gboolean all_headers;
2361   guint count;
2362   GstEvent *event = NULL;
2363
2364   g_return_val_if_fail (segment != NULL, NULL);
2365
2366   if (pending_event == NULL)
2367     goto out;
2368
2369   if (GST_CLOCK_TIME_IS_VALID (pending_key_unit_ts) &&
2370       timestamp == GST_CLOCK_TIME_NONE)
2371     goto out;
2372
2373   running_time = gst_segment_to_running_time (segment,
2374       GST_FORMAT_TIME, timestamp);
2375
2376   GST_INFO ("now %" GST_TIME_FORMAT " wanted %" GST_TIME_FORMAT,
2377       GST_TIME_ARGS (running_time), GST_TIME_ARGS (pending_key_unit_ts));
2378   if (GST_CLOCK_TIME_IS_VALID (pending_key_unit_ts) &&
2379       running_time < pending_key_unit_ts)
2380     goto out;
2381
2382   if (flags & GST_BUFFER_FLAG_DELTA_UNIT) {
2383     GST_DEBUG ("pending force key unit, waiting for keyframe");
2384     goto out;
2385   }
2386
2387   stream_time = gst_segment_to_stream_time (segment,
2388       GST_FORMAT_TIME, timestamp);
2389
2390   if (!gst_video_event_parse_upstream_force_key_unit (pending_event,
2391           NULL, &all_headers, &count)) {
2392     gst_video_event_parse_downstream_force_key_unit (pending_event, NULL,
2393         NULL, NULL, &all_headers, &count);
2394   }
2395
2396   event =
2397       gst_video_event_new_downstream_force_key_unit (timestamp, stream_time,
2398       running_time, all_headers, count);
2399   gst_event_set_seqnum (event, gst_event_get_seqnum (pending_event));
2400
2401 out:
2402   return event;
2403 }
2404
2405 static void
2406 gst_h264_parse_prepare_key_unit (GstH264Parse * parse, GstEvent * event)
2407 {
2408   GstClockTime running_time;
2409   guint count;
2410 #ifndef GST_DISABLE_GST_DEBUG
2411   gboolean have_sps, have_pps;
2412   gint i;
2413 #endif
2414
2415   parse->pending_key_unit_ts = GST_CLOCK_TIME_NONE;
2416   gst_event_replace (&parse->force_key_unit_event, NULL);
2417
2418   gst_video_event_parse_downstream_force_key_unit (event,
2419       NULL, NULL, &running_time, NULL, &count);
2420
2421   GST_INFO_OBJECT (parse, "pushing downstream force-key-unit event %d "
2422       "%" GST_TIME_FORMAT " count %d", gst_event_get_seqnum (event),
2423       GST_TIME_ARGS (running_time), count);
2424   gst_pad_push_event (GST_BASE_PARSE_SRC_PAD (parse), event);
2425
2426 #ifndef GST_DISABLE_GST_DEBUG
2427   have_sps = have_pps = FALSE;
2428   for (i = 0; i < GST_H264_MAX_SPS_COUNT; i++) {
2429     if (parse->sps_nals[i] != NULL) {
2430       have_sps = TRUE;
2431       break;
2432     }
2433   }
2434   for (i = 0; i < GST_H264_MAX_PPS_COUNT; i++) {
2435     if (parse->pps_nals[i] != NULL) {
2436       have_pps = TRUE;
2437       break;
2438     }
2439   }
2440
2441   GST_INFO_OBJECT (parse, "preparing key unit, have sps %d have pps %d",
2442       have_sps, have_pps);
2443 #endif
2444
2445   /* set push_codec to TRUE so that pre_push_frame sends SPS/PPS again */
2446   parse->push_codec = TRUE;
2447 }
2448
2449 static gboolean
2450 gst_h264_parse_handle_sps_pps_nals (GstH264Parse * h264parse,
2451     GstBuffer * buffer, GstBaseParseFrame * frame)
2452 {
2453   GstBuffer *codec_nal;
2454   gint i;
2455   gboolean send_done = FALSE;
2456   GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer);
2457
2458   if (h264parse->have_sps_in_frame && h264parse->have_pps_in_frame) {
2459     GST_DEBUG_OBJECT (h264parse, "SPS/PPS exist in frame, will not insert");
2460     return TRUE;
2461   }
2462
2463   if (h264parse->align == GST_H264_PARSE_ALIGN_NAL) {
2464     /* send separate config NAL buffers */
2465     GST_DEBUG_OBJECT (h264parse, "- sending SPS/PPS");
2466     for (i = 0; i < GST_H264_MAX_SPS_COUNT; i++) {
2467       if ((codec_nal = h264parse->sps_nals[i])) {
2468         GST_DEBUG_OBJECT (h264parse, "sending SPS nal");
2469         gst_h264_parse_push_codec_buffer (h264parse, codec_nal, timestamp);
2470         send_done = TRUE;
2471       }
2472     }
2473     for (i = 0; i < GST_H264_MAX_PPS_COUNT; i++) {
2474       if ((codec_nal = h264parse->pps_nals[i])) {
2475         GST_DEBUG_OBJECT (h264parse, "sending PPS nal");
2476         gst_h264_parse_push_codec_buffer (h264parse, codec_nal, timestamp);
2477         send_done = TRUE;
2478       }
2479     }
2480   } else {
2481     /* insert config NALs into AU */
2482     GstByteWriter bw;
2483     GstBuffer *new_buf;
2484     const gboolean bs = h264parse->format == GST_H264_PARSE_FORMAT_BYTE;
2485     const gint nls = 4 - h264parse->nal_length_size;
2486     gboolean ok;
2487
2488     gst_byte_writer_init_with_size (&bw, gst_buffer_get_size (buffer), FALSE);
2489     ok = gst_byte_writer_put_buffer (&bw, buffer, 0, h264parse->idr_pos);
2490     GST_DEBUG_OBJECT (h264parse, "- inserting SPS/PPS");
2491     for (i = 0; i < GST_H264_MAX_SPS_COUNT; i++) {
2492       if ((codec_nal = h264parse->sps_nals[i])) {
2493         gsize nal_size = gst_buffer_get_size (codec_nal);
2494         GST_DEBUG_OBJECT (h264parse, "inserting SPS nal");
2495         if (bs) {
2496           ok &= gst_byte_writer_put_uint32_be (&bw, 1);
2497         } else {
2498           ok &= gst_byte_writer_put_uint32_be (&bw, (nal_size << (nls * 8)));
2499           ok &= gst_byte_writer_set_pos (&bw,
2500               gst_byte_writer_get_pos (&bw) - nls);
2501         }
2502
2503         ok &= gst_byte_writer_put_buffer (&bw, codec_nal, 0, nal_size);
2504         send_done = TRUE;
2505       }
2506     }
2507     for (i = 0; i < GST_H264_MAX_PPS_COUNT; i++) {
2508       if ((codec_nal = h264parse->pps_nals[i])) {
2509         gsize nal_size = gst_buffer_get_size (codec_nal);
2510         GST_DEBUG_OBJECT (h264parse, "inserting PPS nal");
2511         if (bs) {
2512           ok &= gst_byte_writer_put_uint32_be (&bw, 1);
2513         } else {
2514           ok &= gst_byte_writer_put_uint32_be (&bw, (nal_size << (nls * 8)));
2515           ok &= gst_byte_writer_set_pos (&bw,
2516               gst_byte_writer_get_pos (&bw) - nls);
2517         }
2518         ok &= gst_byte_writer_put_buffer (&bw, codec_nal, 0, nal_size);
2519         send_done = TRUE;
2520       }
2521     }
2522     ok &= gst_byte_writer_put_buffer (&bw, buffer, h264parse->idr_pos, -1);
2523     /* collect result and push */
2524     new_buf = gst_byte_writer_reset_and_get_buffer (&bw);
2525     gst_buffer_copy_into (new_buf, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
2526     /* should already be keyframe/IDR, but it may not have been,
2527      * so mark it as such to avoid being discarded by picky decoder */
2528     GST_BUFFER_FLAG_UNSET (new_buf, GST_BUFFER_FLAG_DELTA_UNIT);
2529     gst_buffer_replace (&frame->out_buffer, new_buf);
2530     gst_buffer_unref (new_buf);
2531     /* some result checking seems to make some compilers happy */
2532     if (G_UNLIKELY (!ok)) {
2533       GST_ERROR_OBJECT (h264parse, "failed to insert SPS/PPS");
2534     }
2535   }
2536
2537   return send_done;
2538 }
2539
2540 static GstFlowReturn
2541 gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
2542 {
2543   GstH264Parse *h264parse;
2544   GstBuffer *buffer;
2545   GstEvent *event;
2546   GstBuffer *parse_buffer = NULL;
2547   gboolean is_interlaced = FALSE;
2548
2549   h264parse = GST_H264_PARSE (parse);
2550
2551   if (!h264parse->sent_codec_tag) {
2552     GstTagList *taglist;
2553     GstCaps *caps;
2554
2555     /* codec tag */
2556     caps = gst_pad_get_current_caps (GST_BASE_PARSE_SRC_PAD (parse));
2557     if (caps == NULL) {
2558       if (GST_PAD_IS_FLUSHING (GST_BASE_PARSE_SRC_PAD (h264parse))) {
2559         GST_INFO_OBJECT (h264parse, "Src pad is flushing");
2560         return GST_FLOW_FLUSHING;
2561       } else {
2562         GST_INFO_OBJECT (h264parse, "Src pad is not negotiated!");
2563         return GST_FLOW_NOT_NEGOTIATED;
2564       }
2565     }
2566
2567     taglist = gst_tag_list_new_empty ();
2568     gst_pb_utils_add_codec_description_to_tag_list (taglist,
2569         GST_TAG_VIDEO_CODEC, caps);
2570     gst_caps_unref (caps);
2571
2572     gst_base_parse_merge_tags (parse, taglist, GST_TAG_MERGE_REPLACE);
2573     gst_tag_list_unref (taglist);
2574
2575     /* also signals the end of first-frame processing */
2576     h264parse->sent_codec_tag = TRUE;
2577   }
2578
2579   /* In case of byte-stream, insert au delimiter by default
2580    * if it doesn't exist */
2581   if (h264parse->aud_insert && h264parse->format == GST_H264_PARSE_FORMAT_BYTE) {
2582     if (h264parse->align == GST_H264_PARSE_ALIGN_AU) {
2583       GstMemory *mem =
2584           gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, (guint8 *) au_delim,
2585           sizeof (au_delim), 0, sizeof (au_delim), NULL, NULL);
2586
2587       frame->out_buffer = gst_buffer_copy (frame->buffer);
2588       gst_buffer_prepend_memory (frame->out_buffer, mem);
2589       if (h264parse->idr_pos >= 0)
2590         h264parse->idr_pos += sizeof (au_delim);
2591
2592       buffer = frame->out_buffer;
2593     } else {
2594       GstBuffer *aud_buffer = gst_buffer_new_allocate (NULL, 2, NULL);
2595       gst_buffer_fill (aud_buffer, 0, (guint8 *) (au_delim + 4), 2);
2596
2597       buffer = frame->buffer;
2598       gst_h264_parse_push_codec_buffer (h264parse, aud_buffer,
2599           GST_BUFFER_TIMESTAMP (buffer));
2600       gst_buffer_unref (aud_buffer);
2601     }
2602   } else {
2603     buffer = frame->buffer;
2604   }
2605
2606   if ((event = check_pending_key_unit_event (h264parse->force_key_unit_event,
2607               &parse->segment, GST_BUFFER_TIMESTAMP (buffer),
2608               GST_BUFFER_FLAGS (buffer), h264parse->pending_key_unit_ts))) {
2609     gst_h264_parse_prepare_key_unit (h264parse, event);
2610   }
2611
2612   /* periodic SPS/PPS sending */
2613   if (h264parse->interval > 0 || h264parse->push_codec) {
2614     GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer);
2615     guint64 diff;
2616     gboolean initial_frame = FALSE;
2617
2618     /* init */
2619     if (!GST_CLOCK_TIME_IS_VALID (h264parse->last_report)) {
2620       h264parse->last_report = timestamp;
2621       initial_frame = TRUE;
2622     }
2623
2624     if (h264parse->idr_pos >= 0) {
2625       GST_LOG_OBJECT (h264parse, "IDR nal at offset %d", h264parse->idr_pos);
2626
2627       if (timestamp > h264parse->last_report)
2628         diff = timestamp - h264parse->last_report;
2629       else
2630         diff = 0;
2631
2632       GST_LOG_OBJECT (h264parse,
2633           "now %" GST_TIME_FORMAT ", last SPS/PPS %" GST_TIME_FORMAT,
2634           GST_TIME_ARGS (timestamp), GST_TIME_ARGS (h264parse->last_report));
2635
2636       GST_DEBUG_OBJECT (h264parse,
2637           "interval since last SPS/PPS %" GST_TIME_FORMAT,
2638           GST_TIME_ARGS (diff));
2639
2640       if (GST_TIME_AS_SECONDS (diff) >= h264parse->interval ||
2641           initial_frame || h264parse->push_codec) {
2642         GstClockTime new_ts;
2643
2644         /* avoid overwriting a perfectly fine timestamp */
2645         new_ts = GST_CLOCK_TIME_IS_VALID (timestamp) ? timestamp :
2646             h264parse->last_report;
2647
2648         if (gst_h264_parse_handle_sps_pps_nals (h264parse, buffer, frame)) {
2649           h264parse->last_report = new_ts;
2650         }
2651       }
2652       /* we pushed whatever we had */
2653       h264parse->push_codec = FALSE;
2654       h264parse->have_sps = FALSE;
2655       h264parse->have_pps = FALSE;
2656       h264parse->state &= GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS;
2657     }
2658   } else if (h264parse->interval == -1) {
2659     if (h264parse->idr_pos >= 0) {
2660       GST_LOG_OBJECT (h264parse, "IDR nal at offset %d", h264parse->idr_pos);
2661
2662       gst_h264_parse_handle_sps_pps_nals (h264parse, buffer, frame);
2663
2664       /* we pushed whatever we had */
2665       h264parse->push_codec = FALSE;
2666       h264parse->have_sps = FALSE;
2667       h264parse->have_pps = FALSE;
2668       h264parse->state &= GST_H264_PARSE_STATE_VALID_PICTURE_HEADERS;
2669     }
2670   }
2671
2672   /* Fixme: setting passthrough mode causing multiple issues:
2673    * For nal aligned multiresoluton streams, passthrough mode make h264parse
2674    * unable to advertise the new resoultions. Also causing issues while
2675    * parsing MVC streams when it has two layers.
2676    * Disabing passthourgh mode for now */
2677 #if 0
2678   /* If SPS/PPS and a keyframe have been parsed, and we're not converting,
2679    * we might switch to passthrough mode now on the basis that we've seen
2680    * the SEI packets and know optional caps params (such as multiview).
2681    * This is an efficiency optimisation that relies on stream properties
2682    * remaining uniform in practice. */
2683   if (h264parse->can_passthrough) {
2684     if (h264parse->keyframe && h264parse->have_sps && h264parse->have_pps) {
2685       GST_LOG_OBJECT (parse, "Switching to passthrough mode");
2686       gst_base_parse_set_passthrough (parse, TRUE);
2687     }
2688   }
2689 #endif
2690
2691   {
2692     guint i = 0;
2693
2694     for (i = 0; i < h264parse->num_clock_timestamp; i++) {
2695       GstH264ClockTimestamp *tim = &h264parse->clock_timestamp[i];
2696       gint field_count = -1;
2697       guint n_frames;
2698       GstVideoTimeCodeFlags flags = 0;
2699
2700       /* Table D-1 */
2701       switch (h264parse->sei_pic_struct) {
2702         case GST_H264_SEI_PIC_STRUCT_FRAME:
2703         case GST_H264_SEI_PIC_STRUCT_TOP_FIELD:
2704         case GST_H264_SEI_PIC_STRUCT_BOTTOM_FIELD:
2705           field_count = h264parse->sei_pic_struct;
2706           break;
2707         case GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM:
2708           field_count = i + 1;
2709           break;
2710         case GST_H264_SEI_PIC_STRUCT_BOTTOM_TOP:
2711           field_count = 2 - i;
2712           break;
2713         case GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
2714           field_count = i % 2 ? 2 : 1;
2715           break;
2716         case GST_H264_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
2717           field_count = i % 2 ? 1 : 2;
2718           break;
2719         case GST_H264_SEI_PIC_STRUCT_FRAME_DOUBLING:
2720         case GST_H264_SEI_PIC_STRUCT_FRAME_TRIPLING:
2721           field_count = 0;
2722           break;
2723       }
2724
2725       if (field_count == -1) {
2726         GST_WARNING_OBJECT (parse,
2727             "failed to determine field count for timecode");
2728         field_count = 0;
2729       }
2730
2731       /* dropping of the two lowest (value 0 and 1) n_frames
2732        * counts when seconds_value is equal to 0 and
2733        * minutes_value is not an integer multiple of 10 */
2734       if (tim->counting_type == 4)
2735         flags |= GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME;
2736
2737       if (tim->ct_type == GST_H264_CT_TYPE_INTERLACED) {
2738         flags |= GST_VIDEO_TIME_CODE_FLAGS_INTERLACED;
2739         is_interlaced = TRUE;
2740       }
2741
2742       n_frames =
2743           gst_util_uint64_scale_int (tim->n_frames, 1,
2744           2 - tim->nuit_field_based_flag);
2745
2746       gst_buffer_add_video_time_code_meta_full (buffer,
2747           h264parse->parsed_fps_n,
2748           h264parse->parsed_fps_d,
2749           NULL,
2750           flags,
2751           tim->hours_flag ? tim->hours_value : 0,
2752           tim->minutes_flag ? tim->minutes_value : 0,
2753           tim->seconds_flag ? tim->seconds_value : 0, n_frames, field_count);
2754     }
2755
2756     h264parse->num_clock_timestamp = 0;
2757   }
2758
2759   if (frame->out_buffer) {
2760     parse_buffer = frame->out_buffer =
2761         gst_buffer_make_writable (frame->out_buffer);
2762   } else {
2763     parse_buffer = frame->buffer = gst_buffer_make_writable (frame->buffer);
2764   }
2765
2766   if (is_interlaced) {
2767     GST_BUFFER_FLAG_SET (parse_buffer, GST_VIDEO_BUFFER_FLAG_INTERLACED);
2768     if (h264parse->sei_pic_struct == GST_H264_SEI_PIC_STRUCT_TOP_FIELD)
2769       GST_BUFFER_FLAG_SET (parse_buffer, GST_VIDEO_BUFFER_FLAG_TFF);
2770   }
2771
2772   gst_video_push_user_data ((GstElement *) h264parse, &h264parse->user_data,
2773       parse_buffer);
2774
2775   gst_h264_parse_reset_frame (h264parse);
2776
2777   return GST_FLOW_OK;
2778 }
2779
2780 static gboolean
2781 gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps)
2782 {
2783   GstH264Parse *h264parse;
2784   GstStructure *str;
2785   const GValue *codec_data_value;
2786   GstBuffer *codec_data = NULL;
2787   gsize size;
2788   guint format, align, off;
2789   GstH264NalUnit nalu;
2790   GstH264ParserResult parseres;
2791   GstCaps *old_caps;
2792
2793   h264parse = GST_H264_PARSE (parse);
2794
2795   /* reset */
2796   h264parse->push_codec = FALSE;
2797
2798   old_caps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (parse));
2799   if (old_caps) {
2800     if (!gst_caps_is_equal (old_caps, caps))
2801       gst_h264_parse_reset_stream_info (h264parse);
2802     gst_caps_unref (old_caps);
2803   }
2804
2805   str = gst_caps_get_structure (caps, 0);
2806
2807   /* accept upstream info if provided */
2808   gst_structure_get_int (str, "width", &h264parse->width);
2809   gst_structure_get_int (str, "height", &h264parse->height);
2810   gst_structure_get_fraction (str, "framerate", &h264parse->fps_num,
2811       &h264parse->fps_den);
2812   gst_structure_get_fraction (str, "pixel-aspect-ratio",
2813       &h264parse->upstream_par_n, &h264parse->upstream_par_d);
2814
2815   /* get upstream format and align from caps */
2816   gst_h264_parse_format_from_caps (caps, &format, &align);
2817
2818   codec_data_value = gst_structure_get_value (str, "codec_data");
2819
2820   /* fix up caps without stream-format for max. backwards compatibility */
2821   if (format == GST_H264_PARSE_FORMAT_NONE) {
2822     /* codec_data implies avc */
2823     if (codec_data_value != NULL) {
2824       GST_ERROR ("video/x-h264 caps with codec_data but no stream-format=avc");
2825       format = GST_H264_PARSE_FORMAT_AVC;
2826     } else {
2827       /* otherwise assume bytestream input */
2828       GST_ERROR ("video/x-h264 caps without codec_data or stream-format");
2829       format = GST_H264_PARSE_FORMAT_BYTE;
2830     }
2831   }
2832
2833   /* avc caps sanity checks */
2834   if (format == GST_H264_PARSE_FORMAT_AVC) {
2835     /* AVC requires codec_data, AVC3 might have one and/or SPS/PPS inline */
2836     if (codec_data_value == NULL)
2837       goto avc_caps_codec_data_missing;
2838
2839     /* AVC implies alignment=au, everything else is not allowed */
2840     if (align == GST_H264_PARSE_ALIGN_NONE)
2841       align = GST_H264_PARSE_ALIGN_AU;
2842     else if (align != GST_H264_PARSE_ALIGN_AU)
2843       goto avc_caps_wrong_alignment;
2844   }
2845
2846   /* bytestream caps sanity checks */
2847   if (format == GST_H264_PARSE_FORMAT_BYTE) {
2848     /* should have SPS/PSS in-band (and/or oob in streamheader field) */
2849     if (codec_data_value != NULL)
2850       goto bytestream_caps_with_codec_data;
2851   }
2852
2853   /* packetized video has codec_data (required for AVC, optional for AVC3) */
2854   if (codec_data_value != NULL) {
2855     GstMapInfo map;
2856     guint8 *data;
2857     guint num_sps, num_pps;
2858 #ifndef GST_DISABLE_GST_DEBUG
2859     guint profile;
2860 #endif
2861     gint i;
2862
2863     GST_DEBUG_OBJECT (h264parse, "have packetized h264");
2864     /* make note for optional split processing */
2865     h264parse->packetized = TRUE;
2866
2867     /* codec_data field should hold a buffer */
2868     if (!GST_VALUE_HOLDS_BUFFER (codec_data_value))
2869       goto avc_caps_codec_data_wrong_type;
2870
2871     codec_data = gst_value_get_buffer (codec_data_value);
2872     if (!codec_data)
2873       goto avc_caps_codec_data_missing;
2874     gst_buffer_map (codec_data, &map, GST_MAP_READ);
2875     data = map.data;
2876     size = map.size;
2877
2878     /* parse the avcC data */
2879     if (size < 7) {             /* when numSPS==0 and numPPS==0, length is 7 bytes */
2880       gst_buffer_unmap (codec_data, &map);
2881       goto avcc_too_small;
2882     }
2883     /* parse the version, this must be 1 */
2884     if (data[0] != 1) {
2885       gst_buffer_unmap (codec_data, &map);
2886       goto wrong_version;
2887     }
2888 #ifndef GST_DISABLE_GST_DEBUG
2889     /* AVCProfileIndication */
2890     /* profile_compat */
2891     /* AVCLevelIndication */
2892     profile = (data[1] << 16) | (data[2] << 8) | data[3];
2893     GST_DEBUG_OBJECT (h264parse, "profile %06x", profile);
2894 #endif
2895
2896     /* 6 bits reserved | 2 bits lengthSizeMinusOne */
2897     /* this is the number of bytes in front of the NAL units to mark their
2898      * length */
2899     h264parse->nal_length_size = (data[4] & 0x03) + 1;
2900     GST_DEBUG_OBJECT (h264parse, "nal length size %u",
2901         h264parse->nal_length_size);
2902
2903     num_sps = data[5] & 0x1f;
2904     off = 6;
2905     for (i = 0; i < num_sps; i++) {
2906       parseres = gst_h264_parser_identify_nalu_avc (h264parse->nalparser,
2907           data, off, size, 2, &nalu);
2908       if (parseres != GST_H264_PARSER_OK) {
2909         gst_buffer_unmap (codec_data, &map);
2910         goto avcc_too_small;
2911       }
2912
2913       gst_h264_parse_process_nal (h264parse, &nalu);
2914       off = nalu.offset + nalu.size;
2915     }
2916
2917     if (off >= size) {
2918       gst_buffer_unmap (codec_data, &map);
2919       goto avcc_too_small;
2920     }
2921     num_pps = data[off];
2922     off++;
2923
2924     for (i = 0; i < num_pps; i++) {
2925       parseres = gst_h264_parser_identify_nalu_avc (h264parse->nalparser,
2926           data, off, size, 2, &nalu);
2927       if (parseres != GST_H264_PARSER_OK) {
2928         gst_buffer_unmap (codec_data, &map);
2929         goto avcc_too_small;
2930       }
2931
2932       gst_h264_parse_process_nal (h264parse, &nalu);
2933       off = nalu.offset + nalu.size;
2934     }
2935
2936     gst_buffer_unmap (codec_data, &map);
2937
2938     gst_buffer_replace (&h264parse->codec_data_in, codec_data);
2939
2940     /* don't confuse codec_data with inband sps/pps */
2941     h264parse->have_sps_in_frame = FALSE;
2942     h264parse->have_pps_in_frame = FALSE;
2943   } else if (format == GST_H264_PARSE_FORMAT_BYTE) {
2944     GST_DEBUG_OBJECT (h264parse, "have bytestream h264");
2945     /* nothing to pre-process */
2946     h264parse->packetized = FALSE;
2947     /* we have 4 sync bytes */
2948     h264parse->nal_length_size = 4;
2949   } else {
2950     /* probably AVC3 without codec_data field, anything to do here? */
2951   }
2952
2953   {
2954     GstCaps *in_caps;
2955
2956     /* prefer input type determined above */
2957     in_caps = gst_caps_new_simple ("video/x-h264",
2958         "parsed", G_TYPE_BOOLEAN, TRUE,
2959         "stream-format", G_TYPE_STRING,
2960         gst_h264_parse_get_string (h264parse, TRUE, format),
2961         "alignment", G_TYPE_STRING,
2962         gst_h264_parse_get_string (h264parse, FALSE, align), NULL);
2963     /* negotiate with downstream, sets ->format and ->align */
2964     gst_h264_parse_negotiate (h264parse, format, in_caps);
2965     gst_caps_unref (in_caps);
2966   }
2967
2968   if (format == h264parse->format && align == h264parse->align) {
2969     /* we did parse codec-data and might supplement src caps */
2970     gst_h264_parse_update_src_caps (h264parse, caps);
2971   } else if (format == GST_H264_PARSE_FORMAT_AVC
2972       || format == GST_H264_PARSE_FORMAT_AVC3) {
2973     /* if input != output, and input is avc, must split before anything else */
2974     /* arrange to insert codec-data in-stream if needed.
2975      * src caps are only arranged for later on */
2976     h264parse->push_codec = TRUE;
2977     h264parse->have_sps = FALSE;
2978     h264parse->have_pps = FALSE;
2979     if (h264parse->align == GST_H264_PARSE_ALIGN_NAL)
2980       h264parse->split_packetized = TRUE;
2981     h264parse->packetized = TRUE;
2982   }
2983
2984   h264parse->in_align = align;
2985
2986   return TRUE;
2987
2988   /* ERRORS */
2989 avc_caps_codec_data_wrong_type:
2990   {
2991     GST_WARNING_OBJECT (parse, "H.264 AVC caps, codec_data field not a buffer");
2992     goto refuse_caps;
2993   }
2994 avc_caps_codec_data_missing:
2995   {
2996     GST_WARNING_OBJECT (parse, "H.264 AVC caps, but no codec_data");
2997     goto refuse_caps;
2998   }
2999 avc_caps_wrong_alignment:
3000   {
3001     GST_WARNING_OBJECT (parse, "H.264 AVC caps with NAL alignment, must be AU");
3002     goto refuse_caps;
3003   }
3004 bytestream_caps_with_codec_data:
3005   {
3006     GST_WARNING_OBJECT (parse, "H.264 bytestream caps with codec_data is not "
3007         "expected, send SPS/PPS in-band with data or in streamheader field");
3008     goto refuse_caps;
3009   }
3010 avcc_too_small:
3011   {
3012     GST_DEBUG_OBJECT (h264parse, "avcC size %" G_GSIZE_FORMAT " < 8", size);
3013     goto refuse_caps;
3014   }
3015 wrong_version:
3016   {
3017     GST_DEBUG_OBJECT (h264parse, "wrong avcC version");
3018     goto refuse_caps;
3019   }
3020 refuse_caps:
3021   {
3022     GST_WARNING_OBJECT (h264parse, "refused caps %" GST_PTR_FORMAT, caps);
3023     return FALSE;
3024   }
3025 }
3026
3027 static void
3028 remove_fields (GstCaps * caps, gboolean all)
3029 {
3030   guint i, n;
3031
3032   n = gst_caps_get_size (caps);
3033   for (i = 0; i < n; i++) {
3034     GstStructure *s = gst_caps_get_structure (caps, i);
3035
3036     if (all) {
3037       gst_structure_remove_field (s, "alignment");
3038       gst_structure_remove_field (s, "stream-format");
3039     }
3040     gst_structure_remove_field (s, "parsed");
3041   }
3042 }
3043
3044 static GstCaps *
3045 gst_h264_parse_get_caps (GstBaseParse * parse, GstCaps * filter)
3046 {
3047   GstCaps *peercaps, *templ;
3048   GstCaps *res, *tmp, *pcopy;
3049
3050   templ = gst_pad_get_pad_template_caps (GST_BASE_PARSE_SINK_PAD (parse));
3051   if (filter) {
3052     GstCaps *fcopy = gst_caps_copy (filter);
3053     /* Remove the fields we convert */
3054     remove_fields (fcopy, TRUE);
3055     peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), fcopy);
3056     gst_caps_unref (fcopy);
3057   } else
3058     peercaps = gst_pad_peer_query_caps (GST_BASE_PARSE_SRC_PAD (parse), NULL);
3059
3060   pcopy = gst_caps_copy (peercaps);
3061   remove_fields (pcopy, TRUE);
3062
3063   res = gst_caps_intersect_full (pcopy, templ, GST_CAPS_INTERSECT_FIRST);
3064   gst_caps_unref (pcopy);
3065   gst_caps_unref (templ);
3066
3067   if (filter) {
3068     GstCaps *tmp = gst_caps_intersect_full (res, filter,
3069         GST_CAPS_INTERSECT_FIRST);
3070     gst_caps_unref (res);
3071     res = tmp;
3072   }
3073
3074   /* Try if we can put the downstream caps first */
3075   pcopy = gst_caps_copy (peercaps);
3076   remove_fields (pcopy, FALSE);
3077   tmp = gst_caps_intersect_full (pcopy, res, GST_CAPS_INTERSECT_FIRST);
3078   gst_caps_unref (pcopy);
3079   if (!gst_caps_is_empty (tmp))
3080     res = gst_caps_merge (tmp, res);
3081   else
3082     gst_caps_unref (tmp);
3083
3084   gst_caps_unref (peercaps);
3085   return res;
3086 }
3087
3088 static gboolean
3089 gst_h264_parse_event (GstBaseParse * parse, GstEvent * event)
3090 {
3091   gboolean res;
3092   GstH264Parse *h264parse = GST_H264_PARSE (parse);
3093
3094   switch (GST_EVENT_TYPE (event)) {
3095     case GST_EVENT_CUSTOM_DOWNSTREAM:
3096     {
3097       GstClockTime timestamp, stream_time, running_time;
3098       gboolean all_headers;
3099       guint count;
3100
3101       if (gst_video_event_is_force_key_unit (event)) {
3102         gst_video_event_parse_downstream_force_key_unit (event,
3103             &timestamp, &stream_time, &running_time, &all_headers, &count);
3104
3105         GST_INFO_OBJECT (h264parse,
3106             "received downstream force key unit event, "
3107             "seqnum %d running_time %" GST_TIME_FORMAT
3108             " all_headers %d count %d", gst_event_get_seqnum (event),
3109             GST_TIME_ARGS (running_time), all_headers, count);
3110         if (h264parse->force_key_unit_event) {
3111           GST_INFO_OBJECT (h264parse, "ignoring force key unit event "
3112               "as one is already queued");
3113         } else {
3114           h264parse->pending_key_unit_ts = running_time;
3115           gst_event_replace (&h264parse->force_key_unit_event, event);
3116         }
3117         gst_event_unref (event);
3118         res = TRUE;
3119       } else {
3120         res = GST_BASE_PARSE_CLASS (parent_class)->sink_event (parse, event);
3121         break;
3122       }
3123       break;
3124     }
3125     case GST_EVENT_FLUSH_STOP:
3126       h264parse->dts = GST_CLOCK_TIME_NONE;
3127       h264parse->ts_trn_nb = GST_CLOCK_TIME_NONE;
3128       h264parse->push_codec = TRUE;
3129
3130       res = GST_BASE_PARSE_CLASS (parent_class)->sink_event (parse, event);
3131       break;
3132     case GST_EVENT_SEGMENT:
3133     {
3134       const GstSegment *segment;
3135
3136       gst_event_parse_segment (event, &segment);
3137       /* don't try to mess with more subtle cases (e.g. seek) */
3138       if (segment->format == GST_FORMAT_TIME &&
3139           (segment->start != 0 || segment->rate != 1.0
3140               || segment->applied_rate != 1.0))
3141         h264parse->do_ts = FALSE;
3142
3143       if (segment->flags & GST_SEEK_FLAG_TRICKMODE_FORWARD_PREDICTED) {
3144         GST_DEBUG_OBJECT (h264parse, "Will discard bidirectional frames");
3145         h264parse->discard_bidirectional = TRUE;
3146       }
3147
3148
3149       h264parse->last_report = GST_CLOCK_TIME_NONE;
3150
3151       res = GST_BASE_PARSE_CLASS (parent_class)->sink_event (parse, event);
3152       break;
3153     }
3154     default:
3155       res = GST_BASE_PARSE_CLASS (parent_class)->sink_event (parse, event);
3156       break;
3157   }
3158   return res;
3159 }
3160
3161 static gboolean
3162 gst_h264_parse_src_event (GstBaseParse * parse, GstEvent * event)
3163 {
3164   gboolean res;
3165   GstH264Parse *h264parse = GST_H264_PARSE (parse);
3166
3167   switch (GST_EVENT_TYPE (event)) {
3168     case GST_EVENT_CUSTOM_UPSTREAM:
3169     {
3170       GstClockTime running_time;
3171       gboolean all_headers;
3172       guint count;
3173
3174       if (gst_video_event_is_force_key_unit (event)) {
3175         gst_video_event_parse_upstream_force_key_unit (event,
3176             &running_time, &all_headers, &count);
3177
3178         GST_INFO_OBJECT (h264parse, "received upstream force-key-unit event, "
3179             "seqnum %d running_time %" GST_TIME_FORMAT
3180             " all_headers %d count %d", gst_event_get_seqnum (event),
3181             GST_TIME_ARGS (running_time), all_headers, count);
3182
3183         if (all_headers) {
3184           h264parse->pending_key_unit_ts = running_time;
3185           gst_event_replace (&h264parse->force_key_unit_event, event);
3186         }
3187       }
3188       res = GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
3189       break;
3190     }
3191     default:
3192       res = GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
3193       break;
3194   }
3195
3196   return res;
3197 }
3198
3199 static void
3200 gst_h264_parse_set_property (GObject * object, guint prop_id,
3201     const GValue * value, GParamSpec * pspec)
3202 {
3203   GstH264Parse *parse;
3204
3205   parse = GST_H264_PARSE (object);
3206
3207   switch (prop_id) {
3208     case PROP_CONFIG_INTERVAL:
3209       parse->interval = g_value_get_int (value);
3210       break;
3211     default:
3212       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3213       break;
3214   }
3215 }
3216
3217 static void
3218 gst_h264_parse_get_property (GObject * object, guint prop_id,
3219     GValue * value, GParamSpec * pspec)
3220 {
3221   GstH264Parse *parse;
3222
3223   parse = GST_H264_PARSE (object);
3224
3225   switch (prop_id) {
3226     case PROP_CONFIG_INTERVAL:
3227       g_value_set_int (value, parse->interval);
3228       break;
3229     default:
3230       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
3231       break;
3232   }
3233 }