baseparse: Forward SEGMENT_DONE events immediately
[platform/upstream/gstreamer.git] / libs / gst / base / gstbaseparse.c
1 /* GStreamer
2  * Copyright (C) 2008 Nokia Corporation. All rights reserved.
3  *   Contact: Stefan Kost <stefan.kost@nokia.com>
4  * Copyright (C) 2008 Sebastian Dröge <sebastian.droege@collabora.co.uk>.
5  * Copyright (C) 2011, Hewlett-Packard Development Company, L.P.
6  *   Author: Sebastian Dröge <sebastian.droege@collabora.co.uk>, Collabora Ltd.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23
24 /**
25  * SECTION:gstbaseparse
26  * @short_description: Base class for stream parsers
27  * @see_also: #GstBaseTransform
28  *
29  * This base class is for parser elements that process data and splits it
30  * into separate audio/video/whatever frames.
31  *
32  * It provides for:
33  * <itemizedlist>
34  *   <listitem><para>provides one sink pad and one source pad</para></listitem>
35  *   <listitem><para>handles state changes</para></listitem>
36  *   <listitem><para>can operate in pull mode or push mode</para></listitem>
37  *   <listitem><para>handles seeking in both modes</para></listitem>
38  *   <listitem><para>handles events (SEGMENT/EOS/FLUSH)</para></listitem>
39  *   <listitem><para>
40  *        handles queries (POSITION/DURATION/SEEKING/FORMAT/CONVERT)
41  *   </para></listitem>
42  *   <listitem><para>handles flushing</para></listitem>
43  * </itemizedlist>
44  *
45  * The purpose of this base class is to provide the basic functionality of
46  * a parser and share a lot of rather complex code.
47  *
48  * Description of the parsing mechanism:
49  * <orderedlist>
50  * <listitem>
51  *   <itemizedlist><title>Set-up phase</title>
52  *   <listitem><para>
53  *     #GstBaseParse calls @start to inform subclass that data processing is
54  *     about to start now.
55  *   </para></listitem>
56  *   <listitem><para>
57  *     #GstBaseParse class calls @set_sink_caps to inform the subclass about
58  *     incoming sinkpad caps. Subclass could already set the srcpad caps
59  *     accordingly, but this might be delayed until calling
60  *     gst_base_parse_finish_frame() with a non-queued frame.
61  *   </para></listitem>
62  *   <listitem><para>
63  *      At least at this point subclass needs to tell the #GstBaseParse class
64  *      how big data chunks it wants to receive (min_frame_size). It can do
65  *      this with gst_base_parse_set_min_frame_size().
66  *   </para></listitem>
67  *   <listitem><para>
68  *      #GstBaseParse class sets up appropriate data passing mode (pull/push)
69  *      and starts to process the data.
70  *   </para></listitem>
71  *   </itemizedlist>
72  * </listitem>
73  * <listitem>
74  *   <itemizedlist>
75  *   <title>Parsing phase</title>
76  *     <listitem><para>
77  *       #GstBaseParse gathers at least min_frame_size bytes of data either
78  *       by pulling it from upstream or collecting buffers in an internal
79  *       #GstAdapter.
80  *     </para></listitem>
81  *     <listitem><para>
82  *       A buffer of (at least) min_frame_size bytes is passed to subclass with
83  *       @handle_frame. Subclass checks the contents and can optionally
84  *       return GST_FLOW_OK along with an amount of data to be skipped to find
85  *       a valid frame (which will result in a subsequent DISCONT).
86  *       If, otherwise, the buffer does not hold a complete frame,
87  *       @handle_frame can merely return and will be called again when additional
88  *       data is available.  In push mode this amounts to an
89  *       additional input buffer (thus minimal additional latency), in pull mode
90  *       this amounts to some arbitrary reasonable buffer size increase.
91  *       Of course, gst_base_parse_set_min_frame_size() could also be used if a
92  *       very specific known amount of additional data is required.
93  *       If, however, the buffer holds a complete valid frame, it can pass
94  *       the size of this frame to gst_base_parse_finish_frame().
95  *       If acting as a converter, it can also merely indicate consumed input data
96  *       while simultaneously providing custom output data.
97  *       Note that baseclass performs some processing (such as tracking
98  *       overall consumed data rate versus duration) for each finished frame,
99  *       but other state is only updated upon each call to @handle_frame
100  *       (such as tracking upstream input timestamp).
101  *       </para><para>
102  *       Subclass is also responsible for setting the buffer metadata
103  *       (e.g. buffer timestamp and duration, or keyframe if applicable).
104  *       (although the latter can also be done by #GstBaseParse if it is
105  *       appropriately configured, see below).  Frame is provided with
106  *       timestamp derived from upstream (as much as generally possible),
107  *       duration obtained from configuration (see below), and offset
108  *       if meaningful (in pull mode).
109  *       </para><para>
110  *       Note that @check_valid_frame might receive any small
111  *       amount of input data when leftover data is being drained (e.g. at EOS).
112  *     </para></listitem>
113  *     <listitem><para>
114  *       As part of finish frame processing,
115  *       just prior to actually pushing the buffer in question,
116  *       it is passed to @pre_push_frame which gives subclass yet one
117  *       last chance to examine buffer metadata, or to send some custom (tag)
118  *       events, or to perform custom (segment) filtering.
119  *     </para></listitem>
120  *     <listitem><para>
121  *       During the parsing process #GstBaseParseClass will handle both srcpad
122  *       and sinkpad events. They will be passed to subclass if @event or
123  *       @src_event callbacks have been provided.
124  *     </para></listitem>
125  *   </itemizedlist>
126  * </listitem>
127  * <listitem>
128  *   <itemizedlist><title>Shutdown phase</title>
129  *   <listitem><para>
130  *     #GstBaseParse class calls @stop to inform the subclass that data
131  *     parsing will be stopped.
132  *   </para></listitem>
133  *   </itemizedlist>
134  * </listitem>
135  * </orderedlist>
136  *
137  * Subclass is responsible for providing pad template caps for
138  * source and sink pads. The pads need to be named "sink" and "src". It also
139  * needs to set the fixed caps on srcpad, when the format is ensured (e.g.
140  * when base class calls subclass' @set_sink_caps function).
141  *
142  * This base class uses %GST_FORMAT_DEFAULT as a meaning of frames. So,
143  * subclass conversion routine needs to know that conversion from
144  * %GST_FORMAT_TIME to %GST_FORMAT_DEFAULT must return the
145  * frame number that can be found from the given byte position.
146  *
147  * #GstBaseParse uses subclasses conversion methods also for seeking (or
148  * otherwise uses its own default one, see also below).
149  *
150  * Subclass @start and @stop functions will be called to inform the beginning
151  * and end of data processing.
152  *
153  * Things that subclass need to take care of:
154  * <itemizedlist>
155  *   <listitem><para>Provide pad templates</para></listitem>
156  *   <listitem><para>
157  *      Fixate the source pad caps when appropriate
158  *   </para></listitem>
159  *   <listitem><para>
160  *      Inform base class how big data chunks should be retrieved. This is
161  *      done with gst_base_parse_set_min_frame_size() function.
162  *   </para></listitem>
163  *   <listitem><para>
164  *      Examine data chunks passed to subclass with @handle_frame and pass
165  *      proper frame(s) to gst_base_parse_finish_frame(), and setting src pad
166  *      caps and timestamps on frame.
167  *   </para></listitem>
168  *   <listitem><para>Provide conversion functions</para></listitem>
169  *   <listitem><para>
170  *      Update the duration information with gst_base_parse_set_duration()
171  *   </para></listitem>
172  *   <listitem><para>
173  *      Optionally passthrough using gst_base_parse_set_passthrough()
174  *   </para></listitem>
175  *   <listitem><para>
176  *      Configure various baseparse parameters using
177  *      gst_base_parse_set_average_bitrate(), gst_base_parse_set_syncable()
178  *      and gst_base_parse_set_frame_rate().
179  *   </para></listitem>
180  *   <listitem><para>
181  *      In particular, if subclass is unable to determine a duration, but
182  *      parsing (or specs) yields a frames per seconds rate, then this can be
183  *      provided to #GstBaseParse to enable it to cater for
184  *      buffer time metadata (which will be taken from upstream as much as
185  *      possible). Internally keeping track of frame durations and respective
186  *      sizes that have been pushed provides #GstBaseParse with an estimated
187  *      bitrate. A default @convert (used if not overridden) will then use these
188  *      rates to perform obvious conversions.  These rates are also used to
189  *      update (estimated) duration at regular frame intervals.
190  *   </para></listitem>
191  * </itemizedlist>
192  *
193  */
194
195 /* TODO:
196  *  - In push mode provide a queue of adapter-"queued" buffers for upstream
197  *    buffer metadata
198  *  - Queue buffers/events until caps are set
199  */
200
201 #ifdef HAVE_CONFIG_H
202 #  include "config.h"
203 #endif
204
205 #include <stdlib.h>
206 #include <string.h>
207
208 #include <gst/base/gstadapter.h>
209
210 #include "gstbaseparse.h"
211
212 /* FIXME: get rid of old GstIndex code */
213 #include "gstindex.h"
214 #include "gstindex.c"
215 #include "gstmemindex.c"
216
217 #define GST_BASE_PARSE_FRAME_PRIVATE_FLAG_NOALLOC  (1 << 0)
218
219 #define MIN_FRAMES_TO_POST_BITRATE 10
220 #define TARGET_DIFFERENCE          (20 * GST_SECOND)
221 #define MAX_INDEX_ENTRIES          4096
222
223 GST_DEBUG_CATEGORY_STATIC (gst_base_parse_debug);
224 #define GST_CAT_DEFAULT gst_base_parse_debug
225
226 /* Supported formats */
227 static const GstFormat fmtlist[] = {
228   GST_FORMAT_DEFAULT,
229   GST_FORMAT_BYTES,
230   GST_FORMAT_TIME,
231   GST_FORMAT_UNDEFINED
232 };
233
234 #define GST_BASE_PARSE_GET_PRIVATE(obj)  \
235     (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_BASE_PARSE, GstBaseParsePrivate))
236
237 struct _GstBaseParsePrivate
238 {
239   GstPadMode pad_mode;
240
241   GstAdapter *adapter;
242
243   gint64 duration;
244   GstFormat duration_fmt;
245   gint64 estimated_duration;
246   gint64 estimated_drift;
247
248   guint min_frame_size;
249   gboolean disable_passthrough;
250   gboolean passthrough;
251   gboolean pts_interpolate;
252   gboolean infer_ts;
253   gboolean syncable;
254   gboolean has_timing_info;
255   guint fps_num, fps_den;
256   gint update_interval;
257   guint bitrate;
258   guint lead_in, lead_out;
259   GstClockTime lead_in_ts, lead_out_ts;
260   GstClockTime min_latency, max_latency;
261
262   gboolean discont;
263   gboolean flushing;
264   gboolean drain;
265   gboolean saw_gaps;
266
267   gint64 offset;
268   gint64 sync_offset;
269   GstClockTime next_pts;
270   GstClockTime next_dts;
271   GstClockTime prev_pts;
272   GstClockTime prev_dts;
273   GstClockTime frame_duration;
274   gboolean seen_keyframe;
275   gboolean is_video;
276   gint flushed;
277
278   guint64 framecount;
279   guint64 bytecount;
280   guint64 data_bytecount;
281   guint64 acc_duration;
282   GstClockTime first_frame_pts;
283   GstClockTime first_frame_dts;
284   gint64 first_frame_offset;
285
286   gboolean post_min_bitrate;
287   gboolean post_avg_bitrate;
288   gboolean post_max_bitrate;
289   guint min_bitrate;
290   guint avg_bitrate;
291   guint max_bitrate;
292   guint posted_avg_bitrate;
293
294   /* frames/buffers that are queued and ready to go on OK */
295   GQueue queued_frames;
296
297   GstBuffer *cache;
298
299   /* index entry storage, either ours or provided */
300   GstIndex *index;
301   gint index_id;
302   gboolean own_index;
303   GMutex index_lock;
304
305   /* seek table entries only maintained if upstream is BYTE seekable */
306   gboolean upstream_seekable;
307   gboolean upstream_has_duration;
308   gint64 upstream_size;
309   GstFormat upstream_format;
310   /* minimum distance between two index entries */
311   GstClockTimeDiff idx_interval;
312   guint64 idx_byte_interval;
313   /* ts and offset of last entry added */
314   GstClockTime index_last_ts;
315   gint64 index_last_offset;
316   gboolean index_last_valid;
317
318   /* timestamps currently produced are accurate, e.g. started from 0 onwards */
319   gboolean exact_position;
320   /* seek events are temporarily kept to match them with newsegments */
321   GSList *pending_seeks;
322
323   /* reverse playback */
324   GSList *buffers_pending;
325   GSList *buffers_head;
326   GSList *buffers_queued;
327   GSList *buffers_send;
328   GstClockTime last_pts;
329   GstClockTime last_dts;
330   gint64 last_offset;
331
332   /* Pending serialized events */
333   GList *pending_events;
334
335   /* If baseparse has checked the caps to identify if it is
336    * handling video or audio */
337   gboolean checked_media;
338
339   /* offset of last parsed frame/data */
340   gint64 prev_offset;
341   /* force a new frame, regardless of offset */
342   gboolean new_frame;
343   /* whether we are merely scanning for a frame */
344   gboolean scanning;
345   /* ... and resulting frame, if any */
346   GstBaseParseFrame *scanned_frame;
347
348   /* TRUE if we're still detecting the format, i.e.
349    * if ::detect() is still called for future buffers */
350   gboolean detecting;
351   GList *detect_buffers;
352   guint detect_buffers_size;
353
354   /* True when no buffers have been received yet */
355   gboolean first_buffer;
356
357   /* if TRUE, a STREAM_START event needs to be pushed */
358   gboolean push_stream_start;
359
360   /* When we need to skip more data than we have currently */
361   guint skip;
362 };
363
364 typedef struct _GstBaseParseSeek
365 {
366   GstSegment segment;
367   gboolean accurate;
368   gint64 offset;
369   GstClockTime start_ts;
370 } GstBaseParseSeek;
371
372 #define DEFAULT_DISABLE_PASSTHROUGH        FALSE
373
374 enum
375 {
376   PROP_0,
377   PROP_DISABLE_PASSTHROUGH,
378   PROP_LAST
379 };
380
381 #define GST_BASE_PARSE_INDEX_LOCK(parse) \
382   g_mutex_lock (&parse->priv->index_lock);
383 #define GST_BASE_PARSE_INDEX_UNLOCK(parse) \
384   g_mutex_unlock (&parse->priv->index_lock);
385
386 static GstElementClass *parent_class = NULL;
387
388 static void gst_base_parse_class_init (GstBaseParseClass * klass);
389 static void gst_base_parse_init (GstBaseParse * parse,
390     GstBaseParseClass * klass);
391
392 GType
393 gst_base_parse_get_type (void)
394 {
395   static volatile gsize base_parse_type = 0;
396
397   if (g_once_init_enter (&base_parse_type)) {
398     static const GTypeInfo base_parse_info = {
399       sizeof (GstBaseParseClass),
400       (GBaseInitFunc) NULL,
401       (GBaseFinalizeFunc) NULL,
402       (GClassInitFunc) gst_base_parse_class_init,
403       NULL,
404       NULL,
405       sizeof (GstBaseParse),
406       0,
407       (GInstanceInitFunc) gst_base_parse_init,
408     };
409     GType _type;
410
411     _type = g_type_register_static (GST_TYPE_ELEMENT,
412         "GstBaseParse", &base_parse_info, G_TYPE_FLAG_ABSTRACT);
413     g_once_init_leave (&base_parse_type, _type);
414   }
415   return (GType) base_parse_type;
416 }
417
418 static void gst_base_parse_finalize (GObject * object);
419
420 static GstStateChangeReturn gst_base_parse_change_state (GstElement * element,
421     GstStateChange transition);
422 static void gst_base_parse_reset (GstBaseParse * parse);
423
424 #if 0
425 static void gst_base_parse_set_index (GstElement * element, GstIndex * index);
426 static GstIndex *gst_base_parse_get_index (GstElement * element);
427 #endif
428
429 static gboolean gst_base_parse_sink_activate (GstPad * sinkpad,
430     GstObject * parent);
431 static gboolean gst_base_parse_sink_activate_mode (GstPad * pad,
432     GstObject * parent, GstPadMode mode, gboolean active);
433 static gboolean gst_base_parse_handle_seek (GstBaseParse * parse,
434     GstEvent * event);
435 static void gst_base_parse_handle_tag (GstBaseParse * parse, GstEvent * event);
436
437 static void gst_base_parse_set_property (GObject * object, guint prop_id,
438     const GValue * value, GParamSpec * pspec);
439 static void gst_base_parse_get_property (GObject * object, guint prop_id,
440     GValue * value, GParamSpec * pspec);
441
442 static gboolean gst_base_parse_src_event (GstPad * pad, GstObject * parent,
443     GstEvent * event);
444 static gboolean gst_base_parse_src_query (GstPad * pad, GstObject * parent,
445     GstQuery * query);
446
447 static gboolean gst_base_parse_sink_event (GstPad * pad, GstObject * parent,
448     GstEvent * event);
449 static gboolean gst_base_parse_sink_query (GstPad * pad, GstObject * parent,
450     GstQuery * query);
451
452 static GstFlowReturn gst_base_parse_chain (GstPad * pad, GstObject * parent,
453     GstBuffer * buffer);
454 static void gst_base_parse_loop (GstPad * pad);
455
456 static GstFlowReturn gst_base_parse_parse_frame (GstBaseParse * parse,
457     GstBaseParseFrame * frame);
458
459 static gboolean gst_base_parse_sink_event_default (GstBaseParse * parse,
460     GstEvent * event);
461
462 static gboolean gst_base_parse_src_event_default (GstBaseParse * parse,
463     GstEvent * event);
464
465 static gboolean gst_base_parse_sink_query_default (GstBaseParse * parse,
466     GstQuery * query);
467 static gboolean gst_base_parse_src_query_default (GstBaseParse * parse,
468     GstQuery * query);
469
470 static void gst_base_parse_drain (GstBaseParse * parse);
471
472 static void gst_base_parse_post_bitrates (GstBaseParse * parse,
473     gboolean post_min, gboolean post_avg, gboolean post_max);
474
475 static gint64 gst_base_parse_find_offset (GstBaseParse * parse,
476     GstClockTime time, gboolean before, GstClockTime * _ts);
477 static GstFlowReturn gst_base_parse_locate_time (GstBaseParse * parse,
478     GstClockTime * _time, gint64 * _offset);
479
480 static GstFlowReturn gst_base_parse_start_fragment (GstBaseParse * parse);
481 static GstFlowReturn gst_base_parse_finish_fragment (GstBaseParse * parse,
482     gboolean prev_head);
483 static GstFlowReturn gst_base_parse_send_buffers (GstBaseParse * parse);
484
485 static inline GstFlowReturn gst_base_parse_check_sync (GstBaseParse * parse);
486
487 static gboolean gst_base_parse_is_seekable (GstBaseParse * parse);
488
489 static void gst_base_parse_push_pending_events (GstBaseParse * parse);
490
491 static void
492 gst_base_parse_clear_queues (GstBaseParse * parse)
493 {
494   g_slist_foreach (parse->priv->buffers_queued, (GFunc) gst_buffer_unref, NULL);
495   g_slist_free (parse->priv->buffers_queued);
496   parse->priv->buffers_queued = NULL;
497   g_slist_foreach (parse->priv->buffers_pending, (GFunc) gst_buffer_unref,
498       NULL);
499   g_slist_free (parse->priv->buffers_pending);
500   parse->priv->buffers_pending = NULL;
501   g_slist_foreach (parse->priv->buffers_head, (GFunc) gst_buffer_unref, NULL);
502   g_slist_free (parse->priv->buffers_head);
503   parse->priv->buffers_head = NULL;
504   g_slist_foreach (parse->priv->buffers_send, (GFunc) gst_buffer_unref, NULL);
505   g_slist_free (parse->priv->buffers_send);
506   parse->priv->buffers_send = NULL;
507
508   g_list_foreach (parse->priv->detect_buffers, (GFunc) gst_buffer_unref, NULL);
509   g_list_free (parse->priv->detect_buffers);
510   parse->priv->detect_buffers = NULL;
511   parse->priv->detect_buffers_size = 0;
512
513   g_queue_foreach (&parse->priv->queued_frames,
514       (GFunc) gst_base_parse_frame_free, NULL);
515   g_queue_clear (&parse->priv->queued_frames);
516
517   gst_buffer_replace (&parse->priv->cache, NULL);
518
519   g_list_foreach (parse->priv->pending_events, (GFunc) gst_event_unref, NULL);
520   g_list_free (parse->priv->pending_events);
521   parse->priv->pending_events = NULL;
522
523   parse->priv->checked_media = FALSE;
524 }
525
526 static void
527 gst_base_parse_finalize (GObject * object)
528 {
529   GstBaseParse *parse = GST_BASE_PARSE (object);
530
531   g_object_unref (parse->priv->adapter);
532
533   if (parse->priv->index) {
534     gst_object_unref (parse->priv->index);
535     parse->priv->index = NULL;
536   }
537   g_mutex_clear (&parse->priv->index_lock);
538
539   gst_base_parse_clear_queues (parse);
540
541   G_OBJECT_CLASS (parent_class)->finalize (object);
542 }
543
544 static void
545 gst_base_parse_class_init (GstBaseParseClass * klass)
546 {
547   GObjectClass *gobject_class;
548   GstElementClass *gstelement_class;
549
550   gobject_class = G_OBJECT_CLASS (klass);
551   g_type_class_add_private (klass, sizeof (GstBaseParsePrivate));
552   parent_class = g_type_class_peek_parent (klass);
553
554   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_base_parse_finalize);
555   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_base_parse_set_property);
556   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_base_parse_get_property);
557
558   /**
559    * GstBaseParse:disable-passthrough:
560    *
561    * If set to %TRUE, baseparse will unconditionally force parsing of the
562    * incoming data. This can be required in the rare cases where the incoming
563    * side-data (caps, pts, dts, ...) is not trusted by the user and wants to
564    * force validation and parsing of the incoming data.
565    * If set to %FALSE, decision of whether to parse the data or not is up to
566    * the implementation (standard behaviour).
567    */
568   g_object_class_install_property (gobject_class, PROP_DISABLE_PASSTHROUGH,
569       g_param_spec_boolean ("disable-passthrough", "Disable passthrough",
570           "Force processing (disables passthrough)",
571           DEFAULT_DISABLE_PASSTHROUGH,
572           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
573
574   gstelement_class = (GstElementClass *) klass;
575   gstelement_class->change_state =
576       GST_DEBUG_FUNCPTR (gst_base_parse_change_state);
577
578 #if 0
579   gstelement_class->set_index = GST_DEBUG_FUNCPTR (gst_base_parse_set_index);
580   gstelement_class->get_index = GST_DEBUG_FUNCPTR (gst_base_parse_get_index);
581 #endif
582
583   /* Default handlers */
584   klass->sink_event = gst_base_parse_sink_event_default;
585   klass->src_event = gst_base_parse_src_event_default;
586   klass->sink_query = gst_base_parse_sink_query_default;
587   klass->src_query = gst_base_parse_src_query_default;
588   klass->convert = gst_base_parse_convert_default;
589
590   GST_DEBUG_CATEGORY_INIT (gst_base_parse_debug, "baseparse", 0,
591       "baseparse element");
592 }
593
594 static void
595 gst_base_parse_init (GstBaseParse * parse, GstBaseParseClass * bclass)
596 {
597   GstPadTemplate *pad_template;
598
599   GST_DEBUG_OBJECT (parse, "gst_base_parse_init");
600
601   parse->priv = GST_BASE_PARSE_GET_PRIVATE (parse);
602
603   pad_template =
604       gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "sink");
605   g_return_if_fail (pad_template != NULL);
606   parse->sinkpad = gst_pad_new_from_template (pad_template, "sink");
607   gst_pad_set_event_function (parse->sinkpad,
608       GST_DEBUG_FUNCPTR (gst_base_parse_sink_event));
609   gst_pad_set_query_function (parse->sinkpad,
610       GST_DEBUG_FUNCPTR (gst_base_parse_sink_query));
611   gst_pad_set_chain_function (parse->sinkpad,
612       GST_DEBUG_FUNCPTR (gst_base_parse_chain));
613   gst_pad_set_activate_function (parse->sinkpad,
614       GST_DEBUG_FUNCPTR (gst_base_parse_sink_activate));
615   gst_pad_set_activatemode_function (parse->sinkpad,
616       GST_DEBUG_FUNCPTR (gst_base_parse_sink_activate_mode));
617   GST_PAD_SET_PROXY_ALLOCATION (parse->sinkpad);
618   gst_element_add_pad (GST_ELEMENT (parse), parse->sinkpad);
619
620   GST_DEBUG_OBJECT (parse, "sinkpad created");
621
622   pad_template =
623       gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "src");
624   g_return_if_fail (pad_template != NULL);
625   parse->srcpad = gst_pad_new_from_template (pad_template, "src");
626   gst_pad_set_event_function (parse->srcpad,
627       GST_DEBUG_FUNCPTR (gst_base_parse_src_event));
628   gst_pad_set_query_function (parse->srcpad,
629       GST_DEBUG_FUNCPTR (gst_base_parse_src_query));
630   gst_pad_use_fixed_caps (parse->srcpad);
631   gst_element_add_pad (GST_ELEMENT (parse), parse->srcpad);
632   GST_DEBUG_OBJECT (parse, "src created");
633
634   g_queue_init (&parse->priv->queued_frames);
635
636   parse->priv->adapter = gst_adapter_new ();
637
638   parse->priv->pad_mode = GST_PAD_MODE_NONE;
639
640   g_mutex_init (&parse->priv->index_lock);
641
642   /* init state */
643   gst_base_parse_reset (parse);
644   GST_DEBUG_OBJECT (parse, "init ok");
645
646   GST_OBJECT_FLAG_SET (parse, GST_ELEMENT_FLAG_INDEXABLE);
647 }
648
649 static void
650 gst_base_parse_set_property (GObject * object, guint prop_id,
651     const GValue * value, GParamSpec * pspec)
652 {
653   GstBaseParse *parse = GST_BASE_PARSE (object);
654
655   switch (prop_id) {
656     case PROP_DISABLE_PASSTHROUGH:
657       parse->priv->disable_passthrough = g_value_get_boolean (value);
658       break;
659     default:
660       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
661       break;
662   }
663 }
664
665 static void
666 gst_base_parse_get_property (GObject * object, guint prop_id, GValue * value,
667     GParamSpec * pspec)
668 {
669   GstBaseParse *parse = GST_BASE_PARSE (object);
670
671   switch (prop_id) {
672     case PROP_DISABLE_PASSTHROUGH:
673       g_value_set_boolean (value, parse->priv->disable_passthrough);
674       break;
675     default:
676       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
677       break;
678   }
679 }
680
681 static GstBaseParseFrame *
682 gst_base_parse_frame_copy (GstBaseParseFrame * frame)
683 {
684   GstBaseParseFrame *copy;
685
686   copy = g_slice_dup (GstBaseParseFrame, frame);
687   copy->buffer = gst_buffer_ref (frame->buffer);
688   copy->_private_flags &= ~GST_BASE_PARSE_FRAME_PRIVATE_FLAG_NOALLOC;
689
690   GST_TRACE ("copied frame %p -> %p", frame, copy);
691
692   return copy;
693 }
694
695 void
696 gst_base_parse_frame_free (GstBaseParseFrame * frame)
697 {
698   GST_TRACE ("freeing frame %p", frame);
699
700   if (frame->buffer) {
701     gst_buffer_unref (frame->buffer);
702     frame->buffer = NULL;
703   }
704
705   if (!(frame->_private_flags & GST_BASE_PARSE_FRAME_PRIVATE_FLAG_NOALLOC)) {
706     g_slice_free (GstBaseParseFrame, frame);
707   } else {
708     memset (frame, 0, sizeof (*frame));
709   }
710 }
711
712 G_DEFINE_BOXED_TYPE (GstBaseParseFrame, gst_base_parse_frame,
713     (GBoxedCopyFunc) gst_base_parse_frame_copy,
714     (GBoxedFreeFunc) gst_base_parse_frame_free);
715
716 /**
717  * gst_base_parse_frame_init:
718  * @frame: #GstBaseParseFrame.
719  *
720  * Sets a #GstBaseParseFrame to initial state.  Currently this means
721  * all public fields are zero-ed and a private flag is set to make
722  * sure gst_base_parse_frame_free() only frees the contents but not
723  * the actual frame. Use this function to initialise a #GstBaseParseFrame
724  * allocated on the stack.
725  */
726 void
727 gst_base_parse_frame_init (GstBaseParseFrame * frame)
728 {
729   memset (frame, 0, sizeof (GstBaseParseFrame));
730   frame->_private_flags = GST_BASE_PARSE_FRAME_PRIVATE_FLAG_NOALLOC;
731   GST_TRACE ("inited frame %p", frame);
732 }
733
734 /**
735  * gst_base_parse_frame_new:
736  * @buffer: (transfer none): a #GstBuffer
737  * @flags: the flags
738  * @overhead: number of bytes in this frame which should be counted as
739  *     metadata overhead, ie. not used to calculate the average bitrate.
740  *     Set to -1 to mark the entire frame as metadata. If in doubt, set to 0.
741  *
742  * Allocates a new #GstBaseParseFrame. This function is mainly for bindings,
743  * elements written in C should usually allocate the frame on the stack and
744  * then use gst_base_parse_frame_init() to initialise it.
745  *
746  * Returns: a newly-allocated #GstBaseParseFrame. Free with
747  *     gst_base_parse_frame_free() when no longer needed.
748  */
749 GstBaseParseFrame *
750 gst_base_parse_frame_new (GstBuffer * buffer, GstBaseParseFrameFlags flags,
751     gint overhead)
752 {
753   GstBaseParseFrame *frame;
754
755   frame = g_slice_new0 (GstBaseParseFrame);
756   frame->buffer = gst_buffer_ref (buffer);
757
758   GST_TRACE ("created frame %p", frame);
759   return frame;
760 }
761
762 static inline void
763 gst_base_parse_frame_update (GstBaseParse * parse, GstBaseParseFrame * frame,
764     GstBuffer * buf)
765 {
766   gst_buffer_replace (&frame->buffer, buf);
767
768   parse->flags = 0;
769
770   /* set flags one by one for clarity */
771   if (G_UNLIKELY (parse->priv->drain))
772     parse->flags |= GST_BASE_PARSE_FLAG_DRAINING;
773
774   /* losing sync is pretty much a discont (and vice versa), no ? */
775   if (G_UNLIKELY (parse->priv->discont))
776     parse->flags |= GST_BASE_PARSE_FLAG_LOST_SYNC;
777 }
778
779 static void
780 gst_base_parse_reset (GstBaseParse * parse)
781 {
782   GST_OBJECT_LOCK (parse);
783   gst_segment_init (&parse->segment, GST_FORMAT_TIME);
784   parse->priv->duration = -1;
785   parse->priv->min_frame_size = 1;
786   parse->priv->discont = TRUE;
787   parse->priv->flushing = FALSE;
788   parse->priv->saw_gaps = FALSE;
789   parse->priv->offset = 0;
790   parse->priv->sync_offset = 0;
791   parse->priv->update_interval = -1;
792   parse->priv->fps_num = parse->priv->fps_den = 0;
793   parse->priv->frame_duration = GST_CLOCK_TIME_NONE;
794   parse->priv->lead_in = parse->priv->lead_out = 0;
795   parse->priv->lead_in_ts = parse->priv->lead_out_ts = 0;
796   parse->priv->bitrate = 0;
797   parse->priv->framecount = 0;
798   parse->priv->bytecount = 0;
799   parse->priv->acc_duration = 0;
800   parse->priv->first_frame_pts = GST_CLOCK_TIME_NONE;
801   parse->priv->first_frame_dts = GST_CLOCK_TIME_NONE;
802   parse->priv->first_frame_offset = -1;
803   parse->priv->estimated_duration = -1;
804   parse->priv->estimated_drift = 0;
805   parse->priv->next_pts = GST_CLOCK_TIME_NONE;
806   parse->priv->next_dts = 0;
807   parse->priv->syncable = TRUE;
808   parse->priv->disable_passthrough = DEFAULT_DISABLE_PASSTHROUGH;
809   parse->priv->passthrough = FALSE;
810   parse->priv->pts_interpolate = TRUE;
811   parse->priv->infer_ts = TRUE;
812   parse->priv->has_timing_info = FALSE;
813   parse->priv->post_min_bitrate = TRUE;
814   parse->priv->post_avg_bitrate = TRUE;
815   parse->priv->post_max_bitrate = TRUE;
816   parse->priv->min_bitrate = G_MAXUINT;
817   parse->priv->max_bitrate = 0;
818   parse->priv->avg_bitrate = 0;
819   parse->priv->posted_avg_bitrate = 0;
820
821   parse->priv->index_last_ts = GST_CLOCK_TIME_NONE;
822   parse->priv->index_last_offset = -1;
823   parse->priv->index_last_valid = TRUE;
824   parse->priv->upstream_seekable = FALSE;
825   parse->priv->upstream_size = 0;
826   parse->priv->upstream_has_duration = FALSE;
827   parse->priv->upstream_format = GST_FORMAT_UNDEFINED;
828   parse->priv->idx_interval = 0;
829   parse->priv->idx_byte_interval = 0;
830   parse->priv->exact_position = TRUE;
831   parse->priv->seen_keyframe = FALSE;
832   parse->priv->checked_media = FALSE;
833
834   parse->priv->last_dts = GST_CLOCK_TIME_NONE;
835   parse->priv->last_pts = GST_CLOCK_TIME_NONE;
836   parse->priv->last_offset = 0;
837
838   parse->priv->skip = 0;
839
840   g_list_foreach (parse->priv->pending_events, (GFunc) gst_mini_object_unref,
841       NULL);
842   g_list_free (parse->priv->pending_events);
843   parse->priv->pending_events = NULL;
844
845   if (parse->priv->cache) {
846     gst_buffer_unref (parse->priv->cache);
847     parse->priv->cache = NULL;
848   }
849
850   g_slist_foreach (parse->priv->pending_seeks, (GFunc) g_free, NULL);
851   g_slist_free (parse->priv->pending_seeks);
852   parse->priv->pending_seeks = NULL;
853
854   if (parse->priv->adapter)
855     gst_adapter_clear (parse->priv->adapter);
856
857   parse->priv->new_frame = TRUE;
858
859   parse->priv->first_buffer = TRUE;
860
861   g_list_foreach (parse->priv->detect_buffers, (GFunc) gst_buffer_unref, NULL);
862   g_list_free (parse->priv->detect_buffers);
863   parse->priv->detect_buffers = NULL;
864   parse->priv->detect_buffers_size = 0;
865   GST_OBJECT_UNLOCK (parse);
866 }
867
868 /* gst_base_parse_parse_frame:
869  * @parse: #GstBaseParse.
870  * @buffer: #GstBuffer.
871  *
872  * Default callback for parse_frame.
873  */
874 static GstFlowReturn
875 gst_base_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
876 {
877   GstBuffer *buffer = frame->buffer;
878
879   if (!GST_BUFFER_PTS_IS_VALID (buffer) &&
880       GST_CLOCK_TIME_IS_VALID (parse->priv->next_pts)) {
881     GST_BUFFER_PTS (buffer) = parse->priv->next_pts;
882   }
883   if (!GST_BUFFER_DTS_IS_VALID (buffer) &&
884       GST_CLOCK_TIME_IS_VALID (parse->priv->next_dts)) {
885     GST_BUFFER_DTS (buffer) = parse->priv->next_dts;
886   }
887   if (!GST_BUFFER_DURATION_IS_VALID (buffer) &&
888       GST_CLOCK_TIME_IS_VALID (parse->priv->frame_duration)) {
889     GST_BUFFER_DURATION (buffer) = parse->priv->frame_duration;
890   }
891   return GST_FLOW_OK;
892 }
893
894 /* gst_base_parse_convert:
895  * @parse: #GstBaseParse.
896  * @src_format: #GstFormat describing the source format.
897  * @src_value: Source value to be converted.
898  * @dest_format: #GstFormat defining the converted format.
899  * @dest_value: Pointer where the conversion result will be put.
900  *
901  * Converts using configured "convert" vmethod in #GstBaseParse class.
902  *
903  * Returns: %TRUE if conversion was successful.
904  */
905 static gboolean
906 gst_base_parse_convert (GstBaseParse * parse,
907     GstFormat src_format,
908     gint64 src_value, GstFormat dest_format, gint64 * dest_value)
909 {
910   GstBaseParseClass *klass = GST_BASE_PARSE_GET_CLASS (parse);
911   gboolean ret;
912
913   g_return_val_if_fail (dest_value != NULL, FALSE);
914
915   if (!klass->convert)
916     return FALSE;
917
918   ret = klass->convert (parse, src_format, src_value, dest_format, dest_value);
919
920 #ifndef GST_DISABLE_GST_DEBUG
921   {
922     if (ret) {
923       if (src_format == GST_FORMAT_TIME && dest_format == GST_FORMAT_BYTES) {
924         GST_LOG_OBJECT (parse,
925             "TIME -> BYTES: %" GST_TIME_FORMAT " -> %" G_GINT64_FORMAT,
926             GST_TIME_ARGS (src_value), *dest_value);
927       } else if (dest_format == GST_FORMAT_TIME &&
928           src_format == GST_FORMAT_BYTES) {
929         GST_LOG_OBJECT (parse,
930             "BYTES -> TIME: %" G_GINT64_FORMAT " -> %" GST_TIME_FORMAT,
931             src_value, GST_TIME_ARGS (*dest_value));
932       } else {
933         GST_LOG_OBJECT (parse,
934             "%s -> %s: %" G_GINT64_FORMAT " -> %" G_GINT64_FORMAT,
935             GST_STR_NULL (gst_format_get_name (src_format)),
936             GST_STR_NULL (gst_format_get_name (dest_format)),
937             src_value, *dest_value);
938       }
939     } else {
940       GST_DEBUG_OBJECT (parse, "conversion failed");
941     }
942   }
943 #endif
944
945   return ret;
946 }
947
948 /* gst_base_parse_sink_event:
949  * @pad: #GstPad that received the event.
950  * @event: #GstEvent to be handled.
951  *
952  * Handler for sink pad events.
953  *
954  * Returns: %TRUE if the event was handled.
955  */
956 static gboolean
957 gst_base_parse_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
958 {
959   GstBaseParse *parse = GST_BASE_PARSE (parent);
960   GstBaseParseClass *bclass = GST_BASE_PARSE_GET_CLASS (parse);
961   gboolean ret;
962
963   ret = bclass->sink_event (parse, event);
964
965   return ret;
966 }
967
968
969 /* gst_base_parse_sink_event_default:
970  * @parse: #GstBaseParse.
971  * @event: #GstEvent to be handled.
972  *
973  * Element-level event handler function.
974  *
975  * The event will be unreffed only if it has been handled and this
976  * function returns %TRUE
977  *
978  * Returns: %TRUE if the event was handled and not need forwarding.
979  */
980 static gboolean
981 gst_base_parse_sink_event_default (GstBaseParse * parse, GstEvent * event)
982 {
983   GstBaseParseClass *klass = GST_BASE_PARSE_GET_CLASS (parse);
984   gboolean ret = FALSE;
985   gboolean forward_immediate = FALSE;
986
987   GST_DEBUG_OBJECT (parse, "handling event %d, %s", GST_EVENT_TYPE (event),
988       GST_EVENT_TYPE_NAME (event));
989
990   switch (GST_EVENT_TYPE (event)) {
991     case GST_EVENT_CAPS:
992     {
993       GstCaps *caps;
994
995       gst_event_parse_caps (event, &caps);
996       GST_DEBUG_OBJECT (parse, "caps: %" GST_PTR_FORMAT, caps);
997
998       if (klass->set_sink_caps)
999         ret = klass->set_sink_caps (parse, caps);
1000       else
1001         ret = TRUE;
1002
1003       /* will send our own caps downstream */
1004       gst_event_unref (event);
1005       event = NULL;
1006       break;
1007     }
1008     case GST_EVENT_SEGMENT:
1009     {
1010       const GstSegment *in_segment;
1011       GstSegment out_segment;
1012       gint64 offset = 0, next_dts;
1013       guint32 seqnum = gst_event_get_seqnum (event);
1014
1015       gst_event_parse_segment (event, &in_segment);
1016       gst_segment_init (&out_segment, GST_FORMAT_TIME);
1017       out_segment.rate = in_segment->rate;
1018       out_segment.applied_rate = in_segment->applied_rate;
1019
1020       GST_DEBUG_OBJECT (parse, "segment %" GST_SEGMENT_FORMAT, in_segment);
1021
1022       parse->priv->upstream_format = in_segment->format;
1023       if (in_segment->format == GST_FORMAT_BYTES) {
1024         GstBaseParseSeek *seek = NULL;
1025         GSList *node;
1026
1027         /* stop time is allowed to be open-ended, but not start & pos */
1028         offset = in_segment->time;
1029
1030         GST_OBJECT_LOCK (parse);
1031         for (node = parse->priv->pending_seeks; node; node = node->next) {
1032           GstBaseParseSeek *tmp = node->data;
1033
1034           if (tmp->offset == offset) {
1035             seek = tmp;
1036             break;
1037           }
1038         }
1039         parse->priv->pending_seeks =
1040             g_slist_remove (parse->priv->pending_seeks, seek);
1041         GST_OBJECT_UNLOCK (parse);
1042
1043         if (seek) {
1044           GST_DEBUG_OBJECT (parse,
1045               "Matched newsegment to%s seek: %" GST_SEGMENT_FORMAT,
1046               seek->accurate ? " accurate" : "", &seek->segment);
1047
1048           out_segment.start = seek->segment.start;
1049           out_segment.stop = seek->segment.stop;
1050           out_segment.time = seek->segment.start;
1051
1052           next_dts = seek->start_ts;
1053           parse->priv->exact_position = seek->accurate;
1054           g_free (seek);
1055         } else {
1056           /* best attempt convert */
1057           /* as these are only estimates, stop is kept open-ended to avoid
1058            * premature cutting */
1059           gst_base_parse_convert (parse, GST_FORMAT_BYTES, in_segment->start,
1060               GST_FORMAT_TIME, (gint64 *) & next_dts);
1061
1062           out_segment.start = next_dts;
1063           out_segment.stop = GST_CLOCK_TIME_NONE;
1064           out_segment.time = next_dts;
1065
1066           parse->priv->exact_position = (in_segment->start == 0);
1067         }
1068
1069         gst_event_unref (event);
1070
1071         event = gst_event_new_segment (&out_segment);
1072         gst_event_set_seqnum (event, seqnum);
1073
1074         GST_DEBUG_OBJECT (parse, "Converted incoming segment to TIME. %"
1075             GST_SEGMENT_FORMAT, in_segment);
1076
1077       } else if (in_segment->format != GST_FORMAT_TIME) {
1078         /* Unknown incoming segment format. Output a default open-ended
1079          * TIME segment */
1080         gst_event_unref (event);
1081
1082         out_segment.start = 0;
1083         out_segment.stop = GST_CLOCK_TIME_NONE;
1084         out_segment.time = 0;
1085
1086         event = gst_event_new_segment (&out_segment);
1087         gst_event_set_seqnum (event, seqnum);
1088
1089         next_dts = 0;
1090       } else {
1091         /* not considered BYTE seekable if it is talking to us in TIME,
1092          * whatever else it might claim */
1093         parse->priv->upstream_seekable = FALSE;
1094         next_dts = in_segment->start;
1095         gst_event_copy_segment (event, &out_segment);
1096       }
1097
1098       memcpy (&parse->segment, &out_segment, sizeof (GstSegment));
1099
1100       /*
1101          gst_segment_set_newsegment (&parse->segment, update, rate,
1102          applied_rate, format, start, stop, start);
1103        */
1104
1105       ret = TRUE;
1106
1107       /* save the segment for later, right before we push a new buffer so that
1108        * the caps are fixed and the next linked element can receive
1109        * the segment but finish the current segment */
1110       GST_DEBUG_OBJECT (parse, "draining current segment");
1111       if (in_segment->rate > 0.0)
1112         gst_base_parse_drain (parse);
1113       else
1114         gst_base_parse_finish_fragment (parse, FALSE);
1115       gst_adapter_clear (parse->priv->adapter);
1116
1117       parse->priv->offset = offset;
1118       parse->priv->sync_offset = offset;
1119       parse->priv->next_dts = next_dts;
1120       parse->priv->next_pts = GST_CLOCK_TIME_NONE;
1121       parse->priv->last_pts = GST_CLOCK_TIME_NONE;
1122       parse->priv->last_dts = GST_CLOCK_TIME_NONE;
1123       parse->priv->prev_pts = GST_CLOCK_TIME_NONE;
1124       parse->priv->prev_dts = GST_CLOCK_TIME_NONE;
1125       parse->priv->discont = TRUE;
1126       parse->priv->seen_keyframe = FALSE;
1127       parse->priv->skip = 0;
1128       break;
1129     }
1130
1131     case GST_EVENT_SEGMENT_DONE:
1132       /* need to drain now, rather than upon a new segment,
1133        * since that would have SEGMENT_DONE come before potential
1134        * delayed last part of the current segment */
1135       GST_DEBUG_OBJECT (parse, "draining current segment");
1136       if (parse->segment.rate > 0.0)
1137         gst_base_parse_drain (parse);
1138       else
1139         gst_base_parse_finish_fragment (parse, FALSE);
1140       /* Also forward event immediately, there might be no new data
1141        * coming afterwards that would allow us to forward it later */
1142       forward_immediate = TRUE;
1143       break;
1144
1145     case GST_EVENT_FLUSH_START:
1146       GST_OBJECT_LOCK (parse);
1147       parse->priv->flushing = TRUE;
1148       GST_OBJECT_UNLOCK (parse);
1149       break;
1150
1151     case GST_EVENT_FLUSH_STOP:
1152       gst_adapter_clear (parse->priv->adapter);
1153       gst_base_parse_clear_queues (parse);
1154       parse->priv->flushing = FALSE;
1155       parse->priv->discont = TRUE;
1156       parse->priv->last_pts = GST_CLOCK_TIME_NONE;
1157       parse->priv->last_dts = GST_CLOCK_TIME_NONE;
1158       parse->priv->new_frame = TRUE;
1159       parse->priv->skip = 0;
1160
1161       forward_immediate = TRUE;
1162       break;
1163
1164     case GST_EVENT_EOS:
1165       if (parse->segment.rate > 0.0)
1166         gst_base_parse_drain (parse);
1167       else
1168         gst_base_parse_finish_fragment (parse, TRUE);
1169
1170       /* If we STILL have zero frames processed, fire an error */
1171       if (parse->priv->framecount == 0 && !parse->priv->saw_gaps &&
1172           !parse->priv->first_buffer) {
1173         GST_ELEMENT_ERROR (parse, STREAM, WRONG_TYPE,
1174             ("No valid frames found before end of stream"), (NULL));
1175       }
1176       /* newsegment and other serialized events before eos */
1177       gst_base_parse_push_pending_events (parse);
1178
1179       if (!parse->priv->saw_gaps
1180           && parse->priv->framecount < MIN_FRAMES_TO_POST_BITRATE) {
1181         /* We've not posted bitrate tags yet - do so now */
1182         gst_base_parse_post_bitrates (parse, TRUE, TRUE, TRUE);
1183       }
1184       forward_immediate = TRUE;
1185       break;
1186     case GST_EVENT_CUSTOM_DOWNSTREAM:{
1187       /* FIXME: Code duplicated from libgstvideo because core can't depend on -base */
1188 #ifndef GST_VIDEO_EVENT_STILL_STATE_NAME
1189 #define GST_VIDEO_EVENT_STILL_STATE_NAME "GstEventStillFrame"
1190 #endif
1191
1192       const GstStructure *s;
1193       gboolean ev_still_state;
1194
1195       s = gst_event_get_structure (event);
1196       if (s != NULL &&
1197           gst_structure_has_name (s, GST_VIDEO_EVENT_STILL_STATE_NAME) &&
1198           gst_structure_get_boolean (s, "still-state", &ev_still_state)) {
1199         if (ev_still_state) {
1200           GST_DEBUG_OBJECT (parse, "draining current data for still-frame");
1201           if (parse->segment.rate > 0.0)
1202             gst_base_parse_drain (parse);
1203           else
1204             gst_base_parse_finish_fragment (parse, TRUE);
1205         }
1206         forward_immediate = TRUE;
1207       }
1208       break;
1209     }
1210     case GST_EVENT_GAP:
1211     {
1212       GST_DEBUG_OBJECT (parse, "draining current data due to gap event");
1213
1214       gst_base_parse_push_pending_events (parse);
1215
1216       if (parse->segment.rate > 0.0)
1217         gst_base_parse_drain (parse);
1218       else
1219         gst_base_parse_finish_fragment (parse, TRUE);
1220       forward_immediate = TRUE;
1221       parse->priv->saw_gaps = TRUE;
1222       break;
1223     }
1224     case GST_EVENT_TAG:
1225       /* See if any bitrate tags were posted */
1226       gst_base_parse_handle_tag (parse, event);
1227       break;
1228
1229     case GST_EVENT_STREAM_START:
1230       if (parse->priv->pad_mode != GST_PAD_MODE_PULL)
1231         forward_immediate = TRUE;
1232       break;
1233
1234     default:
1235       break;
1236   }
1237
1238   /* Forward non-serialized events and EOS/FLUSH_STOP immediately.
1239    * For EOS this is required because no buffer or serialized event
1240    * will come after EOS and nothing could trigger another
1241    * _finish_frame() call.   *
1242    * If the subclass handles sending of EOS manually it can return
1243    * _DROPPED from ::finish() and all other subclasses should have
1244    * decoded/flushed all remaining data before this
1245    *
1246    * For FLUSH_STOP this is required because it is expected
1247    * to be forwarded immediately and no buffers are queued anyway.
1248    */
1249   if (event) {
1250     if (!GST_EVENT_IS_SERIALIZED (event) || forward_immediate) {
1251       ret = gst_pad_push_event (parse->srcpad, event);
1252     } else {
1253       parse->priv->pending_events =
1254           g_list_prepend (parse->priv->pending_events, event);
1255       ret = TRUE;
1256     }
1257   }
1258
1259   GST_DEBUG_OBJECT (parse, "event handled");
1260
1261   return ret;
1262 }
1263
1264 static gboolean
1265 gst_base_parse_sink_query_default (GstBaseParse * parse, GstQuery * query)
1266 {
1267   GstPad *pad;
1268   gboolean res;
1269
1270   pad = GST_BASE_PARSE_SINK_PAD (parse);
1271
1272   switch (GST_QUERY_TYPE (query)) {
1273     case GST_QUERY_CAPS:
1274     {
1275       GstBaseParseClass *bclass;
1276
1277       bclass = GST_BASE_PARSE_GET_CLASS (parse);
1278
1279       if (bclass->get_sink_caps) {
1280         GstCaps *caps, *filter;
1281
1282         gst_query_parse_caps (query, &filter);
1283         caps = bclass->get_sink_caps (parse, filter);
1284         GST_LOG_OBJECT (parse, "sink getcaps returning caps %" GST_PTR_FORMAT,
1285             caps);
1286         gst_query_set_caps_result (query, caps);
1287         gst_caps_unref (caps);
1288
1289         res = TRUE;
1290       } else {
1291         GstCaps *caps, *template_caps, *filter;
1292
1293         gst_query_parse_caps (query, &filter);
1294         template_caps = gst_pad_get_pad_template_caps (pad);
1295         if (filter != NULL) {
1296           caps =
1297               gst_caps_intersect_full (filter, template_caps,
1298               GST_CAPS_INTERSECT_FIRST);
1299           gst_caps_unref (template_caps);
1300         } else {
1301           caps = template_caps;
1302         }
1303         gst_query_set_caps_result (query, caps);
1304         gst_caps_unref (caps);
1305
1306         res = TRUE;
1307       }
1308       break;
1309     }
1310     default:
1311     {
1312       res = gst_pad_query_default (pad, GST_OBJECT_CAST (parse), query);
1313       break;
1314     }
1315   }
1316
1317   return res;
1318 }
1319
1320 static gboolean
1321 gst_base_parse_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
1322 {
1323   GstBaseParseClass *bclass;
1324   GstBaseParse *parse;
1325   gboolean ret;
1326
1327   parse = GST_BASE_PARSE (parent);
1328   bclass = GST_BASE_PARSE_GET_CLASS (parse);
1329
1330   GST_DEBUG_OBJECT (parse, "%s query", GST_QUERY_TYPE_NAME (query));
1331
1332   if (bclass->sink_query)
1333     ret = bclass->sink_query (parse, query);
1334   else
1335     ret = FALSE;
1336
1337   GST_LOG_OBJECT (parse, "%s query result: %d %" GST_PTR_FORMAT,
1338       GST_QUERY_TYPE_NAME (query), ret, query);
1339
1340   return ret;
1341 }
1342
1343 static gboolean
1344 gst_base_parse_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
1345 {
1346   GstBaseParseClass *bclass;
1347   GstBaseParse *parse;
1348   gboolean ret;
1349
1350   parse = GST_BASE_PARSE (parent);
1351   bclass = GST_BASE_PARSE_GET_CLASS (parse);
1352
1353   GST_DEBUG_OBJECT (parse, "%s query: %" GST_PTR_FORMAT,
1354       GST_QUERY_TYPE_NAME (query), query);
1355
1356   if (bclass->src_query)
1357     ret = bclass->src_query (parse, query);
1358   else
1359     ret = FALSE;
1360
1361   GST_LOG_OBJECT (parse, "%s query result: %d %" GST_PTR_FORMAT,
1362       GST_QUERY_TYPE_NAME (query), ret, query);
1363
1364   return ret;
1365 }
1366
1367 /* gst_base_parse_src_event:
1368  * @pad: #GstPad that received the event.
1369  * @event: #GstEvent that was received.
1370  *
1371  * Handler for source pad events.
1372  *
1373  * Returns: %TRUE if the event was handled.
1374  */
1375 static gboolean
1376 gst_base_parse_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
1377 {
1378   GstBaseParse *parse;
1379   GstBaseParseClass *bclass;
1380   gboolean ret = TRUE;
1381
1382   parse = GST_BASE_PARSE (parent);
1383   bclass = GST_BASE_PARSE_GET_CLASS (parse);
1384
1385   GST_DEBUG_OBJECT (parse, "event %d, %s", GST_EVENT_TYPE (event),
1386       GST_EVENT_TYPE_NAME (event));
1387
1388   if (bclass->src_event)
1389     ret = bclass->src_event (parse, event);
1390   else
1391     gst_event_unref (event);
1392
1393   return ret;
1394 }
1395
1396 static gboolean
1397 gst_base_parse_is_seekable (GstBaseParse * parse)
1398 {
1399   /* FIXME: could do more here, e.g. check index or just send data from 0
1400    * in pull mode and let decoder/sink clip */
1401   return parse->priv->syncable;
1402 }
1403
1404 /* gst_base_parse_src_event_default:
1405  * @parse: #GstBaseParse.
1406  * @event: #GstEvent that was received.
1407  *
1408  * Default srcpad event handler.
1409  *
1410  * Returns: %TRUE if the event was handled and can be dropped.
1411  */
1412 static gboolean
1413 gst_base_parse_src_event_default (GstBaseParse * parse, GstEvent * event)
1414 {
1415   gboolean res = FALSE;
1416
1417   switch (GST_EVENT_TYPE (event)) {
1418     case GST_EVENT_SEEK:
1419       if (gst_base_parse_is_seekable (parse))
1420         res = gst_base_parse_handle_seek (parse, event);
1421       break;
1422     default:
1423       res = gst_pad_event_default (parse->srcpad, GST_OBJECT_CAST (parse),
1424           event);
1425       break;
1426   }
1427   return res;
1428 }
1429
1430
1431 /**
1432  * gst_base_parse_convert_default:
1433  * @parse: #GstBaseParse.
1434  * @src_format: #GstFormat describing the source format.
1435  * @src_value: Source value to be converted.
1436  * @dest_format: #GstFormat defining the converted format.
1437  * @dest_value: Pointer where the conversion result will be put.
1438  *
1439  * Default implementation of "convert" vmethod in #GstBaseParse class.
1440  *
1441  * Returns: %TRUE if conversion was successful.
1442  */
1443 gboolean
1444 gst_base_parse_convert_default (GstBaseParse * parse,
1445     GstFormat src_format,
1446     gint64 src_value, GstFormat dest_format, gint64 * dest_value)
1447 {
1448   gboolean ret = FALSE;
1449   guint64 bytes, duration;
1450
1451   if (G_UNLIKELY (src_format == dest_format)) {
1452     *dest_value = src_value;
1453     return TRUE;
1454   }
1455
1456   if (G_UNLIKELY (src_value == -1)) {
1457     *dest_value = -1;
1458     return TRUE;
1459   }
1460
1461   if (G_UNLIKELY (src_value == 0)) {
1462     *dest_value = 0;
1463     return TRUE;
1464   }
1465
1466   /* need at least some frames */
1467   if (!parse->priv->framecount)
1468     goto no_framecount;
1469
1470   duration = parse->priv->acc_duration / GST_MSECOND;
1471   bytes = parse->priv->bytecount;
1472
1473   if (G_UNLIKELY (!duration || !bytes))
1474     goto no_duration_bytes;
1475
1476   if (src_format == GST_FORMAT_BYTES) {
1477     if (dest_format == GST_FORMAT_TIME) {
1478       /* BYTES -> TIME conversion */
1479       GST_DEBUG_OBJECT (parse, "converting bytes -> time");
1480       *dest_value = gst_util_uint64_scale (src_value, duration, bytes);
1481       *dest_value *= GST_MSECOND;
1482       GST_DEBUG_OBJECT (parse, "conversion result: %" G_GINT64_FORMAT " ms",
1483           *dest_value / GST_MSECOND);
1484       ret = TRUE;
1485     } else {
1486       GST_DEBUG_OBJECT (parse, "converting bytes -> other not implemented");
1487     }
1488   } else if (src_format == GST_FORMAT_TIME) {
1489     if (dest_format == GST_FORMAT_BYTES) {
1490       GST_DEBUG_OBJECT (parse, "converting time -> bytes");
1491       *dest_value = gst_util_uint64_scale (src_value / GST_MSECOND, bytes,
1492           duration);
1493       GST_DEBUG_OBJECT (parse,
1494           "time %" G_GINT64_FORMAT " ms in bytes = %" G_GINT64_FORMAT,
1495           src_value / GST_MSECOND, *dest_value);
1496       ret = TRUE;
1497     } else {
1498       GST_DEBUG_OBJECT (parse, "converting time -> other not implemented");
1499     }
1500   } else if (src_format == GST_FORMAT_DEFAULT) {
1501     /* DEFAULT == frame-based */
1502     if (dest_format == GST_FORMAT_TIME) {
1503       GST_DEBUG_OBJECT (parse, "converting default -> time");
1504       if (parse->priv->fps_den) {
1505         *dest_value = gst_util_uint64_scale (src_value,
1506             GST_SECOND * parse->priv->fps_den, parse->priv->fps_num);
1507         ret = TRUE;
1508       }
1509     } else {
1510       GST_DEBUG_OBJECT (parse, "converting default -> other not implemented");
1511     }
1512   } else {
1513     GST_DEBUG_OBJECT (parse, "conversion not implemented");
1514   }
1515   return ret;
1516
1517   /* ERRORS */
1518 no_framecount:
1519   {
1520     GST_DEBUG_OBJECT (parse, "no framecount");
1521     return FALSE;
1522   }
1523 no_duration_bytes:
1524   {
1525     GST_DEBUG_OBJECT (parse, "no duration %" G_GUINT64_FORMAT ", bytes %"
1526         G_GUINT64_FORMAT, duration, bytes);
1527     return FALSE;
1528   }
1529
1530 }
1531
1532 static void
1533 gst_base_parse_update_duration (GstBaseParse * baseparse)
1534 {
1535   GstPad *peer;
1536   GstBaseParse *parse;
1537
1538   parse = GST_BASE_PARSE (baseparse);
1539
1540   peer = gst_pad_get_peer (parse->sinkpad);
1541   if (peer) {
1542     gboolean qres = FALSE;
1543     gint64 ptot, dest_value;
1544
1545     qres = gst_pad_query_duration (peer, GST_FORMAT_BYTES, &ptot);
1546     gst_object_unref (GST_OBJECT (peer));
1547     if (qres) {
1548       if (gst_base_parse_convert (parse, GST_FORMAT_BYTES, ptot,
1549               GST_FORMAT_TIME, &dest_value)) {
1550
1551         /* inform if duration changed, but try to avoid spamming */
1552         parse->priv->estimated_drift +=
1553             dest_value - parse->priv->estimated_duration;
1554
1555         parse->priv->estimated_duration = dest_value;
1556         GST_LOG_OBJECT (parse,
1557             "updated estimated duration to %" GST_TIME_FORMAT,
1558             GST_TIME_ARGS (dest_value));
1559
1560         if (parse->priv->estimated_drift > GST_SECOND ||
1561             parse->priv->estimated_drift < -GST_SECOND) {
1562           gst_element_post_message (GST_ELEMENT (parse),
1563               gst_message_new_duration_changed (GST_OBJECT (parse)));
1564           parse->priv->estimated_drift = 0;
1565         }
1566       }
1567     }
1568   }
1569 }
1570
1571 static void
1572 gst_base_parse_post_bitrates (GstBaseParse * parse, gboolean post_min,
1573     gboolean post_avg, gboolean post_max)
1574 {
1575   GstTagList *taglist = NULL;
1576
1577   if (post_min && parse->priv->post_min_bitrate) {
1578     taglist = gst_tag_list_new_empty ();
1579
1580     gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE,
1581         GST_TAG_MINIMUM_BITRATE, parse->priv->min_bitrate, NULL);
1582   }
1583
1584   if (post_avg && parse->priv->post_avg_bitrate) {
1585     if (taglist == NULL)
1586       taglist = gst_tag_list_new_empty ();
1587
1588     parse->priv->posted_avg_bitrate = parse->priv->avg_bitrate;
1589     gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE, GST_TAG_BITRATE,
1590         parse->priv->avg_bitrate, NULL);
1591   }
1592
1593   if (post_max && parse->priv->post_max_bitrate) {
1594     if (taglist == NULL)
1595       taglist = gst_tag_list_new_empty ();
1596
1597     gst_tag_list_add (taglist, GST_TAG_MERGE_REPLACE,
1598         GST_TAG_MAXIMUM_BITRATE, parse->priv->max_bitrate, NULL);
1599   }
1600
1601   GST_DEBUG_OBJECT (parse, "Updated bitrates. Min: %u, Avg: %u, Max: %u",
1602       parse->priv->min_bitrate, parse->priv->avg_bitrate,
1603       parse->priv->max_bitrate);
1604
1605   if (taglist != NULL) {
1606     gst_pad_push_event (parse->srcpad, gst_event_new_tag (taglist));
1607   }
1608 }
1609
1610 /* gst_base_parse_update_bitrates:
1611  * @parse: #GstBaseParse.
1612  * @buffer: Current frame as a #GstBuffer
1613  *
1614  * Keeps track of the minimum and maximum bitrates, and also maintains a
1615  * running average bitrate of the stream so far.
1616  */
1617 static void
1618 gst_base_parse_update_bitrates (GstBaseParse * parse, GstBaseParseFrame * frame)
1619 {
1620   /* Only update the tag on a 10 kbps delta */
1621   static const gint update_threshold = 10000;
1622
1623   guint64 data_len, frame_dur;
1624   gint overhead, frame_bitrate, old_avg_bitrate;
1625   gboolean update_min = FALSE, update_avg = FALSE, update_max = FALSE;
1626   GstBuffer *buffer = frame->buffer;
1627
1628   overhead = frame->overhead;
1629   if (overhead == -1)
1630     return;
1631
1632   data_len = gst_buffer_get_size (buffer) - overhead;
1633   parse->priv->data_bytecount += data_len;
1634
1635   /* duration should be valid by now,
1636    * either set by subclass or maybe based on fps settings */
1637   if (GST_BUFFER_DURATION_IS_VALID (buffer) && parse->priv->acc_duration != 0) {
1638     /* Calculate duration of a frame from buffer properties */
1639     frame_dur = GST_BUFFER_DURATION (buffer);
1640     parse->priv->avg_bitrate = (8 * parse->priv->data_bytecount * GST_SECOND) /
1641         parse->priv->acc_duration;
1642
1643   } else {
1644     /* No way to figure out frame duration (is this even possible?) */
1645     return;
1646   }
1647
1648   /* override if subclass provided bitrate, e.g. metadata based */
1649   if (parse->priv->bitrate) {
1650     parse->priv->avg_bitrate = parse->priv->bitrate;
1651     /* spread this (confirmed) info ASAP */
1652     if (parse->priv->posted_avg_bitrate != parse->priv->avg_bitrate)
1653       gst_base_parse_post_bitrates (parse, FALSE, TRUE, FALSE);
1654   }
1655
1656   if (frame_dur)
1657     frame_bitrate = (8 * data_len * GST_SECOND) / frame_dur;
1658   else
1659     return;
1660
1661   GST_LOG_OBJECT (parse, "frame bitrate %u, avg bitrate %u", frame_bitrate,
1662       parse->priv->avg_bitrate);
1663
1664   if (parse->priv->framecount < MIN_FRAMES_TO_POST_BITRATE) {
1665     goto exit;
1666   } else if (parse->priv->framecount == MIN_FRAMES_TO_POST_BITRATE) {
1667     /* always post all at threshold time */
1668     update_min = update_max = update_avg = TRUE;
1669   }
1670
1671   if (G_LIKELY (parse->priv->framecount >= MIN_FRAMES_TO_POST_BITRATE)) {
1672     if (frame_bitrate < parse->priv->min_bitrate) {
1673       parse->priv->min_bitrate = frame_bitrate;
1674       update_min = TRUE;
1675     }
1676
1677     if (frame_bitrate > parse->priv->max_bitrate) {
1678       parse->priv->max_bitrate = frame_bitrate;
1679       update_max = TRUE;
1680     }
1681
1682     old_avg_bitrate = parse->priv->posted_avg_bitrate;
1683     if ((gint) (old_avg_bitrate - parse->priv->avg_bitrate) > update_threshold
1684         || (gint) (parse->priv->avg_bitrate - old_avg_bitrate) >
1685         update_threshold)
1686       update_avg = TRUE;
1687   }
1688
1689   if ((update_min || update_avg || update_max))
1690     gst_base_parse_post_bitrates (parse, update_min, update_avg, update_max);
1691
1692 exit:
1693   return;
1694 }
1695
1696 /**
1697  * gst_base_parse_add_index_entry:
1698  * @parse: #GstBaseParse.
1699  * @offset: offset of entry
1700  * @ts: timestamp associated with offset
1701  * @key: whether entry refers to keyframe
1702  * @force: add entry disregarding sanity checks
1703  *
1704  * Adds an entry to the index associating @offset to @ts.  It is recommended
1705  * to only add keyframe entries.  @force allows to bypass checks, such as
1706  * whether the stream is (upstream) seekable, another entry is already "close"
1707  * to the new entry, etc.
1708  *
1709  * Returns: #gboolean indicating whether entry was added
1710  */
1711 gboolean
1712 gst_base_parse_add_index_entry (GstBaseParse * parse, guint64 offset,
1713     GstClockTime ts, gboolean key, gboolean force)
1714 {
1715   gboolean ret = FALSE;
1716   GstIndexAssociation associations[2];
1717
1718   GST_LOG_OBJECT (parse, "Adding key=%d index entry %" GST_TIME_FORMAT
1719       " @ offset 0x%08" G_GINT64_MODIFIER "x", key, GST_TIME_ARGS (ts), offset);
1720
1721   if (G_LIKELY (!force)) {
1722
1723     if (!parse->priv->upstream_seekable) {
1724       GST_DEBUG_OBJECT (parse, "upstream not seekable; discarding");
1725       goto exit;
1726     }
1727
1728     /* FIXME need better helper data structure that handles these issues
1729      * related to ongoing collecting of index entries */
1730     if (parse->priv->index_last_offset + parse->priv->idx_byte_interval >=
1731         (gint64) offset) {
1732       GST_LOG_OBJECT (parse,
1733           "already have entries up to offset 0x%08" G_GINT64_MODIFIER "x",
1734           parse->priv->index_last_offset + parse->priv->idx_byte_interval);
1735       goto exit;
1736     }
1737
1738     if (GST_CLOCK_TIME_IS_VALID (parse->priv->index_last_ts) &&
1739         GST_CLOCK_DIFF (parse->priv->index_last_ts, ts) <
1740         parse->priv->idx_interval) {
1741       GST_LOG_OBJECT (parse, "entry too close to last time %" GST_TIME_FORMAT,
1742           GST_TIME_ARGS (parse->priv->index_last_ts));
1743       goto exit;
1744     }
1745
1746     /* if last is not really the last one */
1747     if (!parse->priv->index_last_valid) {
1748       GstClockTime prev_ts;
1749
1750       gst_base_parse_find_offset (parse, ts, TRUE, &prev_ts);
1751       if (GST_CLOCK_DIFF (prev_ts, ts) < parse->priv->idx_interval) {
1752         GST_LOG_OBJECT (parse,
1753             "entry too close to existing entry %" GST_TIME_FORMAT,
1754             GST_TIME_ARGS (prev_ts));
1755         parse->priv->index_last_offset = offset;
1756         parse->priv->index_last_ts = ts;
1757         goto exit;
1758       }
1759     }
1760   }
1761
1762   associations[0].format = GST_FORMAT_TIME;
1763   associations[0].value = ts;
1764   associations[1].format = GST_FORMAT_BYTES;
1765   associations[1].value = offset;
1766
1767   /* index might change on-the-fly, although that would be nutty app ... */
1768   GST_BASE_PARSE_INDEX_LOCK (parse);
1769   gst_index_add_associationv (parse->priv->index, parse->priv->index_id,
1770       (key) ? GST_INDEX_ASSOCIATION_FLAG_KEY_UNIT :
1771       GST_INDEX_ASSOCIATION_FLAG_DELTA_UNIT, 2,
1772       (const GstIndexAssociation *) &associations);
1773   GST_BASE_PARSE_INDEX_UNLOCK (parse);
1774
1775   if (key) {
1776     parse->priv->index_last_offset = offset;
1777     parse->priv->index_last_ts = ts;
1778   }
1779
1780   ret = TRUE;
1781
1782 exit:
1783   return ret;
1784 }
1785
1786 /* check for seekable upstream, above and beyond a mere query */
1787 static void
1788 gst_base_parse_check_seekability (GstBaseParse * parse)
1789 {
1790   GstQuery *query;
1791   gboolean seekable = FALSE;
1792   gint64 start = -1, stop = -1;
1793   guint idx_interval = 0;
1794   guint64 idx_byte_interval = 0;
1795
1796   query = gst_query_new_seeking (GST_FORMAT_BYTES);
1797   if (!gst_pad_peer_query (parse->sinkpad, query)) {
1798     GST_DEBUG_OBJECT (parse, "seeking query failed");
1799     goto done;
1800   }
1801
1802   gst_query_parse_seeking (query, NULL, &seekable, &start, &stop);
1803
1804   /* try harder to query upstream size if we didn't get it the first time */
1805   if (seekable && stop == -1) {
1806     GST_DEBUG_OBJECT (parse, "doing duration query to fix up unset stop");
1807     gst_pad_peer_query_duration (parse->sinkpad, GST_FORMAT_BYTES, &stop);
1808   }
1809
1810   /* if upstream doesn't know the size, it's likely that it's not seekable in
1811    * practice even if it technically may be seekable */
1812   if (seekable && (start != 0 || stop <= start)) {
1813     GST_DEBUG_OBJECT (parse, "seekable but unknown start/stop -> disable");
1814     seekable = FALSE;
1815   }
1816
1817   /* let's not put every single frame into our index */
1818   if (seekable) {
1819     if (stop < 10 * 1024 * 1024)
1820       idx_interval = 100;
1821     else if (stop < 100 * 1024 * 1024)
1822       idx_interval = 500;
1823     else
1824       idx_interval = 1000;
1825
1826     /* ensure that even for large files (e.g. very long audio files), the index
1827      * stays reasonably-size, with some arbitrary limit to the total number of
1828      * index entries */
1829     idx_byte_interval = (stop - start) / MAX_INDEX_ENTRIES;
1830     GST_DEBUG_OBJECT (parse,
1831         "Limiting index entries to %d, indexing byte interval %"
1832         G_GUINT64_FORMAT " bytes", MAX_INDEX_ENTRIES, idx_byte_interval);
1833   }
1834
1835 done:
1836   gst_query_unref (query);
1837
1838   GST_DEBUG_OBJECT (parse, "seekable: %d (%" G_GUINT64_FORMAT " - %"
1839       G_GUINT64_FORMAT ")", seekable, start, stop);
1840   parse->priv->upstream_seekable = seekable;
1841   parse->priv->upstream_size = seekable ? stop : 0;
1842
1843   GST_DEBUG_OBJECT (parse, "idx_interval: %ums", idx_interval);
1844   parse->priv->idx_interval = idx_interval * GST_MSECOND;
1845   parse->priv->idx_byte_interval = idx_byte_interval;
1846 }
1847
1848 /* some misc checks on upstream */
1849 static void
1850 gst_base_parse_check_upstream (GstBaseParse * parse)
1851 {
1852   gint64 stop;
1853
1854   if (gst_pad_peer_query_duration (parse->sinkpad, GST_FORMAT_TIME, &stop))
1855     if (GST_CLOCK_TIME_IS_VALID (stop) && stop) {
1856       /* upstream has one, accept it also, and no further updates */
1857       gst_base_parse_set_duration (parse, GST_FORMAT_TIME, stop, 0);
1858       parse->priv->upstream_has_duration = TRUE;
1859     }
1860
1861   GST_DEBUG_OBJECT (parse, "upstream_has_duration: %d",
1862       parse->priv->upstream_has_duration);
1863 }
1864
1865 /* checks src caps to determine if dealing with audio or video */
1866 /* TODO maybe forego automagic stuff and let subclass configure it ? */
1867 static void
1868 gst_base_parse_check_media (GstBaseParse * parse)
1869 {
1870   GstCaps *caps;
1871   GstStructure *s;
1872
1873   caps = gst_pad_get_current_caps (parse->srcpad);
1874   if (G_LIKELY (caps) && (s = gst_caps_get_structure (caps, 0))) {
1875     parse->priv->is_video =
1876         g_str_has_prefix (gst_structure_get_name (s), "video");
1877   } else {
1878     /* historical default */
1879     parse->priv->is_video = FALSE;
1880   }
1881   if (caps)
1882     gst_caps_unref (caps);
1883
1884   parse->priv->checked_media = TRUE;
1885   GST_DEBUG_OBJECT (parse, "media is video: %d", parse->priv->is_video);
1886 }
1887
1888 /* takes ownership of frame */
1889 static void
1890 gst_base_parse_queue_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
1891 {
1892   if (!(frame->_private_flags & GST_BASE_PARSE_FRAME_PRIVATE_FLAG_NOALLOC)) {
1893     /* frame allocated on the heap, we can just take ownership */
1894     g_queue_push_tail (&parse->priv->queued_frames, frame);
1895     GST_TRACE ("queued frame %p", frame);
1896   } else {
1897     GstBaseParseFrame *copy;
1898
1899     /* probably allocated on the stack, must make a proper copy */
1900     copy = gst_base_parse_frame_copy (frame);
1901     g_queue_push_tail (&parse->priv->queued_frames, copy);
1902     GST_TRACE ("queued frame %p (copy of %p)", copy, frame);
1903     gst_base_parse_frame_free (frame);
1904   }
1905 }
1906
1907 /* makes sure that @buf is properly prepared and decorated for passing
1908  * to baseclass, and an equally setup frame is returned setup with @buf.
1909  * Takes ownership of @buf. */
1910 static GstBaseParseFrame *
1911 gst_base_parse_prepare_frame (GstBaseParse * parse, GstBuffer * buffer)
1912 {
1913   GstBaseParseFrame *frame = NULL;
1914
1915   buffer = gst_buffer_make_writable (buffer);
1916
1917   GST_LOG_OBJECT (parse,
1918       "preparing frame at offset %" G_GUINT64_FORMAT
1919       " (%#" G_GINT64_MODIFIER "x) of size %" G_GSIZE_FORMAT,
1920       GST_BUFFER_OFFSET (buffer), GST_BUFFER_OFFSET (buffer),
1921       gst_buffer_get_size (buffer));
1922
1923   if (parse->priv->discont) {
1924     GST_DEBUG_OBJECT (parse, "marking DISCONT");
1925     GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
1926     parse->priv->discont = FALSE;
1927   }
1928
1929   GST_BUFFER_OFFSET (buffer) = parse->priv->offset;
1930
1931   frame = gst_base_parse_frame_new (buffer, 0, 0);
1932
1933   /* also ensure to update state flags */
1934   gst_base_parse_frame_update (parse, frame, buffer);
1935   gst_buffer_unref (buffer);
1936
1937   if (parse->priv->prev_offset != parse->priv->offset || parse->priv->new_frame) {
1938     GST_LOG_OBJECT (parse, "marking as new frame");
1939     parse->priv->new_frame = FALSE;
1940     frame->flags |= GST_BASE_PARSE_FRAME_FLAG_NEW_FRAME;
1941   }
1942
1943   frame->offset = parse->priv->prev_offset = parse->priv->offset;
1944
1945   /* use default handler to provide initial (upstream) metadata */
1946   gst_base_parse_parse_frame (parse, frame);
1947
1948   return frame;
1949 }
1950
1951 /* Wraps buffer in a frame and dispatches to subclass.
1952  * Also manages data skipping and offset handling (including adapter flushing).
1953  * Takes ownership of @buffer */
1954 static GstFlowReturn
1955 gst_base_parse_handle_buffer (GstBaseParse * parse, GstBuffer * buffer,
1956     gint * skip, gint * flushed)
1957 {
1958   GstBaseParseClass *klass = GST_BASE_PARSE_GET_CLASS (parse);
1959   GstBaseParseFrame *frame;
1960   GstFlowReturn ret;
1961
1962   g_return_val_if_fail (skip != NULL || flushed != NULL, GST_FLOW_ERROR);
1963
1964   GST_LOG_OBJECT (parse,
1965       "handling buffer of size %" G_GSIZE_FORMAT " with dts %" GST_TIME_FORMAT
1966       ", pts %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT,
1967       gst_buffer_get_size (buffer), GST_TIME_ARGS (GST_BUFFER_DTS (buffer)),
1968       GST_TIME_ARGS (GST_BUFFER_PTS (buffer)),
1969       GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
1970
1971   /* track what is being flushed during this single round of frame processing */
1972   parse->priv->flushed = 0;
1973   *skip = 0;
1974
1975   /* make it easy for _finish_frame to pick up input data */
1976   if (parse->priv->pad_mode == GST_PAD_MODE_PULL) {
1977     gst_buffer_ref (buffer);
1978     gst_adapter_push (parse->priv->adapter, buffer);
1979   }
1980
1981   frame = gst_base_parse_prepare_frame (parse, buffer);
1982   ret = klass->handle_frame (parse, frame, skip);
1983
1984   *flushed = parse->priv->flushed;
1985
1986   GST_LOG_OBJECT (parse, "handle_frame skipped %d, flushed %d",
1987       *skip, *flushed);
1988
1989   /* subclass can only do one of these, or semantics are too unclear */
1990   g_assert (*skip == 0 || *flushed == 0);
1991
1992   /* track skipping */
1993   if (*skip > 0) {
1994     GstClockTime pts, dts;
1995     GstBuffer *outbuf;
1996
1997     GST_LOG_OBJECT (parse, "finding sync, skipping %d bytes", *skip);
1998     if (parse->segment.rate < 0.0 && !parse->priv->buffers_queued) {
1999       /* reverse playback, and no frames found yet, so we are skipping
2000        * the leading part of a fragment, which may form the tail of
2001        * fragment coming later, hopefully subclass skips efficiently ... */
2002       pts = gst_adapter_prev_pts (parse->priv->adapter, NULL);
2003       dts = gst_adapter_prev_dts (parse->priv->adapter, NULL);
2004       outbuf = gst_adapter_take_buffer (parse->priv->adapter, *skip);
2005       outbuf = gst_buffer_make_writable (outbuf);
2006       GST_BUFFER_PTS (outbuf) = pts;
2007       GST_BUFFER_DTS (outbuf) = dts;
2008       parse->priv->buffers_head =
2009           g_slist_prepend (parse->priv->buffers_head, outbuf);
2010       outbuf = NULL;
2011     } else {
2012       /* If we're asked to skip more than is available in the adapter,
2013          we need to remember what we need to skip for next iteration */
2014       gsize av = gst_adapter_available (parse->priv->adapter);
2015       GST_DEBUG ("Asked to skip %u (%" G_GSIZE_FORMAT " available)", *skip, av);
2016       if (av >= *skip) {
2017         gst_adapter_flush (parse->priv->adapter, *skip);
2018       } else {
2019         GST_DEBUG
2020             ("This is more than available, flushing %" G_GSIZE_FORMAT
2021             ", storing %u to skip", av, (guint) (*skip - av));
2022         parse->priv->skip = *skip - av;
2023         gst_adapter_flush (parse->priv->adapter, av);
2024         *skip = av;
2025       }
2026     }
2027     if (!parse->priv->discont)
2028       parse->priv->sync_offset = parse->priv->offset;
2029     parse->priv->offset += *skip;
2030     parse->priv->discont = TRUE;
2031     /* check for indefinite skipping */
2032     if (ret == GST_FLOW_OK)
2033       ret = gst_base_parse_check_sync (parse);
2034   }
2035
2036   parse->priv->offset += *flushed;
2037
2038   if (parse->priv->pad_mode == GST_PAD_MODE_PULL) {
2039     gst_adapter_clear (parse->priv->adapter);
2040   }
2041
2042   gst_base_parse_frame_free (frame);
2043
2044   return ret;
2045 }
2046
2047 /* gst_base_parse_push_pending_events:
2048  * @parse: #GstBaseParse
2049  *
2050  * Pushes the pending events
2051  */
2052 static void
2053 gst_base_parse_push_pending_events (GstBaseParse * parse)
2054 {
2055   if (G_UNLIKELY (parse->priv->pending_events)) {
2056     GList *r = g_list_reverse (parse->priv->pending_events);
2057     GList *l;
2058
2059     parse->priv->pending_events = NULL;
2060     for (l = r; l != NULL; l = l->next) {
2061       gst_pad_push_event (parse->srcpad, GST_EVENT_CAST (l->data));
2062     }
2063     g_list_free (r);
2064   }
2065 }
2066
2067 /* gst_base_parse_handle_and_push_frame:
2068  * @parse: #GstBaseParse.
2069  * @klass: #GstBaseParseClass.
2070  * @frame: (transfer full): a #GstBaseParseFrame
2071  *
2072  * Parses the frame from given buffer and pushes it forward. Also performs
2073  * timestamp handling and checks the segment limits.
2074  *
2075  * This is called with srcpad STREAM_LOCK held.
2076  *
2077  * Returns: #GstFlowReturn
2078  */
2079 static GstFlowReturn
2080 gst_base_parse_handle_and_push_frame (GstBaseParse * parse,
2081     GstBaseParseFrame * frame)
2082 {
2083   gint64 offset;
2084   GstBuffer *buffer;
2085
2086   g_return_val_if_fail (frame != NULL, GST_FLOW_ERROR);
2087
2088   buffer = frame->buffer;
2089   offset = frame->offset;
2090
2091   /* check if subclass/format can provide ts.
2092    * If so, that allows and enables extra seek and duration determining options */
2093   if (G_UNLIKELY (parse->priv->first_frame_offset < 0)) {
2094     if (GST_BUFFER_PTS_IS_VALID (buffer) && parse->priv->has_timing_info
2095         && parse->priv->pad_mode == GST_PAD_MODE_PULL) {
2096       parse->priv->first_frame_offset = offset;
2097       parse->priv->first_frame_pts = GST_BUFFER_PTS (buffer);
2098       parse->priv->first_frame_dts = GST_BUFFER_DTS (buffer);
2099       GST_DEBUG_OBJECT (parse, "subclass provided dts %" GST_TIME_FORMAT
2100           ", pts %" GST_TIME_FORMAT " for first frame at offset %"
2101           G_GINT64_FORMAT, GST_TIME_ARGS (parse->priv->first_frame_dts),
2102           GST_TIME_ARGS (parse->priv->first_frame_pts),
2103           parse->priv->first_frame_offset);
2104       if (!GST_CLOCK_TIME_IS_VALID (parse->priv->duration)) {
2105         gint64 off;
2106         GstClockTime last_ts = G_MAXINT64;
2107
2108         GST_DEBUG_OBJECT (parse, "no duration; trying scan to determine");
2109         gst_base_parse_locate_time (parse, &last_ts, &off);
2110         if (GST_CLOCK_TIME_IS_VALID (last_ts))
2111           gst_base_parse_set_duration (parse, GST_FORMAT_TIME, last_ts, 0);
2112       }
2113     } else {
2114       /* disable further checks */
2115       parse->priv->first_frame_offset = 0;
2116     }
2117   }
2118
2119   /* track upstream time if provided, not subclass' internal notion of it */
2120   if (parse->priv->upstream_format == GST_FORMAT_TIME) {
2121     GST_BUFFER_PTS (frame->buffer) = GST_CLOCK_TIME_NONE;
2122     GST_BUFFER_DTS (frame->buffer) = GST_CLOCK_TIME_NONE;
2123   }
2124
2125   /* interpolating and no valid pts yet,
2126    * start with dts and carry on from there */
2127   if (parse->priv->infer_ts && parse->priv->pts_interpolate
2128       && !GST_CLOCK_TIME_IS_VALID (parse->priv->next_pts))
2129     parse->priv->next_pts = parse->priv->next_dts;
2130
2131   /* again use default handler to add missing metadata;
2132    * we may have new information on frame properties */
2133   gst_base_parse_parse_frame (parse, frame);
2134
2135   parse->priv->next_pts = GST_CLOCK_TIME_NONE;
2136   if (GST_BUFFER_DTS_IS_VALID (buffer) && GST_BUFFER_DURATION_IS_VALID (buffer)) {
2137     parse->priv->next_dts =
2138         GST_BUFFER_DTS (buffer) + GST_BUFFER_DURATION (buffer);
2139     if (parse->priv->pts_interpolate && GST_BUFFER_PTS_IS_VALID (buffer)) {
2140       GstClockTime next_pts =
2141           GST_BUFFER_PTS (buffer) + GST_BUFFER_DURATION (buffer);
2142       if (next_pts >= parse->priv->next_dts)
2143         parse->priv->next_pts = next_pts;
2144     }
2145   } else {
2146     /* we lost track, do not produce bogus time next time around
2147      * (probably means parser subclass has given up on parsing as well) */
2148     GST_DEBUG_OBJECT (parse, "no next fallback timestamp");
2149     parse->priv->next_dts = GST_CLOCK_TIME_NONE;
2150   }
2151
2152   if (parse->priv->upstream_seekable && parse->priv->exact_position &&
2153       GST_BUFFER_PTS_IS_VALID (buffer))
2154     gst_base_parse_add_index_entry (parse, offset,
2155         GST_BUFFER_PTS (buffer),
2156         !GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT), FALSE);
2157
2158   /* All OK, push queued frames if there are any */
2159   if (G_UNLIKELY (!g_queue_is_empty (&parse->priv->queued_frames))) {
2160     GstBaseParseFrame *queued_frame;
2161
2162     while ((queued_frame = g_queue_pop_head (&parse->priv->queued_frames))) {
2163       gst_base_parse_push_frame (parse, queued_frame);
2164       gst_base_parse_frame_free (queued_frame);
2165     }
2166   }
2167
2168   return gst_base_parse_push_frame (parse, frame);
2169 }
2170
2171 /**
2172  * gst_base_parse_push_frame:
2173  * @parse: #GstBaseParse.
2174  * @frame: (transfer none): a #GstBaseParseFrame
2175  *
2176  * Pushes the frame's buffer downstream, sends any pending events and
2177  * does some timestamp and segment handling. Takes ownership of
2178  * frame's buffer, though caller retains ownership of @frame.
2179  *
2180  * This must be called with sinkpad STREAM_LOCK held.
2181  *
2182  * Returns: #GstFlowReturn
2183  */
2184 GstFlowReturn
2185 gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
2186 {
2187   GstFlowReturn ret = GST_FLOW_OK;
2188   GstClockTime last_start = GST_CLOCK_TIME_NONE;
2189   GstClockTime last_stop = GST_CLOCK_TIME_NONE;
2190   GstBaseParseClass *klass = GST_BASE_PARSE_GET_CLASS (parse);
2191   GstBuffer *buffer;
2192   gsize size;
2193
2194   g_return_val_if_fail (frame != NULL, GST_FLOW_ERROR);
2195   g_return_val_if_fail (frame->buffer != NULL, GST_FLOW_ERROR);
2196
2197   GST_TRACE_OBJECT (parse, "pushing frame %p", frame);
2198
2199   buffer = frame->buffer;
2200
2201   GST_LOG_OBJECT (parse,
2202       "processing buffer of size %" G_GSIZE_FORMAT " with dts %" GST_TIME_FORMAT
2203       ", pts %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT,
2204       gst_buffer_get_size (buffer),
2205       GST_TIME_ARGS (GST_BUFFER_DTS (buffer)),
2206       GST_TIME_ARGS (GST_BUFFER_PTS (buffer)),
2207       GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
2208
2209   /* update stats */
2210   parse->priv->bytecount += frame->size;
2211   if (G_LIKELY (!(frame->flags & GST_BASE_PARSE_FRAME_FLAG_NO_FRAME))) {
2212     parse->priv->framecount++;
2213     if (GST_BUFFER_DURATION_IS_VALID (buffer)) {
2214       parse->priv->acc_duration += GST_BUFFER_DURATION (buffer);
2215     }
2216   }
2217   /* 0 means disabled */
2218   if (parse->priv->update_interval < 0)
2219     parse->priv->update_interval = 50;
2220   else if (parse->priv->update_interval > 0 &&
2221       (parse->priv->framecount % parse->priv->update_interval) == 0)
2222     gst_base_parse_update_duration (parse);
2223
2224   if (GST_BUFFER_PTS_IS_VALID (buffer))
2225     last_start = last_stop = GST_BUFFER_PTS (buffer);
2226   if (last_start != GST_CLOCK_TIME_NONE
2227       && GST_BUFFER_DURATION_IS_VALID (buffer))
2228     last_stop = last_start + GST_BUFFER_DURATION (buffer);
2229
2230   /* should have caps by now */
2231   if (!gst_pad_has_current_caps (parse->srcpad))
2232     goto no_caps;
2233
2234   if (G_UNLIKELY (!parse->priv->checked_media)) {
2235     /* have caps; check identity */
2236     gst_base_parse_check_media (parse);
2237   }
2238
2239   /* Push pending events, including SEGMENT events */
2240   gst_base_parse_push_pending_events (parse);
2241
2242   /* segment adjustment magic; only if we are running the whole show */
2243   if (!parse->priv->passthrough && parse->segment.rate > 0.0 &&
2244       (parse->priv->pad_mode == GST_PAD_MODE_PULL ||
2245           parse->priv->upstream_seekable)) {
2246     /* handle gaps */
2247     if (GST_CLOCK_TIME_IS_VALID (parse->segment.position) &&
2248         GST_CLOCK_TIME_IS_VALID (last_start)) {
2249       GstClockTimeDiff diff;
2250
2251       /* only send newsegments with increasing start times,
2252        * otherwise if these go back and forth downstream (sinks) increase
2253        * accumulated time and running_time */
2254       diff = GST_CLOCK_DIFF (parse->segment.position, last_start);
2255       if (G_UNLIKELY (diff > 2 * GST_SECOND
2256               && last_start > parse->segment.start
2257               && (!GST_CLOCK_TIME_IS_VALID (parse->segment.stop)
2258                   || last_start < parse->segment.stop))) {
2259
2260         GST_DEBUG_OBJECT (parse,
2261             "Gap of %" G_GINT64_FORMAT " ns detected in stream " "(%"
2262             GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
2263             "Sending updated SEGMENT events", diff,
2264             GST_TIME_ARGS (parse->segment.position),
2265             GST_TIME_ARGS (last_start));
2266
2267         /* skip gap FIXME */
2268         gst_pad_push_event (parse->srcpad,
2269             gst_event_new_segment (&parse->segment));
2270
2271         parse->segment.position = last_start;
2272       }
2273     }
2274   }
2275
2276   /* update bitrates and optionally post corresponding tags
2277    * (following newsegment) */
2278   gst_base_parse_update_bitrates (parse, frame);
2279
2280   if (klass->pre_push_frame) {
2281     ret = klass->pre_push_frame (parse, frame);
2282   } else {
2283     frame->flags |= GST_BASE_PARSE_FRAME_FLAG_CLIP;
2284   }
2285
2286   /* take final ownership of frame buffer */
2287   if (frame->out_buffer) {
2288     buffer = frame->out_buffer;
2289     frame->out_buffer = NULL;
2290     gst_buffer_replace (&frame->buffer, NULL);
2291   } else {
2292     buffer = frame->buffer;
2293     frame->buffer = NULL;
2294   }
2295
2296   /* subclass must play nice */
2297   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
2298
2299   size = gst_buffer_get_size (buffer);
2300
2301   parse->priv->seen_keyframe |= parse->priv->is_video &&
2302       !GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
2303
2304   if (frame->flags & GST_BASE_PARSE_FRAME_FLAG_CLIP) {
2305     if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
2306         GST_CLOCK_TIME_IS_VALID (parse->segment.stop) &&
2307         GST_BUFFER_TIMESTAMP (buffer) >
2308         parse->segment.stop + parse->priv->lead_out_ts) {
2309       GST_LOG_OBJECT (parse, "Dropped frame, after segment");
2310       ret = GST_FLOW_EOS;
2311     } else if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
2312         GST_BUFFER_DURATION_IS_VALID (buffer) &&
2313         GST_CLOCK_TIME_IS_VALID (parse->segment.start) &&
2314         GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer) +
2315         parse->priv->lead_in_ts < parse->segment.start) {
2316       if (parse->priv->seen_keyframe) {
2317         GST_LOG_OBJECT (parse, "Frame before segment, after keyframe");
2318         ret = GST_FLOW_OK;
2319       } else {
2320         GST_LOG_OBJECT (parse, "Dropped frame, before segment");
2321         ret = GST_BASE_PARSE_FLOW_DROPPED;
2322       }
2323     } else {
2324       ret = GST_FLOW_OK;
2325     }
2326   }
2327
2328   if (ret == GST_BASE_PARSE_FLOW_DROPPED) {
2329     GST_LOG_OBJECT (parse, "frame (%" G_GSIZE_FORMAT " bytes) dropped", size);
2330     gst_buffer_unref (buffer);
2331     ret = GST_FLOW_OK;
2332   } else if (ret == GST_FLOW_OK) {
2333     if (parse->segment.rate > 0.0) {
2334       GST_LOG_OBJECT (parse, "pushing frame (%" G_GSIZE_FORMAT " bytes) now..",
2335           size);
2336       ret = gst_pad_push (parse->srcpad, buffer);
2337       GST_LOG_OBJECT (parse, "frame pushed, flow %s", gst_flow_get_name (ret));
2338     } else if (!parse->priv->disable_passthrough && parse->priv->passthrough) {
2339
2340       /* in backwards playback mode, if on passthrough we need to push buffers
2341        * directly without accumulating them into the buffers_queued as baseparse
2342        * will never check for a DISCONT while on passthrough and those buffers
2343        * will never be pushed.
2344        *
2345        * also, as we are on reverse playback, it might be possible that
2346        * passthrough might have just been enabled, so make sure to drain the
2347        * buffers_queued list */
2348       if (G_UNLIKELY (parse->priv->buffers_queued != NULL)) {
2349         gst_base_parse_finish_fragment (parse, TRUE);
2350         ret = gst_base_parse_send_buffers (parse);
2351       }
2352
2353       if (ret == GST_FLOW_OK) {
2354         GST_LOG_OBJECT (parse,
2355             "pushing frame (%" G_GSIZE_FORMAT " bytes) now..", size);
2356         ret = gst_pad_push (parse->srcpad, buffer);
2357         GST_LOG_OBJECT (parse, "frame pushed, flow %s",
2358             gst_flow_get_name (ret));
2359       } else {
2360         GST_LOG_OBJECT (parse,
2361             "frame (%" G_GSIZE_FORMAT " bytes) not pushed: %s", size,
2362             gst_flow_get_name (ret));
2363         gst_buffer_unref (buffer);
2364       }
2365
2366     } else {
2367       GST_LOG_OBJECT (parse, "frame (%" G_GSIZE_FORMAT " bytes) queued for now",
2368           size);
2369       parse->priv->buffers_queued =
2370           g_slist_prepend (parse->priv->buffers_queued, buffer);
2371       ret = GST_FLOW_OK;
2372     }
2373   } else {
2374     GST_LOG_OBJECT (parse, "frame (%" G_GSIZE_FORMAT " bytes) not pushed: %s",
2375         size, gst_flow_get_name (ret));
2376     gst_buffer_unref (buffer);
2377     /* if we are not sufficiently in control, let upstream decide on EOS */
2378     if (ret == GST_FLOW_EOS && !parse->priv->disable_passthrough &&
2379         (parse->priv->passthrough ||
2380             (parse->priv->pad_mode == GST_PAD_MODE_PUSH &&
2381                 !parse->priv->upstream_seekable)))
2382       ret = GST_FLOW_OK;
2383   }
2384
2385   /* Update current running segment position */
2386   if (ret == GST_FLOW_OK && last_stop != GST_CLOCK_TIME_NONE &&
2387       parse->segment.position < last_stop)
2388     parse->segment.position = last_stop;
2389
2390   return ret;
2391
2392   /* ERRORS */
2393 no_caps:
2394   {
2395     if (GST_PAD_IS_FLUSHING (parse->srcpad))
2396       return GST_FLOW_FLUSHING;
2397
2398     GST_ELEMENT_ERROR (parse, STREAM, DECODE, ("No caps set"), (NULL));
2399     return GST_FLOW_ERROR;
2400   }
2401 }
2402
2403 /**
2404  * gst_base_parse_finish_frame:
2405  * @parse: a #GstBaseParse
2406  * @frame: a #GstBaseParseFrame
2407  * @size: consumed input data represented by frame
2408  *
2409  * Collects parsed data and pushes this downstream.
2410  * Source pad caps must be set when this is called.
2411  *
2412  * If @frame's out_buffer is set, that will be used as subsequent frame data.
2413  * Otherwise, @size samples will be taken from the input and used for output,
2414  * and the output's metadata (timestamps etc) will be taken as (optionally)
2415  * set by the subclass on @frame's (input) buffer (which is otherwise
2416  * ignored for any but the above purpose/information).
2417  *
2418  * Note that the latter buffer is invalidated by this call, whereas the
2419  * caller retains ownership of @frame.
2420  *
2421  * Returns: a #GstFlowReturn that should be escalated to caller (of caller)
2422  */
2423 GstFlowReturn
2424 gst_base_parse_finish_frame (GstBaseParse * parse, GstBaseParseFrame * frame,
2425     gint size)
2426 {
2427   GstFlowReturn ret = GST_FLOW_OK;
2428
2429   g_return_val_if_fail (frame != NULL, GST_FLOW_ERROR);
2430   g_return_val_if_fail (frame->buffer != NULL, GST_FLOW_ERROR);
2431   g_return_val_if_fail (size > 0 || frame->out_buffer, GST_FLOW_ERROR);
2432   g_return_val_if_fail (gst_adapter_available (parse->priv->adapter) >= size,
2433       GST_FLOW_ERROR);
2434
2435   GST_LOG_OBJECT (parse, "finished frame at offset %" G_GUINT64_FORMAT ", "
2436       "flushing size %d", frame->offset, size);
2437
2438   /* some one-time start-up */
2439   if (G_UNLIKELY (parse->priv->framecount == 0)) {
2440     gst_base_parse_check_seekability (parse);
2441     gst_base_parse_check_upstream (parse);
2442   }
2443
2444   parse->priv->flushed += size;
2445
2446   if (parse->priv->scanning && frame->buffer) {
2447     if (!parse->priv->scanned_frame) {
2448       parse->priv->scanned_frame = gst_base_parse_frame_copy (frame);
2449     }
2450     goto exit;
2451   }
2452
2453   /* either PUSH or PULL mode arranges for adapter data */
2454   /* ensure output buffer */
2455   if (!frame->out_buffer) {
2456     GstBuffer *src, *dest;
2457
2458     frame->out_buffer = gst_adapter_take_buffer (parse->priv->adapter, size);
2459     dest = frame->out_buffer;
2460     src = frame->buffer;
2461     GST_BUFFER_PTS (dest) = GST_BUFFER_PTS (src);
2462     GST_BUFFER_DTS (dest) = GST_BUFFER_DTS (src);
2463     GST_BUFFER_OFFSET (dest) = GST_BUFFER_OFFSET (src);
2464     GST_BUFFER_DURATION (dest) = GST_BUFFER_DURATION (src);
2465     GST_BUFFER_OFFSET_END (dest) = GST_BUFFER_OFFSET_END (src);
2466     GST_MINI_OBJECT_FLAGS (dest) = GST_MINI_OBJECT_FLAGS (src);
2467   } else {
2468     gst_adapter_flush (parse->priv->adapter, size);
2469   }
2470
2471   /* use as input for subsequent processing */
2472   gst_buffer_replace (&frame->buffer, frame->out_buffer);
2473   gst_buffer_unref (frame->out_buffer);
2474   frame->out_buffer = NULL;
2475
2476   /* mark input size consumed */
2477   frame->size = size;
2478
2479   /* subclass might queue frames/data internally if it needs more
2480    * frames to decide on the format, or might request us to queue here. */
2481   if (frame->flags & GST_BASE_PARSE_FRAME_FLAG_DROP) {
2482     gst_buffer_replace (&frame->buffer, NULL);
2483     goto exit;
2484   } else if (frame->flags & GST_BASE_PARSE_FRAME_FLAG_QUEUE) {
2485     GstBaseParseFrame *copy;
2486
2487     copy = gst_base_parse_frame_copy (frame);
2488     copy->flags &= ~GST_BASE_PARSE_FRAME_FLAG_QUEUE;
2489     gst_base_parse_queue_frame (parse, copy);
2490     goto exit;
2491   }
2492
2493   ret = gst_base_parse_handle_and_push_frame (parse, frame);
2494
2495 exit:
2496   return ret;
2497 }
2498
2499 /* gst_base_parse_drain:
2500  *
2501  * Drains the adapter until it is empty. It decreases the min_frame_size to
2502  * match the current adapter size and calls chain method until the adapter
2503  * is emptied or chain returns with error.
2504  */
2505 static void
2506 gst_base_parse_drain (GstBaseParse * parse)
2507 {
2508   guint avail;
2509
2510   GST_DEBUG_OBJECT (parse, "draining");
2511   parse->priv->drain = TRUE;
2512
2513   for (;;) {
2514     avail = gst_adapter_available (parse->priv->adapter);
2515     if (!avail)
2516       break;
2517
2518     if (gst_base_parse_chain (parse->sinkpad, GST_OBJECT_CAST (parse),
2519             NULL) != GST_FLOW_OK) {
2520       break;
2521     }
2522
2523     /* nothing changed, maybe due to truncated frame; break infinite loop */
2524     if (avail == gst_adapter_available (parse->priv->adapter)) {
2525       GST_DEBUG_OBJECT (parse, "no change during draining; flushing");
2526       gst_adapter_clear (parse->priv->adapter);
2527     }
2528   }
2529
2530   parse->priv->drain = FALSE;
2531 }
2532
2533 /* gst_base_parse_send_buffers
2534  *
2535  * Sends buffers collected in send_buffers downstream, and ensures that list
2536  * is empty at the end (errors or not).
2537  */
2538 static GstFlowReturn
2539 gst_base_parse_send_buffers (GstBaseParse * parse)
2540 {
2541   GSList *send = NULL;
2542   GstBuffer *buf;
2543   GstFlowReturn ret = GST_FLOW_OK;
2544   gboolean first = TRUE;
2545
2546   send = parse->priv->buffers_send;
2547
2548   /* send buffers */
2549   while (send) {
2550     buf = GST_BUFFER_CAST (send->data);
2551     GST_LOG_OBJECT (parse, "pushing buffer %p, dts %"
2552         GST_TIME_FORMAT ", pts %" GST_TIME_FORMAT ", duration %" GST_TIME_FORMAT
2553         ", offset %" G_GINT64_FORMAT, buf,
2554         GST_TIME_ARGS (GST_BUFFER_DTS (buf)),
2555         GST_TIME_ARGS (GST_BUFFER_PTS (buf)),
2556         GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_BUFFER_OFFSET (buf));
2557
2558     /* Make sure the first buffer is always DISCONT. If we split
2559      * GOPs inside the parser this is otherwise not guaranteed */
2560     if (first) {
2561       GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
2562       first = FALSE;
2563     }
2564
2565     /* iterate output queue an push downstream */
2566     ret = gst_pad_push (parse->srcpad, buf);
2567     send = g_slist_delete_link (send, send);
2568
2569     /* clear any leftover if error */
2570     if (G_UNLIKELY (ret != GST_FLOW_OK)) {
2571       while (send) {
2572         buf = GST_BUFFER_CAST (send->data);
2573         gst_buffer_unref (buf);
2574         send = g_slist_delete_link (send, send);
2575       }
2576     }
2577   }
2578
2579   parse->priv->buffers_send = send;
2580
2581   return ret;
2582 }
2583
2584 /* gst_base_parse_start_fragment:
2585  *
2586  * Prepares for processing a reverse playback (forward) fragment
2587  * by (re)setting proper state variables.
2588  */
2589 static GstFlowReturn
2590 gst_base_parse_start_fragment (GstBaseParse * parse)
2591 {
2592   GST_LOG_OBJECT (parse, "starting fragment");
2593
2594   /* invalidate so no fall-back timestamping is performed;
2595    * ok if taken from subclass or upstream */
2596   parse->priv->next_pts = GST_CLOCK_TIME_NONE;
2597   parse->priv->prev_pts = GST_CLOCK_TIME_NONE;
2598   parse->priv->next_dts = GST_CLOCK_TIME_NONE;
2599   parse->priv->prev_dts = GST_CLOCK_TIME_NONE;
2600   /* prevent it hanging around stop all the time */
2601   parse->segment.position = GST_CLOCK_TIME_NONE;
2602   /* mark next run */
2603   parse->priv->discont = TRUE;
2604
2605   /* head of previous fragment is now pending tail of current fragment */
2606   parse->priv->buffers_pending = parse->priv->buffers_head;
2607   parse->priv->buffers_head = NULL;
2608
2609   return GST_FLOW_OK;
2610 }
2611
2612
2613 /* gst_base_parse_finish_fragment:
2614  *
2615  * Processes a reverse playback (forward) fragment:
2616  * - append head of last fragment that was skipped to current fragment data
2617  * - drain the resulting current fragment data (i.e. repeated chain)
2618  * - add time/duration (if needed) to frames queued by chain
2619  * - push queued data
2620  */
2621 static GstFlowReturn
2622 gst_base_parse_finish_fragment (GstBaseParse * parse, gboolean prev_head)
2623 {
2624   GstBuffer *buf;
2625   GstFlowReturn ret = GST_FLOW_OK;
2626   gboolean seen_key = FALSE, seen_delta = FALSE;
2627
2628   GST_LOG_OBJECT (parse, "finishing fragment");
2629
2630   /* restore order */
2631   parse->priv->buffers_pending = g_slist_reverse (parse->priv->buffers_pending);
2632   while (parse->priv->buffers_pending) {
2633     buf = GST_BUFFER_CAST (parse->priv->buffers_pending->data);
2634     if (prev_head) {
2635       GST_LOG_OBJECT (parse, "adding pending buffer (size %" G_GSIZE_FORMAT ")",
2636           gst_buffer_get_size (buf));
2637       gst_adapter_push (parse->priv->adapter, buf);
2638     } else {
2639       GST_LOG_OBJECT (parse, "discarding head buffer");
2640       gst_buffer_unref (buf);
2641     }
2642     parse->priv->buffers_pending =
2643         g_slist_delete_link (parse->priv->buffers_pending,
2644         parse->priv->buffers_pending);
2645   }
2646
2647   /* chain looks for frames and queues resulting ones (in stead of pushing) */
2648   /* initial skipped data is added to buffers_pending */
2649   gst_base_parse_drain (parse);
2650
2651   if (parse->priv->buffers_send) {
2652     buf = GST_BUFFER_CAST (parse->priv->buffers_send->data);
2653     seen_key |= !GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT);
2654   }
2655
2656   /* add metadata (if needed to queued buffers */
2657   GST_LOG_OBJECT (parse, "last timestamp: %" GST_TIME_FORMAT,
2658       GST_TIME_ARGS (parse->priv->last_pts));
2659   while (parse->priv->buffers_queued) {
2660     buf = GST_BUFFER_CAST (parse->priv->buffers_queued->data);
2661
2662     /* no touching if upstream or parsing provided time */
2663     if (GST_BUFFER_PTS_IS_VALID (buf)) {
2664       GST_LOG_OBJECT (parse, "buffer has time %" GST_TIME_FORMAT,
2665           GST_TIME_ARGS (GST_BUFFER_PTS (buf)));
2666     } else if (GST_BUFFER_DURATION_IS_VALID (buf)) {
2667       if (GST_CLOCK_TIME_IS_VALID (parse->priv->last_pts)) {
2668         if (G_LIKELY (GST_BUFFER_DURATION (buf) <= parse->priv->last_pts))
2669           parse->priv->last_pts -= GST_BUFFER_DURATION (buf);
2670         else
2671           parse->priv->last_pts = 0;
2672         GST_BUFFER_PTS (buf) = parse->priv->last_pts;
2673         GST_LOG_OBJECT (parse, "applied time %" GST_TIME_FORMAT,
2674             GST_TIME_ARGS (GST_BUFFER_PTS (buf)));
2675       }
2676       if (GST_CLOCK_TIME_IS_VALID (parse->priv->last_dts)) {
2677         if (G_LIKELY (GST_BUFFER_DURATION (buf) <= parse->priv->last_dts))
2678           parse->priv->last_dts -= GST_BUFFER_DURATION (buf);
2679         else
2680           parse->priv->last_dts = 0;
2681         GST_BUFFER_DTS (buf) = parse->priv->last_dts;
2682         GST_LOG_OBJECT (parse, "applied dts %" GST_TIME_FORMAT,
2683             GST_TIME_ARGS (GST_BUFFER_DTS (buf)));
2684       }
2685     } else {
2686       /* no idea, very bad */
2687       GST_WARNING_OBJECT (parse, "could not determine time for buffer");
2688     }
2689
2690     parse->priv->last_pts = GST_BUFFER_PTS (buf);
2691     parse->priv->last_dts = GST_BUFFER_DTS (buf);
2692
2693     /* reverse order for ascending sending */
2694     /* send downstream at keyframe not preceded by a keyframe
2695      * (e.g. that should identify start of collection of IDR nals) */
2696     if (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT)) {
2697       if (seen_key) {
2698         ret = gst_base_parse_send_buffers (parse);
2699         /* if a problem, throw all to sending */
2700         if (ret != GST_FLOW_OK) {
2701           parse->priv->buffers_send =
2702               g_slist_reverse (parse->priv->buffers_queued);
2703           parse->priv->buffers_queued = NULL;
2704           break;
2705         }
2706         seen_key = FALSE;
2707       }
2708       seen_delta = TRUE;
2709     } else {
2710       seen_key = TRUE;
2711     }
2712
2713     parse->priv->buffers_send =
2714         g_slist_prepend (parse->priv->buffers_send, buf);
2715     parse->priv->buffers_queued =
2716         g_slist_delete_link (parse->priv->buffers_queued,
2717         parse->priv->buffers_queued);
2718   }
2719
2720   /* audio may have all marked as keyframe, so arrange to send here. Also
2721    * we might have ended the loop above on a keyframe, in which case we
2722    * should */
2723   if (!seen_delta || seen_key)
2724     ret = gst_base_parse_send_buffers (parse);
2725
2726   /* any trailing unused no longer usable (ideally none) */
2727   if (G_UNLIKELY (gst_adapter_available (parse->priv->adapter))) {
2728     GST_DEBUG_OBJECT (parse, "discarding %" G_GSIZE_FORMAT " trailing bytes",
2729         gst_adapter_available (parse->priv->adapter));
2730     gst_adapter_clear (parse->priv->adapter);
2731   }
2732
2733   return ret;
2734 }
2735
2736 /* small helper that checks whether we have been trying to resync too long */
2737 static inline GstFlowReturn
2738 gst_base_parse_check_sync (GstBaseParse * parse)
2739 {
2740   if (G_UNLIKELY (parse->priv->discont &&
2741           parse->priv->offset - parse->priv->sync_offset > 2 * 1024 * 1024)) {
2742     GST_ELEMENT_ERROR (parse, STREAM, DECODE,
2743         ("Failed to parse stream"), (NULL));
2744     return GST_FLOW_ERROR;
2745   }
2746
2747   return GST_FLOW_OK;
2748 }
2749
2750 static GstFlowReturn
2751 gst_base_parse_process_streamheader (GstBaseParse * parse)
2752 {
2753   GstCaps *caps;
2754   GstStructure *str;
2755   const GValue *value;
2756   GstFlowReturn ret = GST_FLOW_OK;
2757
2758   caps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (parse));
2759   if (caps == NULL)
2760     goto notfound;
2761
2762   str = gst_caps_get_structure (caps, 0);
2763   value = gst_structure_get_value (str, "streamheader");
2764   if (value == NULL)
2765     goto notfound;
2766
2767   GST_DEBUG_OBJECT (parse, "Found streamheader field on input caps");
2768
2769   if (GST_VALUE_HOLDS_ARRAY (value)) {
2770     gint i;
2771     gsize len = gst_value_array_get_size (value);
2772
2773     for (i = 0; i < len; i++) {
2774       GstBuffer *buffer =
2775           gst_value_get_buffer (gst_value_array_get_value (value, i));
2776       ret =
2777           gst_base_parse_chain (GST_BASE_PARSE_SINK_PAD (parse),
2778           GST_OBJECT_CAST (parse), gst_buffer_ref (buffer));
2779     }
2780
2781   } else if (GST_VALUE_HOLDS_BUFFER (value)) {
2782     GstBuffer *buffer = gst_value_get_buffer (value);
2783     ret =
2784         gst_base_parse_chain (GST_BASE_PARSE_SINK_PAD (parse),
2785         GST_OBJECT_CAST (parse), gst_buffer_ref (buffer));
2786   }
2787
2788   gst_caps_unref (caps);
2789
2790   return ret;
2791
2792 notfound:
2793   {
2794     if (caps) {
2795       gst_caps_unref (caps);
2796     }
2797
2798     GST_DEBUG_OBJECT (parse, "No streamheader on caps");
2799     return GST_FLOW_OK;
2800   }
2801 }
2802
2803 static GstFlowReturn
2804 gst_base_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
2805 {
2806   GstBaseParseClass *bclass;
2807   GstBaseParse *parse;
2808   GstFlowReturn ret = GST_FLOW_OK;
2809   GstFlowReturn old_ret = GST_FLOW_OK;
2810   GstBuffer *tmpbuf = NULL;
2811   guint fsize = 1;
2812   gint skip = -1;
2813   const guint8 *data;
2814   guint min_size, av;
2815   GstClockTime pts, dts;
2816
2817   parse = GST_BASE_PARSE (parent);
2818   bclass = GST_BASE_PARSE_GET_CLASS (parse);
2819   GST_DEBUG_OBJECT (parent, "chain");
2820
2821   /* early out for speed, if we need to skip */
2822   if (buffer && GST_BUFFER_IS_DISCONT (buffer))
2823     parse->priv->skip = 0;
2824   if (parse->priv->skip > 0) {
2825     gsize bsize = gst_buffer_get_size (buffer);
2826     GST_DEBUG ("Got %" G_GSIZE_FORMAT " buffer, need to skip %u", bsize,
2827         parse->priv->skip);
2828     if (parse->priv->skip >= bsize) {
2829       parse->priv->skip -= bsize;
2830       GST_DEBUG ("All the buffer is skipped");
2831       parse->priv->offset += bsize;
2832       parse->priv->sync_offset = parse->priv->offset;
2833       return GST_FLOW_OK;
2834     }
2835     buffer = gst_buffer_make_writable (buffer);
2836     gst_buffer_resize (buffer, parse->priv->skip, bsize - parse->priv->skip);
2837     parse->priv->offset += parse->priv->skip;
2838     GST_DEBUG ("Done skipping, we have %u left on this buffer",
2839         (unsigned) (bsize - parse->priv->skip));
2840     parse->priv->skip = 0;
2841     parse->priv->discont = TRUE;
2842   }
2843
2844   if (G_UNLIKELY (parse->priv->first_buffer)) {
2845     parse->priv->first_buffer = FALSE;
2846     if (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_HEADER)) {
2847       /* this stream has no header buffers, check if we just prepend the
2848        * streamheader from caps to the stream */
2849       GST_DEBUG_OBJECT (parse, "Looking for streamheader field on caps to "
2850           "prepend to the stream");
2851       gst_base_parse_process_streamheader (parse);
2852     } else {
2853       GST_DEBUG_OBJECT (parse, "Stream has header buffers, not prepending "
2854           "streamheader from caps");
2855     }
2856   }
2857
2858   if (parse->priv->detecting) {
2859     GstBuffer *detect_buf;
2860
2861     if (parse->priv->detect_buffers_size == 0) {
2862       detect_buf = gst_buffer_ref (buffer);
2863     } else {
2864       GList *l;
2865       guint offset = 0;
2866
2867       detect_buf = gst_buffer_new ();
2868
2869       for (l = parse->priv->detect_buffers; l; l = l->next) {
2870         gsize tmpsize = gst_buffer_get_size (l->data);
2871
2872         gst_buffer_copy_into (detect_buf, GST_BUFFER_CAST (l->data),
2873             GST_BUFFER_COPY_MEMORY, offset, tmpsize);
2874         offset += tmpsize;
2875       }
2876       if (buffer)
2877         gst_buffer_copy_into (detect_buf, buffer, GST_BUFFER_COPY_MEMORY,
2878             offset, gst_buffer_get_size (buffer));
2879     }
2880
2881     ret = bclass->detect (parse, detect_buf);
2882     gst_buffer_unref (detect_buf);
2883
2884     if (ret == GST_FLOW_OK) {
2885       GList *l;
2886
2887       /* Detected something */
2888       parse->priv->detecting = FALSE;
2889
2890       for (l = parse->priv->detect_buffers; l; l = l->next) {
2891         if (ret == GST_FLOW_OK && !parse->priv->flushing)
2892           ret =
2893               gst_base_parse_chain (GST_BASE_PARSE_SINK_PAD (parse),
2894               parent, GST_BUFFER_CAST (l->data));
2895         else
2896           gst_buffer_unref (GST_BUFFER_CAST (l->data));
2897       }
2898       g_list_free (parse->priv->detect_buffers);
2899       parse->priv->detect_buffers = NULL;
2900       parse->priv->detect_buffers_size = 0;
2901
2902       if (ret != GST_FLOW_OK) {
2903         return ret;
2904       }
2905
2906       /* Handle the current buffer */
2907     } else if (ret == GST_FLOW_NOT_NEGOTIATED) {
2908       /* Still detecting, append buffer or error out if draining */
2909
2910       if (parse->priv->drain) {
2911         GST_DEBUG_OBJECT (parse, "Draining but did not detect format yet");
2912         return GST_FLOW_ERROR;
2913       } else if (parse->priv->flushing) {
2914         g_list_foreach (parse->priv->detect_buffers, (GFunc) gst_buffer_unref,
2915             NULL);
2916         g_list_free (parse->priv->detect_buffers);
2917         parse->priv->detect_buffers = NULL;
2918         parse->priv->detect_buffers_size = 0;
2919       } else {
2920         parse->priv->detect_buffers =
2921             g_list_append (parse->priv->detect_buffers, buffer);
2922         parse->priv->detect_buffers_size += gst_buffer_get_size (buffer);
2923         return GST_FLOW_OK;
2924       }
2925     } else {
2926       /* Something went wrong, subclass responsible for error reporting */
2927       return ret;
2928     }
2929
2930     /* And now handle the current buffer if detection worked */
2931   }
2932
2933   if (G_LIKELY (buffer)) {
2934     GST_LOG_OBJECT (parse,
2935         "buffer size: %" G_GSIZE_FORMAT ", offset = %" G_GINT64_FORMAT
2936         ", dts %" GST_TIME_FORMAT ", pts %" GST_TIME_FORMAT,
2937         gst_buffer_get_size (buffer), GST_BUFFER_OFFSET (buffer),
2938         GST_TIME_ARGS (GST_BUFFER_DTS (buffer)),
2939         GST_TIME_ARGS (GST_BUFFER_PTS (buffer)));
2940
2941     if (G_UNLIKELY (!parse->priv->disable_passthrough
2942             && parse->priv->passthrough)) {
2943       GstBaseParseFrame frame;
2944
2945       gst_base_parse_frame_init (&frame);
2946       frame.buffer = gst_buffer_make_writable (buffer);
2947       ret = gst_base_parse_push_frame (parse, &frame);
2948       gst_base_parse_frame_free (&frame);
2949       return ret;
2950     }
2951     /* upstream feeding us in reverse playback;
2952      * finish previous fragment and start new upon DISCONT */
2953     if (parse->segment.rate < 0.0) {
2954       if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT))) {
2955         GST_DEBUG_OBJECT (parse, "buffer starts new reverse playback fragment");
2956         ret = gst_base_parse_finish_fragment (parse, TRUE);
2957         gst_base_parse_start_fragment (parse);
2958       }
2959     }
2960     gst_adapter_push (parse->priv->adapter, buffer);
2961   }
2962
2963   /* Parse and push as many frames as possible */
2964   /* Stop either when adapter is empty or we are flushing */
2965   while (!parse->priv->flushing) {
2966     gint flush = 0;
2967
2968     /* note: if subclass indicates MAX fsize,
2969      * this will not likely be available anyway ... */
2970     min_size = MAX (parse->priv->min_frame_size, fsize);
2971     av = gst_adapter_available (parse->priv->adapter);
2972
2973     if (G_UNLIKELY (parse->priv->drain)) {
2974       min_size = av;
2975       GST_DEBUG_OBJECT (parse, "draining, data left: %d", min_size);
2976       if (G_UNLIKELY (!min_size)) {
2977         goto done;
2978       }
2979     }
2980
2981     /* Collect at least min_frame_size bytes */
2982     if (av < min_size) {
2983       GST_DEBUG_OBJECT (parse, "not enough data available (only %d bytes)", av);
2984       goto done;
2985     }
2986
2987     /* move along with upstream timestamp (if any),
2988      * but interpolate in between */
2989     pts = gst_adapter_prev_pts (parse->priv->adapter, NULL);
2990     dts = gst_adapter_prev_dts (parse->priv->adapter, NULL);
2991     if (GST_CLOCK_TIME_IS_VALID (pts) && (parse->priv->prev_pts != pts))
2992       parse->priv->prev_pts = parse->priv->next_pts = pts;
2993
2994     if (GST_CLOCK_TIME_IS_VALID (dts) && (parse->priv->prev_dts != dts))
2995       parse->priv->prev_dts = parse->priv->next_dts = dts;
2996
2997     /* we can mess with, erm interpolate, timestamps,
2998      * and incoming stuff has PTS but no DTS seen so far,
2999      * then pick up DTS from PTS and hope for the best ... */
3000     if (parse->priv->infer_ts &&
3001         parse->priv->pts_interpolate &&
3002         !GST_CLOCK_TIME_IS_VALID (dts) &&
3003         !GST_CLOCK_TIME_IS_VALID (parse->priv->prev_dts) &&
3004         GST_CLOCK_TIME_IS_VALID (pts))
3005       parse->priv->next_dts = pts;
3006
3007     /* always pass all available data */
3008     data = gst_adapter_map (parse->priv->adapter, av);
3009     /* arrange for actual data to be copied if subclass tries to,
3010      * since what is passed is tied to the adapter */
3011     tmpbuf = gst_buffer_new_wrapped_full (GST_MEMORY_FLAG_READONLY |
3012         GST_MEMORY_FLAG_NO_SHARE, (gpointer) data, av, 0, av, NULL, NULL);
3013
3014     /* already inform subclass what timestamps we have planned,
3015      * at least if provided by time-based upstream */
3016     if (parse->priv->upstream_format == GST_FORMAT_TIME) {
3017       GST_BUFFER_PTS (tmpbuf) = parse->priv->next_pts;
3018       GST_BUFFER_DTS (tmpbuf) = parse->priv->next_dts;
3019     }
3020
3021     /* keep the adapter mapped, so keep track of what has to be flushed */
3022     ret = gst_base_parse_handle_buffer (parse, tmpbuf, &skip, &flush);
3023     tmpbuf = NULL;
3024
3025     /* probably already implicitly unmapped due to adapter operation,
3026      * but for good measure ... */
3027     gst_adapter_unmap (parse->priv->adapter);
3028     if (ret != GST_FLOW_OK && ret != GST_FLOW_NOT_LINKED) {
3029       goto done;
3030     }
3031     if (skip == 0 && flush == 0) {
3032       GST_LOG_OBJECT (parse, "nothing skipped and no frames finished, "
3033           "breaking to get more data");
3034       /* ignore this return as it produced no data */
3035       ret = old_ret;
3036       goto done;
3037     }
3038     old_ret = ret;
3039   }
3040
3041 done:
3042   GST_LOG_OBJECT (parse, "chain leaving");
3043   return ret;
3044 }
3045
3046 /* pull @size bytes at current offset,
3047  * i.e. at least try to and possibly return a shorter buffer if near the end */
3048 static GstFlowReturn
3049 gst_base_parse_pull_range (GstBaseParse * parse, guint size,
3050     GstBuffer ** buffer)
3051 {
3052   GstFlowReturn ret = GST_FLOW_OK;
3053
3054   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
3055
3056   /* Caching here actually makes much less difference than one would expect.
3057    * We do it mainly to avoid pulling buffers of 1 byte all the time */
3058   if (parse->priv->cache) {
3059     gint64 cache_offset = GST_BUFFER_OFFSET (parse->priv->cache);
3060     gint cache_size = gst_buffer_get_size (parse->priv->cache);
3061
3062     if (cache_offset <= parse->priv->offset &&
3063         (parse->priv->offset + size) <= (cache_offset + cache_size)) {
3064       *buffer = gst_buffer_copy_region (parse->priv->cache, GST_BUFFER_COPY_ALL,
3065           parse->priv->offset - cache_offset, size);
3066       GST_BUFFER_OFFSET (*buffer) = parse->priv->offset;
3067       return GST_FLOW_OK;
3068     }
3069     /* not enough data in the cache, free cache and get a new one */
3070     gst_buffer_unref (parse->priv->cache);
3071     parse->priv->cache = NULL;
3072   }
3073
3074   /* refill the cache */
3075   ret =
3076       gst_pad_pull_range (parse->sinkpad, parse->priv->offset, MAX (size,
3077           64 * 1024), &parse->priv->cache);
3078   if (ret != GST_FLOW_OK) {
3079     parse->priv->cache = NULL;
3080     return ret;
3081   }
3082
3083   if (gst_buffer_get_size (parse->priv->cache) >= size) {
3084     *buffer =
3085         gst_buffer_copy_region (parse->priv->cache, GST_BUFFER_COPY_ALL, 0,
3086         size);
3087     GST_BUFFER_OFFSET (*buffer) = parse->priv->offset;
3088     return GST_FLOW_OK;
3089   }
3090
3091   /* Not possible to get enough data, try a last time with
3092    * requesting exactly the size we need */
3093   gst_buffer_unref (parse->priv->cache);
3094   parse->priv->cache = NULL;
3095
3096   ret = gst_pad_pull_range (parse->sinkpad, parse->priv->offset, size,
3097       &parse->priv->cache);
3098
3099   if (ret != GST_FLOW_OK) {
3100     GST_DEBUG_OBJECT (parse, "pull_range returned %d", ret);
3101     *buffer = NULL;
3102     return ret;
3103   }
3104
3105   if (gst_buffer_get_size (parse->priv->cache) < size) {
3106     GST_DEBUG_OBJECT (parse, "Returning short buffer at offset %"
3107         G_GUINT64_FORMAT ": wanted %u bytes, got %" G_GSIZE_FORMAT " bytes",
3108         parse->priv->offset, size, gst_buffer_get_size (parse->priv->cache));
3109
3110     *buffer = parse->priv->cache;
3111     parse->priv->cache = NULL;
3112
3113     return GST_FLOW_OK;
3114   }
3115
3116   *buffer =
3117       gst_buffer_copy_region (parse->priv->cache, GST_BUFFER_COPY_ALL, 0, size);
3118   GST_BUFFER_OFFSET (*buffer) = parse->priv->offset;
3119
3120   return GST_FLOW_OK;
3121 }
3122
3123 static GstFlowReturn
3124 gst_base_parse_handle_previous_fragment (GstBaseParse * parse)
3125 {
3126   gint64 offset = 0;
3127   GstClockTime ts = 0;
3128   GstBuffer *buffer;
3129   GstFlowReturn ret;
3130
3131   GST_DEBUG_OBJECT (parse, "fragment ended; last_ts = %" GST_TIME_FORMAT
3132       ", last_offset = %" G_GINT64_FORMAT,
3133       GST_TIME_ARGS (parse->priv->last_pts), parse->priv->last_offset);
3134
3135   if (!parse->priv->last_offset
3136       || parse->priv->last_pts <= parse->segment.start) {
3137     GST_DEBUG_OBJECT (parse, "past start of segment %" GST_TIME_FORMAT,
3138         GST_TIME_ARGS (parse->segment.start));
3139     ret = GST_FLOW_EOS;
3140     goto exit;
3141   }
3142
3143   /* last fragment started at last_offset / last_ts;
3144    * seek back 10s capped at 1MB */
3145   if (parse->priv->last_pts >= 10 * GST_SECOND)
3146     ts = parse->priv->last_pts - 10 * GST_SECOND;
3147   /* if we are exact now, we will be more so going backwards */
3148   if (parse->priv->exact_position) {
3149     offset = gst_base_parse_find_offset (parse, ts, TRUE, NULL);
3150   } else {
3151     if (!gst_base_parse_convert (parse, GST_FORMAT_TIME, ts,
3152             GST_FORMAT_BYTES, &offset)) {
3153       GST_DEBUG_OBJECT (parse, "conversion failed, only BYTE based");
3154     }
3155   }
3156   offset = CLAMP (offset, parse->priv->last_offset - 1024 * 1024,
3157       parse->priv->last_offset - 1024);
3158   offset = MAX (0, offset);
3159
3160   GST_DEBUG_OBJECT (parse, "next fragment from offset %" G_GINT64_FORMAT,
3161       offset);
3162   parse->priv->offset = offset;
3163
3164   ret = gst_base_parse_pull_range (parse, parse->priv->last_offset - offset,
3165       &buffer);
3166   if (ret != GST_FLOW_OK)
3167     goto exit;
3168
3169   /* offset will increase again as fragment is processed/parsed */
3170   parse->priv->last_offset = offset;
3171
3172   gst_base_parse_start_fragment (parse);
3173   gst_adapter_push (parse->priv->adapter, buffer);
3174   ret = gst_base_parse_finish_fragment (parse, TRUE);
3175   if (ret != GST_FLOW_OK)
3176     goto exit;
3177
3178   /* force previous fragment */
3179   parse->priv->offset = -1;
3180
3181 exit:
3182   return ret;
3183 }
3184
3185 /* PULL mode:
3186  * pull and scan for next frame starting from current offset
3187  * ajusts sync, drain and offset going along */
3188 static GstFlowReturn
3189 gst_base_parse_scan_frame (GstBaseParse * parse, GstBaseParseClass * klass)
3190 {
3191   GstBuffer *buffer;
3192   GstFlowReturn ret = GST_FLOW_OK;
3193   guint fsize, min_size;
3194   gint flushed = 0;
3195   gint skip = 0;
3196
3197   GST_LOG_OBJECT (parse, "scanning for frame at offset %" G_GUINT64_FORMAT
3198       " (%#" G_GINT64_MODIFIER "x)", parse->priv->offset, parse->priv->offset);
3199
3200   /* let's make this efficient for all subclass once and for all;
3201    * maybe it does not need this much, but in the latter case, we know we are
3202    * in pull mode here and might as well try to read and supply more anyway
3203    * (so does the buffer caching mechanism) */
3204   fsize = 64 * 1024;
3205
3206   while (TRUE) {
3207     min_size = MAX (parse->priv->min_frame_size, fsize);
3208
3209     GST_LOG_OBJECT (parse, "reading buffer size %u", min_size);
3210
3211     ret = gst_base_parse_pull_range (parse, min_size, &buffer);
3212     if (ret != GST_FLOW_OK)
3213       goto done;
3214
3215     /* if we got a short read, inform subclass we are draining leftover
3216      * and no more is to be expected */
3217     if (gst_buffer_get_size (buffer) < min_size) {
3218       GST_LOG_OBJECT (parse, "... but did not get that; marked draining");
3219       parse->priv->drain = TRUE;
3220     }
3221
3222     if (parse->priv->detecting) {
3223       ret = klass->detect (parse, buffer);
3224       if (ret == GST_FLOW_NOT_NEGOTIATED) {
3225         /* If draining we error out, otherwise request a buffer
3226          * with 64kb more */
3227         if (parse->priv->drain) {
3228           gst_buffer_unref (buffer);
3229           GST_ERROR_OBJECT (parse, "Failed to detect format but draining");
3230           return GST_FLOW_ERROR;
3231         } else {
3232           fsize += 64 * 1024;
3233           gst_buffer_unref (buffer);
3234           continue;
3235         }
3236       } else if (ret != GST_FLOW_OK) {
3237         gst_buffer_unref (buffer);
3238         GST_ERROR_OBJECT (parse, "detect() returned %s",
3239             gst_flow_get_name (ret));
3240         return ret;
3241       }
3242
3243       /* Else handle this buffer normally */
3244     }
3245
3246     ret = gst_base_parse_handle_buffer (parse, buffer, &skip, &flushed);
3247     if (ret != GST_FLOW_OK)
3248       break;
3249
3250     /* If a large amount of data was requested to be skipped, _handle_buffer
3251        might have set the priv->skip flag to an extra amount on top of skip.
3252        In pull mode, we can just pull from the new offset directly. */
3253     parse->priv->offset += parse->priv->skip;
3254     parse->priv->skip = 0;
3255
3256     /* something flushed means something happened,
3257      * and we should bail out of this loop so as not to occupy
3258      * the task thread indefinitely */
3259     if (flushed) {
3260       GST_LOG_OBJECT (parse, "frame finished, breaking loop");
3261       break;
3262     }
3263     /* nothing flushed, no skip and draining, so nothing left to do */
3264     if (!skip && parse->priv->drain) {
3265       GST_LOG_OBJECT (parse, "no activity or result when draining; "
3266           "breaking loop and marking EOS");
3267       ret = GST_FLOW_EOS;
3268       break;
3269     }
3270     /* otherwise, get some more data
3271      * note that is checked this does not happen indefinitely */
3272     if (!skip) {
3273       GST_LOG_OBJECT (parse, "getting some more data");
3274       fsize += 64 * 1024;
3275     }
3276     parse->priv->drain = FALSE;
3277   }
3278
3279 done:
3280   return ret;
3281 }
3282
3283 /* Loop that is used in pull mode to retrieve data from upstream */
3284 static void
3285 gst_base_parse_loop (GstPad * pad)
3286 {
3287   GstBaseParse *parse;
3288   GstBaseParseClass *klass;
3289   GstFlowReturn ret = GST_FLOW_OK;
3290
3291   parse = GST_BASE_PARSE (gst_pad_get_parent (pad));
3292   klass = GST_BASE_PARSE_GET_CLASS (parse);
3293
3294   GST_LOG_OBJECT (parse, "Entering parse loop");
3295
3296   if (G_UNLIKELY (parse->priv->push_stream_start)) {
3297     gchar *stream_id;
3298     GstEvent *event;
3299
3300     stream_id =
3301         gst_pad_create_stream_id (parse->srcpad, GST_ELEMENT_CAST (parse),
3302         NULL);
3303
3304     event = gst_event_new_stream_start (stream_id);
3305     gst_event_set_group_id (event, gst_util_group_id_next ());
3306
3307     GST_DEBUG_OBJECT (parse, "Pushing STREAM_START");
3308     gst_pad_push_event (parse->srcpad, event);
3309     parse->priv->push_stream_start = FALSE;
3310     g_free (stream_id);
3311   }
3312
3313   /* reverse playback:
3314    * first fragment (closest to stop time) is handled normally below,
3315    * then we pull in fragments going backwards */
3316   if (parse->segment.rate < 0.0) {
3317     /* check if we jumped back to a previous fragment,
3318      * which is a post-first fragment */
3319     if (parse->priv->offset < 0) {
3320       ret = gst_base_parse_handle_previous_fragment (parse);
3321       goto done;
3322     }
3323   }
3324
3325   ret = gst_base_parse_scan_frame (parse, klass);
3326   if (ret != GST_FLOW_OK)
3327     goto done;
3328
3329   /* eat expected eos signalling past segment in reverse playback */
3330   if (parse->segment.rate < 0.0 && ret == GST_FLOW_EOS &&
3331       parse->segment.position >= parse->segment.stop) {
3332     GST_DEBUG_OBJECT (parse, "downstream has reached end of segment");
3333     /* push what was accumulated during loop run */
3334     gst_base_parse_finish_fragment (parse, FALSE);
3335     /* force previous fragment */
3336     parse->priv->offset = -1;
3337     ret = GST_FLOW_OK;
3338   }
3339
3340 done:
3341   if (ret == GST_FLOW_EOS)
3342     goto eos;
3343   else if (ret != GST_FLOW_OK)
3344     goto pause;
3345
3346   gst_object_unref (parse);
3347   return;
3348
3349   /* ERRORS */
3350 eos:
3351   {
3352     ret = GST_FLOW_EOS;
3353     GST_DEBUG_OBJECT (parse, "eos");
3354     /* fall-through */
3355   }
3356 pause:
3357   {
3358     gboolean push_eos = FALSE;
3359
3360     GST_DEBUG_OBJECT (parse, "pausing task, reason %s",
3361         gst_flow_get_name (ret));
3362     gst_pad_pause_task (parse->sinkpad);
3363
3364     if (ret == GST_FLOW_EOS) {
3365       /* handle end-of-stream/segment */
3366       if (parse->segment.flags & GST_SEGMENT_FLAG_SEGMENT) {
3367         gint64 stop;
3368
3369         if ((stop = parse->segment.stop) == -1)
3370           stop = parse->segment.duration;
3371
3372         GST_DEBUG_OBJECT (parse, "sending segment_done");
3373
3374         gst_element_post_message
3375             (GST_ELEMENT_CAST (parse),
3376             gst_message_new_segment_done (GST_OBJECT_CAST (parse),
3377                 GST_FORMAT_TIME, stop));
3378         gst_pad_push_event (parse->srcpad,
3379             gst_event_new_segment_done (GST_FORMAT_TIME, stop));
3380       } else {
3381         /* If we STILL have zero frames processed, fire an error */
3382         if (parse->priv->framecount == 0) {
3383           GST_ELEMENT_ERROR (parse, STREAM, WRONG_TYPE,
3384               ("No valid frames found before end of stream"), (NULL));
3385         }
3386         push_eos = TRUE;
3387       }
3388     } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
3389       /* for fatal errors we post an error message, wrong-state is
3390        * not fatal because it happens due to flushes and only means
3391        * that we should stop now. */
3392       GST_ELEMENT_ERROR (parse, STREAM, FAILED, (NULL),
3393           ("streaming stopped, reason %s", gst_flow_get_name (ret)));
3394       push_eos = TRUE;
3395     }
3396     if (push_eos) {
3397       /* Push pending events, including SEGMENT events */
3398       gst_base_parse_push_pending_events (parse);
3399
3400       gst_pad_push_event (parse->srcpad, gst_event_new_eos ());
3401     }
3402     gst_object_unref (parse);
3403   }
3404 }
3405
3406 static gboolean
3407 gst_base_parse_sink_activate (GstPad * sinkpad, GstObject * parent)
3408 {
3409   GstSchedulingFlags sched_flags;
3410   GstBaseParse *parse;
3411   GstQuery *query;
3412   gboolean pull_mode;
3413
3414   parse = GST_BASE_PARSE (parent);
3415
3416   GST_DEBUG_OBJECT (parse, "sink activate");
3417
3418   query = gst_query_new_scheduling ();
3419   if (!gst_pad_peer_query (sinkpad, query)) {
3420     gst_query_unref (query);
3421     goto baseparse_push;
3422   }
3423
3424   gst_query_parse_scheduling (query, &sched_flags, NULL, NULL, NULL);
3425
3426   pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL)
3427       && ((sched_flags & GST_SCHEDULING_FLAG_SEEKABLE) != 0);
3428
3429   gst_query_unref (query);
3430
3431   if (!pull_mode)
3432     goto baseparse_push;
3433
3434   GST_DEBUG_OBJECT (parse, "trying to activate in pull mode");
3435   if (!gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE))
3436     goto baseparse_push;
3437
3438   parse->priv->push_stream_start = TRUE;
3439
3440   return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_base_parse_loop,
3441       sinkpad, NULL);
3442   /* fallback */
3443 baseparse_push:
3444   {
3445     GST_DEBUG_OBJECT (parse, "trying to activate in push mode");
3446     return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
3447   }
3448 }
3449
3450 static gboolean
3451 gst_base_parse_activate (GstBaseParse * parse, gboolean active)
3452 {
3453   GstBaseParseClass *klass;
3454   gboolean result = TRUE;
3455
3456   GST_DEBUG_OBJECT (parse, "activate %d", active);
3457
3458   klass = GST_BASE_PARSE_GET_CLASS (parse);
3459
3460   if (active) {
3461     if (parse->priv->pad_mode == GST_PAD_MODE_NONE && klass->start)
3462       result = klass->start (parse);
3463
3464     /* If the subclass implements ::detect we want to
3465      * call it for the first buffers now */
3466     parse->priv->detecting = (klass->detect != NULL);
3467   } else {
3468     /* We must make sure streaming has finished before resetting things
3469      * and calling the ::stop vfunc */
3470     GST_PAD_STREAM_LOCK (parse->sinkpad);
3471     GST_PAD_STREAM_UNLOCK (parse->sinkpad);
3472
3473     if (parse->priv->pad_mode != GST_PAD_MODE_NONE && klass->stop)
3474       result = klass->stop (parse);
3475
3476     parse->priv->pad_mode = GST_PAD_MODE_NONE;
3477   }
3478   GST_DEBUG_OBJECT (parse, "activate return: %d", result);
3479   return result;
3480 }
3481
3482 static gboolean
3483 gst_base_parse_sink_activate_mode (GstPad * pad, GstObject * parent,
3484     GstPadMode mode, gboolean active)
3485 {
3486   gboolean result;
3487   GstBaseParse *parse;
3488
3489   parse = GST_BASE_PARSE (parent);
3490
3491   GST_DEBUG_OBJECT (parse, "sink %sactivate in %s mode",
3492       (active) ? "" : "de", gst_pad_mode_get_name (mode));
3493
3494   if (!gst_base_parse_activate (parse, active))
3495     goto activate_failed;
3496
3497   switch (mode) {
3498     case GST_PAD_MODE_PULL:
3499       if (active) {
3500         parse->priv->pending_events =
3501             g_list_prepend (parse->priv->pending_events,
3502             gst_event_new_segment (&parse->segment));
3503         result = TRUE;
3504       } else {
3505         result = gst_pad_stop_task (pad);
3506       }
3507       break;
3508     default:
3509       result = TRUE;
3510       break;
3511   }
3512   if (result)
3513     parse->priv->pad_mode = active ? mode : GST_PAD_MODE_NONE;
3514
3515   GST_DEBUG_OBJECT (parse, "sink activate return: %d", result);
3516
3517   return result;
3518
3519   /* ERRORS */
3520 activate_failed:
3521   {
3522     GST_DEBUG_OBJECT (parse, "activate failed");
3523     return FALSE;
3524   }
3525 }
3526
3527 /**
3528  * gst_base_parse_set_duration:
3529  * @parse: #GstBaseParse.
3530  * @fmt: #GstFormat.
3531  * @duration: duration value.
3532  * @interval: how often to update the duration estimate based on bitrate, or 0.
3533  *
3534  * Sets the duration of the currently playing media. Subclass can use this
3535  * when it is able to determine duration and/or notices a change in the media
3536  * duration.  Alternatively, if @interval is non-zero (default), then stream
3537  * duration is determined based on estimated bitrate, and updated every @interval
3538  * frames.
3539  */
3540 void
3541 gst_base_parse_set_duration (GstBaseParse * parse,
3542     GstFormat fmt, gint64 duration, gint interval)
3543 {
3544   g_return_if_fail (parse != NULL);
3545
3546   if (parse->priv->upstream_has_duration) {
3547     GST_DEBUG_OBJECT (parse, "using upstream duration; discarding update");
3548     goto exit;
3549   }
3550
3551   if (duration != parse->priv->duration) {
3552     GstMessage *m;
3553
3554     m = gst_message_new_duration_changed (GST_OBJECT (parse));
3555     gst_element_post_message (GST_ELEMENT (parse), m);
3556
3557     /* TODO: what about duration tag? */
3558   }
3559   parse->priv->duration = duration;
3560   parse->priv->duration_fmt = fmt;
3561   GST_DEBUG_OBJECT (parse, "set duration: %" G_GINT64_FORMAT, duration);
3562   if (fmt == GST_FORMAT_TIME && GST_CLOCK_TIME_IS_VALID (duration)) {
3563     if (interval != 0) {
3564       GST_DEBUG_OBJECT (parse, "valid duration provided, disabling estimate");
3565       interval = 0;
3566     }
3567   }
3568   GST_DEBUG_OBJECT (parse, "set update interval: %d", interval);
3569   parse->priv->update_interval = interval;
3570 exit:
3571   return;
3572 }
3573
3574 /**
3575  * gst_base_parse_set_average_bitrate:
3576  * @parse: #GstBaseParse.
3577  * @bitrate: average bitrate in bits/second
3578  *
3579  * Optionally sets the average bitrate detected in media (if non-zero),
3580  * e.g. based on metadata, as it will be posted to the application.
3581  *
3582  * By default, announced average bitrate is estimated. The average bitrate
3583  * is used to estimate the total duration of the stream and to estimate
3584  * a seek position, if there's no index and the format is syncable
3585  * (see gst_base_parse_set_syncable()).
3586  */
3587 void
3588 gst_base_parse_set_average_bitrate (GstBaseParse * parse, guint bitrate)
3589 {
3590   parse->priv->bitrate = bitrate;
3591   GST_DEBUG_OBJECT (parse, "bitrate %u", bitrate);
3592 }
3593
3594 /**
3595  * gst_base_parse_set_min_frame_size:
3596  * @parse: #GstBaseParse.
3597  * @min_size: Minimum size of the data that this base class should give to
3598  *            subclass.
3599  *
3600  * Subclass can use this function to tell the base class that it needs to
3601  * give at least #min_size buffers.
3602  */
3603 void
3604 gst_base_parse_set_min_frame_size (GstBaseParse * parse, guint min_size)
3605 {
3606   g_return_if_fail (parse != NULL);
3607
3608   parse->priv->min_frame_size = min_size;
3609   GST_LOG_OBJECT (parse, "set frame_min_size: %d", min_size);
3610 }
3611
3612 /**
3613  * gst_base_parse_set_frame_rate:
3614  * @parse: the #GstBaseParse to set
3615  * @fps_num: frames per second (numerator).
3616  * @fps_den: frames per second (denominator).
3617  * @lead_in: frames needed before a segment for subsequent decode
3618  * @lead_out: frames needed after a segment
3619  *
3620  * If frames per second is configured, parser can take care of buffer duration
3621  * and timestamping.  When performing segment clipping, or seeking to a specific
3622  * location, a corresponding decoder might need an initial @lead_in and a
3623  * following @lead_out number of frames to ensure the desired segment is
3624  * entirely filled upon decoding.
3625  */
3626 void
3627 gst_base_parse_set_frame_rate (GstBaseParse * parse, guint fps_num,
3628     guint fps_den, guint lead_in, guint lead_out)
3629 {
3630   g_return_if_fail (parse != NULL);
3631
3632   parse->priv->fps_num = fps_num;
3633   parse->priv->fps_den = fps_den;
3634   if (!fps_num || !fps_den) {
3635     GST_DEBUG_OBJECT (parse, "invalid fps (%d/%d), ignoring parameters",
3636         fps_num, fps_den);
3637     fps_num = fps_den = 0;
3638     parse->priv->frame_duration = GST_CLOCK_TIME_NONE;
3639     parse->priv->lead_in = parse->priv->lead_out = 0;
3640     parse->priv->lead_in_ts = parse->priv->lead_out_ts = 0;
3641   } else {
3642     parse->priv->frame_duration =
3643         gst_util_uint64_scale (GST_SECOND, fps_den, fps_num);
3644     parse->priv->lead_in = lead_in;
3645     parse->priv->lead_out = lead_out;
3646     parse->priv->lead_in_ts =
3647         gst_util_uint64_scale (GST_SECOND, fps_den * lead_in, fps_num);
3648     parse->priv->lead_out_ts =
3649         gst_util_uint64_scale (GST_SECOND, fps_den * lead_out, fps_num);
3650     /* aim for about 1.5s to estimate duration */
3651     if (parse->priv->update_interval < 0) {
3652       parse->priv->update_interval = fps_num * 3 / (fps_den * 2);
3653       GST_LOG_OBJECT (parse, "estimated update interval to %d frames",
3654           parse->priv->update_interval);
3655     }
3656   }
3657   GST_LOG_OBJECT (parse, "set fps: %d/%d => duration: %" G_GINT64_FORMAT " ms",
3658       fps_num, fps_den, parse->priv->frame_duration / GST_MSECOND);
3659   GST_LOG_OBJECT (parse, "set lead in: %d frames = %" G_GUINT64_FORMAT " ms, "
3660       "lead out: %d frames = %" G_GUINT64_FORMAT " ms",
3661       lead_in, parse->priv->lead_in_ts / GST_MSECOND,
3662       lead_out, parse->priv->lead_out_ts / GST_MSECOND);
3663 }
3664
3665 /**
3666  * gst_base_parse_set_has_timing_info:
3667  * @parse: a #GstBaseParse
3668  * @has_timing: whether frames carry timing information
3669  *
3670  * Set if frames carry timing information which the subclass can (generally)
3671  * parse and provide.  In particular, intrinsic (rather than estimated) time
3672  * can be obtained following a seek.
3673  */
3674 void
3675 gst_base_parse_set_has_timing_info (GstBaseParse * parse, gboolean has_timing)
3676 {
3677   parse->priv->has_timing_info = has_timing;
3678   GST_INFO_OBJECT (parse, "has_timing: %s", (has_timing) ? "yes" : "no");
3679 }
3680
3681 /**
3682  * gst_base_parse_set_syncable:
3683  * @parse: a #GstBaseParse
3684  * @syncable: set if frame starts can be identified
3685  *
3686  * Set if frame starts can be identified. This is set by default and
3687  * determines whether seeking based on bitrate averages
3688  * is possible for a format/stream.
3689  */
3690 void
3691 gst_base_parse_set_syncable (GstBaseParse * parse, gboolean syncable)
3692 {
3693   parse->priv->syncable = syncable;
3694   GST_INFO_OBJECT (parse, "syncable: %s", (syncable) ? "yes" : "no");
3695 }
3696
3697 /**
3698  * gst_base_parse_set_passthrough:
3699  * @parse: a #GstBaseParse
3700  * @passthrough: %TRUE if parser should run in passthrough mode
3701  *
3702  * Set if the nature of the format or configuration does not allow (much)
3703  * parsing, and the parser should operate in passthrough mode (which only
3704  * applies when operating in push mode). That is, incoming buffers are
3705  * pushed through unmodified, i.e. no @check_valid_frame or @parse_frame
3706  * callbacks will be invoked, but @pre_push_frame will still be invoked,
3707  * so subclass can perform as much or as little is appropriate for
3708  * passthrough semantics in @pre_push_frame.
3709  */
3710 void
3711 gst_base_parse_set_passthrough (GstBaseParse * parse, gboolean passthrough)
3712 {
3713   parse->priv->passthrough = passthrough;
3714   GST_INFO_OBJECT (parse, "passthrough: %s", (passthrough) ? "yes" : "no");
3715 }
3716
3717 /**
3718  * gst_base_parse_set_pts_interpolation:
3719  * @parse: a #GstBaseParse
3720  * @pts_interpolate: %TRUE if parser should interpolate PTS timestamps
3721  *
3722  * By default, the base class will guess PTS timestamps using a simple
3723  * interpolation (previous timestamp + duration), which is incorrect for
3724  * data streams with reordering, where PTS can go backward. Sub-classes
3725  * implementing such formats should disable PTS interpolation.
3726  */
3727 void
3728 gst_base_parse_set_pts_interpolation (GstBaseParse * parse,
3729     gboolean pts_interpolate)
3730 {
3731   parse->priv->pts_interpolate = pts_interpolate;
3732   GST_INFO_OBJECT (parse, "PTS interpolation: %s",
3733       (pts_interpolate) ? "yes" : "no");
3734 }
3735
3736 /**
3737  * gst_base_parse_set_infer_ts:
3738  * @parse: a #GstBaseParse
3739  * @infer_ts: %TRUE if parser should infer DTS/PTS from each other
3740  *
3741  * By default, the base class might try to infer PTS from DTS and vice
3742  * versa.  While this is generally correct for audio data, it may not
3743  * be otherwise. Sub-classes implementing such formats should disable
3744  * timestamp inferring.
3745  */
3746 void
3747 gst_base_parse_set_infer_ts (GstBaseParse * parse, gboolean infer_ts)
3748 {
3749   parse->priv->infer_ts = infer_ts;
3750   GST_INFO_OBJECT (parse, "TS inferring: %s", (infer_ts) ? "yes" : "no");
3751 }
3752
3753 /**
3754  * gst_base_parse_set_latency:
3755  * @parse: a #GstBaseParse
3756  * @min_latency: minimum parse latency
3757  * @max_latency: maximum parse latency
3758  *
3759  * Sets the minimum and maximum (which may likely be equal) latency introduced
3760  * by the parsing process.  If there is such a latency, which depends on the
3761  * particular parsing of the format, it typically corresponds to 1 frame duration.
3762  */
3763 void
3764 gst_base_parse_set_latency (GstBaseParse * parse, GstClockTime min_latency,
3765     GstClockTime max_latency)
3766 {
3767   g_return_if_fail (min_latency != GST_CLOCK_TIME_NONE);
3768   g_return_if_fail (min_latency <= max_latency);
3769
3770   GST_OBJECT_LOCK (parse);
3771   parse->priv->min_latency = min_latency;
3772   parse->priv->max_latency = max_latency;
3773   GST_OBJECT_UNLOCK (parse);
3774   GST_INFO_OBJECT (parse, "min/max latency %" GST_TIME_FORMAT ", %"
3775       GST_TIME_FORMAT, GST_TIME_ARGS (min_latency),
3776       GST_TIME_ARGS (max_latency));
3777 }
3778
3779 static gboolean
3780 gst_base_parse_get_duration (GstBaseParse * parse, GstFormat format,
3781     GstClockTime * duration)
3782 {
3783   gboolean res = FALSE;
3784
3785   g_return_val_if_fail (duration != NULL, FALSE);
3786
3787   *duration = GST_CLOCK_TIME_NONE;
3788   if (parse->priv->duration != -1 && format == parse->priv->duration_fmt) {
3789     GST_LOG_OBJECT (parse, "using provided duration");
3790     *duration = parse->priv->duration;
3791     res = TRUE;
3792   } else if (parse->priv->duration != -1) {
3793     GST_LOG_OBJECT (parse, "converting provided duration");
3794     res = gst_base_parse_convert (parse, parse->priv->duration_fmt,
3795         parse->priv->duration, format, (gint64 *) duration);
3796   } else if (format == GST_FORMAT_TIME && parse->priv->estimated_duration != -1) {
3797     GST_LOG_OBJECT (parse, "using estimated duration");
3798     *duration = parse->priv->estimated_duration;
3799     res = TRUE;
3800   } else {
3801     GST_LOG_OBJECT (parse, "cannot estimate duration");
3802   }
3803
3804   GST_LOG_OBJECT (parse, "res: %d, duration %" GST_TIME_FORMAT, res,
3805       GST_TIME_ARGS (*duration));
3806   return res;
3807 }
3808
3809 static gboolean
3810 gst_base_parse_src_query_default (GstBaseParse * parse, GstQuery * query)
3811 {
3812   gboolean res = FALSE;
3813   GstPad *pad;
3814
3815   pad = GST_BASE_PARSE_SRC_PAD (parse);
3816
3817   switch (GST_QUERY_TYPE (query)) {
3818     case GST_QUERY_POSITION:
3819     {
3820       gint64 dest_value;
3821       GstFormat format;
3822
3823       GST_DEBUG_OBJECT (parse, "position query");
3824       gst_query_parse_position (query, &format, NULL);
3825
3826       /* try upstream first */
3827       res = gst_pad_query_default (pad, GST_OBJECT_CAST (parse), query);
3828       if (!res) {
3829         /* Fall back on interpreting segment */
3830         GST_OBJECT_LOCK (parse);
3831         if (format == GST_FORMAT_BYTES) {
3832           dest_value = parse->priv->offset;
3833           res = TRUE;
3834         } else if (format == parse->segment.format &&
3835             GST_CLOCK_TIME_IS_VALID (parse->segment.position)) {
3836           dest_value = gst_segment_to_stream_time (&parse->segment,
3837               parse->segment.format, parse->segment.position);
3838           res = TRUE;
3839         }
3840         GST_OBJECT_UNLOCK (parse);
3841         if (!res) {
3842           /* no precise result, upstream no idea either, then best estimate */
3843           /* priv->offset is updated in both PUSH/PULL modes */
3844           res = gst_base_parse_convert (parse,
3845               GST_FORMAT_BYTES, parse->priv->offset, format, &dest_value);
3846         }
3847         if (res)
3848           gst_query_set_position (query, format, dest_value);
3849       }
3850       break;
3851     }
3852     case GST_QUERY_DURATION:
3853     {
3854       GstFormat format;
3855       GstClockTime duration;
3856
3857       GST_DEBUG_OBJECT (parse, "duration query");
3858       gst_query_parse_duration (query, &format, NULL);
3859
3860       /* consult upstream */
3861       res = gst_pad_query_default (pad, GST_OBJECT_CAST (parse), query);
3862
3863       /* otherwise best estimate from us */
3864       if (!res) {
3865         res = gst_base_parse_get_duration (parse, format, &duration);
3866         if (res)
3867           gst_query_set_duration (query, format, duration);
3868       }
3869       break;
3870     }
3871     case GST_QUERY_SEEKING:
3872     {
3873       GstFormat fmt;
3874       GstClockTime duration = GST_CLOCK_TIME_NONE;
3875       gboolean seekable = FALSE;
3876
3877       GST_DEBUG_OBJECT (parse, "seeking query");
3878       gst_query_parse_seeking (query, &fmt, NULL, NULL, NULL);
3879
3880       /* consult upstream */
3881       res = gst_pad_query_default (pad, GST_OBJECT_CAST (parse), query);
3882
3883       /* we may be able to help if in TIME */
3884       if (fmt == GST_FORMAT_TIME && gst_base_parse_is_seekable (parse)) {
3885         gst_query_parse_seeking (query, &fmt, &seekable, NULL, NULL);
3886         /* already OK if upstream takes care */
3887         GST_LOG_OBJECT (parse, "upstream handled %d, seekable %d",
3888             res, seekable);
3889         if (!(res && seekable)) {
3890           if (!gst_base_parse_get_duration (parse, GST_FORMAT_TIME, &duration)
3891               || duration == -1) {
3892             /* seekable if we still have a chance to get duration later on */
3893             seekable =
3894                 parse->priv->upstream_seekable && parse->priv->update_interval;
3895           } else {
3896             seekable = parse->priv->upstream_seekable;
3897             GST_LOG_OBJECT (parse, "already determine upstream seekabled: %d",
3898                 seekable);
3899           }
3900           gst_query_set_seeking (query, GST_FORMAT_TIME, seekable, 0, duration);
3901           res = TRUE;
3902         }
3903       }
3904       break;
3905     }
3906     case GST_QUERY_FORMATS:
3907       gst_query_set_formatsv (query, 3, fmtlist);
3908       res = TRUE;
3909       break;
3910     case GST_QUERY_CONVERT:
3911     {
3912       GstFormat src_format, dest_format;
3913       gint64 src_value, dest_value;
3914
3915       gst_query_parse_convert (query, &src_format, &src_value,
3916           &dest_format, &dest_value);
3917
3918       res = gst_base_parse_convert (parse, src_format, src_value,
3919           dest_format, &dest_value);
3920       if (res) {
3921         gst_query_set_convert (query, src_format, src_value,
3922             dest_format, dest_value);
3923       }
3924       break;
3925     }
3926     case GST_QUERY_LATENCY:
3927     {
3928       if ((res = gst_pad_peer_query (parse->sinkpad, query))) {
3929         gboolean live;
3930         GstClockTime min_latency, max_latency;
3931
3932         gst_query_parse_latency (query, &live, &min_latency, &max_latency);
3933         GST_DEBUG_OBJECT (parse, "Peer latency: live %d, min %"
3934             GST_TIME_FORMAT " max %" GST_TIME_FORMAT, live,
3935             GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency));
3936
3937         GST_OBJECT_LOCK (parse);
3938         /* add our latency */
3939         min_latency += parse->priv->min_latency;
3940         if (max_latency == -1 || parse->priv->max_latency == -1)
3941           max_latency = -1;
3942         else
3943           max_latency += parse->priv->max_latency;
3944         GST_OBJECT_UNLOCK (parse);
3945
3946         gst_query_set_latency (query, live, min_latency, max_latency);
3947       }
3948       break;
3949     }
3950     case GST_QUERY_SEGMENT:
3951     {
3952       GstFormat format;
3953       gint64 start, stop;
3954
3955       format = parse->segment.format;
3956
3957       start =
3958           gst_segment_to_stream_time (&parse->segment, format,
3959           parse->segment.start);
3960       if ((stop = parse->segment.stop) == -1)
3961         stop = parse->segment.duration;
3962       else
3963         stop = gst_segment_to_stream_time (&parse->segment, format, stop);
3964
3965       gst_query_set_segment (query, parse->segment.rate, format, start, stop);
3966       res = TRUE;
3967       break;
3968     }
3969     default:
3970       res = gst_pad_query_default (pad, GST_OBJECT_CAST (parse), query);
3971       break;
3972   }
3973   return res;
3974 }
3975
3976 /* scans for a cluster start from @pos,
3977  * return GST_FLOW_OK and frame position/time in @pos/@time if found */
3978 static GstFlowReturn
3979 gst_base_parse_find_frame (GstBaseParse * parse, gint64 * pos,
3980     GstClockTime * time, GstClockTime * duration)
3981 {
3982   GstBaseParseClass *klass;
3983   gint64 orig_offset;
3984   gboolean orig_drain, orig_discont;
3985   GstFlowReturn ret = GST_FLOW_OK;
3986   GstBuffer *buf = NULL;
3987   GstBaseParseFrame *sframe = NULL;
3988
3989   g_return_val_if_fail (pos != NULL, GST_FLOW_ERROR);
3990   g_return_val_if_fail (time != NULL, GST_FLOW_ERROR);
3991   g_return_val_if_fail (duration != NULL, GST_FLOW_ERROR);
3992
3993   klass = GST_BASE_PARSE_GET_CLASS (parse);
3994
3995   *time = GST_CLOCK_TIME_NONE;
3996   *duration = GST_CLOCK_TIME_NONE;
3997
3998   /* save state */
3999   orig_offset = parse->priv->offset;
4000   orig_discont = parse->priv->discont;
4001   orig_drain = parse->priv->drain;
4002
4003   GST_DEBUG_OBJECT (parse, "scanning for frame starting at %" G_GINT64_FORMAT
4004       " (%#" G_GINT64_MODIFIER "x)", *pos, *pos);
4005
4006   /* jump elsewhere and locate next frame */
4007   parse->priv->offset = *pos;
4008   /* mark as scanning so frames don't get processed all the way */
4009   parse->priv->scanning = TRUE;
4010   ret = gst_base_parse_scan_frame (parse, klass);
4011   parse->priv->scanning = FALSE;
4012   /* retrieve frame found during scan */
4013   sframe = parse->priv->scanned_frame;
4014   parse->priv->scanned_frame = NULL;
4015
4016   if (ret != GST_FLOW_OK || !sframe)
4017     goto done;
4018
4019   /* get offset first, subclass parsing might dump other stuff in there */
4020   *pos = sframe->offset;
4021   buf = sframe->buffer;
4022   g_assert (buf);
4023
4024   /* but it should provide proper time */
4025   *time = GST_BUFFER_TIMESTAMP (buf);
4026   *duration = GST_BUFFER_DURATION (buf);
4027
4028   GST_LOG_OBJECT (parse,
4029       "frame with time %" GST_TIME_FORMAT " at offset %" G_GINT64_FORMAT,
4030       GST_TIME_ARGS (*time), *pos);
4031
4032 done:
4033   if (sframe)
4034     gst_base_parse_frame_free (sframe);
4035
4036   /* restore state */
4037   parse->priv->offset = orig_offset;
4038   parse->priv->discont = orig_discont;
4039   parse->priv->drain = orig_drain;
4040
4041   return ret;
4042 }
4043
4044 /* bisect and scan through file for frame starting before @time,
4045  * returns OK and @time/@offset if found, NONE and/or error otherwise
4046  * If @time == G_MAXINT64, scan for duration ( == last frame) */
4047 static GstFlowReturn
4048 gst_base_parse_locate_time (GstBaseParse * parse, GstClockTime * _time,
4049     gint64 * _offset)
4050 {
4051   GstFlowReturn ret = GST_FLOW_OK;
4052   gint64 lpos, hpos, newpos;
4053   GstClockTime time, ltime, htime, newtime, dur;
4054   gboolean cont = TRUE;
4055   const GstClockTime tolerance = TARGET_DIFFERENCE;
4056   const guint chunk = 4 * 1024;
4057
4058   g_return_val_if_fail (_time != NULL, GST_FLOW_ERROR);
4059   g_return_val_if_fail (_offset != NULL, GST_FLOW_ERROR);
4060
4061   GST_DEBUG_OBJECT (parse, "Bisecting for time %" GST_TIME_FORMAT,
4062       GST_TIME_ARGS (*_time));
4063
4064   /* TODO also make keyframe aware if useful some day */
4065
4066   time = *_time;
4067
4068   /* basic cases */
4069   if (time == 0) {
4070     *_offset = 0;
4071     return GST_FLOW_OK;
4072   }
4073
4074   if (time == -1) {
4075     *_offset = -1;
4076     return GST_FLOW_OK;
4077   }
4078
4079   /* do not know at first */
4080   *_offset = -1;
4081   *_time = GST_CLOCK_TIME_NONE;
4082
4083   /* need initial positions; start and end */
4084   lpos = parse->priv->first_frame_offset;
4085   ltime = parse->priv->first_frame_pts;
4086   /* try other one if no luck */
4087   if (!GST_CLOCK_TIME_IS_VALID (ltime))
4088     ltime = parse->priv->first_frame_dts;
4089   if (!gst_base_parse_get_duration (parse, GST_FORMAT_TIME, &htime)) {
4090     GST_DEBUG_OBJECT (parse, "Unknown time duration, cannot bisect");
4091     return GST_FLOW_ERROR;
4092   }
4093   hpos = parse->priv->upstream_size;
4094
4095   GST_DEBUG_OBJECT (parse,
4096       "Bisection initial bounds: bytes %" G_GINT64_FORMAT " %" G_GINT64_FORMAT
4097       ", times %" GST_TIME_FORMAT " %" GST_TIME_FORMAT, lpos, hpos,
4098       GST_TIME_ARGS (ltime), GST_TIME_ARGS (htime));
4099
4100   /* check preconditions are satisfied;
4101    * start and end are needed, except for special case where we scan for
4102    * last frame to determine duration */
4103   if (parse->priv->pad_mode != GST_PAD_MODE_PULL || !hpos ||
4104       !GST_CLOCK_TIME_IS_VALID (ltime) ||
4105       (!GST_CLOCK_TIME_IS_VALID (htime) && time != G_MAXINT64)) {
4106     return GST_FLOW_OK;
4107   }
4108
4109   /* shortcut cases */
4110   if (time < ltime) {
4111     goto exit;
4112   } else if (time < ltime + tolerance) {
4113     *_offset = lpos;
4114     *_time = ltime;
4115     goto exit;
4116   } else if (time >= htime) {
4117     *_offset = hpos;
4118     *_time = htime;
4119     goto exit;
4120   }
4121
4122   while (htime > ltime && cont) {
4123     GST_LOG_OBJECT (parse,
4124         "lpos: %" G_GUINT64_FORMAT ", ltime: %" GST_TIME_FORMAT, lpos,
4125         GST_TIME_ARGS (ltime));
4126     GST_LOG_OBJECT (parse,
4127         "hpos: %" G_GUINT64_FORMAT ", htime: %" GST_TIME_FORMAT, hpos,
4128         GST_TIME_ARGS (htime));
4129     if (G_UNLIKELY (time == G_MAXINT64)) {
4130       newpos = hpos;
4131     } else if (G_LIKELY (hpos > lpos)) {
4132       newpos =
4133           gst_util_uint64_scale (hpos - lpos, time - ltime, htime - ltime) +
4134           lpos - chunk;
4135     } else {
4136       /* should mean lpos == hpos, since lpos <= hpos is invariant */
4137       newpos = lpos;
4138       /* we check this case once, but not forever, so break loop */
4139       cont = FALSE;
4140     }
4141
4142     /* ensure */
4143     newpos = CLAMP (newpos, lpos, hpos);
4144     GST_LOG_OBJECT (parse,
4145         "estimated _offset for %" GST_TIME_FORMAT ": %" G_GINT64_FORMAT,
4146         GST_TIME_ARGS (time), newpos);
4147
4148     ret = gst_base_parse_find_frame (parse, &newpos, &newtime, &dur);
4149     if (ret == GST_FLOW_EOS) {
4150       /* heuristic HACK */
4151       hpos = MAX (lpos, hpos - chunk);
4152       continue;
4153     } else if (ret != GST_FLOW_OK) {
4154       goto exit;
4155     }
4156
4157     if (newtime == -1 || newpos == -1) {
4158       GST_DEBUG_OBJECT (parse, "subclass did not provide metadata; aborting");
4159       break;
4160     }
4161
4162     if (G_UNLIKELY (time == G_MAXINT64)) {
4163       *_offset = newpos;
4164       *_time = newtime;
4165       if (GST_CLOCK_TIME_IS_VALID (dur))
4166         *_time += dur;
4167       break;
4168     } else if (newtime > time) {
4169       /* overshoot */
4170       hpos = (newpos >= hpos) ? MAX (lpos, hpos - chunk) : MAX (lpos, newpos);
4171       htime = newtime;
4172     } else if (newtime + tolerance > time) {
4173       /* close enough undershoot */
4174       *_offset = newpos;
4175       *_time = newtime;
4176       break;
4177     } else if (newtime < ltime) {
4178       /* so a position beyond lpos resulted in earlier time than ltime ... */
4179       GST_DEBUG_OBJECT (parse, "non-ascending time; aborting");
4180       break;
4181     } else {
4182       /* undershoot too far */
4183       newpos += newpos == lpos ? chunk : 0;
4184       lpos = CLAMP (newpos, lpos, hpos);
4185       ltime = newtime;
4186     }
4187   }
4188
4189 exit:
4190   GST_LOG_OBJECT (parse, "return offset %" G_GINT64_FORMAT ", time %"
4191       GST_TIME_FORMAT, *_offset, GST_TIME_ARGS (*_time));
4192   return ret;
4193 }
4194
4195 static gint64
4196 gst_base_parse_find_offset (GstBaseParse * parse, GstClockTime time,
4197     gboolean before, GstClockTime * _ts)
4198 {
4199   gint64 bytes = 0, ts = 0;
4200   GstIndexEntry *entry = NULL;
4201
4202   if (time == GST_CLOCK_TIME_NONE) {
4203     ts = time;
4204     bytes = -1;
4205     goto exit;
4206   }
4207
4208   GST_BASE_PARSE_INDEX_LOCK (parse);
4209   if (parse->priv->index) {
4210     /* Let's check if we have an index entry for that time */
4211     entry = gst_index_get_assoc_entry (parse->priv->index,
4212         parse->priv->index_id,
4213         before ? GST_INDEX_LOOKUP_BEFORE : GST_INDEX_LOOKUP_AFTER,
4214         GST_INDEX_ASSOCIATION_FLAG_KEY_UNIT, GST_FORMAT_TIME, time);
4215   }
4216
4217   if (entry) {
4218     gst_index_entry_assoc_map (entry, GST_FORMAT_BYTES, &bytes);
4219     gst_index_entry_assoc_map (entry, GST_FORMAT_TIME, &ts);
4220
4221     GST_DEBUG_OBJECT (parse, "found index entry for %" GST_TIME_FORMAT
4222         " at %" GST_TIME_FORMAT ", offset %" G_GINT64_FORMAT,
4223         GST_TIME_ARGS (time), GST_TIME_ARGS (ts), bytes);
4224   } else {
4225     GST_DEBUG_OBJECT (parse, "no index entry found for %" GST_TIME_FORMAT,
4226         GST_TIME_ARGS (time));
4227     if (!before) {
4228       bytes = -1;
4229       ts = GST_CLOCK_TIME_NONE;
4230     }
4231   }
4232   GST_BASE_PARSE_INDEX_UNLOCK (parse);
4233
4234 exit:
4235   if (_ts)
4236     *_ts = ts;
4237
4238   return bytes;
4239 }
4240
4241 /* returns TRUE if seek succeeded */
4242 static gboolean
4243 gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
4244 {
4245   gdouble rate;
4246   GstFormat format;
4247   GstSeekFlags flags;
4248   GstSeekType start_type = GST_SEEK_TYPE_NONE, stop_type;
4249   gboolean flush, update, res = TRUE, accurate;
4250   gint64 start, stop, seekpos, seekstop;
4251   GstSegment seeksegment = { 0, };
4252   GstClockTime start_ts;
4253   guint32 seqnum;
4254   GstEvent *segment_event;
4255
4256   /* try upstream first, unless we're driving the streaming thread ourselves */
4257   if (parse->priv->pad_mode != GST_PAD_MODE_PULL) {
4258     res = gst_pad_push_event (parse->sinkpad, gst_event_ref (event));
4259     if (res)
4260       goto done;
4261   }
4262
4263   gst_event_parse_seek (event, &rate, &format, &flags,
4264       &start_type, &start, &stop_type, &stop);
4265   seqnum = gst_event_get_seqnum (event);
4266
4267   GST_DEBUG_OBJECT (parse, "seek to format %s, rate %f, "
4268       "start type %d at %" GST_TIME_FORMAT ", end type %d at %"
4269       GST_TIME_FORMAT, gst_format_get_name (format), rate,
4270       start_type, GST_TIME_ARGS (start), stop_type, GST_TIME_ARGS (stop));
4271
4272   /* we can only handle TIME, so check if subclass can convert
4273    * to TIME format if it's some other format (such as DEFAULT) */
4274   if (format != GST_FORMAT_TIME) {
4275     if (!gst_base_parse_convert (parse, format, start, GST_FORMAT_TIME, &start)
4276         || !gst_base_parse_convert (parse, format, stop, GST_FORMAT_TIME,
4277             &stop))
4278       goto no_convert_to_time;
4279
4280     GST_INFO_OBJECT (parse, "converted %s format to start time "
4281         "%" GST_TIME_FORMAT " and stop time %" GST_TIME_FORMAT,
4282         gst_format_get_name (format), GST_TIME_ARGS (start),
4283         GST_TIME_ARGS (stop));
4284
4285     format = GST_FORMAT_TIME;
4286   }
4287
4288   /* no negative rates in push mode (unless upstream takes care of that, but
4289    * we've already tried upstream and it didn't handle the seek request) */
4290   if (rate < 0.0 && parse->priv->pad_mode == GST_PAD_MODE_PUSH)
4291     goto negative_rate;
4292
4293   if (rate < 0.0 && parse->priv->pad_mode == GST_PAD_MODE_PULL)
4294     goto negative_rate_pull_mode;
4295
4296   if (start_type != GST_SEEK_TYPE_SET ||
4297       (stop_type != GST_SEEK_TYPE_SET && stop_type != GST_SEEK_TYPE_NONE))
4298     goto wrong_type;
4299
4300   /* get flush flag */
4301   flush = flags & GST_SEEK_FLAG_FLUSH;
4302
4303   /* copy segment, we need this because we still need the old
4304    * segment when we close the current segment. */
4305   gst_segment_copy_into (&parse->segment, &seeksegment);
4306
4307   GST_DEBUG_OBJECT (parse, "configuring seek");
4308   gst_segment_do_seek (&seeksegment, rate, format, flags,
4309       start_type, start, stop_type, stop, &update);
4310
4311   /* accurate seeking implies seek tables are used to obtain position,
4312    * and the requested segment is maintained exactly, not adjusted any way */
4313   accurate = flags & GST_SEEK_FLAG_ACCURATE;
4314
4315   /* maybe we can be accurate for (almost) free */
4316   gst_base_parse_find_offset (parse, seeksegment.position, TRUE, &start_ts);
4317   if (seeksegment.position <= start_ts + TARGET_DIFFERENCE) {
4318     GST_DEBUG_OBJECT (parse, "accurate seek possible");
4319     accurate = TRUE;
4320   }
4321   if (accurate) {
4322     GstClockTime startpos = seeksegment.position;
4323
4324     /* accurate requested, so ... seek a bit before target */
4325     if (startpos < parse->priv->lead_in_ts)
4326       startpos = 0;
4327     else
4328       startpos -= parse->priv->lead_in_ts;
4329     seekpos = gst_base_parse_find_offset (parse, startpos, TRUE, &start_ts);
4330     seekstop = gst_base_parse_find_offset (parse, seeksegment.stop, FALSE,
4331         NULL);
4332   } else {
4333     start_ts = seeksegment.position;
4334     if (!gst_base_parse_convert (parse, format, seeksegment.position,
4335             GST_FORMAT_BYTES, &seekpos))
4336       goto convert_failed;
4337     if (!gst_base_parse_convert (parse, format, seeksegment.stop,
4338             GST_FORMAT_BYTES, &seekstop))
4339       goto convert_failed;
4340   }
4341
4342   GST_DEBUG_OBJECT (parse,
4343       "seek position %" G_GINT64_FORMAT " in bytes: %" G_GINT64_FORMAT,
4344       start_ts, seekpos);
4345   GST_DEBUG_OBJECT (parse,
4346       "seek stop %" G_GINT64_FORMAT " in bytes: %" G_GINT64_FORMAT,
4347       seeksegment.stop, seekstop);
4348
4349   if (parse->priv->pad_mode == GST_PAD_MODE_PULL) {
4350     gint64 last_stop;
4351
4352     GST_DEBUG_OBJECT (parse, "seek in PULL mode");
4353
4354     if (flush) {
4355       if (parse->srcpad) {
4356         GstEvent *fevent = gst_event_new_flush_start ();
4357         GST_DEBUG_OBJECT (parse, "sending flush start");
4358
4359         gst_event_set_seqnum (fevent, seqnum);
4360
4361         gst_pad_push_event (parse->srcpad, gst_event_ref (fevent));
4362         /* unlock upstream pull_range */
4363         gst_pad_push_event (parse->sinkpad, fevent);
4364       }
4365     } else {
4366       gst_pad_pause_task (parse->sinkpad);
4367     }
4368
4369     /* we should now be able to grab the streaming thread because we stopped it
4370      * with the above flush/pause code */
4371     GST_PAD_STREAM_LOCK (parse->sinkpad);
4372
4373     /* save current position */
4374     last_stop = parse->segment.position;
4375     GST_DEBUG_OBJECT (parse, "stopped streaming at %" G_GINT64_FORMAT,
4376         last_stop);
4377
4378     /* now commit to new position */
4379
4380     /* prepare for streaming again */
4381     if (flush) {
4382       GstEvent *fevent = gst_event_new_flush_stop (TRUE);
4383       GST_DEBUG_OBJECT (parse, "sending flush stop");
4384       gst_event_set_seqnum (fevent, seqnum);
4385       gst_pad_push_event (parse->srcpad, gst_event_ref (fevent));
4386       gst_pad_push_event (parse->sinkpad, fevent);
4387       gst_base_parse_clear_queues (parse);
4388     } else {
4389       /* keep track of our position */
4390       seeksegment.base = gst_segment_to_running_time (&seeksegment,
4391           seeksegment.format, parse->segment.position);
4392     }
4393
4394     memcpy (&parse->segment, &seeksegment, sizeof (GstSegment));
4395
4396     /* store the newsegment event so it can be sent from the streaming thread. */
4397     /* This will be sent later in _loop() */
4398     segment_event = gst_event_new_segment (&parse->segment);
4399     gst_event_set_seqnum (segment_event, seqnum);
4400     parse->priv->pending_events =
4401         g_list_prepend (parse->priv->pending_events, segment_event);
4402
4403     GST_DEBUG_OBJECT (parse, "Created newseg format %d, "
4404         "start = %" GST_TIME_FORMAT ", stop = %" GST_TIME_FORMAT
4405         ", time = %" GST_TIME_FORMAT, format,
4406         GST_TIME_ARGS (parse->segment.start),
4407         GST_TIME_ARGS (parse->segment.stop),
4408         GST_TIME_ARGS (parse->segment.time));
4409
4410     /* one last chance in pull mode to stay accurate;
4411      * maybe scan and subclass can find where to go */
4412     if (!accurate) {
4413       gint64 scanpos;
4414       GstClockTime ts = seeksegment.position;
4415
4416       gst_base_parse_locate_time (parse, &ts, &scanpos);
4417       if (scanpos >= 0) {
4418         accurate = TRUE;
4419         seekpos = scanpos;
4420         /* running collected index now consists of several intervals,
4421          * so optimized check no longer possible */
4422         parse->priv->index_last_valid = FALSE;
4423         parse->priv->index_last_offset = 0;
4424         parse->priv->index_last_ts = 0;
4425       }
4426     }
4427
4428     /* mark discont if we are going to stream from another position. */
4429     if (seekpos != parse->priv->offset) {
4430       GST_DEBUG_OBJECT (parse,
4431           "mark DISCONT, we did a seek to another position");
4432       parse->priv->offset = seekpos;
4433       parse->priv->last_offset = seekpos;
4434       parse->priv->seen_keyframe = FALSE;
4435       parse->priv->discont = TRUE;
4436       parse->priv->next_dts = start_ts;
4437       parse->priv->next_pts = GST_CLOCK_TIME_NONE;
4438       parse->priv->last_dts = GST_CLOCK_TIME_NONE;
4439       parse->priv->last_pts = GST_CLOCK_TIME_NONE;
4440       parse->priv->sync_offset = seekpos;
4441       parse->priv->exact_position = accurate;
4442     }
4443
4444     /* Start streaming thread if paused */
4445     gst_pad_start_task (parse->sinkpad,
4446         (GstTaskFunction) gst_base_parse_loop, parse->sinkpad, NULL);
4447
4448     GST_PAD_STREAM_UNLOCK (parse->sinkpad);
4449
4450     /* handled seek */
4451     res = TRUE;
4452   } else {
4453     GstEvent *new_event;
4454     GstBaseParseSeek *seek;
4455     GstSeekFlags flags = (flush ? GST_SEEK_FLAG_FLUSH : GST_SEEK_FLAG_NONE);
4456
4457     /* The only thing we need to do in PUSH-mode is to send the
4458        seek event (in bytes) to upstream. Segment / flush handling happens
4459        in corresponding src event handlers */
4460     GST_DEBUG_OBJECT (parse, "seek in PUSH mode");
4461     if (seekstop >= 0 && seekstop <= seekpos)
4462       seekstop = seekpos;
4463     new_event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags,
4464         GST_SEEK_TYPE_SET, seekpos, stop_type, seekstop);
4465     gst_event_set_seqnum (new_event, seqnum);
4466
4467     /* store segment info so its precise details can be reconstructed when
4468      * receiving newsegment;
4469      * this matters for all details when accurate seeking,
4470      * is most useful to preserve NONE stop time otherwise */
4471     seek = g_new0 (GstBaseParseSeek, 1);
4472     seek->segment = seeksegment;
4473     seek->accurate = accurate;
4474     seek->offset = seekpos;
4475     seek->start_ts = start_ts;
4476     GST_OBJECT_LOCK (parse);
4477     /* less optimal, but preserves order */
4478     parse->priv->pending_seeks =
4479         g_slist_append (parse->priv->pending_seeks, seek);
4480     GST_OBJECT_UNLOCK (parse);
4481
4482     res = gst_pad_push_event (parse->sinkpad, new_event);
4483
4484     if (!res) {
4485       GST_OBJECT_LOCK (parse);
4486       parse->priv->pending_seeks =
4487           g_slist_remove (parse->priv->pending_seeks, seek);
4488       GST_OBJECT_UNLOCK (parse);
4489       g_free (seek);
4490     }
4491   }
4492
4493 done:
4494   gst_event_unref (event);
4495   return res;
4496
4497   /* ERRORS */
4498 negative_rate_pull_mode:
4499   {
4500     GST_FIXME_OBJECT (parse, "negative playback in pull mode needs fixing");
4501     res = FALSE;
4502     goto done;
4503   }
4504 negative_rate:
4505   {
4506     GST_DEBUG_OBJECT (parse, "negative playback rates delegated upstream.");
4507     res = FALSE;
4508     goto done;
4509   }
4510 wrong_type:
4511   {
4512     GST_DEBUG_OBJECT (parse, "unsupported seek type.");
4513     res = FALSE;
4514     goto done;
4515   }
4516 no_convert_to_time:
4517   {
4518     GST_DEBUG_OBJECT (parse, "seek in %s format was requested, but subclass "
4519         "couldn't convert that into TIME format", gst_format_get_name (format));
4520     res = FALSE;
4521     goto done;
4522   }
4523 convert_failed:
4524   {
4525     GST_DEBUG_OBJECT (parse, "conversion TIME to BYTES failed.");
4526     res = FALSE;
4527     goto done;
4528   }
4529 }
4530
4531 /* Checks if bitrates are available from upstream tags so that we don't
4532  * override them later
4533  */
4534 static void
4535 gst_base_parse_handle_tag (GstBaseParse * parse, GstEvent * event)
4536 {
4537   GstTagList *taglist = NULL;
4538   guint tmp;
4539
4540   gst_event_parse_tag (event, &taglist);
4541
4542   /* We only care about stream tags here */
4543   if (gst_tag_list_get_scope (taglist) != GST_TAG_SCOPE_STREAM)
4544     return;
4545
4546   if (gst_tag_list_get_uint (taglist, GST_TAG_MINIMUM_BITRATE, &tmp)) {
4547     GST_DEBUG_OBJECT (parse, "upstream min bitrate %d", tmp);
4548     parse->priv->post_min_bitrate = FALSE;
4549   }
4550   if (gst_tag_list_get_uint (taglist, GST_TAG_BITRATE, &tmp)) {
4551     GST_DEBUG_OBJECT (parse, "upstream avg bitrate %d", tmp);
4552     parse->priv->post_avg_bitrate = FALSE;
4553   }
4554   if (gst_tag_list_get_uint (taglist, GST_TAG_MAXIMUM_BITRATE, &tmp)) {
4555     GST_DEBUG_OBJECT (parse, "upstream max bitrate %d", tmp);
4556     parse->priv->post_max_bitrate = FALSE;
4557   }
4558 }
4559
4560 #if 0
4561 static void
4562 gst_base_parse_set_index (GstElement * element, GstIndex * index)
4563 {
4564   GstBaseParse *parse = GST_BASE_PARSE (element);
4565
4566   GST_BASE_PARSE_INDEX_LOCK (parse);
4567   if (parse->priv->index)
4568     gst_object_unref (parse->priv->index);
4569   if (index) {
4570     parse->priv->index = gst_object_ref (index);
4571     gst_index_get_writer_id (index, GST_OBJECT_CAST (element),
4572         &parse->priv->index_id);
4573     parse->priv->own_index = FALSE;
4574   } else {
4575     parse->priv->index = NULL;
4576   }
4577   GST_BASE_PARSE_INDEX_UNLOCK (parse);
4578 }
4579
4580 static GstIndex *
4581 gst_base_parse_get_index (GstElement * element)
4582 {
4583   GstBaseParse *parse = GST_BASE_PARSE (element);
4584   GstIndex *result = NULL;
4585
4586   GST_BASE_PARSE_INDEX_LOCK (parse);
4587   if (parse->priv->index)
4588     result = gst_object_ref (parse->priv->index);
4589   GST_BASE_PARSE_INDEX_UNLOCK (parse);
4590
4591   return result;
4592 }
4593 #endif
4594
4595 static GstStateChangeReturn
4596 gst_base_parse_change_state (GstElement * element, GstStateChange transition)
4597 {
4598   GstBaseParse *parse;
4599   GstStateChangeReturn result;
4600
4601   parse = GST_BASE_PARSE (element);
4602
4603   switch (transition) {
4604     case GST_STATE_CHANGE_READY_TO_PAUSED:
4605       /* If this is our own index destroy it as the
4606        * old entries might be wrong for the new stream */
4607       GST_BASE_PARSE_INDEX_LOCK (parse);
4608       if (parse->priv->own_index) {
4609         gst_object_unref (parse->priv->index);
4610         parse->priv->index = NULL;
4611         parse->priv->own_index = FALSE;
4612       }
4613
4614       /* If no index was created, generate one */
4615       if (G_UNLIKELY (!parse->priv->index)) {
4616         GST_DEBUG_OBJECT (parse, "no index provided creating our own");
4617
4618         parse->priv->index = g_object_new (gst_mem_index_get_type (), NULL);
4619         gst_index_get_writer_id (parse->priv->index, GST_OBJECT (parse),
4620             &parse->priv->index_id);
4621         parse->priv->own_index = TRUE;
4622       }
4623       GST_BASE_PARSE_INDEX_UNLOCK (parse);
4624       break;
4625     default:
4626       break;
4627   }
4628
4629   result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
4630
4631   switch (transition) {
4632     case GST_STATE_CHANGE_PAUSED_TO_READY:
4633       gst_base_parse_reset (parse);
4634       break;
4635     default:
4636       break;
4637   }
4638
4639   return result;
4640 }
4641
4642 /**
4643  * gst_base_parse_set_ts_at_offset:
4644  * @parse: a #GstBaseParse
4645  * @offset: offset into current buffer
4646  *
4647  * This function should only be called from a @handle_frame implementation.
4648  *
4649  * #GstBaseParse creates initial timestamps for frames by using the last
4650  * timestamp seen in the stream before the frame starts.  In certain
4651  * cases, the correct timestamps will occur in the stream after the
4652  * start of the frame, but before the start of the actual picture data.
4653  * This function can be used to set the timestamps based on the offset
4654  * into the frame data that the picture starts.
4655  *
4656  * Since: 1.2
4657  */
4658 void
4659 gst_base_parse_set_ts_at_offset (GstBaseParse * parse, gsize offset)
4660 {
4661   GstClockTime pts, dts;
4662
4663   g_return_if_fail (GST_IS_BASE_PARSE (parse));
4664
4665   pts = gst_adapter_prev_pts_at_offset (parse->priv->adapter, offset, NULL);
4666   dts = gst_adapter_prev_dts_at_offset (parse->priv->adapter, offset, NULL);
4667
4668   if (!GST_CLOCK_TIME_IS_VALID (pts) || !GST_CLOCK_TIME_IS_VALID (dts)) {
4669     GST_DEBUG_OBJECT (parse,
4670         "offset adapter timestamps dts=%" GST_TIME_FORMAT " pts=%"
4671         GST_TIME_FORMAT, GST_TIME_ARGS (dts), GST_TIME_ARGS (pts));
4672   }
4673   if (GST_CLOCK_TIME_IS_VALID (pts) && (parse->priv->prev_pts != pts))
4674     parse->priv->prev_pts = parse->priv->next_pts = pts;
4675
4676   if (GST_CLOCK_TIME_IS_VALID (dts) && (parse->priv->prev_dts != dts))
4677     parse->priv->prev_dts = parse->priv->next_dts = dts;
4678 }