h264parse: fix test and set not using the same input
[gstreamer-omap:gst-plugins-bad.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., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #  include "config.h"
27 #endif
28
29 #include <gst/base/gstbytereader.h>
30 #include <gst/base/gstbytewriter.h>
31 #include <gst/base/gstadapter.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 #define GST_BUFFER_FLAG_B_FRAME (GST_BUFFER_FLAG_LAST << 0)
41
42 enum
43 {
44   PROP_0,
45   PROP_CONFIG_INTERVAL,
46   PROP_LAST
47 };
48
49 enum
50 {
51   GST_H264_PARSE_FORMAT_NONE,
52   GST_H264_PARSE_FORMAT_AVC,
53   GST_H264_PARSE_FORMAT_BYTE
54 };
55
56 enum
57 {
58   GST_H264_PARSE_ALIGN_NONE = 0,
59   GST_H264_PARSE_ALIGN_NAL,
60   GST_H264_PARSE_ALIGN_AU
61 };
62
63 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
64     GST_PAD_SINK,
65     GST_PAD_ALWAYS,
66     GST_STATIC_CAPS ("video/x-h264"));
67
68 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
69     GST_PAD_SRC,
70     GST_PAD_ALWAYS,
71     GST_STATIC_CAPS ("video/x-h264, parsed = (boolean) true, "
72         "stream-format=(string) { avc, byte-stream }, "
73         "alignment=(string) { au, nal }"));
74
75 GST_BOILERPLATE (GstH264Parse, gst_h264_parse, GstBaseParse,
76     GST_TYPE_BASE_PARSE);
77
78 static void gst_h264_parse_finalize (GObject * object);
79
80 static gboolean gst_h264_parse_start (GstBaseParse * parse);
81 static gboolean gst_h264_parse_stop (GstBaseParse * parse);
82 static gboolean gst_h264_parse_check_valid_frame (GstBaseParse * parse,
83     GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
84 static GstFlowReturn gst_h264_parse_parse_frame (GstBaseParse * parse,
85     GstBaseParseFrame * frame);
86 static GstFlowReturn gst_h264_parse_pre_push_frame (GstBaseParse * parse,
87     GstBaseParseFrame * frame);
88
89 static void gst_h264_parse_set_property (GObject * object, guint prop_id,
90     const GValue * value, GParamSpec * pspec);
91 static void gst_h264_parse_get_property (GObject * object, guint prop_id,
92     GValue * value, GParamSpec * pspec);
93
94 static gboolean gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps);
95 static GstFlowReturn gst_h264_parse_chain (GstPad * pad, GstBuffer * buffer);
96 static gboolean gst_h264_parse_event (GstBaseParse * parse, GstEvent * event);
97
98 static void
99 gst_h264_parse_base_init (gpointer g_class)
100 {
101   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
102
103   gst_element_class_add_pad_template (gstelement_class,
104       gst_static_pad_template_get (&srctemplate));
105   gst_element_class_add_pad_template (gstelement_class,
106       gst_static_pad_template_get (&sinktemplate));
107
108   gst_element_class_set_details_simple (gstelement_class, "H.264 parser",
109       "Codec/Parser/Converter/Video",
110       "Parses H.264 streams",
111       "Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>");
112
113   GST_DEBUG_CATEGORY_INIT (h264_parse_debug, "h264parse", 0, "h264 parser");
114 }
115
116 static void
117 gst_h264_parse_class_init (GstH264ParseClass * klass)
118 {
119   GObjectClass *gobject_class = (GObjectClass *) klass;
120   GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
121
122   gobject_class->finalize = gst_h264_parse_finalize;
123   gobject_class->set_property = gst_h264_parse_set_property;
124   gobject_class->get_property = gst_h264_parse_get_property;
125
126   g_object_class_install_property (gobject_class, PROP_CONFIG_INTERVAL,
127       g_param_spec_uint ("config-interval",
128           "SPS PPS Send Interval",
129           "Send SPS and PPS Insertion Interval in seconds (sprop parameter sets "
130           "will be multiplexed in the data stream when detected.) (0 = disabled)",
131           0, 3600, DEFAULT_CONFIG_INTERVAL,
132           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
133
134   /* Override BaseParse vfuncs */
135   parse_class->start = GST_DEBUG_FUNCPTR (gst_h264_parse_start);
136   parse_class->stop = GST_DEBUG_FUNCPTR (gst_h264_parse_stop);
137   parse_class->check_valid_frame =
138       GST_DEBUG_FUNCPTR (gst_h264_parse_check_valid_frame);
139   parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_h264_parse_parse_frame);
140   parse_class->pre_push_frame =
141       GST_DEBUG_FUNCPTR (gst_h264_parse_pre_push_frame);
142   parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_h264_parse_set_caps);
143   parse_class->event = GST_DEBUG_FUNCPTR (gst_h264_parse_event);
144 }
145
146 static void
147 gst_h264_parse_init (GstH264Parse * h264parse, GstH264ParseClass * g_class)
148 {
149   h264parse->frame_out = gst_adapter_new ();
150
151   /* retrieve and intercept baseparse.
152    * Quite HACKish, but fairly OK since it is needed to perform avc packet
153    * splitting, which is the penultimate de-parsing */
154   h264parse->parse_chain =
155       GST_PAD_CHAINFUNC (GST_BASE_PARSE_SINK_PAD (h264parse));
156   gst_pad_set_chain_function (GST_BASE_PARSE_SINK_PAD (h264parse),
157       gst_h264_parse_chain);
158 }
159
160
161 static void
162 gst_h264_parse_finalize (GObject * object)
163 {
164   GstH264Parse *h264parse = GST_H264_PARSE (object);
165
166   g_object_unref (h264parse->frame_out);
167
168   G_OBJECT_CLASS (parent_class)->finalize (object);
169 }
170
171 static void
172 gst_h264_parse_reset_frame (GstH264Parse * h264parse)
173 {
174   GST_DEBUG_OBJECT (h264parse, "reset frame");
175
176   /* done parsing; reset state */
177   h264parse->nalu.valid = FALSE;
178   h264parse->nalu.offset = 0;
179   h264parse->nalu.size = 0;
180   h264parse->current_off = 0;
181
182   h264parse->picture_start = FALSE;
183   h264parse->update_caps = FALSE;
184   h264parse->idr_pos = -1;
185   h264parse->keyframe = FALSE;
186   h264parse->frame_start = FALSE;
187   h264parse->b_frame = FALSE;
188   gst_adapter_clear (h264parse->frame_out);
189 }
190
191 static void
192 gst_h264_parse_reset (GstH264Parse * h264parse)
193 {
194   h264parse->width = 0;
195   h264parse->height = 0;
196   h264parse->fps_num = 0;
197   h264parse->fps_den = 0;
198   h264parse->aspect_ratio_idc = 0;
199   h264parse->sar_width = 0;
200   h264parse->sar_height = 0;
201   gst_buffer_replace (&h264parse->codec_data, NULL);
202   h264parse->nal_length_size = 4;
203   h264parse->packetized = FALSE;
204
205   h264parse->align = GST_H264_PARSE_ALIGN_NONE;
206   h264parse->format = GST_H264_PARSE_FORMAT_NONE;
207
208   h264parse->last_report = GST_CLOCK_TIME_NONE;
209   h264parse->push_codec = FALSE;
210   h264parse->have_pps = FALSE;
211   h264parse->have_sps = FALSE;
212
213   h264parse->dts = GST_CLOCK_TIME_NONE;
214   h264parse->ts_trn_nb = GST_CLOCK_TIME_NONE;
215   h264parse->do_ts = TRUE;
216
217   gst_h264_parse_reset_frame (h264parse);
218 }
219
220 static gboolean
221 gst_h264_parse_start (GstBaseParse * parse)
222 {
223   GstH264Parse *h264parse = GST_H264_PARSE (parse);
224
225   GST_DEBUG_OBJECT (parse, "start");
226   gst_h264_parse_reset (h264parse);
227
228   h264parse->nalparser = gst_h264_nal_parser_new ();
229
230   h264parse->dts = GST_CLOCK_TIME_NONE;
231   h264parse->ts_trn_nb = GST_CLOCK_TIME_NONE;
232   h264parse->sei_pic_struct_pres_flag = FALSE;
233   h264parse->sei_pic_struct = 0;
234   h264parse->field_pic_flag = 0;
235
236   gst_base_parse_set_min_frame_size (parse, 6);
237
238   return TRUE;
239 }
240
241 static gboolean
242 gst_h264_parse_stop (GstBaseParse * parse)
243 {
244   guint i;
245   GstH264Parse *h264parse = GST_H264_PARSE (parse);
246
247   GST_DEBUG_OBJECT (parse, "stop");
248   gst_h264_parse_reset (h264parse);
249
250   for (i = 0; i < GST_H264_MAX_SPS_COUNT; i++)
251     gst_buffer_replace (&h264parse->sps_nals[i], NULL);
252   for (i = 0; i < GST_H264_MAX_PPS_COUNT; i++)
253     gst_buffer_replace (&h264parse->pps_nals[i], NULL);
254
255   gst_h264_nal_parser_free (h264parse->nalparser);
256
257   return TRUE;
258 }
259
260 static const gchar *
261 gst_h264_parse_get_string (GstH264Parse * parse, gboolean format, gint code)
262 {
263   if (format) {
264     switch (code) {
265       case GST_H264_PARSE_FORMAT_AVC:
266         return "avc";
267       case GST_H264_PARSE_FORMAT_BYTE:
268         return "byte-stream";
269       default:
270         return "none";
271     }
272   } else {
273     switch (code) {
274       case GST_H264_PARSE_ALIGN_NAL:
275         return "nal";
276       case GST_H264_PARSE_ALIGN_AU:
277         return "au";
278       default:
279         return "none";
280     }
281   }
282 }
283
284 static void
285 gst_h264_parse_format_from_caps (GstCaps * caps, guint * format, guint * align)
286 {
287
288   if (format)
289     *format = GST_H264_PARSE_FORMAT_NONE;
290
291   if (align)
292     *align = GST_H264_PARSE_ALIGN_NONE;
293
294   if (caps && gst_caps_get_size (caps) > 0) {
295     GstStructure *s = gst_caps_get_structure (caps, 0);
296     const gchar *str = NULL;
297
298     if (format) {
299       if ((str = gst_structure_get_string (s, "stream-format"))) {
300         if (strcmp (str, "avc") == 0)
301           *format = GST_H264_PARSE_FORMAT_AVC;
302         else if (strcmp (str, "byte-stream") == 0)
303           *format = GST_H264_PARSE_FORMAT_BYTE;
304       }
305     }
306
307     if (align) {
308       if ((str = gst_structure_get_string (s, "alignment"))) {
309         if (strcmp (str, "au") == 0)
310           *align = GST_H264_PARSE_ALIGN_AU;
311         else if (strcmp (str, "nal") == 0)
312           *align = GST_H264_PARSE_ALIGN_NAL;
313       }
314     }
315   }
316 }
317
318 /* check downstream caps to configure format and alignment */
319 static void
320 gst_h264_parse_negotiate (GstH264Parse * h264parse, GstCaps * in_caps)
321 {
322   GstCaps *caps;
323   guint format = GST_H264_PARSE_FORMAT_NONE;
324   guint align = GST_H264_PARSE_ALIGN_NONE;
325
326   caps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (h264parse));
327   GST_DEBUG_OBJECT (h264parse, "allowed caps: %" GST_PTR_FORMAT, caps);
328
329   if (in_caps && caps) {
330     if (gst_caps_can_intersect (in_caps, caps)) {
331       GST_DEBUG_OBJECT (h264parse, "downstream accepts upstream caps");
332       gst_h264_parse_format_from_caps (in_caps, &format, &align);
333       gst_caps_unref (caps);
334       caps = NULL;
335     }
336   }
337
338   if (caps) {
339     gst_h264_parse_format_from_caps (caps, &format, &align);
340     gst_caps_unref (caps);
341   }
342
343   /* default */
344   if (!format)
345     format = GST_H264_PARSE_FORMAT_BYTE;
346   if (!align)
347     align = GST_H264_PARSE_ALIGN_AU;
348
349   GST_DEBUG_OBJECT (h264parse, "selected format %s, alignment %s",
350       gst_h264_parse_get_string (h264parse, TRUE, format),
351       gst_h264_parse_get_string (h264parse, FALSE, align));
352
353   h264parse->format = format;
354   h264parse->align = align;
355 }
356
357 static GstBuffer *
358 gst_h264_parse_wrap_nal (GstH264Parse * h264parse, guint format, guint8 * data,
359     guint size)
360 {
361   GstBuffer *buf;
362   guint nl = h264parse->nal_length_size;
363
364   GST_DEBUG_OBJECT (h264parse, "nal length %d", size);
365
366   buf = gst_buffer_new_and_alloc (size + nl + 4);
367   if (format == GST_H264_PARSE_FORMAT_AVC) {
368     GST_WRITE_UINT32_BE (GST_BUFFER_DATA (buf), size << (32 - 8 * nl));
369   } else {
370     /* HACK: nl should always be 4 here, otherwise this won't work. 
371      * There are legit cases where nl in avc stream is 2, but byte-stream
372      * SC is still always 4 bytes. */
373     nl = 4;
374     GST_WRITE_UINT32_BE (GST_BUFFER_DATA (buf), 1);
375   }
376
377   GST_BUFFER_SIZE (buf) = size + nl;
378   memcpy (GST_BUFFER_DATA (buf) + nl, data, size);
379
380   return buf;
381 }
382
383 static void
384 gst_h264_parser_store_nal (GstH264Parse * h264parse, guint id,
385     GstH264NalUnitType naltype, GstH264NalUnit * nalu)
386 {
387   GstBuffer *buf, **store;
388   guint size = nalu->size, store_size;
389
390   if (naltype == GST_H264_NAL_SPS) {
391     store_size = GST_H264_MAX_SPS_COUNT;
392     store = h264parse->sps_nals;
393     GST_DEBUG_OBJECT (h264parse, "storing sps %u", id);
394   } else if (naltype == GST_H264_NAL_PPS) {
395     store_size = GST_H264_MAX_PPS_COUNT;
396     store = h264parse->pps_nals;
397     GST_DEBUG_OBJECT (h264parse, "storing pps %u", id);
398   } else
399     return;
400
401   if (id >= store_size) {
402     GST_DEBUG_OBJECT (h264parse, "unable to store nal, id out-of-range %d", id);
403     return;
404   }
405
406   buf = gst_buffer_new_and_alloc (size);
407   memcpy (GST_BUFFER_DATA (buf), nalu->data + nalu->offset, size);
408
409   if (store[id])
410     gst_buffer_unref (store[id]);
411
412   store[id] = buf;
413 }
414
415 /* SPS/PPS/IDR considered key, all others DELTA;
416  * so downstream waiting for keyframe can pick up at SPS/PPS/IDR */
417 #define NAL_TYPE_IS_KEY(nt) (((nt) == 5) || ((nt) == 7) || ((nt) == 8))
418
419 /* caller guarantees 2 bytes of nal payload */
420 static void
421 gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu)
422 {
423   guint nal_type;
424   GstH264SliceHdr slice;
425   GstH264PPS pps;
426   GstH264SPS sps;
427   GstH264SEIMessage sei;
428
429   gboolean slcparsed = FALSE;
430   GstH264NalParser *nalparser = h264parse->nalparser;
431
432
433   /* nothing to do for broken input */
434   if (G_UNLIKELY (nalu->size < 2)) {
435     GST_DEBUG_OBJECT (h264parse, "not processing nal size %u", nalu->size);
436     return;
437   }
438
439   /* we have a peek as well */
440   nal_type = nalu->type;
441   h264parse->keyframe |= NAL_TYPE_IS_KEY (nal_type);
442
443   GST_DEBUG_OBJECT (h264parse, "processing nal of type %u, size %u",
444       nal_type, nalu->size);
445
446   switch (nal_type) {
447     case GST_H264_NAL_SPS:
448       gst_h264_parser_parse_sps (nalparser, nalu, &sps, TRUE);
449
450       GST_DEBUG_OBJECT (h264parse, "triggering src caps check");
451       h264parse->update_caps = TRUE;
452       h264parse->have_sps = TRUE;
453       if (h264parse->push_codec && h264parse->have_pps) {
454         /* SPS and PPS found in stream before the first pre_push_frame, no need
455          * to forcibly push at start */
456         GST_INFO_OBJECT (h264parse, "have SPS/PPS in stream");
457         h264parse->push_codec = FALSE;
458         h264parse->have_sps = FALSE;
459         h264parse->have_pps = FALSE;
460       }
461
462       gst_h264_parser_store_nal (h264parse, sps.id, nal_type, nalu);
463       break;
464     case GST_H264_NAL_PPS:
465       gst_h264_parser_parse_pps (nalparser, nalu, &pps);
466       /* parameters might have changed, force caps check */
467       GST_DEBUG_OBJECT (h264parse, "triggering src caps check");
468       h264parse->update_caps = TRUE;
469       h264parse->have_pps = TRUE;
470       if (h264parse->push_codec && h264parse->have_sps) {
471         /* SPS and PPS found in stream before the first pre_push_frame, no need
472          * to forcibly push at start */
473         GST_INFO_OBJECT (h264parse, "have SPS/PPS in stream");
474         h264parse->push_codec = FALSE;
475         h264parse->have_sps = FALSE;
476         h264parse->have_pps = FALSE;
477       }
478
479       gst_h264_parser_store_nal (h264parse, pps.id, nal_type, nalu);
480       break;
481     case GST_H264_NAL_SEI:
482       gst_h264_parser_parse_sei (nalparser, nalu, &sei);
483       switch (sei.payloadType) {
484         case GST_H264_SEI_PIC_TIMING:
485           h264parse->sei_pic_struct_pres_flag =
486               sei.pic_timing.pic_struct_present_flag;
487           h264parse->sei_cpb_removal_delay = sei.pic_timing.cpb_removal_delay;
488           if (h264parse->sei_pic_struct_pres_flag)
489             h264parse->sei_pic_struct = sei.pic_timing.pic_struct;
490           break;
491         case GST_H264_SEI_BUF_PERIOD:
492           if (h264parse->ts_trn_nb == GST_CLOCK_TIME_NONE ||
493               h264parse->dts == GST_CLOCK_TIME_NONE)
494             h264parse->ts_trn_nb = 0;
495           else
496             h264parse->ts_trn_nb = h264parse->dts;
497
498           GST_LOG_OBJECT (h264parse,
499               "new buffering period; ts_trn_nb updated: %" GST_TIME_FORMAT,
500               GST_TIME_ARGS (h264parse->ts_trn_nb));
501           break;
502       }
503       break;
504
505     case GST_H264_NAL_SLICE:
506     case GST_H264_NAL_SLICE_DPA:
507     case GST_H264_NAL_SLICE_DPB:
508     case GST_H264_NAL_SLICE_DPC:
509       slcparsed = TRUE;
510       if (gst_h264_parser_parse_slice_hdr (nalparser, nalu,
511               &slice, FALSE, FALSE) == GST_H264_PARSER_ERROR)
512         return;
513
514       /* real frame data */
515       h264parse->frame_start |= (slice.first_mb_in_slice == 0);
516       if (slice.type == GST_H264_B_SLICE || slice.type == GST_H264_S_B_SLICE)
517         h264parse->b_frame = TRUE;
518       else
519         h264parse->b_frame = FALSE;
520       /* if we need to sneak codec NALs into the stream,
521        * this is a good place, so fake it as IDR
522        * (which should be at start anyway) */
523       GST_DEBUG_OBJECT (h264parse, "frame start: %i first_mb_in_slice %i",
524           h264parse->frame_start, slice.first_mb_in_slice);
525       if (G_LIKELY (!h264parse->push_codec))
526         break;
527       /* fall-through */
528     case GST_H264_NAL_SLICE_IDR:
529       if (!slcparsed) {
530         if (gst_h264_parser_parse_slice_hdr (nalparser, nalu,
531                 &slice, FALSE, FALSE) == GST_H264_PARSER_ERROR)
532           return;
533         GST_DEBUG_OBJECT (h264parse, "frame start: %i first_mb_in_slice %i",
534             h264parse->frame_start, slice.first_mb_in_slice);
535       }
536       /* real frame data */
537       h264parse->frame_start |= (slice.first_mb_in_slice == 0);
538
539       /* mark where config needs to go if interval expired */
540       /* mind replacement buffer if applicable */
541       if (h264parse->idr_pos == -1) {
542         if (h264parse->format == GST_H264_PARSE_FORMAT_AVC)
543           h264parse->idr_pos = gst_adapter_available (h264parse->frame_out);
544         else
545           h264parse->idr_pos = nalu->offset - 4;
546         GST_DEBUG_OBJECT (h264parse, "marking IDR in frame at offset %d",
547             h264parse->idr_pos);
548       }
549
550       GST_DEBUG_OBJECT (h264parse, "first MB: %u, slice type: %u",
551           slice.first_mb_in_slice, slice.type);
552       break;
553     default:
554       gst_h264_parser_parse_nal (nalparser, nalu);
555   }
556
557   /* if AVC output needed, collect properly prefixed nal in adapter,
558    * and use that to replace outgoing buffer data later on */
559   if (h264parse->format == GST_H264_PARSE_FORMAT_AVC) {
560     GstBuffer *buf;
561
562     GST_LOG_OBJECT (h264parse, "collecting NAL in AVC frame");
563     buf = gst_h264_parse_wrap_nal (h264parse, h264parse->format,
564         nalu->data + nalu->offset, nalu->size);
565     gst_adapter_push (h264parse->frame_out, buf);
566   }
567 }
568
569 /* caller guarantees at least 2 bytes of nal payload for each nal
570  * returns TRUE if next_nal indicates that nal terminates an AU */
571 static inline gboolean
572 gst_h264_parse_collect_nal (GstH264Parse * h264parse, const guint8 * data,
573     guint size, GstH264NalUnit * nalu)
574 {
575   gboolean complete;
576   GstH264ParserResult parse_res;
577   GstH264NalUnitType nal_type = nalu->type;
578   GstH264NalUnit nnalu;
579
580   GST_DEBUG_OBJECT (h264parse, "parsing collected nal");
581   parse_res = gst_h264_parser_identify_nalu (h264parse->nalparser, data,
582       nalu->offset + nalu->size, size, &nnalu);
583
584   if (parse_res == GST_H264_PARSER_ERROR)
585     return FALSE;
586
587   if (h264parse->align == GST_H264_PARSE_ALIGN_NAL) {
588     return TRUE;
589   }
590
591   /* determine if AU complete */
592   GST_LOG_OBJECT (h264parse, "nal type: %d", nal_type);
593   /* coded slice NAL starts a picture,
594    * i.e. other types become aggregated in front of it */
595   h264parse->picture_start |= (nal_type == GST_H264_NAL_SLICE ||
596       nal_type == GST_H264_NAL_SLICE_DPA || nal_type == GST_H264_NAL_SLICE_IDR);
597
598   /* consider a coded slices (IDR or not) to start a picture,
599    * (so ending the previous one) if first_mb_in_slice == 0
600    * (non-0 is part of previous one) */
601   /* NOTE this is not entirely according to Access Unit specs in 7.4.1.2.4,
602    * but in practice it works in sane cases, needs not much parsing,
603    * and also works with broken frame_num in NAL
604    * (where spec-wise would fail) */
605   nal_type = nnalu.type;
606   complete = h264parse->picture_start && (nal_type >= GST_H264_NAL_SEI &&
607       nal_type <= GST_H264_NAL_AU_DELIMITER);
608
609   GST_LOG_OBJECT (h264parse, "next nal type: %d", nal_type);
610   complete |= h264parse->picture_start &&
611       (nal_type == GST_H264_NAL_SLICE ||
612       nal_type == GST_H264_NAL_SLICE_DPA ||
613       nal_type == GST_H264_NAL_SLICE_IDR) &&
614       /* first_mb_in_slice == 0 considered start of frame */
615       (nnalu.data[nnalu.offset + 1] & 0x80);
616
617   GST_LOG_OBJECT (h264parse, "au complete: %d", complete);
618
619   return complete;
620 }
621
622 /* FIXME move into baseparse, or anything equivalent;
623  * see https://bugzilla.gnome.org/show_bug.cgi?id=650093 */
624 #define GST_BASE_PARSE_FRAME_FLAG_PARSING   0x10000
625
626 static gboolean
627 gst_h264_parse_check_valid_frame (GstBaseParse * parse,
628     GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
629 {
630   GstH264Parse *h264parse = GST_H264_PARSE (parse);
631   GstBuffer *buffer = frame->buffer;
632   guint8 *data;
633   guint size, current_off = 0;
634   gboolean drain;
635   GstH264NalParser *nalparser = h264parse->nalparser;
636   GstH264NalUnit nalu = h264parse->nalu;
637
638   /* expect at least 3 bytes startcode == sc, and 2 bytes NALU payload */
639   if (G_UNLIKELY (GST_BUFFER_SIZE (buffer) < 5))
640     return FALSE;
641
642   /* need to configure aggregation */
643   if (G_UNLIKELY (h264parse->format == GST_H264_PARSE_FORMAT_NONE))
644     gst_h264_parse_negotiate (h264parse, NULL);
645
646   /* avoid stale cached parsing state */
647   if (!(frame->flags & GST_BASE_PARSE_FRAME_FLAG_PARSING)) {
648     GST_LOG_OBJECT (h264parse, "parsing new frame");
649     gst_h264_parse_reset_frame (h264parse);
650     frame->flags |= GST_BASE_PARSE_FRAME_FLAG_PARSING;
651   } else {
652     GST_LOG_OBJECT (h264parse, "resuming frame parsing");
653   }
654
655   data = GST_BUFFER_DATA (buffer);
656   size = GST_BUFFER_SIZE (buffer);
657
658   drain = FALSE;
659   current_off = h264parse->current_off;
660
661   GST_DEBUG_OBJECT (h264parse, "last parse position %u", current_off);
662   while (TRUE) {
663     switch (gst_h264_parser_identify_nalu (nalparser, data, current_off,
664             size, &nalu)) {
665       case GST_H264_PARSER_OK:
666         GST_DEBUG_OBJECT (h264parse, "complete nal found. "
667             "current offset: %u, Nal offset: %u, Nal Size: %u",
668             current_off, nalu.offset, nalu.size);
669
670         GST_DEBUG_OBJECT (h264parse, "current off. %u",
671             nalu.offset + nalu.size);
672         if (!h264parse->nalu.size && !h264parse->nalu.valid)
673           h264parse->nalu = nalu;
674         break;
675       case GST_H264_PARSER_BROKEN_LINK:
676         return FALSE;
677       case GST_H264_PARSER_ERROR:
678         current_off = size - 3;
679         goto parsing_error;
680       case GST_H264_PARSER_NO_NAL:
681         /* don't expect to have found any NAL so far */
682         g_assert (h264parse->nalu.size == 0);
683         current_off = h264parse->nalu.sc_offset = size - 3;
684         goto more;
685       case GST_H264_PARSER_BROKEN_DATA:
686         GST_WARNING_OBJECT (h264parse, "input stream is corrupt; "
687             "it contains a NAL unit of length %d", nalu.size);
688
689         /* broken nal at start -> arrange to skip it,
690          * otherwise have it terminate current au
691          * (and so it will be skipped on next frame round) */
692         if (nalu.sc_offset == h264parse->nalu.sc_offset) {
693           *skipsize = nalu.offset;
694
695           GST_DEBUG_OBJECT (h264parse, "skipping broken nal");
696           return FALSE;
697         } else {
698           nalu.size = 0;
699           goto end;
700         }
701       case GST_H264_PARSER_NO_NAL_END:
702         GST_DEBUG_OBJECT (h264parse, "not a complete nal found at offset %u",
703             nalu.offset);
704
705         current_off = nalu.sc_offset;
706         /* We keep the reference to this nal so we start over the parsing
707          * here */
708         if (!h264parse->nalu.size && !h264parse->nalu.valid)
709           h264parse->nalu = nalu;
710
711         if (GST_BASE_PARSE_DRAINING (parse)) {
712           drain = TRUE;
713           GST_DEBUG_OBJECT (h264parse, "draining NAL %u %u %u", size,
714               h264parse->nalu.offset, h264parse->nalu.size);
715           /*  Can't parse the nalu */
716           if (size - h264parse->nalu.offset < 2) {
717             *skipsize = nalu.offset;
718             return FALSE;
719           }
720
721           /* We parse it anyway */
722           nalu.size = size - nalu.offset;
723           break;
724         }
725         goto more;
726     }
727
728     current_off = nalu.offset + nalu.size;
729
730     GST_DEBUG_OBJECT (h264parse, "%p complete nal found. Off: %u, Size: %u",
731         data, nalu.offset, nalu.size);
732
733     gst_h264_parse_process_nal (h264parse, &nalu);
734     if (gst_h264_parse_collect_nal (h264parse, data, size, &nalu) || drain)
735       break;
736   }
737
738 end:
739   /* FIXME this shouldnt be needed */
740   if (h264parse->nalu.sc_offset > 0 && data[h264parse->nalu.sc_offset - 1] == 0)
741     h264parse->nalu.sc_offset--;
742
743   *skipsize = h264parse->nalu.sc_offset;
744   *framesize = nalu.offset + nalu.size - h264parse->nalu.sc_offset;     /* CHECKME */
745   h264parse->current_off = current_off;
746
747   return TRUE;
748
749 parsing_error:
750   GST_DEBUG_OBJECT (h264parse, "error parsing Nal Unit");
751 more:
752
753   /* ask for best next available */
754   *framesize = G_MAXUINT;
755   if (!h264parse->nalu.size) {
756     /* skip up to initial startcode */
757     *skipsize = h264parse->nalu.sc_offset;
758   } else {
759     *skipsize = 0;
760   }
761
762   /* Restart parsing from here next time */
763   h264parse->current_off = current_off;
764
765   return FALSE;
766 }
767
768 /* byte together avc codec data based on collected pps and sps so far */
769 static GstBuffer *
770 gst_h264_parse_make_codec_data (GstH264Parse * h264parse)
771 {
772   GstBuffer *buf, *nal;
773   gint i, sps_size = 0, pps_size = 0, num_sps = 0, num_pps = 0;
774   guint8 profile_idc = 0, profile_comp = 0, level_idc = 0;
775   gboolean found = FALSE;
776   guint8 *data;
777
778   /* only nal payload in stored nals */
779
780   for (i = 0; i < GST_H264_MAX_SPS_COUNT; i++) {
781     if ((nal = h264parse->sps_nals[i])) {
782       num_sps++;
783       /* size bytes also count */
784       sps_size += GST_BUFFER_SIZE (nal) + 2;
785       if (GST_BUFFER_SIZE (nal) >= 4) {
786         found = TRUE;
787         profile_idc = (GST_BUFFER_DATA (nal))[1];
788         profile_comp = (GST_BUFFER_DATA (nal))[2];
789         level_idc = (GST_BUFFER_DATA (nal))[3];
790       }
791     }
792   }
793   for (i = 0; i < GST_H264_MAX_PPS_COUNT; i++) {
794     if ((nal = h264parse->pps_nals[i])) {
795       num_pps++;
796       /* size bytes also count */
797       pps_size += GST_BUFFER_SIZE (nal) + 2;
798     }
799   }
800
801   GST_DEBUG_OBJECT (h264parse,
802       "constructing codec_data: num_sps=%d, num_pps=%d", num_sps, num_pps);
803
804   if (!found || !num_pps)
805     return NULL;
806
807   buf = gst_buffer_new_and_alloc (5 + 1 + sps_size + 1 + pps_size);
808   data = GST_BUFFER_DATA (buf);
809
810   data[0] = 1;                  /* AVC Decoder Configuration Record ver. 1 */
811   data[1] = profile_idc;        /* profile_idc                             */
812   data[2] = profile_comp;       /* profile_compability                     */
813   data[3] = level_idc;          /* level_idc                               */
814   data[4] = 0xfc | (4 - 1);     /* nal_length_size_minus1                  */
815   data[5] = 0xe0 | num_sps;     /* number of SPSs */
816
817   data += 6;
818   for (i = 0; i < GST_H264_MAX_SPS_COUNT; i++) {
819     if ((nal = h264parse->sps_nals[i])) {
820       GST_WRITE_UINT16_BE (data, GST_BUFFER_SIZE (nal));
821       memcpy (data + 2, GST_BUFFER_DATA (nal), GST_BUFFER_SIZE (nal));
822       data += 2 + GST_BUFFER_SIZE (nal);
823     }
824   }
825
826   data[0] = num_pps;
827   data++;
828   for (i = 0; i < GST_H264_MAX_PPS_COUNT; i++) {
829     if ((nal = h264parse->pps_nals[i])) {
830       GST_WRITE_UINT16_BE (data, GST_BUFFER_SIZE (nal));
831       memcpy (data + 2, GST_BUFFER_DATA (nal), GST_BUFFER_SIZE (nal));
832       data += 2 + GST_BUFFER_SIZE (nal);
833     }
834   }
835
836   return buf;
837 }
838
839 static void
840 gst_h264_parse_get_par (GstH264Parse * h264parse, gint * num, gint * den)
841 {
842   gint par_n, par_d;
843
844   par_n = par_d = 0;
845   switch (h264parse->aspect_ratio_idc) {
846     case 0:
847       par_n = par_d = 0;
848       break;
849     case 1:
850       par_n = 1;
851       par_d = 1;
852       break;
853     case 2:
854       par_n = 12;
855       par_d = 11;
856       break;
857     case 3:
858       par_n = 10;
859       par_d = 11;
860       break;
861     case 4:
862       par_n = 16;
863       par_d = 11;
864       break;
865     case 5:
866       par_n = 40;
867       par_d = 33;
868       break;
869     case 6:
870       par_n = 24;
871       par_d = 11;
872       break;
873     case 7:
874       par_n = 20;
875       par_d = 11;
876       break;
877     case 8:
878       par_n = 32;
879       par_d = 11;
880       break;
881     case 9:
882       par_n = 80;
883       par_d = 33;
884       break;
885     case 10:
886       par_n = 18;
887       par_d = 11;
888       break;
889     case 11:
890       par_n = 15;
891       par_d = 11;
892       break;
893     case 12:
894       par_n = 64;
895       par_d = 33;
896       break;
897     case 13:
898       par_n = 160;
899       par_d = 99;
900       break;
901     case 14:
902       par_n = 4;
903       par_d = 3;
904       break;
905     case 15:
906       par_n = 3;
907       par_d = 2;
908       break;
909     case 16:
910       par_n = 2;
911       par_d = 1;
912       break;
913     case 255:
914       par_n = h264parse->sar_width;
915       par_d = h264parse->sar_height;
916       break;
917     default:
918       par_n = par_d = 0;
919   }
920
921   *num = par_n;
922   *den = par_d;
923 }
924
925 static void
926 gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps)
927 {
928   GstH264SPS *sps;
929   GstCaps *sink_caps;
930   gboolean modified = FALSE;
931   GstBuffer *buf = NULL;
932
933   if (G_UNLIKELY (!GST_PAD_CAPS (GST_BASE_PARSE_SRC_PAD (h264parse))))
934     modified = TRUE;
935   else if (G_UNLIKELY (!h264parse->update_caps))
936     return;
937
938   /* if this is being called from the first _setcaps call, caps on the sinkpad
939    * aren't set yet and so they need to be passed as an argument */
940   if (caps)
941     sink_caps = caps;
942   else
943     sink_caps = GST_PAD_CAPS (GST_BASE_PARSE_SINK_PAD (h264parse));
944
945   /* carry over input caps as much as possible; override with our own stuff */
946   if (sink_caps)
947     gst_caps_ref (sink_caps);
948   else
949     sink_caps = gst_caps_new_simple ("video/x-h264", NULL);
950
951   sps = h264parse->nalparser->last_sps;
952   GST_DEBUG_OBJECT (h264parse, "sps: %p", sps);
953
954   /* only codec-data for nice-and-clean au aligned packetized avc format */
955   if (h264parse->format == GST_H264_PARSE_FORMAT_AVC &&
956       h264parse->align == GST_H264_PARSE_ALIGN_AU) {
957     buf = gst_h264_parse_make_codec_data (h264parse);
958     if (buf && h264parse->codec_data) {
959       if (GST_BUFFER_SIZE (buf) != GST_BUFFER_SIZE (h264parse->codec_data) ||
960           memcmp (GST_BUFFER_DATA (buf),
961               GST_BUFFER_DATA (h264parse->codec_data), GST_BUFFER_SIZE (buf)))
962         modified = TRUE;
963     } else {
964       if (h264parse->codec_data)
965         buf = gst_buffer_ref (h264parse->codec_data);
966       modified = TRUE;
967     }
968   }
969
970   caps = NULL;
971   if (G_UNLIKELY (!sps)) {
972     caps = gst_caps_copy (sink_caps);
973   } else {
974     if (G_UNLIKELY (h264parse->width != sps->width ||
975             h264parse->height != sps->height)) {
976       GST_INFO_OBJECT (h264parse, "resolution changed %dx%d",
977           sps->width, sps->height);
978       h264parse->width = sps->width;
979       h264parse->height = sps->height;
980       modified = TRUE;
981     }
982
983     /* 0/1 is set as the default in the codec parser */
984     if (sps->vui_parameters.timing_info_present_flag &&
985         !(sps->fps_num == 0 && sps->fps_den == 1)) {
986       if (G_UNLIKELY (h264parse->fps_num != sps->fps_num
987               || h264parse->fps_den != sps->fps_den)) {
988         GST_INFO_OBJECT (h264parse, "framerate changed %d/%d",
989             sps->fps_num, sps->fps_den);
990         h264parse->fps_num = sps->fps_num;
991         h264parse->fps_den = sps->fps_den;
992         gst_base_parse_set_frame_rate (GST_BASE_PARSE (h264parse),
993             h264parse->fps_num, h264parse->fps_den, 0, 0);
994         modified = TRUE;
995       }
996     }
997
998     if (sps->vui_parameters.aspect_ratio_info_present_flag) {
999       if (G_UNLIKELY (h264parse->aspect_ratio_idc !=
1000               sps->vui_parameters.aspect_ratio_idc)) {
1001         h264parse->aspect_ratio_idc = sps->vui_parameters.aspect_ratio_idc;
1002         GST_INFO_OBJECT (h264parse, "aspect ratio idc changed %d",
1003             h264parse->aspect_ratio_idc);
1004         modified = TRUE;
1005       }
1006
1007       /* 255 means sar_width and sar_height present */
1008       if (G_UNLIKELY (sps->vui_parameters.aspect_ratio_idc == 255 &&
1009               (h264parse->sar_width != sps->vui_parameters.sar_width ||
1010                   h264parse->sar_height != sps->vui_parameters.sar_height))) {
1011         h264parse->sar_width = sps->vui_parameters.sar_width;
1012         h264parse->sar_height = sps->vui_parameters.sar_height;
1013         GST_INFO_OBJECT (h264parse, "aspect ratio SAR changed %d/%d",
1014             h264parse->sar_width, h264parse->sar_height);
1015         modified = TRUE;
1016       }
1017     }
1018
1019     if (G_UNLIKELY (modified)) {
1020       caps = gst_caps_copy (sink_caps);
1021       /* sps should give this */
1022       gst_caps_set_simple (caps, "width", G_TYPE_INT, sps->width,
1023           "height", G_TYPE_INT, sps->height, NULL);
1024       /* but not necessarily or reliably this */
1025       if (sps->fps_num > 0 && sps->fps_den > 0)
1026         gst_caps_set_simple (caps, "framerate",
1027             GST_TYPE_FRACTION, sps->fps_num, sps->fps_den, NULL);
1028     }
1029   }
1030
1031   if (caps) {
1032     gint par_n, par_d;
1033
1034     gst_caps_set_simple (caps, "parsed", G_TYPE_BOOLEAN, TRUE,
1035         "stream-format", G_TYPE_STRING,
1036         gst_h264_parse_get_string (h264parse, TRUE, h264parse->format),
1037         "alignment", G_TYPE_STRING,
1038         gst_h264_parse_get_string (h264parse, FALSE, h264parse->align), NULL);
1039
1040     gst_h264_parse_get_par (h264parse, &par_n, &par_d);
1041     if (par_n != 0 && par_d != 0) {
1042       GST_INFO_OBJECT (h264parse, "PAR %d/%d", par_n, par_d);
1043       gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
1044           par_n, par_d, NULL);
1045     }
1046
1047     if (buf) {
1048       gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
1049       gst_buffer_replace (&h264parse->codec_data, buf);
1050       gst_buffer_unref (buf);
1051       buf = NULL;
1052     } else {
1053       GstStructure *s;
1054       /* remove any left-over codec-data hanging around */
1055       s = gst_caps_get_structure (caps, 0);
1056       gst_structure_remove_field (s, "codec_data");
1057     }
1058     gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (h264parse), caps);
1059     gst_caps_unref (caps);
1060   }
1061
1062   gst_caps_unref (sink_caps);
1063   if (buf)
1064     gst_buffer_unref (buf);
1065 }
1066
1067 static void
1068 gst_h264_parse_get_timestamp (GstH264Parse * h264parse,
1069     GstClockTime * out_ts, GstClockTime * out_dur, gboolean frame)
1070 {
1071   GstH264SPS *sps = h264parse->nalparser->last_sps;
1072   GstClockTime upstream;
1073   gint duration = 1;
1074
1075   g_return_if_fail (out_dur != NULL);
1076   g_return_if_fail (out_ts != NULL);
1077
1078   upstream = *out_ts;
1079
1080   if (!frame) {
1081     GST_LOG_OBJECT (h264parse, "no frame data ->  0 duration");
1082     *out_dur = 0;
1083     goto exit;
1084   } else {
1085     *out_ts = upstream;
1086   }
1087
1088   if (!sps) {
1089     GST_DEBUG_OBJECT (h264parse, "referred SPS invalid");
1090     goto exit;
1091   } else if (!sps->vui_parameters.timing_info_present_flag) {
1092     GST_DEBUG_OBJECT (h264parse,
1093         "unable to compute timestamp: timing info not present");
1094     goto exit;
1095   } else if (sps->vui_parameters.time_scale == 0) {
1096     GST_DEBUG_OBJECT (h264parse,
1097         "unable to compute timestamp: time_scale = 0 "
1098         "(this is forbidden in spec; bitstream probably contains error)");
1099     goto exit;
1100   }
1101
1102   if (h264parse->sei_pic_struct_pres_flag &&
1103       h264parse->sei_pic_struct != (guint8) - 1) {
1104     /* Note that when h264parse->sei_pic_struct == -1 (unspecified), there
1105      * are ways to infer its value. This is related to computing the
1106      * TopFieldOrderCnt and BottomFieldOrderCnt, which looks
1107      * complicated and thus not implemented for the time being. Yet
1108      * the value we have here is correct for many applications
1109      */
1110     switch (h264parse->sei_pic_struct) {
1111       case GST_H264_SEI_PIC_STRUCT_TOP_FIELD:
1112       case GST_H264_SEI_PIC_STRUCT_BOTTOM_FIELD:
1113         duration = 1;
1114         break;
1115       case GST_H264_SEI_PIC_STRUCT_FRAME:
1116       case GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM:
1117       case GST_H264_SEI_PIC_STRUCT_BOTTOM_TOP:
1118         duration = 2;
1119         break;
1120       case GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP:
1121       case GST_H264_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM:
1122         duration = 3;
1123         break;
1124       case GST_H264_SEI_PIC_STRUCT_FRAME_DOUBLING:
1125         duration = 4;
1126         break;
1127       case GST_H264_SEI_PIC_STRUCT_FRAME_TRIPLING:
1128         duration = 6;
1129         break;
1130       default:
1131         GST_DEBUG_OBJECT (h264parse,
1132             "h264parse->sei_pic_struct of unknown value %d. Not parsed",
1133             h264parse->sei_pic_struct);
1134         break;
1135     }
1136   } else {
1137     duration = h264parse->field_pic_flag ? 1 : 2;
1138   }
1139
1140   GST_LOG_OBJECT (h264parse, "frame tick duration %d", duration);
1141
1142   /*
1143    * h264parse.264 C.1.2 Timing of coded picture removal (equivalent to DTS):
1144    * Tr,n(0) = initial_cpb_removal_delay[ SchedSelIdx ] / 90000
1145    * Tr,n(n) = Tr,n(nb) + Tc * cpb_removal_delay(n)
1146    * where
1147    * Tc = num_units_in_tick / time_scale
1148    */
1149
1150   if (h264parse->ts_trn_nb != GST_CLOCK_TIME_NONE) {
1151     GST_LOG_OBJECT (h264parse, "buffering based ts");
1152     /* buffering period is present */
1153     if (upstream != GST_CLOCK_TIME_NONE) {
1154       /* If upstream timestamp is valid, we respect it and adjust current
1155        * reference point */
1156       h264parse->ts_trn_nb = upstream -
1157           (GstClockTime) gst_util_uint64_scale_int
1158           (h264parse->sei_cpb_removal_delay * GST_SECOND,
1159           sps->vui_parameters.num_units_in_tick,
1160           sps->vui_parameters.time_scale);
1161     } else {
1162       /* If no upstream timestamp is given, we write in new timestamp */
1163       upstream = h264parse->dts = h264parse->ts_trn_nb +
1164           (GstClockTime) gst_util_uint64_scale_int
1165           (h264parse->sei_cpb_removal_delay * GST_SECOND,
1166           sps->vui_parameters.num_units_in_tick,
1167           sps->vui_parameters.time_scale);
1168     }
1169   } else {
1170     GstClockTime dur;
1171
1172     GST_LOG_OBJECT (h264parse, "duration based ts");
1173     /* naive method: no removal delay specified
1174      * track upstream timestamp and provide best guess frame duration */
1175     dur = gst_util_uint64_scale_int (duration * GST_SECOND,
1176         sps->vui_parameters.num_units_in_tick, sps->vui_parameters.time_scale);
1177     /* sanity check */
1178     if (dur < GST_MSECOND) {
1179       GST_DEBUG_OBJECT (h264parse, "discarding dur %" GST_TIME_FORMAT,
1180           GST_TIME_ARGS (dur));
1181     } else {
1182       *out_dur = dur;
1183     }
1184   }
1185
1186 exit:
1187   if (GST_CLOCK_TIME_IS_VALID (upstream))
1188     *out_ts = h264parse->dts = upstream;
1189
1190   if (GST_CLOCK_TIME_IS_VALID (*out_dur) &&
1191       GST_CLOCK_TIME_IS_VALID (h264parse->dts))
1192     h264parse->dts += *out_dur;
1193 }
1194
1195 static GstFlowReturn
1196 gst_h264_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
1197 {
1198   GstH264Parse *h264parse;
1199   GstBuffer *buffer;
1200   guint av;
1201
1202   h264parse = GST_H264_PARSE (parse);
1203   buffer = frame->buffer;
1204
1205   gst_h264_parse_update_src_caps (h264parse, NULL);
1206
1207   /* don't mess with timestamps if provided by upstream,
1208    * particularly since our ts not that good they handle seeking etc */
1209   if (h264parse->do_ts)
1210     gst_h264_parse_get_timestamp (h264parse,
1211         &GST_BUFFER_TIMESTAMP (buffer), &GST_BUFFER_DURATION (buffer),
1212         h264parse->frame_start);
1213
1214   if (h264parse->keyframe)
1215     GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
1216   else
1217     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
1218
1219   if (h264parse->b_frame)
1220     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_B_FRAME);
1221
1222   /* replace with transformed AVC output if applicable */
1223   av = gst_adapter_available (h264parse->frame_out);
1224   if (av) {
1225     GstBuffer *buf;
1226
1227     buf = gst_adapter_take_buffer (h264parse->frame_out, av);
1228     gst_buffer_copy_metadata (buf, buffer, GST_BUFFER_COPY_ALL);
1229     gst_buffer_replace (&frame->buffer, buf);
1230     gst_buffer_unref (buf);
1231   }
1232
1233   return GST_FLOW_OK;
1234 }
1235
1236 /* sends a codec NAL downstream, decorating and transforming as needed.
1237  * No ownership is taken of @nal */
1238 static GstFlowReturn
1239 gst_h264_parse_push_codec_buffer (GstH264Parse * h264parse, GstBuffer * nal,
1240     GstClockTime ts)
1241 {
1242   nal = gst_h264_parse_wrap_nal (h264parse, h264parse->format,
1243       GST_BUFFER_DATA (nal), GST_BUFFER_SIZE (nal));
1244
1245   GST_BUFFER_TIMESTAMP (nal) = ts;
1246   GST_BUFFER_DURATION (nal) = 0;
1247
1248   gst_buffer_set_caps (nal, GST_PAD_CAPS (GST_BASE_PARSE_SRC_PAD (h264parse)));
1249
1250   return gst_pad_push (GST_BASE_PARSE_SRC_PAD (h264parse), nal);
1251 }
1252
1253 static GstFlowReturn
1254 gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
1255 {
1256   GstH264Parse *h264parse;
1257   GstBuffer *buffer;
1258
1259   h264parse = GST_H264_PARSE (parse);
1260   buffer = frame->buffer;
1261
1262   /* periodic SPS/PPS sending */
1263   if (h264parse->interval > 0 || h264parse->push_codec) {
1264     GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer);
1265     guint64 diff;
1266
1267     /* init */
1268     if (!GST_CLOCK_TIME_IS_VALID (h264parse->last_report)) {
1269       h264parse->last_report = timestamp;
1270     }
1271
1272     if (h264parse->idr_pos >= 0) {
1273       GST_LOG_OBJECT (h264parse, "IDR nal at offset %d", h264parse->idr_pos);
1274
1275       if (timestamp > h264parse->last_report)
1276         diff = timestamp - h264parse->last_report;
1277       else
1278         diff = 0;
1279
1280       GST_LOG_OBJECT (h264parse,
1281           "now %" GST_TIME_FORMAT ", last SPS/PPS %" GST_TIME_FORMAT,
1282           GST_TIME_ARGS (timestamp), GST_TIME_ARGS (h264parse->last_report));
1283
1284       GST_DEBUG_OBJECT (h264parse,
1285           "interval since last SPS/PPS %" GST_TIME_FORMAT,
1286           GST_TIME_ARGS (diff));
1287
1288       if (GST_TIME_AS_SECONDS (diff) >= h264parse->interval ||
1289           h264parse->push_codec) {
1290         GstBuffer *codec_nal;
1291         gint i;
1292         GstClockTime new_ts;
1293
1294         /* avoid overwriting a perfectly fine timestamp */
1295         new_ts = GST_CLOCK_TIME_IS_VALID (timestamp) ? timestamp :
1296             h264parse->last_report;
1297
1298         if (h264parse->align == GST_H264_PARSE_ALIGN_NAL) {
1299           /* send separate config NAL buffers */
1300           GST_DEBUG_OBJECT (h264parse, "- sending SPS/PPS");
1301           for (i = 0; i < GST_H264_MAX_SPS_COUNT; i++) {
1302             if ((codec_nal = h264parse->sps_nals[i])) {
1303               GST_DEBUG_OBJECT (h264parse, "sending SPS nal");
1304               gst_h264_parse_push_codec_buffer (h264parse, codec_nal,
1305                   timestamp);
1306               h264parse->last_report = new_ts;
1307             }
1308           }
1309           for (i = 0; i < GST_H264_MAX_PPS_COUNT; i++) {
1310             if ((codec_nal = h264parse->pps_nals[i])) {
1311               GST_DEBUG_OBJECT (h264parse, "sending PPS nal");
1312               gst_h264_parse_push_codec_buffer (h264parse, codec_nal,
1313                   timestamp);
1314               h264parse->last_report = new_ts;
1315             }
1316           }
1317         } else {
1318           /* insert config NALs into AU */
1319           GstByteWriter bw;
1320           GstBuffer *new_buf;
1321           const gboolean bs = h264parse->format == GST_H264_PARSE_FORMAT_BYTE;
1322
1323           gst_byte_writer_init_with_size (&bw, GST_BUFFER_SIZE (buffer), FALSE);
1324           gst_byte_writer_put_data (&bw, GST_BUFFER_DATA (buffer),
1325               h264parse->idr_pos);
1326           GST_DEBUG_OBJECT (h264parse, "- inserting SPS/PPS");
1327           for (i = 0; i < GST_H264_MAX_SPS_COUNT; i++) {
1328             if ((codec_nal = h264parse->sps_nals[i])) {
1329               GST_DEBUG_OBJECT (h264parse, "inserting SPS nal");
1330               gst_byte_writer_put_uint32_be (&bw,
1331                   bs ? 1 : GST_BUFFER_SIZE (codec_nal));
1332               gst_byte_writer_put_data (&bw, GST_BUFFER_DATA (codec_nal),
1333                   GST_BUFFER_SIZE (codec_nal));
1334               h264parse->last_report = new_ts;
1335             }
1336           }
1337           for (i = 0; i < GST_H264_MAX_PPS_COUNT; i++) {
1338             if ((codec_nal = h264parse->pps_nals[i])) {
1339               GST_DEBUG_OBJECT (h264parse, "inserting PPS nal");
1340               gst_byte_writer_put_uint32_be (&bw,
1341                   bs ? 1 : GST_BUFFER_SIZE (codec_nal));
1342               gst_byte_writer_put_data (&bw, GST_BUFFER_DATA (codec_nal),
1343                   GST_BUFFER_SIZE (codec_nal));
1344               h264parse->last_report = new_ts;
1345             }
1346           }
1347           gst_byte_writer_put_data (&bw,
1348               GST_BUFFER_DATA (buffer) + h264parse->idr_pos,
1349               GST_BUFFER_SIZE (buffer) - h264parse->idr_pos);
1350           /* collect result and push */
1351           new_buf = gst_byte_writer_reset_and_get_buffer (&bw);
1352           gst_buffer_copy_metadata (new_buf, buffer, GST_BUFFER_COPY_ALL);
1353           /* should already be keyframe/IDR, but it may not have been,
1354            * so mark it as such to avoid being discarded by picky decoder */
1355           GST_BUFFER_FLAG_UNSET (new_buf, GST_BUFFER_FLAG_DELTA_UNIT);
1356           gst_buffer_replace (&frame->buffer, new_buf);
1357           gst_buffer_unref (new_buf);
1358         }
1359       }
1360       /* we pushed whatever we had */
1361       h264parse->push_codec = FALSE;
1362       h264parse->have_sps = FALSE;
1363       h264parse->have_pps = FALSE;
1364     }
1365   }
1366
1367   gst_h264_parse_reset_frame (h264parse);
1368
1369   return GST_FLOW_OK;
1370 }
1371
1372 static gboolean
1373 gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps)
1374 {
1375   GstH264Parse *h264parse;
1376   GstStructure *str;
1377   const GValue *value;
1378   GstBuffer *codec_data = NULL;
1379   guint size, format, align, off;
1380   GstH264NalUnit nalu;
1381   GstH264ParserResult parseres;
1382
1383   h264parse = GST_H264_PARSE (parse);
1384
1385   /* reset */
1386   h264parse->push_codec = FALSE;
1387
1388   str = gst_caps_get_structure (caps, 0);
1389
1390   /* accept upstream info if provided */
1391   gst_structure_get_int (str, "width", &h264parse->width);
1392   gst_structure_get_int (str, "height", &h264parse->height);
1393   gst_structure_get_fraction (str, "framerate", &h264parse->fps_num,
1394       &h264parse->fps_den);
1395   gst_structure_get_fraction (str, "pixel-aspect-ratio", &h264parse->sar_width,
1396       &h264parse->sar_height);
1397
1398   /* get upstream format and align from caps */
1399   gst_h264_parse_format_from_caps (caps, &format, &align);
1400
1401   /* packetized video has a codec_data */
1402   if (format == GST_H264_PARSE_FORMAT_AVC &&
1403       (value = gst_structure_get_value (str, "codec_data"))) {
1404     guint8 *data;
1405     guint num_sps, num_pps, profile;
1406     gint i;
1407
1408     GST_DEBUG_OBJECT (h264parse, "have packetized h264");
1409     /* make note for optional split processing */
1410     h264parse->packetized = TRUE;
1411
1412     codec_data = gst_value_get_buffer (value);
1413     if (!codec_data)
1414       goto wrong_type;
1415     data = GST_BUFFER_DATA (codec_data);
1416     size = GST_BUFFER_SIZE (codec_data);
1417
1418     /* parse the avcC data */
1419     if (size < 8)
1420       goto avcc_too_small;
1421
1422     /* parse the version, this must be 1 */
1423     if (data[0] != 1)
1424       goto wrong_version;
1425
1426     /* AVCProfileIndication */
1427     /* profile_compat */
1428     /* AVCLevelIndication */
1429     profile = (data[1] << 16) | (data[2] << 8) | data[3];
1430     GST_DEBUG_OBJECT (h264parse, "profile %06x", profile);
1431
1432     /* 6 bits reserved | 2 bits lengthSizeMinusOne */
1433     /* this is the number of bytes in front of the NAL units to mark their
1434      * length */
1435     h264parse->nal_length_size = (data[4] & 0x03) + 1;
1436     GST_DEBUG_OBJECT (h264parse, "nal length size %u",
1437         h264parse->nal_length_size);
1438
1439     num_sps = data[5] & 0x1f;
1440     off = 6;
1441     for (i = 0; i < num_sps; i++) {
1442       parseres = gst_h264_parser_identify_nalu_avc (h264parse->nalparser,
1443           data, off, size, 2, &nalu);
1444       if (parseres != GST_H264_PARSER_OK)
1445         goto avcc_too_small;
1446
1447       gst_h264_parse_process_nal (h264parse, &nalu);
1448       off = nalu.offset + nalu.size;
1449     }
1450
1451     num_pps = data[off];
1452     off++;
1453
1454     for (i = 0; i < num_pps; i++) {
1455       parseres = gst_h264_parser_identify_nalu_avc (h264parse->nalparser,
1456           data, off, size, 2, &nalu);
1457       if (parseres != GST_H264_PARSER_OK) {
1458         goto avcc_too_small;
1459       }
1460
1461       gst_h264_parse_process_nal (h264parse, &nalu);
1462       off = nalu.offset + nalu.size;
1463     }
1464
1465     h264parse->codec_data = gst_buffer_ref (codec_data);
1466
1467     /* if upstream sets codec_data without setting stream-format and alignment, we
1468      * assume stream-format=avc,alignment=au */
1469     if (format == GST_H264_PARSE_FORMAT_NONE) {
1470       format = GST_H264_PARSE_FORMAT_AVC;
1471       align = GST_H264_PARSE_ALIGN_AU;
1472     }
1473   } else {
1474     GST_DEBUG_OBJECT (h264parse, "have bytestream h264");
1475     /* nothing to pre-process */
1476     h264parse->packetized = FALSE;
1477     /* we have 4 sync bytes */
1478     h264parse->nal_length_size = 4;
1479
1480     if (format == GST_H264_PARSE_FORMAT_NONE) {
1481       format = GST_H264_PARSE_FORMAT_BYTE;
1482       align = GST_H264_PARSE_ALIGN_AU;
1483     }
1484   }
1485
1486   {
1487     GstCaps *in_caps;
1488
1489     /* prefer input type determined above */
1490     in_caps = gst_caps_new_simple ("video/x-h264",
1491         "parsed", G_TYPE_BOOLEAN, TRUE,
1492         "stream-format", G_TYPE_STRING,
1493         gst_h264_parse_get_string (h264parse, TRUE, format),
1494         "alignment", G_TYPE_STRING,
1495         gst_h264_parse_get_string (h264parse, FALSE, align), NULL);
1496     /* negotiate with downstream, sets ->format and ->align */
1497     gst_h264_parse_negotiate (h264parse, in_caps);
1498     gst_caps_unref (in_caps);
1499   }
1500
1501   if (format == h264parse->format && align == h264parse->align) {
1502     gst_base_parse_set_passthrough (parse, TRUE);
1503
1504     /* we did parse codec-data and might supplement src caps */
1505     gst_h264_parse_update_src_caps (h264parse, caps);
1506   } else if (format == GST_H264_PARSE_FORMAT_AVC) {
1507     /* if input != output, and input is avc, must split before anything else */
1508     /* arrange to insert codec-data in-stream if needed.
1509      * src caps are only arranged for later on */
1510     h264parse->push_codec = TRUE;
1511     h264parse->have_sps = FALSE;
1512     h264parse->have_pps = FALSE;
1513     h264parse->split_packetized = TRUE;
1514     h264parse->packetized = TRUE;
1515   }
1516
1517   return TRUE;
1518
1519   /* ERRORS */
1520 avcc_too_small:
1521   {
1522     GST_DEBUG_OBJECT (h264parse, "avcC size %u < 8", size);
1523     goto refuse_caps;
1524   }
1525 wrong_version:
1526   {
1527     GST_DEBUG_OBJECT (h264parse, "wrong avcC version");
1528     goto refuse_caps;
1529   }
1530 wrong_type:
1531   {
1532     GST_DEBUG_OBJECT (h264parse, "wrong codec-data type");
1533     goto refuse_caps;
1534   }
1535 refuse_caps:
1536   {
1537     GST_WARNING_OBJECT (h264parse, "refused caps %" GST_PTR_FORMAT, caps);
1538     return FALSE;
1539   }
1540 }
1541
1542 static gboolean
1543 gst_h264_parse_event (GstBaseParse * parse, GstEvent * event)
1544 {
1545   gboolean handled = FALSE;
1546   GstH264Parse *h264parse = GST_H264_PARSE (parse);
1547
1548   switch (GST_EVENT_TYPE (event)) {
1549     case GST_EVENT_FLUSH_STOP:
1550       h264parse->dts = GST_CLOCK_TIME_NONE;
1551       h264parse->ts_trn_nb = GST_CLOCK_TIME_NONE;
1552       break;
1553     case GST_EVENT_NEWSEGMENT:
1554     {
1555       gdouble rate, applied_rate;
1556       GstFormat format;
1557       gint64 start;
1558
1559       gst_event_parse_new_segment_full (event, NULL, &rate, &applied_rate,
1560           &format, &start, NULL, NULL);
1561       /* don't try to mess with more subtle cases (e.g. seek) */
1562       if (format == GST_FORMAT_TIME &&
1563           (start != 0 || rate != 1.0 || applied_rate != 1.0))
1564         h264parse->do_ts = FALSE;
1565       break;
1566     }
1567     default:
1568       break;
1569   }
1570
1571   return handled;
1572 }
1573
1574 static GstFlowReturn
1575 gst_h264_parse_chain (GstPad * pad, GstBuffer * buffer)
1576 {
1577   GstH264Parse *h264parse = GST_H264_PARSE (GST_PAD_PARENT (pad));
1578
1579   if (h264parse->packetized && buffer) {
1580     GstBuffer *sub;
1581     GstFlowReturn ret = GST_FLOW_OK;
1582     GstH264ParserResult parse_res;
1583     GstH264NalUnit nalu;
1584     const guint nl = h264parse->nal_length_size;
1585
1586     if (nl < 1 || nl > 4) {
1587       GST_DEBUG_OBJECT (h264parse, "insufficient data to split input");
1588       gst_buffer_unref (buffer);
1589
1590       return GST_FLOW_NOT_NEGOTIATED;
1591     }
1592
1593     GST_LOG_OBJECT (h264parse, "processing packet buffer of size %d",
1594         GST_BUFFER_SIZE (buffer));
1595
1596     parse_res = gst_h264_parser_identify_nalu_avc (h264parse->nalparser,
1597         GST_BUFFER_DATA (buffer), 0, GST_BUFFER_SIZE (buffer), nl, &nalu);
1598
1599     while (parse_res == GST_H264_PARSER_OK) {
1600       GST_DEBUG_OBJECT (h264parse, "AVC nal offset %d",
1601           nalu.offset + nalu.size);
1602
1603       if (h264parse->split_packetized) {
1604         /* convert to NAL aligned byte stream input */
1605         sub = gst_h264_parse_wrap_nal (h264parse, GST_H264_PARSE_FORMAT_BYTE,
1606             nalu.data + nalu.offset, nalu.size);
1607         /* at least this should make sense */
1608         GST_BUFFER_TIMESTAMP (sub) = GST_BUFFER_TIMESTAMP (buffer);
1609         GST_LOG_OBJECT (h264parse, "pushing NAL of size %d", nalu.size);
1610         ret = h264parse->parse_chain (pad, sub);
1611       } else {
1612         /* pass-through: no looking for frames (and nal processing),
1613          * so need to parse to collect data here */
1614         /* NOTE: so if it is really configured to do so,
1615          * pre_push can/will still insert codec-data at intervals,
1616          * which is not really pure pass-through, but anyway ... */
1617         gst_h264_parse_process_nal (h264parse, &nalu);
1618
1619       }
1620
1621       parse_res = gst_h264_parser_identify_nalu_avc (h264parse->nalparser,
1622           GST_BUFFER_DATA (buffer), nalu.offset + nalu.size,
1623           GST_BUFFER_SIZE (buffer), nl, &nalu);
1624     }
1625
1626     if (h264parse->split_packetized) {
1627       gst_buffer_unref (buffer);
1628       return ret;
1629     } else {
1630       /* nal processing in pass-through might have collected stuff;
1631        * ensure nothing happens with this later on */
1632       gst_adapter_clear (h264parse->frame_out);
1633     }
1634
1635     if (parse_res == GST_H264_PARSER_NO_NAL_END ||
1636         parse_res == GST_H264_PARSER_BROKEN_DATA) {
1637
1638       if (h264parse->split_packetized) {
1639         GST_ELEMENT_ERROR (h264parse, STREAM, FAILED, (NULL),
1640             ("invalid AVC input data"));
1641         gst_buffer_unref (buffer);
1642
1643         return GST_FLOW_ERROR;
1644       } else {
1645         /* do not meddle to much in this case */
1646         GST_DEBUG_OBJECT (h264parse, "parsing packet failed");
1647       }
1648     }
1649   }
1650
1651   return h264parse->parse_chain (pad, buffer);
1652 }
1653
1654 static void
1655 gst_h264_parse_set_property (GObject * object, guint prop_id,
1656     const GValue * value, GParamSpec * pspec)
1657 {
1658   GstH264Parse *parse;
1659
1660   parse = GST_H264_PARSE (object);
1661
1662   switch (prop_id) {
1663     case PROP_CONFIG_INTERVAL:
1664       parse->interval = g_value_get_uint (value);
1665       break;
1666     default:
1667       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1668       break;
1669   }
1670 }
1671
1672 static void
1673 gst_h264_parse_get_property (GObject * object, guint prop_id, GValue * value,
1674     GParamSpec * pspec)
1675 {
1676   GstH264Parse *parse;
1677
1678   parse = GST_H264_PARSE (object);
1679
1680   switch (prop_id) {
1681     case PROP_CONFIG_INTERVAL:
1682       g_value_set_uint (value, parse->interval);
1683       break;
1684     default:
1685       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1686       break;
1687   }
1688 }