h264parse: gracefully handle truncated input NAL units
[gstreamer-omap:gst-plugins-bad.git] / gst / videoparsers / gsth264parse.c
1 /* GStreamer H.264 Parser
2  * Copyright (C) <2010> Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
3  * Copyright (C) <2010> Collabora Multimedia
4  * Copyright (C) <2010> Nokia Corporation
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #  include "config.h"
24 #endif
25
26 #include <gst/base/gstbytereader.h>
27 #include <gst/base/gstbytewriter.h>
28 #include <gst/base/gstadapter.h>
29 #include "gsth264parse.h"
30
31 #include <string.h>
32
33 GST_DEBUG_CATEGORY (h264_parse_debug);
34 #define GST_CAT_DEFAULT h264_parse_debug
35
36 #define DEFAULT_SPLIT_PACKETIZED     FALSE
37 #define DEFAULT_CONFIG_INTERVAL      (0)
38
39 enum
40 {
41   PROP_0,
42   PROP_SPLIT_PACKETIZED,
43   PROP_CONFIG_INTERVAL,
44   PROP_LAST
45 };
46
47 enum
48 {
49   GST_H264_PARSE_FORMAT_NONE,
50   GST_H264_PARSE_FORMAT_AVC,
51   GST_H264_PARSE_FORMAT_BYTE
52 };
53
54 enum
55 {
56   GST_H264_PARSE_ALIGN_NONE = 0,
57   GST_H264_PARSE_ALIGN_NAL,
58   GST_H264_PARSE_ALIGN_AU
59 };
60
61 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
62     GST_PAD_SINK,
63     GST_PAD_ALWAYS,
64     GST_STATIC_CAPS ("video/x-h264, parsed = (boolean) false"));
65
66 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
67     GST_PAD_SRC,
68     GST_PAD_ALWAYS,
69     GST_STATIC_CAPS ("video/x-h264, parsed = (boolean) true"));
70
71 GST_BOILERPLATE (GstH264Parse, gst_h264_parse, GstBaseParse,
72     GST_TYPE_BASE_PARSE);
73
74 static void gst_h264_parse_finalize (GObject * object);
75
76 static gboolean gst_h264_parse_start (GstBaseParse * parse);
77 static gboolean gst_h264_parse_stop (GstBaseParse * parse);
78 static gboolean gst_h264_parse_check_valid_frame (GstBaseParse * parse,
79     GstBaseParseFrame * frame, guint * framesize, gint * skipsize);
80 static GstFlowReturn gst_h264_parse_parse_frame (GstBaseParse * parse,
81     GstBaseParseFrame * frame);
82 static GstFlowReturn gst_h264_parse_pre_push_frame (GstBaseParse * parse,
83     GstBaseParseFrame * frame);
84
85 static void gst_h264_parse_set_property (GObject * object, guint prop_id,
86     const GValue * value, GParamSpec * pspec);
87 static void gst_h264_parse_get_property (GObject * object, guint prop_id,
88     GValue * value, GParamSpec * pspec);
89
90 static gboolean gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps);
91 static GstFlowReturn gst_h264_parse_chain (GstPad * pad, GstBuffer * buffer);
92
93 static void
94 gst_h264_parse_base_init (gpointer g_class)
95 {
96   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
97
98   gst_element_class_add_pad_template (gstelement_class,
99       gst_static_pad_template_get (&srctemplate));
100   gst_element_class_add_pad_template (gstelement_class,
101       gst_static_pad_template_get (&sinktemplate));
102
103   gst_element_class_set_details_simple (gstelement_class, "H.264 parser",
104       "Codec/Parser/Video",
105       "Parses H.264 streams",
106       "Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>");
107
108   GST_DEBUG_CATEGORY_INIT (h264_parse_debug, "h264parse", 0, "h264 parser");
109 }
110
111 static void
112 gst_h264_parse_class_init (GstH264ParseClass * klass)
113 {
114   GObjectClass *gobject_class = (GObjectClass *) klass;
115   GstBaseParseClass *parse_class = GST_BASE_PARSE_CLASS (klass);
116
117   gobject_class->finalize = gst_h264_parse_finalize;
118   gobject_class->set_property = gst_h264_parse_set_property;
119   gobject_class->get_property = gst_h264_parse_get_property;
120
121   g_object_class_install_property (gobject_class, PROP_SPLIT_PACKETIZED,
122       g_param_spec_boolean ("split-packetized", "Split packetized",
123           "Split NAL units of packetized streams", DEFAULT_SPLIT_PACKETIZED,
124           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
125   g_object_class_install_property (gobject_class, PROP_CONFIG_INTERVAL,
126       g_param_spec_uint ("config-interval",
127           "SPS PPS Send Interval",
128           "Send SPS and PPS Insertion Interval in seconds (sprop parameter sets "
129           "will be multiplexed in the data stream when detected.) (0 = disabled)",
130           0, 3600, DEFAULT_CONFIG_INTERVAL,
131           G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
132
133   /* Override BaseParse vfuncs */
134   parse_class->start = GST_DEBUG_FUNCPTR (gst_h264_parse_start);
135   parse_class->stop = GST_DEBUG_FUNCPTR (gst_h264_parse_stop);
136   parse_class->check_valid_frame =
137       GST_DEBUG_FUNCPTR (gst_h264_parse_check_valid_frame);
138   parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_h264_parse_parse_frame);
139   parse_class->pre_push_frame =
140       GST_DEBUG_FUNCPTR (gst_h264_parse_pre_push_frame);
141   parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_h264_parse_set_caps);
142 }
143
144 static void
145 gst_h264_parse_init (GstH264Parse * h264parse, GstH264ParseClass * g_class)
146 {
147   h264parse->frame_out = gst_adapter_new ();
148
149   /* retrieve and intercept baseparse.
150    * Quite HACKish, but fairly OK since it is needed to perform avc packet
151    * splitting, which is the penultimate de-parsing */
152   h264parse->parse_chain =
153       GST_PAD_CHAINFUNC (GST_BASE_PARSE_SINK_PAD (h264parse));
154   gst_pad_set_chain_function (GST_BASE_PARSE_SINK_PAD (h264parse),
155       gst_h264_parse_chain);
156 }
157
158
159 static void
160 gst_h264_parse_finalize (GObject * object)
161 {
162   GstH264Parse *h264parse = GST_H264_PARSE (object);
163
164   g_object_unref (h264parse->frame_out);
165
166   G_OBJECT_CLASS (parent_class)->finalize (object);
167 }
168
169 static void
170 gst_h264_parse_reset_frame (GstH264Parse * h264parse)
171 {
172   /* done parsing; reset state */
173   h264parse->last_nal_pos = 0;
174   h264parse->next_sc_pos = 0;
175   h264parse->picture_start = FALSE;
176   h264parse->update_caps = FALSE;
177   h264parse->idr_pos = -1;
178   h264parse->keyframe = FALSE;
179   h264parse->frame_start = FALSE;
180 }
181
182 static void
183 gst_h264_parse_reset (GstH264Parse * h264parse)
184 {
185   h264parse->width = 0;
186   h264parse->height = 0;
187   h264parse->fps_num = 0;
188   h264parse->fps_den = 0;
189   gst_buffer_replace (&h264parse->codec_data, NULL);
190   h264parse->nal_length_size = 4;
191   h264parse->packetized = FALSE;
192
193   h264parse->align = GST_H264_PARSE_ALIGN_NONE;
194   h264parse->format = GST_H264_PARSE_FORMAT_NONE;
195
196   h264parse->last_report = GST_CLOCK_TIME_NONE;
197   h264parse->push_codec = FALSE;
198
199   gst_h264_parse_reset_frame (h264parse);
200 }
201
202 static gboolean
203 gst_h264_parse_start (GstBaseParse * parse)
204 {
205   GstH264Parse *h264parse = GST_H264_PARSE (parse);
206
207   GST_DEBUG_OBJECT (parse, "start");
208   gst_h264_parse_reset (h264parse);
209
210   gst_h264_params_create (&h264parse->params, GST_ELEMENT (h264parse));
211
212   gst_base_parse_set_min_frame_size (parse, 512);
213
214   return TRUE;
215 }
216
217 static gboolean
218 gst_h264_parse_stop (GstBaseParse * parse)
219 {
220   GstH264Parse *h264parse = GST_H264_PARSE (parse);
221
222   GST_DEBUG_OBJECT (parse, "stop");
223   gst_h264_parse_reset (h264parse);
224
225   gst_h264_params_free (h264parse->params);
226   h264parse->params = NULL;
227
228   return TRUE;
229 }
230
231 static const gchar *
232 gst_h264_parse_get_string (GstH264Parse * parse, gboolean format, gint code)
233 {
234   if (format) {
235     switch (code) {
236       case GST_H264_PARSE_FORMAT_AVC:
237         return "avc";
238       case GST_H264_PARSE_FORMAT_BYTE:
239         return "byte-stream";
240       default:
241         return "none";
242     }
243   } else {
244     switch (code) {
245       case GST_H264_PARSE_ALIGN_NAL:
246         return "nal";
247       case GST_H264_PARSE_ALIGN_AU:
248         return "au";
249       default:
250         return "none";
251     }
252   }
253 }
254
255 /* check downstream caps to configure format and alignment */
256 static void
257 gst_h264_parse_negotiate (GstH264Parse * h264parse)
258 {
259   GstCaps *caps;
260   guint format = GST_H264_PARSE_FORMAT_NONE;
261   guint align = GST_H264_PARSE_ALIGN_NONE;
262
263   caps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (h264parse));
264   GST_DEBUG_OBJECT (h264parse, "allowed caps: %" GST_PTR_FORMAT, caps);
265
266   if (caps && gst_caps_get_size (caps) > 0) {
267     GstStructure *s = gst_caps_get_structure (caps, 0);
268     const gchar *str = NULL;
269
270     if ((str = gst_structure_get_string (s, "stream-format"))) {
271       if (strcmp (str, "avc") == 0) {
272         format = GST_H264_PARSE_FORMAT_AVC;
273       } else if (strcmp (str, "byte-stream") == 0) {
274         format = GST_H264_PARSE_FORMAT_BYTE;
275       } else {
276         GST_DEBUG_OBJECT (h264parse, "unknown stream-format: %s", str);
277       }
278     }
279
280     if ((str = gst_structure_get_string (s, "alignment"))) {
281       if (strcmp (str, "au") == 0) {
282         align = GST_H264_PARSE_ALIGN_AU;
283       } else if (strcmp (str, "nal") == 0) {
284         align = GST_H264_PARSE_ALIGN_NAL;
285       } else {
286         GST_DEBUG_OBJECT (h264parse, "unknown alignment: %s", str);
287       }
288     }
289   }
290
291   if (caps)
292     gst_caps_unref (caps);
293
294   /* default */
295   if (!format)
296     format = GST_H264_PARSE_FORMAT_BYTE;
297   if (!align)
298     align = GST_H264_PARSE_ALIGN_AU;
299
300   GST_DEBUG_OBJECT (h264parse, "selected format %s, alignment %s",
301       gst_h264_parse_get_string (h264parse, TRUE, format),
302       gst_h264_parse_get_string (h264parse, FALSE, align));
303
304   h264parse->format = format;
305   h264parse->align = align;
306 }
307
308 static GstBuffer *
309 gst_h264_parse_wrap_nal (GstH264Parse * h264parse, guint format, guint8 * data,
310     guint size)
311 {
312   GstBuffer *buf;
313   const guint nl = h264parse->nal_length_size;
314
315   buf = gst_buffer_new_and_alloc (size + nl + 4);
316   if (format == GST_H264_PARSE_FORMAT_AVC) {
317     GST_WRITE_UINT32_BE (GST_BUFFER_DATA (buf), size << (32 - 8 * nl));
318   } else {
319     g_assert (nl == 4);
320     GST_WRITE_UINT32_BE (GST_BUFFER_DATA (buf), 1);
321   }
322
323   GST_BUFFER_SIZE (buf) = size + nl;
324   memcpy (GST_BUFFER_DATA (buf) + nl, data, size);
325
326   return buf;
327 }
328
329 /* SPS/PPS/IDR considered key, all others DELTA;
330  * so downstream waiting for keyframe can pick up at SPS/PPS/IDR */
331 #define NAL_TYPE_IS_KEY(nt) (((nt) == 5) || ((nt) == 7) || ((nt) == 8))
332
333 /* caller guarantees 2 bytes of nal payload */
334 static void
335 gst_h264_parse_process_nal (GstH264Parse * h264parse, guint8 * data,
336     gint sc_pos, gint nal_pos, guint nal_size)
337 {
338   guint nal_type;
339
340   g_return_if_fail (nal_pos - sc_pos > 0 && nal_pos - sc_pos <= 4);
341
342   /* nothing to do for broken input */
343   if (G_UNLIKELY (nal_size < 2)) {
344     GST_DEBUG_OBJECT (h264parse, "not processing nal size %u", nal_size);
345     return;
346   }
347
348   /* lower layer collects params */
349   gst_h264_params_parse_nal (h264parse->params, data + nal_pos, nal_size);
350
351   /* we have a peek as well */
352   nal_type = data[nal_pos] & 0x1f;
353   h264parse->keyframe |= NAL_TYPE_IS_KEY (nal_type);
354
355   switch (nal_type) {
356     case NAL_SPS:
357     case NAL_PPS:
358       /* parameters might have changed, force caps check */
359       GST_DEBUG_OBJECT (h264parse, "triggering src caps check");
360       h264parse->update_caps = TRUE;
361       /* found in stream, no need to forcibly push at start */
362       h264parse->push_codec = FALSE;
363       break;
364     case NAL_SLICE:
365     case NAL_SLICE_DPA:
366     case NAL_SLICE_DPB:
367     case NAL_SLICE_DPC:
368       /* real frame data */
369       h264parse->frame_start |= (h264parse->params->first_mb_in_slice == 0);
370       /* if we need to sneak codec NALs into the stream,
371        * this is a good place, so fake it as IDR
372        * (which should be at start anyway) */
373       if (G_LIKELY (!h264parse->push_codec))
374         break;
375       /* fall-through */
376     case NAL_SLICE_IDR:
377       /* real frame data */
378       h264parse->frame_start |= (h264parse->params->first_mb_in_slice == 0);
379       /* mark where config needs to go if interval expired */
380       /* mind replacement buffer if applicable */
381       if (h264parse->format == GST_H264_PARSE_FORMAT_AVC)
382         h264parse->idr_pos = gst_adapter_available (h264parse->frame_out);
383       else
384         h264parse->idr_pos = sc_pos;
385       GST_DEBUG_OBJECT (h264parse, "marking IDR in frame at offset %d",
386           h264parse->idr_pos);
387       break;
388   }
389
390   /* if AVC output needed, collect properly prefixed nal in adapter,
391    * and use that to replace outgoing buffer data later on */
392   if (h264parse->format == GST_H264_PARSE_FORMAT_AVC) {
393     GstBuffer *buf;
394
395     GST_LOG_OBJECT (h264parse, "collecting NAL in AVC frame");
396     buf = gst_h264_parse_wrap_nal (h264parse, h264parse->format,
397         data + nal_pos, nal_size);
398     gst_adapter_push (h264parse->frame_out, buf);
399   }
400 }
401
402 /* caller guarantees at least 2 bytes of nal payload for each nal
403  * returns TRUE if next_nal indicates that nal terminates an AU */
404 static inline gboolean
405 gst_h264_parse_collect_nal (GstH264Parse * h264parse, guint8 * nal,
406     guint8 * next_nal)
407 {
408   gint nal_type;
409   gboolean complete;
410
411   if (h264parse->align == GST_H264_PARSE_ALIGN_NAL)
412     return TRUE;
413
414   /* determine if AU complete */
415   nal_type = nal[0] & 0x1f;
416   GST_LOG_OBJECT (h264parse, "nal type: %d", nal_type);
417   /* coded slice NAL starts a picture,
418    * i.e. other types become aggregated in front of it */
419   h264parse->picture_start |= (nal_type == 1 || nal_type == 2 || nal_type == 5);
420
421   /* consider a coded slices (IDR or not) to start a picture,
422    * (so ending the previous one) if first_mb_in_slice == 0
423    * (non-0 is part of previous one) */
424   /* NOTE this is not entirely according to Access Unit specs in 7.4.1.2.4,
425    * but in practice it works in sane cases, needs not much parsing,
426    * and also works with broken frame_num in NAL
427    * (where spec-wise would fail) */
428   nal_type = next_nal[0] & 0x1f;
429   GST_LOG_OBJECT (h264parse, "next nal type: %d", nal_type);
430   complete = h264parse->picture_start && (nal_type >= 6 && nal_type <= 9);
431   complete |= h264parse->picture_start &&
432       (nal_type == 1 || nal_type == 2 || nal_type == 5) &&
433       /* first_mb_in_slice == 0 considered start of frame */
434       (next_nal[1] & 0x80);
435
436   GST_LOG_OBJECT (h264parse, "au complete: %d", complete);
437
438   return complete;
439 }
440
441 /* finds next startcode == 00 00 01, along with a subsequent byte */
442 static guint
443 gst_h264_parse_find_sc (GstBuffer * buffer, guint skip)
444 {
445   GstByteReader br;
446   guint sc_pos = -1;
447
448   gst_byte_reader_init_from_buffer (&br, buffer);
449
450   /* NALU not empty, so we can at least expect 1 (even 2) bytes following sc */
451   sc_pos = gst_byte_reader_masked_scan_uint32 (&br, 0xffffff00, 0x00000100,
452       skip, gst_byte_reader_get_remaining (&br) - skip);
453
454   return sc_pos;
455 }
456
457 static gboolean
458 gst_h264_parse_check_valid_frame (GstBaseParse * parse,
459     GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
460 {
461   GstH264Parse *h264parse = GST_H264_PARSE (parse);
462   GstBuffer *buffer = frame->buffer;
463   gint sc_pos, nal_pos, next_sc_pos, next_nal_pos;
464   guint8 *data;
465   guint size;
466   gboolean drain;
467
468   /* expect at least 3 bytes startcode == sc, and 2 bytes NALU payload */
469   if (G_UNLIKELY (GST_BUFFER_SIZE (buffer) < 5))
470     return FALSE;
471
472   /* need to configure aggregation */
473   if (G_UNLIKELY (h264parse->format == GST_H264_PARSE_FORMAT_NONE))
474     gst_h264_parse_negotiate (h264parse);
475
476   data = GST_BUFFER_DATA (buffer);
477   size = GST_BUFFER_SIZE (buffer);
478
479   GST_LOG_OBJECT (h264parse, "last_nal_pos: %d, last_scan_pos %d",
480       h264parse->last_nal_pos, h264parse->next_sc_pos);
481
482   nal_pos = h264parse->last_nal_pos;
483   next_sc_pos = h264parse->next_sc_pos;
484
485   if (!next_sc_pos) {
486     sc_pos = gst_h264_parse_find_sc (buffer, 0);
487
488     if (sc_pos == -1) {
489       /* SC not found, need more data */
490       sc_pos = GST_BUFFER_SIZE (buffer) - 3;
491       goto more;
492     }
493
494     nal_pos = sc_pos + 3;
495     next_sc_pos = nal_pos;
496     /* sc might have 2 or 3 0-bytes */
497     if (sc_pos > 0 && data[sc_pos - 1] == 00)
498       sc_pos--;
499     GST_LOG_OBJECT (h264parse, "found sc at offset %d", sc_pos);
500   } else {
501     /* previous checks already arrange sc at start */
502     sc_pos = 0;
503   }
504
505   drain = GST_BASE_PARSE_DRAINING (parse);
506   while (TRUE) {
507     gint prev_sc_pos;
508
509     next_sc_pos = gst_h264_parse_find_sc (buffer, next_sc_pos);
510     if (next_sc_pos == -1) {
511       GST_LOG_OBJECT (h264parse, "no next sc");
512       if (drain) {
513         /* FLUSH/EOS, it's okay if we can't find the next frame */
514         next_sc_pos = size;
515         next_nal_pos = size;
516       } else {
517         next_sc_pos = size - 3;
518         goto more;
519       }
520     } else {
521       next_nal_pos = next_sc_pos + 3;
522       if (data[next_sc_pos - 1] == 00)
523         next_sc_pos--;
524       GST_LOG_OBJECT (h264parse, "found next sc at offset %d", next_sc_pos);
525       /* need at least 1 more byte of next NAL */
526       if (!drain && (next_nal_pos == size - 1))
527         goto more;
528     }
529
530     /* determine nal's sc position */
531     prev_sc_pos = nal_pos - 3;
532     g_assert (prev_sc_pos >= 0);
533     if (prev_sc_pos > 0 && data[prev_sc_pos - 1] == 0)
534       prev_sc_pos--;
535
536     /* already consume and gather info from NAL */
537     if (G_UNLIKELY (next_sc_pos - nal_pos < 2)) {
538       GST_WARNING_OBJECT (h264parse, "input stream is corrupt; "
539           "it contains a NAL unit of length %d", next_sc_pos - nal_pos);
540       /* broken nal at start -> arrange to skip it,
541        * otherwise have it terminate current au
542        * (and so it will be skippd on next frame round) */
543       if (prev_sc_pos == sc_pos) {
544         *skipsize = sc_pos + 2;
545         return FALSE;
546       } else {
547         next_sc_pos = prev_sc_pos;
548         break;
549       }
550     }
551     gst_h264_parse_process_nal (h264parse, data, prev_sc_pos, nal_pos,
552         next_sc_pos - nal_pos);
553     if (next_nal_pos >= size - 1 ||
554         gst_h264_parse_collect_nal (h264parse, data + nal_pos,
555             data + next_nal_pos))
556       break;
557
558     /* move along */
559     next_sc_pos = nal_pos = next_nal_pos;
560   }
561
562   *skipsize = sc_pos;
563   *framesize = next_sc_pos - sc_pos;
564
565   return TRUE;
566
567 more:
568   /* Ask for 1024 bytes more - this is an arbitrary choice */
569   gst_base_parse_set_min_frame_size (parse, GST_BUFFER_SIZE (buffer) + 1024);
570
571   /* skip up to initial startcode */
572   *skipsize = sc_pos;
573   /* resume scanning here next time */
574   h264parse->last_nal_pos = nal_pos;
575   h264parse->next_sc_pos = next_sc_pos;
576
577   return FALSE;
578 }
579
580 /* byte together avc codec data based on collected pps and sps so far */
581 static GstBuffer *
582 gst_h264_parse_make_codec_data (GstH264Parse * h264parse)
583 {
584   GstBuffer *buf, *nal;
585   gint i, sps_size = 0, pps_size = 0, num_sps = 0, num_pps = 0;
586   guint8 profile_idc = 0, profile_comp = 0, level_idc = 0;
587   gboolean found = FALSE;
588   guint8 *data;
589
590   /* only nal payload in stored nals */
591
592   for (i = 0; i < MAX_SPS_COUNT; i++) {
593     if ((nal = h264parse->params->sps_nals[i])) {
594       num_sps++;
595       /* size bytes also count */
596       sps_size += GST_BUFFER_SIZE (nal) + 2;
597       if (GST_BUFFER_SIZE (nal) >= 4) {
598         found = TRUE;
599         profile_idc = (GST_BUFFER_DATA (nal))[1];
600         profile_comp = (GST_BUFFER_DATA (nal))[2];
601         level_idc = (GST_BUFFER_DATA (nal))[3];
602       }
603     }
604   }
605   for (i = 0; i < MAX_PPS_COUNT; i++) {
606     if ((nal = h264parse->params->pps_nals[i])) {
607       num_pps++;
608       /* size bytes also count */
609       pps_size += GST_BUFFER_SIZE (nal) + 2;
610     }
611   }
612
613   GST_DEBUG_OBJECT (h264parse,
614       "constructing codec_data: num_sps=%d, num_pps=%d", num_sps, num_pps);
615
616   if (!found || !num_pps)
617     return NULL;
618
619   buf = gst_buffer_new_and_alloc (5 + 1 + sps_size + 1 + pps_size);
620   data = GST_BUFFER_DATA (buf);
621
622   data[0] = 1;                  /* AVC Decoder Configuration Record ver. 1 */
623   data[1] = profile_idc;        /* profile_idc                             */
624   data[2] = profile_comp;       /* profile_compability                     */
625   data[3] = level_idc;          /* level_idc                               */
626   data[4] = 0xfc | (4 - 1);     /* nal_length_size_minus1                  */
627   data[5] = 0xe0 | num_sps;     /* number of SPSs */
628
629   data += 6;
630   for (i = 0; i < MAX_SPS_COUNT; i++) {
631     if ((nal = h264parse->params->sps_nals[i])) {
632       GST_WRITE_UINT16_BE (data, GST_BUFFER_SIZE (nal));
633       memcpy (data + 2, GST_BUFFER_DATA (nal), GST_BUFFER_SIZE (nal));
634       data += 2 + GST_BUFFER_SIZE (nal);
635     }
636   }
637
638   data[0] = num_pps;
639   data++;
640   for (i = 0; i < MAX_PPS_COUNT; i++) {
641     if ((nal = h264parse->params->pps_nals[i])) {
642       GST_WRITE_UINT16_BE (data, GST_BUFFER_SIZE (nal));
643       memcpy (data + 2, GST_BUFFER_DATA (nal), GST_BUFFER_SIZE (nal));
644       data += 2 + GST_BUFFER_SIZE (nal);
645     }
646   }
647
648   return buf;
649 }
650
651 static void
652 gst_h264_parse_update_src_caps (GstH264Parse * h264parse)
653 {
654   GstH264ParamsSPS *sps;
655   GstCaps *caps = NULL, *sink_caps;
656   gboolean modified = FALSE;
657   GstBuffer *buf = NULL;
658
659   if (G_UNLIKELY (!GST_PAD_CAPS (GST_BASE_PARSE_SRC_PAD (h264parse))))
660     modified = TRUE;
661   else if (G_UNLIKELY (!h264parse->update_caps))
662     return;
663
664   /* carry over input caps as much as possible; override with our own stuff */
665   sink_caps = GST_PAD_CAPS (GST_BASE_PARSE_SINK_PAD (h264parse));
666   if (sink_caps)
667     gst_caps_ref (sink_caps);
668   else
669     sink_caps = gst_caps_new_simple ("video/x-h264", NULL);
670
671   sps = h264parse->params->sps;
672   GST_DEBUG_OBJECT (h264parse, "sps: %p", sps);
673
674   /* only codec-data for nice-and-clean au aligned packetized avc format */
675   if (h264parse->format == GST_H264_PARSE_FORMAT_AVC &&
676       h264parse->align == GST_H264_PARSE_ALIGN_AU) {
677     buf = gst_h264_parse_make_codec_data (h264parse);
678     if (buf && h264parse->codec_data) {
679       if (GST_BUFFER_SIZE (buf) != GST_BUFFER_SIZE (h264parse->codec_data) ||
680           memcmp (GST_BUFFER_DATA (buf),
681               GST_BUFFER_DATA (h264parse->codec_data), GST_BUFFER_SIZE (buf)))
682         modified = TRUE;
683     } else {
684       if (h264parse->codec_data)
685         buf = gst_buffer_ref (h264parse->codec_data);
686       modified = TRUE;
687     }
688   }
689
690   if (G_UNLIKELY (!sps)) {
691     caps = gst_caps_copy (sink_caps);
692   } else if (G_UNLIKELY (h264parse->width != sps->width ||
693           h264parse->height != sps->height || h264parse->fps_num != sps->fps_num
694           || h264parse->fps_den != sps->fps_den || modified)) {
695     caps = gst_caps_copy (sink_caps);
696     /* sps should give this */
697     gst_caps_set_simple (caps, "width", G_TYPE_INT, sps->width,
698         "height", G_TYPE_INT, sps->height, NULL);
699     h264parse->height = sps->height;
700     h264parse->width = sps->width;
701     /* but not necessarily or reliably this */
702     if ((!h264parse->fps_num || !h264parse->fps_den) &&
703         sps->fps_num > 0 && sps->fps_den > 0) {
704       gst_caps_set_simple (caps, "framerate",
705           GST_TYPE_FRACTION, sps->fps_num, sps->fps_den, NULL);
706       h264parse->fps_num = sps->fps_num;
707       h264parse->fps_den = sps->fps_den;
708       gst_base_parse_set_frame_rate (GST_BASE_PARSE (h264parse),
709           h264parse->fps_num, h264parse->fps_den, 0, 0);
710     }
711   }
712
713   if (caps) {
714     gst_caps_set_simple (caps, "parsed", G_TYPE_BOOLEAN, TRUE,
715         "stream-format", G_TYPE_STRING,
716         gst_h264_parse_get_string (h264parse, TRUE, h264parse->format),
717         "alignment", G_TYPE_STRING,
718         gst_h264_parse_get_string (h264parse, FALSE, h264parse->align), NULL);
719     if (buf) {
720       gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buf, NULL);
721       gst_buffer_replace (&h264parse->codec_data, buf);
722       gst_buffer_unref (buf);
723       buf = NULL;
724     } else {
725       GstStructure *s;
726       /* remove any left-over codec-data hanging around */
727       s = gst_caps_get_structure (caps, 0);
728       gst_structure_remove_field (s, "codec_data");
729     }
730     gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (h264parse), caps);
731     gst_caps_unref (caps);
732   }
733
734   gst_caps_unref (sink_caps);
735   if (buf)
736     gst_buffer_unref (buf);
737 }
738
739 static GstFlowReturn
740 gst_h264_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
741 {
742   GstH264Parse *h264parse;
743   GstBuffer *buffer;
744   guint av;
745
746   h264parse = GST_H264_PARSE (parse);
747   buffer = frame->buffer;
748
749   gst_h264_parse_update_src_caps (h264parse);
750
751   gst_h264_params_get_timestamp (h264parse->params,
752       &GST_BUFFER_TIMESTAMP (buffer), &GST_BUFFER_DURATION (buffer),
753       h264parse->frame_start);
754
755   if (h264parse->keyframe)
756     GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
757   else
758     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
759
760   /* replace with transformed AVC output if applicable */
761   av = gst_adapter_available (h264parse->frame_out);
762   if (av) {
763     GstBuffer *buf;
764
765     buf = gst_adapter_take_buffer (h264parse->frame_out, av);
766     gst_buffer_copy_metadata (buf, buffer, GST_BUFFER_COPY_ALL);
767     gst_buffer_replace (&frame->buffer, buf);
768     gst_buffer_unref (buf);
769   }
770
771   return GST_FLOW_OK;
772 }
773
774 /* sends a codec NAL downstream, decorating and transforming as needed.
775  * No ownership is taken of @nal */
776 static GstFlowReturn
777 gst_h264_parse_push_codec_buffer (GstH264Parse * h264parse, GstBuffer * nal,
778     GstClockTime ts)
779 {
780   nal = gst_h264_parse_wrap_nal (h264parse, h264parse->format,
781       GST_BUFFER_DATA (nal), GST_BUFFER_SIZE (nal));
782
783   GST_BUFFER_TIMESTAMP (nal) = ts;
784   GST_BUFFER_DURATION (nal) = 0;
785
786   gst_buffer_set_caps (nal, GST_PAD_CAPS (GST_BASE_PARSE_SRC_PAD (h264parse)));
787
788   return gst_pad_push (GST_BASE_PARSE_SRC_PAD (h264parse), nal);
789 }
790
791 static GstFlowReturn
792 gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
793 {
794   GstH264Parse *h264parse;
795   GstBuffer *buffer;
796
797   h264parse = GST_H264_PARSE (parse);
798   buffer = frame->buffer;
799
800   /* periodic SPS/PPS sending */
801   if (h264parse->interval > 0 || h264parse->push_codec) {
802     GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer);
803     guint64 diff;
804
805     /* init */
806     if (!GST_CLOCK_TIME_IS_VALID (h264parse->last_report)) {
807       h264parse->last_report = timestamp;
808     }
809
810     if (h264parse->idr_pos >= 0) {
811       GST_LOG_OBJECT (h264parse, "IDR nal at offset %d", h264parse->idr_pos);
812
813       if (timestamp > h264parse->last_report)
814         diff = timestamp - h264parse->last_report;
815       else
816         diff = 0;
817
818       GST_LOG_OBJECT (h264parse,
819           "now %" GST_TIME_FORMAT ", last SPS/PPS %" GST_TIME_FORMAT,
820           GST_TIME_ARGS (timestamp), GST_TIME_ARGS (h264parse->last_report));
821
822       GST_DEBUG_OBJECT (h264parse,
823           "interval since last SPS/PPS %" GST_TIME_FORMAT,
824           GST_TIME_ARGS (diff));
825
826       if (GST_TIME_AS_SECONDS (diff) >= h264parse->interval ||
827           h264parse->push_codec) {
828         GstBuffer *codec_nal;
829         gint i;
830         GstClockTime new_ts;
831
832         /* avoid overwriting a perfectly fine timestamp */
833         new_ts = GST_CLOCK_TIME_IS_VALID (timestamp) ? timestamp :
834             h264parse->last_report;
835
836         if (h264parse->align == GST_H264_PARSE_ALIGN_NAL) {
837           /* send separate config NAL buffers */
838           GST_DEBUG_OBJECT (h264parse, "- sending SPS/PPS");
839           for (i = 0; i < MAX_SPS_COUNT; i++) {
840             if ((codec_nal = h264parse->params->sps_nals[i])) {
841               GST_DEBUG_OBJECT (h264parse, "sending SPS nal");
842               gst_h264_parse_push_codec_buffer (h264parse, codec_nal,
843                   timestamp);
844               h264parse->last_report = new_ts;
845             }
846           }
847           for (i = 0; i < MAX_PPS_COUNT; i++) {
848             if ((codec_nal = h264parse->params->pps_nals[i])) {
849               GST_DEBUG_OBJECT (h264parse, "sending PPS nal");
850               gst_h264_parse_push_codec_buffer (h264parse, codec_nal,
851                   timestamp);
852               h264parse->last_report = new_ts;
853             }
854           }
855         } else {
856           /* insert config NALs into AU */
857           GstByteWriter bw;
858           GstBuffer *new_buf;
859           const gboolean bs = h264parse->format == GST_H264_PARSE_FORMAT_BYTE;
860
861           gst_byte_writer_init_with_size (&bw, GST_BUFFER_SIZE (buffer), FALSE);
862           gst_byte_writer_put_data (&bw, GST_BUFFER_DATA (buffer),
863               h264parse->idr_pos);
864           GST_DEBUG_OBJECT (h264parse, "- inserting SPS/PPS");
865           for (i = 0; i < MAX_SPS_COUNT; i++) {
866             if ((codec_nal = h264parse->params->sps_nals[i])) {
867               GST_DEBUG_OBJECT (h264parse, "inserting SPS nal");
868               gst_byte_writer_put_uint32_be (&bw,
869                   bs ? 1 : GST_BUFFER_SIZE (codec_nal));
870               gst_byte_writer_put_data (&bw, GST_BUFFER_DATA (codec_nal),
871                   GST_BUFFER_SIZE (codec_nal));
872               h264parse->last_report = new_ts;
873             }
874           }
875           for (i = 0; i < MAX_PPS_COUNT; i++) {
876             if ((codec_nal = h264parse->params->pps_nals[i])) {
877               GST_DEBUG_OBJECT (h264parse, "inserting PPS nal");
878               gst_byte_writer_put_uint32_be (&bw,
879                   bs ? 1 : GST_BUFFER_SIZE (codec_nal));
880               gst_byte_writer_put_data (&bw, GST_BUFFER_DATA (codec_nal),
881                   GST_BUFFER_SIZE (codec_nal));
882               h264parse->last_report = new_ts;
883             }
884           }
885           gst_byte_writer_put_data (&bw,
886               GST_BUFFER_DATA (buffer) + h264parse->idr_pos,
887               GST_BUFFER_SIZE (buffer) - h264parse->idr_pos);
888           /* collect result and push */
889           new_buf = gst_byte_writer_reset_and_get_buffer (&bw);
890           gst_buffer_copy_metadata (new_buf, buffer, GST_BUFFER_COPY_ALL);
891           gst_buffer_replace (&frame->buffer, new_buf);
892           gst_buffer_unref (new_buf);
893         }
894       }
895       /* we pushed whatever we had */
896       h264parse->push_codec = FALSE;
897     }
898   }
899
900   gst_h264_parse_reset_frame (h264parse);
901
902   return GST_FLOW_OK;
903 }
904
905 static gboolean
906 gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps)
907 {
908   GstH264Parse *h264parse;
909   GstStructure *str;
910   const GValue *value;
911   GstBuffer *buffer = NULL;
912   guint size;
913
914   h264parse = GST_H264_PARSE (parse);
915
916   /* reset */
917   h264parse->push_codec = FALSE;
918
919   str = gst_caps_get_structure (caps, 0);
920
921   /* accept upstream info if provided */
922   gst_structure_get_int (str, "width", &h264parse->width);
923   gst_structure_get_int (str, "height", &h264parse->height);
924   gst_structure_get_fraction (str, "framerate", &h264parse->fps_num,
925       &h264parse->fps_den);
926
927   /* packetized video has a codec_data */
928   if ((value = gst_structure_get_value (str, "codec_data"))) {
929     guint8 *data;
930     guint num_sps, num_pps, profile, len;
931     gint i;
932
933     GST_DEBUG_OBJECT (h264parse, "have packetized h264");
934     /* make note for optional split processing */
935     h264parse->packetized = TRUE;
936
937     buffer = gst_value_get_buffer (value);
938     if (!buffer)
939       goto wrong_type;
940     data = GST_BUFFER_DATA (buffer);
941     size = GST_BUFFER_SIZE (buffer);
942
943     /* parse the avcC data */
944     if (size < 7)
945       goto avcc_too_small;
946     /* parse the version, this must be 1 */
947     if (data[0] != 1)
948       goto wrong_version;
949
950     /* AVCProfileIndication */
951     /* profile_compat */
952     /* AVCLevelIndication */
953     profile = (data[1] << 16) | (data[2] << 8) | data[3];
954     GST_DEBUG_OBJECT (h264parse, "profile %06x", profile);
955
956     /* 6 bits reserved | 2 bits lengthSizeMinusOne */
957     /* this is the number of bytes in front of the NAL units to mark their
958      * length */
959     h264parse->nal_length_size = (data[4] & 0x03) + 1;
960     GST_DEBUG_OBJECT (h264parse, "nal length %u", h264parse->nal_length_size);
961
962     num_sps = data[5] & 0x1f;
963     data += 6;
964     size -= 6;
965     for (i = 0; i < num_sps; i++) {
966       len = GST_READ_UINT16_BE (data);
967       if (size < len + 2 || len < 2)
968         goto avcc_too_small;
969       /* digest for later reference */
970       gst_h264_parse_process_nal (h264parse, data, 0, 2, len);
971       data += len + 2;
972       size -= len + 2;
973     }
974     num_pps = data[0];
975     data++;
976     size++;
977     for (i = 0; i < num_pps; i++) {
978       len = GST_READ_UINT16_BE (data);
979       if (size < len + 2 || len < 2)
980         goto avcc_too_small;
981       /* digest for later reference */
982       gst_h264_parse_process_nal (h264parse, data, 0, 2, len);
983       data += len + 2;
984       size -= len + 2;
985     }
986   } else {
987     GST_DEBUG_OBJECT (h264parse, "have bytestream h264");
988     /* nothing to pre-process */
989     h264parse->packetized = FALSE;
990     /* we have 4 sync bytes */
991     h264parse->nal_length_size = 4;
992   }
993
994   if (h264parse->packetized) {
995     if (h264parse->split_packetized) {
996       GST_DEBUG_OBJECT (h264parse,
997           "converting AVC to nal bytestream prior to parsing");
998       /* negotiate behaviour with upstream */
999       gst_h264_parse_negotiate (h264parse);
1000       if (h264parse->format == GST_H264_PARSE_FORMAT_BYTE) {
1001         /* arrange to insert codec-data in-stream if needed */
1002         h264parse->push_codec = h264parse->packetized;
1003       }
1004       gst_base_parse_set_passthrough (parse, FALSE);
1005     } else {
1006       GST_DEBUG_OBJECT (h264parse, "passing on packetized AVC");
1007       /* no choice to negotiate */
1008       h264parse->format = GST_H264_PARSE_FORMAT_AVC;
1009       h264parse->align = GST_H264_PARSE_ALIGN_AU;
1010       /* fallback codec-data */
1011       h264parse->codec_data = gst_buffer_ref (buffer);
1012       /* pass through unharmed, though _chain will parse a bit */
1013       gst_base_parse_set_passthrough (parse, TRUE);
1014       /* we did parse codec-data and might supplement src caps */
1015       gst_h264_parse_update_src_caps (h264parse);
1016     }
1017   }
1018
1019   /* src caps are only arranged for later on */
1020   return TRUE;
1021
1022   /* ERRORS */
1023 avcc_too_small:
1024   {
1025     GST_DEBUG_OBJECT (h264parse, "avcC size %u < 7", size);
1026     goto refuse_caps;
1027   }
1028 wrong_version:
1029   {
1030     GST_DEBUG_OBJECT (h264parse, "wrong avcC version");
1031     goto refuse_caps;
1032   }
1033 wrong_type:
1034   {
1035     GST_DEBUG_OBJECT (h264parse, "wrong codec-data type");
1036     goto refuse_caps;
1037   }
1038 refuse_caps:
1039   {
1040     GST_WARNING_OBJECT (h264parse, "refused caps %" GST_PTR_FORMAT, caps);
1041     return FALSE;
1042   }
1043 }
1044
1045 static GstFlowReturn
1046 gst_h264_parse_chain (GstPad * pad, GstBuffer * buffer)
1047 {
1048   GstH264Parse *h264parse = GST_H264_PARSE (GST_PAD_PARENT (pad));
1049
1050   if (h264parse->packetized && buffer) {
1051     GstByteReader br;
1052     GstBuffer *sub;
1053     GstFlowReturn ret = GST_FLOW_OK;
1054     guint32 len;
1055     const guint nl = h264parse->nal_length_size;
1056
1057     GST_LOG_OBJECT (h264parse, "processing packet buffer of size %d",
1058         GST_BUFFER_SIZE (buffer));
1059     gst_byte_reader_init_from_buffer (&br, buffer);
1060     while (ret == GST_FLOW_OK && gst_byte_reader_get_remaining (&br)) {
1061       GST_DEBUG_OBJECT (h264parse, "AVC nal offset %d",
1062           gst_byte_reader_get_pos (&br));
1063       if (gst_byte_reader_get_remaining (&br) < nl)
1064         goto parse_failed;
1065       switch (nl) {
1066         case 4:
1067           len = gst_byte_reader_get_uint32_be_unchecked (&br);
1068           break;
1069         case 3:
1070           len = gst_byte_reader_get_uint24_be_unchecked (&br);
1071           break;
1072         case 2:
1073           len = gst_byte_reader_get_uint16_be_unchecked (&br);
1074           break;
1075         case 1:
1076           len = gst_byte_reader_get_uint8_unchecked (&br);
1077           break;
1078         default:
1079           goto not_negotiated;
1080           break;
1081       }
1082       GST_DEBUG_OBJECT (h264parse, "AVC nal size %d", len);
1083       if (gst_byte_reader_get_remaining (&br) < len)
1084         goto parse_failed;
1085       if (h264parse->split_packetized) {
1086         /* convert to NAL aligned byte stream input */
1087         sub = gst_h264_parse_wrap_nal (h264parse, GST_H264_PARSE_FORMAT_BYTE,
1088             (guint8 *) gst_byte_reader_get_data_unchecked (&br, len), len);
1089         /* at least this should make sense */
1090         GST_BUFFER_TIMESTAMP (sub) = GST_BUFFER_TIMESTAMP (buffer);
1091         GST_LOG_OBJECT (h264parse, "pushing NAL of size %d", len);
1092         ret = h264parse->parse_chain (pad, sub);
1093       } else {
1094         /* pass-through: no looking for frames (and nal processing),
1095          * so need to parse to collect data here */
1096         /* NOTE: so if it is really configured to do so,
1097          * pre_push can/will still insert codec-data at intervals,
1098          * which is not really pure pass-through, but anyway ... */
1099         gst_h264_parse_process_nal (h264parse,
1100             GST_BUFFER_DATA (buffer), gst_byte_reader_get_pos (&br) - nl,
1101             gst_byte_reader_get_pos (&br), len);
1102         gst_byte_reader_skip_unchecked (&br, len);
1103       }
1104     }
1105     if (h264parse->split_packetized)
1106       return ret;
1107   }
1108
1109 exit:
1110   /* nal processing in pass-through might have collected stuff;
1111    * ensure nothing happens with this later on */
1112   gst_adapter_clear (h264parse->frame_out);
1113
1114   return h264parse->parse_chain (pad, buffer);
1115
1116   /* ERRORS */
1117 not_negotiated:
1118   {
1119     GST_DEBUG_OBJECT (h264parse, "insufficient data to split input");
1120     return GST_FLOW_NOT_NEGOTIATED;
1121   }
1122 parse_failed:
1123   {
1124     if (h264parse->split_packetized) {
1125       GST_ELEMENT_ERROR (h264parse, STREAM, FAILED, (NULL),
1126           ("invalid AVC input data"));
1127       return GST_FLOW_ERROR;
1128     } else {
1129       /* do not meddle to much in this case */
1130       GST_DEBUG_OBJECT (h264parse, "parsing packet failed");
1131       goto exit;
1132     }
1133   }
1134 }
1135
1136 static void
1137 gst_h264_parse_set_property (GObject * object, guint prop_id,
1138     const GValue * value, GParamSpec * pspec)
1139 {
1140   GstH264Parse *parse;
1141
1142   parse = GST_H264_PARSE (object);
1143
1144   switch (prop_id) {
1145     case PROP_SPLIT_PACKETIZED:
1146       parse->split_packetized = g_value_get_boolean (value);
1147       break;
1148     case PROP_CONFIG_INTERVAL:
1149       parse->interval = g_value_get_uint (value);
1150       break;
1151     default:
1152       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1153       break;
1154   }
1155 }
1156
1157 static void
1158 gst_h264_parse_get_property (GObject * object, guint prop_id, GValue * value,
1159     GParamSpec * pspec)
1160 {
1161   GstH264Parse *parse;
1162
1163   parse = GST_H264_PARSE (object);
1164
1165   switch (prop_id) {
1166     case PROP_SPLIT_PACKETIZED:
1167       g_value_set_boolean (value, parse->split_packetized);
1168       break;
1169     case PROP_CONFIG_INTERVAL:
1170       g_value_set_uint (value, parse->interval);
1171       break;
1172     default:
1173       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1174       break;
1175   }
1176 }