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