Merging gst-plugins-bad
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-bad / ext / resindvd / gstmpegdemux.c
1 /*
2  * The contents of this file are subject to the Mozilla Public License
3  * Version 1.1 (the "License"); you may not use this file except in
4  * compliance with the License. You may obtain a copy of the License at
5  * http://www.mozilla.org/MPL/.
6  *
7  * Software distributed under the License is distributed on an "AS IS"
8  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
9  * License for the specific language governing rights and limitations
10  * under the License.
11  *
12  * The Original Code is Fluendo MPEG Demuxer plugin.
13  *
14  * The Initial Developer of the Original Code is Fluendo, S.L.
15  * Portions created by Fluendo, S.L. are Copyright (C) 2005
16  * Fluendo, S.L. All Rights Reserved.
17  *
18  * Contributor(s): Wim Taymans <wim@fluendo.com>
19  *                 Jan Schmidt <thaytan@noraisin.net>
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <string.h>
27
28 #include <gst/video/video.h>
29 #include <gst/tag/tag.h>
30 #include <gst/pbutils/pbutils.h>
31
32 #include "gstmpegdefs.h"
33 #include "gstmpegdemux.h"
34
35 #define SEGMENT_THRESHOLD (300*GST_MSECOND)
36 #define VIDEO_SEGMENT_THRESHOLD (500*GST_MSECOND)
37
38 /* The SCR_MUNGE value is used to offset the scr_adjust value, to avoid
39  * ever generating a negative timestamp */
40 #define SCR_MUNGE (10 * GST_SECOND)
41
42 /* We clamp scr delta with 0 so negative bytes won't be possible */
43 #define GSTTIME_TO_BYTES(time) \
44   ((time != -1) ? gst_util_uint64_scale (MAX(0,(gint64) (GSTTIME_TO_MPEGTIME(time))), demux->scr_rate_n, demux->scr_rate_d) : -1)
45 #define BYTES_TO_GSTTIME(bytes) ((bytes != -1) ? MPEGTIME_TO_GSTTIME(gst_util_uint64_scale (bytes, demux->scr_rate_d, demux->scr_rate_n)) : -1)
46
47 #define ADAPTER_OFFSET_FLUSH(_bytes_) demux->adapter_offset += (_bytes_)
48
49 GST_DEBUG_CATEGORY_STATIC (gstflupsdemux_debug);
50 #define GST_CAT_DEFAULT (gstflupsdemux_debug)
51
52 GST_DEBUG_CATEGORY_EXTERN (mpegpspesfilter_debug);
53
54 /* MPEG2Demux signals and args */
55 enum
56 {
57   /* FILL ME */
58   LAST_SIGNAL
59 };
60
61 enum
62 {
63   ARG_0,
64   /* FILL ME */
65 };
66
67 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
68     GST_PAD_SINK,
69     GST_PAD_ALWAYS,
70     GST_STATIC_CAPS ("application/x-resin-dvd")
71     );
72
73 static GstStaticPadTemplate video_template =
74     GST_STATIC_PAD_TEMPLATE ("video_%02x",
75     GST_PAD_SRC,
76     GST_PAD_SOMETIMES,
77     GST_STATIC_CAPS ("video/mpeg, "
78         "mpegversion = (int) { 1, 2, 4 }, " "systemstream = (boolean) FALSE, "
79         "parsed = (boolean) FALSE; " "video/x-h264")
80     );
81
82 static GstStaticPadTemplate audio_template =
83     GST_STATIC_PAD_TEMPLATE ("audio_%02x",
84     GST_PAD_SRC,
85     GST_PAD_SOMETIMES,
86     GST_STATIC_CAPS ("audio/mpeg, mpegversion = (int) 1;"
87         "audio/mpeg, mpegversion = (int) 4, stream-format = (string) { adts, loas };"
88         "audio/x-private1-lpcm; "
89         "audio/x-private1-ac3;" "audio/x-private1-dts;" "audio/ac3")
90     );
91
92 static GstStaticPadTemplate subpicture_template =
93 GST_STATIC_PAD_TEMPLATE ("subpicture_%02x",
94     GST_PAD_SRC,
95     GST_PAD_SOMETIMES,
96     GST_STATIC_CAPS ("subpicture/x-dvd")
97     );
98
99 static GstStaticPadTemplate private_template =
100 GST_STATIC_PAD_TEMPLATE ("private_%d",
101     GST_PAD_SRC,
102     GST_PAD_SOMETIMES,
103     GST_STATIC_CAPS_ANY);
104
105 static void gst_flups_demux_base_init (GstFluPSDemuxClass * klass);
106 static void gst_flups_demux_class_init (GstFluPSDemuxClass * klass);
107 static void gst_flups_demux_init (GstFluPSDemux * demux);
108 static void gst_flups_demux_finalize (GstFluPSDemux * demux);
109 static void gst_flups_demux_reset (GstFluPSDemux * demux);
110
111 static gboolean gst_flups_demux_sink_event (GstPad * pad, GstObject * parent,
112     GstEvent * event);
113 static GstFlowReturn gst_flups_demux_chain (GstPad * pad, GstObject * parent,
114     GstBuffer * buffer);
115 static gboolean gst_flups_demux_sink_activate (GstPad * sinkpad,
116     GstObject * parent);
117 static gboolean gst_flups_demux_sink_activate_mode (GstPad * pad,
118     GstObject * parent, GstPadMode mode, gboolean active);
119 // static void gst_flups_demux_loop (GstPad * pad);
120
121 static gboolean gst_flups_demux_src_event (GstPad * pad, GstObject * parent,
122     GstEvent * event);
123 static gboolean gst_flups_demux_src_query (GstPad * pad, GstObject * parent,
124     GstQuery * query);
125
126 static GstStateChangeReturn gst_flups_demux_change_state (GstElement * element,
127     GstStateChange transition);
128
129 static inline void gst_flups_demux_send_gap_updates (GstFluPSDemux * demux,
130     GstClockTime new_time, gboolean no_threshold);
131 static inline void gst_flups_demux_clear_times (GstFluPSDemux * demux);
132
133 static void gst_flups_demux_reset_psm (GstFluPSDemux * demux);
134 static void gst_flups_demux_flush (GstFluPSDemux * demux);
135
136 static GstElementClass *parent_class = NULL;
137
138 static void gst_segment_set_position (GstSegment * segment, GstFormat format,
139     guint64 position);
140 //static void gst_segment_set_duration (GstSegment * segment, GstFormat format,
141 //    guint64 duration);
142
143 /*static guint gst_flups_demux_signals[LAST_SIGNAL] = { 0 };*/
144
145 GType
146 gst_flups_demux_get_type (void)
147 {
148   static GType flups_demux_type = 0;
149
150   if (!flups_demux_type) {
151     static const GTypeInfo flups_demux_info = {
152       sizeof (GstFluPSDemuxClass),
153       (GBaseInitFunc) gst_flups_demux_base_init,
154       NULL,
155       (GClassInitFunc) gst_flups_demux_class_init,
156       NULL,
157       NULL,
158       sizeof (GstFluPSDemux),
159       0,
160       (GInstanceInitFunc) gst_flups_demux_init,
161       NULL
162     };
163
164     flups_demux_type =
165         g_type_register_static (GST_TYPE_ELEMENT, "RsnDVDDemux",
166         &flups_demux_info, 0);
167
168     GST_DEBUG_CATEGORY_INIT (gstflupsdemux_debug, "rsndvddemux", 0,
169         "MPEG program stream demultiplexer element");
170   }
171
172   return flups_demux_type;
173 }
174
175 static void
176 gst_flups_demux_base_init (GstFluPSDemuxClass * klass)
177 {
178   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
179
180   klass->sink_template = gst_static_pad_template_get (&sink_template);
181   klass->video_template = gst_static_pad_template_get (&video_template);
182   klass->audio_template = gst_static_pad_template_get (&audio_template);
183   klass->subpicture_template =
184       gst_static_pad_template_get (&subpicture_template);
185   klass->private_template = gst_static_pad_template_get (&private_template);
186
187   gst_element_class_add_pad_template (element_class, klass->video_template);
188   gst_element_class_add_pad_template (element_class, klass->audio_template);
189   gst_element_class_add_pad_template (element_class,
190       klass->subpicture_template);
191   gst_element_class_add_pad_template (element_class, klass->private_template);
192   gst_element_class_add_pad_template (element_class, klass->sink_template);
193
194   gst_element_class_set_static_metadata (element_class,
195       "MPEG Program Demuxer", "Codec/Demuxer",
196       "Demultiplexes MPEG Program Streams",
197       "Jan Schmidt <thaytan@noraisin.net>");
198 }
199
200 static void
201 gst_flups_demux_class_init (GstFluPSDemuxClass * klass)
202 {
203   GObjectClass *gobject_class;
204   GstElementClass *gstelement_class;
205
206   parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
207
208   gobject_class = (GObjectClass *) klass;
209   gstelement_class = (GstElementClass *) klass;
210
211   gobject_class->finalize = (GObjectFinalizeFunc) gst_flups_demux_finalize;
212
213   gstelement_class->change_state = gst_flups_demux_change_state;
214 }
215
216 static void
217 gst_flups_demux_init (GstFluPSDemux * demux)
218 {
219   GstFluPSDemuxClass *klass = GST_FLUPS_DEMUX_GET_CLASS (demux);
220
221   demux->sinkpad = gst_pad_new_from_template (klass->sink_template, "sink");
222   gst_pad_set_event_function (demux->sinkpad,
223       GST_DEBUG_FUNCPTR (gst_flups_demux_sink_event));
224   gst_pad_set_chain_function (demux->sinkpad,
225       GST_DEBUG_FUNCPTR (gst_flups_demux_chain));
226   gst_pad_set_activate_function (demux->sinkpad,
227       GST_DEBUG_FUNCPTR (gst_flups_demux_sink_activate));
228   gst_pad_set_activatemode_function (demux->sinkpad,
229       GST_DEBUG_FUNCPTR (gst_flups_demux_sink_activate_mode));
230
231   gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);
232
233   demux->streams =
234       g_malloc0 (sizeof (GstFluPSStream *) * (GST_FLUPS_DEMUX_MAX_STREAMS));
235   demux->streams_found =
236       g_malloc0 (sizeof (GstFluPSStream *) * (GST_FLUPS_DEMUX_MAX_STREAMS));
237   demux->found_count = 0;
238
239   demux->adapter = gst_adapter_new ();
240   demux->rev_adapter = gst_adapter_new ();
241
242   demux->scr_adjust = GSTTIME_TO_MPEGTIME (SCR_MUNGE);
243
244   gst_flups_demux_reset (demux);
245 }
246
247 static void
248 gst_flups_demux_finalize (GstFluPSDemux * demux)
249 {
250   gst_flups_demux_reset (demux);
251   g_free (demux->streams);
252   g_free (demux->streams_found);
253
254   g_object_unref (demux->adapter);
255   g_object_unref (demux->rev_adapter);
256
257   G_OBJECT_CLASS (parent_class)->finalize (G_OBJECT (demux));
258 }
259
260 static void
261 gst_flups_demux_reset (GstFluPSDemux * demux)
262 {
263   /* Clean up the streams and pads we allocated */
264   gint i;
265
266   for (i = 0; i < GST_FLUPS_DEMUX_MAX_STREAMS; i++) {
267     GstFluPSStream *stream = demux->streams[i];
268
269     if (stream != NULL) {
270       if (stream->pad && GST_PAD_PARENT (stream->pad))
271         gst_element_remove_pad (GST_ELEMENT_CAST (demux), stream->pad);
272
273       if (stream->pending_tags)
274         gst_tag_list_unref (stream->pending_tags);
275       g_free (stream);
276       demux->streams[i] = NULL;
277     }
278   }
279   memset (demux->streams_found, 0,
280       sizeof (GstFluPSStream *) * (GST_FLUPS_DEMUX_MAX_STREAMS));
281   demux->found_count = 0;
282
283   gst_adapter_clear (demux->adapter);
284   gst_adapter_clear (demux->rev_adapter);
285
286   demux->adapter_offset = G_MAXUINT64;
287   demux->first_scr = G_MAXUINT64;
288   demux->current_scr = G_MAXUINT64;
289   demux->base_time = G_MAXUINT64;
290   demux->scr_rate_n = G_MAXUINT64;
291   demux->scr_rate_d = G_MAXUINT64;
292   demux->mux_rate = G_MAXUINT64;
293   demux->next_pts = G_MAXUINT64;
294   demux->next_dts = G_MAXUINT64;
295   demux->need_no_more_pads = TRUE;
296   gst_flups_demux_reset_psm (demux);
297   gst_segment_init (&demux->sink_segment, GST_FORMAT_UNDEFINED);
298   gst_segment_init (&demux->src_segment, GST_FORMAT_TIME);
299   gst_flups_demux_flush (demux);
300   demux->have_group_id = FALSE;
301   demux->group_id = G_MAXUINT;
302
303   demux->scr_adjust = GSTTIME_TO_MPEGTIME (SCR_MUNGE);
304 }
305
306 static GstFluPSStream *
307 gst_flups_demux_create_stream (GstFluPSDemux * demux, gint id, gint stream_type)
308 {
309   GstFluPSStream *stream;
310   GstPadTemplate *template;
311   gchar *name;
312   GstFluPSDemuxClass *klass = GST_FLUPS_DEMUX_GET_CLASS (demux);
313   GstCaps *caps;
314   GstClockTime threshold = SEGMENT_THRESHOLD;
315   GstEvent *event;
316   gchar *stream_id;
317
318   name = NULL;
319   template = NULL;
320   caps = NULL;
321
322   GST_DEBUG_OBJECT (demux, "create stream id 0x%02x, type 0x%02x", id,
323       stream_type);
324
325   switch (stream_type) {
326     case ST_VIDEO_MPEG1:
327     case ST_VIDEO_MPEG2:
328     case ST_VIDEO_MPEG4:
329     case ST_GST_VIDEO_MPEG1_OR_2:
330     {
331       gint mpeg_version = 1;
332       if (stream_type == ST_VIDEO_MPEG2 ||
333           (stream_type == ST_GST_VIDEO_MPEG1_OR_2 && demux->is_mpeg2_pack)) {
334         mpeg_version = 2;
335       }
336       if (stream_type == ST_VIDEO_MPEG4) {
337         mpeg_version = 4;
338       }
339
340       template = klass->video_template;
341       name = g_strdup_printf ("video_%02x", id);
342       caps = gst_caps_new_simple ("video/mpeg",
343           "mpegversion", G_TYPE_INT, mpeg_version,
344           "systemstream", G_TYPE_BOOLEAN, FALSE,
345           "parsed", G_TYPE_BOOLEAN, FALSE, NULL);
346       threshold = VIDEO_SEGMENT_THRESHOLD;
347       break;
348     }
349     case ST_AUDIO_MPEG1:
350     case ST_AUDIO_MPEG2:
351       template = klass->audio_template;
352       name = g_strdup_printf ("audio_%02x", id);
353       caps = gst_caps_new_simple ("audio/mpeg",
354           "mpegversion", G_TYPE_INT, 1, NULL);
355       break;
356     case ST_PRIVATE_SECTIONS:
357     case ST_PRIVATE_DATA:
358     case ST_MHEG:
359     case ST_DSMCC:
360       break;
361     case ST_AUDIO_AAC_ADTS:
362       template = klass->audio_template;
363       name = g_strdup_printf ("audio_%02x", id);
364       caps = gst_caps_new_simple ("audio/mpeg",
365           "mpegversion", G_TYPE_INT, 4,
366           "stream-format", G_TYPE_STRING, "adts", NULL);
367       break;
368     case ST_AUDIO_AAC_LOAS:    // LATM/LOAS AAC syntax
369       template = klass->audio_template;
370       name = g_strdup_printf ("audio_%02x", id);
371       caps = gst_caps_new_simple ("audio/mpeg",
372           "mpegversion", G_TYPE_INT, 4,
373           "stream-format", G_TYPE_STRING, "loas", NULL);
374       break;
375     case ST_VIDEO_H264:
376       template = klass->video_template;
377       name = g_strdup_printf ("video_%02x", id);
378       caps = gst_caps_new_empty_simple ("video/x-h264");
379       threshold = VIDEO_SEGMENT_THRESHOLD;
380       break;
381     case ST_PS_AUDIO_AC3:
382       template = klass->audio_template;
383       name = g_strdup_printf ("audio_%02x", id);
384       caps = gst_caps_new_empty_simple ("audio/x-private1-ac3");
385       break;
386     case ST_PS_AUDIO_DTS:
387       template = klass->audio_template;
388       name = g_strdup_printf ("audio_%02x", id);
389       caps = gst_caps_new_empty_simple ("audio/x-private1-dts");
390       break;
391     case ST_PS_AUDIO_LPCM:
392       template = klass->audio_template;
393       name = g_strdup_printf ("audio_%02x", id);
394       caps = gst_caps_new_empty_simple ("audio/x-private1-lpcm");
395       break;
396     case ST_PS_DVD_SUBPICTURE:
397       template = klass->subpicture_template;
398       name = g_strdup_printf ("subpicture_%02x", id);
399       caps = gst_caps_new_empty_simple ("subpicture/x-dvd");
400       break;
401     case ST_GST_AUDIO_RAWA52:
402       template = klass->audio_template;
403       name = g_strdup_printf ("audio_%02x", id);
404       caps = gst_caps_new_empty_simple ("audio/ac3");
405       break;
406     default:
407       break;
408   }
409
410   if (name == NULL || template == NULL || caps == NULL) {
411     g_free (name);
412     if (caps)
413       gst_caps_unref (caps);
414     return FALSE;
415   }
416
417   stream = g_new0 (GstFluPSStream, 1);
418   stream->id = id;
419   stream->discont = TRUE;
420   stream->need_segment = TRUE;
421   stream->notlinked = FALSE;
422   stream->last_flow = GST_FLOW_OK;
423   stream->type = stream_type;
424   stream->pending_tags = NULL;
425   stream->pad = gst_pad_new_from_template (template, name);
426   stream->segment_thresh = threshold;
427   gst_pad_set_event_function (stream->pad,
428       GST_DEBUG_FUNCPTR (gst_flups_demux_src_event));
429   gst_pad_set_query_function (stream->pad,
430       GST_DEBUG_FUNCPTR (gst_flups_demux_src_query));
431   gst_pad_use_fixed_caps (stream->pad);
432
433   /* needed for set_caps to work */
434   if (!gst_pad_set_active (stream->pad, TRUE)) {
435     GST_WARNING_OBJECT (demux, "Failed to activate pad %" GST_PTR_FORMAT,
436         stream->pad);
437   }
438
439   stream_id =
440       gst_pad_create_stream_id_printf (stream->pad, GST_ELEMENT_CAST (demux),
441       "%02x", id);
442
443   event = gst_pad_get_sticky_event (demux->sinkpad, GST_EVENT_STREAM_START, 0);
444   if (event) {
445     if (gst_event_parse_group_id (event, &demux->group_id))
446       demux->have_group_id = TRUE;
447     else
448       demux->have_group_id = FALSE;
449     gst_event_unref (event);
450   } else if (!demux->have_group_id) {
451     demux->have_group_id = TRUE;
452     demux->group_id = gst_util_group_id_next ();
453   }
454   event = gst_event_new_stream_start (stream_id);
455   if (demux->have_group_id)
456     gst_event_set_group_id (event, demux->group_id);
457
458   gst_pad_push_event (stream->pad, event);
459   g_free (stream_id);
460
461   gst_pad_set_caps (stream->pad, caps);
462
463   if (!stream->pending_tags)
464     stream->pending_tags = gst_tag_list_new_empty ();
465   gst_pb_utils_add_codec_description_to_tag_list (stream->pending_tags, NULL,
466       caps);
467
468   GST_DEBUG_OBJECT (demux, "create pad %s, caps %" GST_PTR_FORMAT, name, caps);
469   gst_caps_unref (caps);
470   g_free (name);
471
472   return stream;
473 }
474
475 static GstFluPSStream *
476 gst_flups_demux_get_stream (GstFluPSDemux * demux, gint id, gint type)
477 {
478   GstFluPSStream *stream = demux->streams[id];
479
480   if (stream == NULL && !demux->disable_stream_creation) {
481     if (!(stream = gst_flups_demux_create_stream (demux, id, type)))
482       goto unknown_stream;
483
484     GST_DEBUG_OBJECT (demux, "adding pad for stream id 0x%02x type 0x%02x", id,
485         type);
486
487     gst_element_add_pad (GST_ELEMENT (demux), stream->pad);
488
489     demux->streams[id] = stream;
490     demux->streams_found[demux->found_count++] = stream;
491   }
492   return stream;
493
494   /* ERROR */
495 unknown_stream:
496   {
497     GST_DEBUG_OBJECT (demux, "unknown stream id 0x%02x type 0x%02x", id, type);
498     return NULL;
499   }
500 }
501
502 static GstFlowReturn
503 gst_flups_demux_send_data (GstFluPSDemux * demux, GstFluPSStream * stream,
504     GstBuffer * buf)
505 {
506   GstFlowReturn result;
507   GstClockTime pts = GST_CLOCK_TIME_NONE, dts = GST_CLOCK_TIME_NONE;
508
509   if (stream == NULL)
510     goto no_stream;
511
512   /* timestamps */
513   if (G_UNLIKELY (demux->next_pts != G_MAXUINT64))
514     pts = MPEGTIME_TO_GSTTIME (demux->next_pts);
515   if (G_UNLIKELY (demux->next_dts != G_MAXUINT64))
516     dts = MPEGTIME_TO_GSTTIME (demux->next_dts);
517
518   if (G_UNLIKELY (stream->pending_tags)) {
519     GST_DEBUG_OBJECT (demux, "Sending pending_tags %p for pad %s:%s : %"
520         GST_PTR_FORMAT, stream->pending_tags,
521         GST_DEBUG_PAD_NAME (stream->pad), stream->pending_tags);
522     gst_pad_push_event (stream->pad, gst_event_new_tag (stream->pending_tags));
523     stream->pending_tags = NULL;
524   }
525
526   if (demux->current_scr != G_MAXUINT64) {
527     GstClockTime cur_scr_time = MPEGTIME_TO_GSTTIME (demux->current_scr);
528
529     if (stream->last_ts == GST_CLOCK_TIME_NONE ||
530         stream->last_ts < cur_scr_time) {
531 #if 0
532       g_print ("last_ts update on pad %s to time %" GST_TIME_FORMAT "\n",
533           GST_PAD_NAME (stream->pad), GST_TIME_ARGS (cur_scr_time));
534 #endif
535       stream->last_ts = cur_scr_time;
536     }
537   }
538
539   /* OK, sent new segment now prepare the buffer for sending */
540   GST_BUFFER_PTS (buf) = pts;
541   GST_BUFFER_DTS (buf) = dts;
542
543   /* Set the buffer discont flag, and clear discont state on the stream */
544   if (stream->discont) {
545     GST_DEBUG_OBJECT (demux, "discont buffer to pad %" GST_PTR_FORMAT
546         " with PTS %" GST_TIME_FORMAT " DTS %" GST_TIME_FORMAT,
547         stream->pad, GST_TIME_ARGS (pts), GST_TIME_ARGS (dts));
548     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
549
550     stream->discont = FALSE;
551   } else {
552     GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
553   }
554
555   demux->next_pts = G_MAXUINT64;
556   demux->next_dts = G_MAXUINT64;
557
558   GST_LOG_OBJECT (demux, "pushing stream id 0x%02x type 0x%02x, pts time: %"
559       GST_TIME_FORMAT ", size %" G_GSIZE_FORMAT,
560       stream->id, stream->type, GST_TIME_ARGS (pts), gst_buffer_get_size (buf));
561   stream->last_flow = result = gst_pad_push (stream->pad, buf);
562   GST_LOG_OBJECT (demux, "result: %s", gst_flow_get_name (result));
563
564   return result;
565
566   /* ERROR */
567 no_stream:
568   {
569     GST_DEBUG_OBJECT (demux, "no stream given");
570     gst_buffer_unref (buf);
571     return GST_FLOW_OK;
572   }
573 }
574
575 static inline void
576 gst_flups_demux_mark_discont (GstFluPSDemux * demux, gboolean discont,
577     gboolean need_segment)
578 {
579   gint i, count = demux->found_count;
580
581   /* mark discont on all streams */
582   for (i = 0; i < count; i++) {
583     GstFluPSStream *stream = demux->streams_found[i];
584
585     if (G_LIKELY (stream)) {
586       stream->discont |= discont;
587       stream->need_segment |= need_segment;
588       GST_DEBUG_OBJECT (demux, "marked stream as discont %d, need_segment %d",
589           stream->discont, stream->need_segment);
590     }
591   }
592 }
593
594 static gboolean
595 gst_flups_demux_send_event (GstFluPSDemux * demux, GstEvent * event)
596 {
597   gint i, count = demux->found_count;
598   gboolean ret = FALSE;
599
600   for (i = 0; i < count; i++) {
601     GstFluPSStream *stream = demux->streams_found[i];
602
603     if (stream) {
604       if (!gst_pad_push_event (stream->pad, gst_event_ref (event))) {
605         GST_DEBUG_OBJECT (stream->pad, "%s event was not handled",
606             GST_EVENT_TYPE_NAME (event));
607       } else {
608         /* If at least one push returns TRUE, then we return TRUE. */
609         GST_DEBUG_OBJECT (stream->pad, "%s event was handled",
610             GST_EVENT_TYPE_NAME (event));
611         ret = TRUE;
612       }
613     }
614   }
615
616   gst_event_unref (event);
617   return ret;
618 }
619
620 static gboolean
621 gst_flups_demux_handle_dvd_event (GstFluPSDemux * demux, GstEvent * event)
622 {
623   const GstStructure *structure = gst_event_get_structure (event);
624   const char *type = gst_structure_get_string (structure, "event");
625   gint i;
626   gchar cur_stream_name[32];
627   GstFluPSStream *temp = NULL;
628   const gchar *lang_code;
629   gboolean ret = TRUE;
630
631   if (strcmp (type, "dvd-lang-codes") == 0) {
632     GST_DEBUG_OBJECT (demux, "Handling language codes event");
633
634     demux->disable_stream_creation = FALSE;
635
636     /* Create a video pad to ensure it exists before emitting no more pads */
637     temp = gst_flups_demux_get_stream (demux, 0xe0, ST_VIDEO_MPEG2);
638     /* Send a video format event downstream */
639     {
640       gboolean is_widescreen, is_pal;
641
642       if (gst_structure_get_boolean (structure,
643               "video-widescreen", &is_widescreen) &&
644           gst_structure_get_boolean (structure, "video-pal-format", &is_pal)) {
645         GstEvent *v_format;
646         GstStructure *v_struct;
647
648         v_struct = gst_structure_new ("application/x-gst-dvd",
649             "event", G_TYPE_STRING, "dvd-video-format",
650             "video-widescreen", G_TYPE_BOOLEAN, is_widescreen,
651             "video-pal-format", G_TYPE_BOOLEAN, is_pal, NULL);
652         v_format = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, v_struct);
653         gst_pad_push_event (temp->pad, v_format);
654       }
655     }
656
657     /* Read out the languages for audio streams and request each one that 
658      * is present */
659     for (i = 0; i < MAX_DVD_AUDIO_STREAMS; i++) {
660       gint stream_format;
661       gint stream_id;
662
663       g_snprintf (cur_stream_name, 32, "audio-%d-format", i);
664       if (!gst_structure_get_int (structure, cur_stream_name, &stream_format))
665         continue;
666
667       g_snprintf (cur_stream_name, 32, "audio-%d-stream", i);
668       if (!gst_structure_get_int (structure, cur_stream_name, &stream_id))
669         continue;
670       if (stream_id < 0 || stream_id >= MAX_DVD_AUDIO_STREAMS)
671         continue;
672
673       switch (stream_format) {
674         case 0x0:
675           /* AC3 */
676           stream_id += 0x80;
677           GST_DEBUG_OBJECT (demux,
678               "Audio stream %d format %d ID 0x%02x - AC3", i,
679               stream_format, stream_id);
680           temp = gst_flups_demux_get_stream (demux, stream_id, ST_PS_AUDIO_AC3);
681           break;
682         case 0x2:
683         case 0x3:
684           /* MPEG audio without and with extension stream are
685            * treated the same */
686           stream_id += 0xC0;
687           GST_DEBUG_OBJECT (demux,
688               "Audio stream %d format %d ID 0x%02x - MPEG audio", i,
689               stream_format, stream_id);
690           temp = gst_flups_demux_get_stream (demux, stream_id, ST_AUDIO_MPEG1);
691           break;
692         case 0x4:
693           /* LPCM */
694           stream_id += 0xA0;
695           GST_DEBUG_OBJECT (demux,
696               "Audio stream %d format %d ID 0x%02x - DVD LPCM", i,
697               stream_format, stream_id);
698           temp =
699               gst_flups_demux_get_stream (demux, stream_id, ST_PS_AUDIO_LPCM);
700           break;
701         case 0x6:
702           /* DTS */
703           stream_id += 0x88;
704           GST_DEBUG_OBJECT (demux,
705               "Audio stream %d format %d ID 0x%02x - DTS", i,
706               stream_format, stream_id);
707           temp = gst_flups_demux_get_stream (demux, stream_id, ST_PS_AUDIO_DTS);
708           break;
709         case 0x7:
710           /* FIXME: What range is SDDS? */
711           GST_WARNING_OBJECT (demux,
712               "Unsupported audio stream format in language code event: %d",
713               stream_format);
714           temp = NULL;
715           continue;
716         default:
717           GST_WARNING_OBJECT (demux,
718               "Unknown audio stream format in language code event: %d",
719               stream_format);
720           temp = NULL;
721           continue;
722       }
723
724       demux->audio_stream_map[i] = stream_id;
725
726       g_snprintf (cur_stream_name, 32, "audio-%d-language", i);
727       lang_code = gst_structure_get_string (structure, cur_stream_name);
728       if (lang_code) {
729         GstTagList *list = temp->pending_tags;
730
731         if (!list)
732           list = gst_tag_list_new_empty ();
733         gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
734             GST_TAG_LANGUAGE_CODE, lang_code, NULL);
735         temp->pending_tags = list;
736       }
737     }
738
739     /* And subtitle streams */
740     for (i = 0; i < MAX_DVD_SUBPICTURE_STREAMS; i++) {
741       gint stream_id;
742
743       g_snprintf (cur_stream_name, 32, "subpicture-%d-format", i);
744       if (!gst_structure_get_int (structure, cur_stream_name, &stream_id))
745         continue;
746
747       g_snprintf (cur_stream_name, 32, "subpicture-%d-stream", i);
748       if (!gst_structure_get_int (structure, cur_stream_name, &stream_id))
749         continue;
750       if (stream_id < 0 || stream_id >= MAX_DVD_SUBPICTURE_STREAMS)
751         continue;
752
753       GST_DEBUG_OBJECT (demux, "Subpicture stream %d ID 0x%02x", i,
754           0x20 + stream_id);
755
756       /* Retrieve the subpicture stream to force pad creation */
757       temp = gst_flups_demux_get_stream (demux, 0x20 + stream_id,
758           ST_PS_DVD_SUBPICTURE);
759
760       g_snprintf (cur_stream_name, 32, "subpicture-%d-language", i);
761       lang_code = gst_structure_get_string (structure, cur_stream_name);
762       if (lang_code) {
763         GstTagList *list = temp->pending_tags;
764
765         if (!list)
766           list = gst_tag_list_new_empty ();
767         gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
768             GST_TAG_LANGUAGE_CODE, lang_code, NULL);
769         temp->pending_tags = list;
770       }
771     }
772
773     demux->disable_stream_creation = TRUE;
774
775     GST_DEBUG_OBJECT (demux, "Created all pads from Language Codes event, "
776         "signalling no-more-pads");
777
778     gst_element_no_more_pads (GST_ELEMENT (demux));
779     demux->need_no_more_pads = FALSE;
780     gst_event_unref (event);
781   } else if (strcmp (type, "dvd-set-subpicture-track") == 0) {
782     gint stream_id;
783     gboolean forced_only;
784
785     gst_structure_get_boolean (structure, "forced-only", &forced_only);
786
787     if (gst_structure_get_int (structure, "physical-id", &stream_id)) {
788       temp = demux->streams[(0x20 + stream_id) % GST_FLUPS_DEMUX_MAX_STREAMS];
789       if (temp != NULL && temp->pad != NULL) {
790         /* Send event to the selector to activate the desired pad */
791         GstStructure *s = gst_structure_new ("application/x-gst-dvd",
792             "event", G_TYPE_STRING, "select-pad", NULL);
793         GstEvent *sel_event =
794             gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s);
795
796         temp->notlinked = FALSE;
797         gst_pad_push_event (temp->pad, sel_event);
798
799         gst_event_ref (event);
800         ret = gst_pad_push_event (temp->pad, event);
801         GST_INFO_OBJECT (demux,
802             "Subpicture physical ID change to %d, forced %d", stream_id,
803             forced_only);
804       }
805     }
806     gst_event_unref (event);
807   } else if (strcmp (type, "dvd-set-audio-track") == 0) {
808     gint stream_id;
809
810     if (gst_structure_get_int (structure, "physical-id", &stream_id)) {
811       stream_id = demux->audio_stream_map[stream_id % MAX_DVD_AUDIO_STREAMS];
812       temp = demux->streams[stream_id];
813
814       GST_INFO_OBJECT (demux, "Have DVD audio stream select event: "
815           "stream 0x%02x", stream_id);
816       if (temp != NULL && temp->pad != NULL) {
817         /* Send event to the selector to activate the desired pad */
818         GstStructure *s = gst_structure_new ("application/x-gst-dvd",
819             "event", G_TYPE_STRING, "select-pad", NULL);
820         GstEvent *sel_event =
821             gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s);
822         gst_pad_push_event (temp->pad, sel_event);
823
824         gst_event_ref (event);
825         ret = gst_pad_push_event (temp->pad, event);
826       }
827     }
828     gst_event_unref (event);
829   } else {
830     /* forward to all pads, e.g. dvd clut event */
831     ret = gst_flups_demux_send_event (demux, event);
832   }
833   return ret;
834 }
835
836 static void
837 gst_flups_demux_flush (GstFluPSDemux * demux)
838 {
839   GST_DEBUG_OBJECT (demux, "flushing demuxer");
840   gst_adapter_clear (demux->adapter);
841   gst_adapter_clear (demux->rev_adapter);
842   gst_pes_filter_drain (&demux->filter);
843   gst_flups_demux_clear_times (demux);
844   demux->adapter_offset = G_MAXUINT64;
845   demux->current_scr = G_MAXUINT64;
846   demux->bytes_since_scr = 0;
847   demux->scr_adjust = GSTTIME_TO_MPEGTIME (SCR_MUNGE);
848   demux->in_still = FALSE;
849 }
850
851 static inline void
852 gst_flups_demux_clear_times (GstFluPSDemux * demux)
853 {
854   gint i, count = demux->found_count;
855
856   /* Clear the last ts for all streams */
857   for (i = 0; i < count; i++) {
858     GstFluPSStream *stream = demux->streams_found[i];
859
860     if (G_LIKELY (stream)) {
861       stream->last_ts = GST_CLOCK_TIME_NONE;
862       stream->last_flow = GST_FLOW_OK;
863     }
864   }
865 }
866
867 static inline void
868 gst_flups_demux_send_gap_updates (GstFluPSDemux * demux, GstClockTime new_time,
869     gboolean no_threshold)
870 {
871   gint i, count = demux->found_count;
872   GstEvent *event = NULL;
873
874   /* Advance all lagging streams by sending a segment update */
875   if (new_time > demux->src_segment.stop)
876     return;
877
878   /* FIXME: Handle reverse playback */
879   for (i = 0; i < count; i++) {
880     GstFluPSStream *stream = demux->streams_found[i];
881
882     if (stream) {
883       GstClockTime gap_threshold = no_threshold ? 0 : stream->segment_thresh;
884
885       if (stream->last_ts == GST_CLOCK_TIME_NONE ||
886           stream->last_ts < demux->src_segment.start)
887         stream->last_ts = demux->src_segment.start;
888       if (stream->last_ts + gap_threshold < new_time) {
889         GST_LOG_OBJECT (demux,
890             "Sending gap update to pad %s time %" GST_TIME_FORMAT " to %"
891             GST_TIME_FORMAT, GST_PAD_NAME (stream->pad),
892             GST_TIME_ARGS (stream->last_ts), GST_TIME_ARGS (new_time));
893         event = gst_event_new_gap (stream->last_ts, new_time - stream->last_ts);
894         gst_pad_push_event (stream->pad, event);
895         stream->last_ts = new_time;
896       }
897     }
898   }
899 }
900
901 static gboolean
902 gst_flups_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
903 {
904   gboolean res = TRUE;
905   GstFluPSDemux *demux = GST_FLUPS_DEMUX (parent);
906
907   switch (GST_EVENT_TYPE (event)) {
908     case GST_EVENT_STREAM_START:
909       gst_event_unref (event);
910       break;
911     case GST_EVENT_FLUSH_START:
912       gst_flups_demux_send_event (demux, event);
913       break;
914     case GST_EVENT_FLUSH_STOP:
915       gst_flups_demux_send_event (demux, event);
916       gst_segment_init (&demux->sink_segment, GST_FORMAT_UNDEFINED);
917       gst_flups_demux_flush (demux);
918       break;
919     case GST_EVENT_SEGMENT:
920     {
921       const GstSegment *segment;
922
923       gint64 start, stop, time;
924       gint64 base, dur, position;
925       GstClockTimeDiff adjust;
926
927       gst_event_parse_segment (event, &segment);
928
929       if (segment->format != GST_FORMAT_TIME)
930         return FALSE;
931
932       gst_segment_copy_into (segment, &demux->sink_segment);
933
934       dur = segment->stop - segment->start;
935
936       base = demux->sink_segment.base;
937       start = demux->sink_segment.start;
938       stop = demux->sink_segment.stop;
939       time = demux->sink_segment.time;
940
941       demux->first_scr = GSTTIME_TO_MPEGTIME (start);
942       demux->current_scr = demux->first_scr + demux->scr_adjust;
943       demux->base_time = time;
944       demux->bytes_since_scr = 0;
945
946       GST_DEBUG_OBJECT (demux,
947           "demux: received new segment %" GST_SEGMENT_FORMAT,
948           &demux->sink_segment);
949 #if 0
950       g_print ("demux: received new segment start %" G_GINT64_FORMAT " stop %"
951           G_GINT64_FORMAT " time %" G_GINT64_FORMAT
952           " base %" G_GINT64_FORMAT "\n", start, stop, time, base);
953 #endif
954       adjust = base - start + SCR_MUNGE;
955       if (adjust >= 0)
956         demux->scr_adjust = GSTTIME_TO_MPEGTIME (adjust);
957       else
958         demux->scr_adjust = -GSTTIME_TO_MPEGTIME (-adjust);
959
960       position = start = SCR_MUNGE;
961       base = 0;
962
963       if (stop != -1)
964         stop = start + dur;
965
966       demux->src_segment.rate = segment->rate;
967       demux->src_segment.applied_rate = segment->applied_rate;
968       demux->src_segment.format = segment->format;
969       demux->src_segment.start = start;
970       demux->src_segment.stop = stop;
971       demux->src_segment.time = time;
972       demux->src_segment.base = base;
973       demux->src_segment.position = position;
974
975       GST_DEBUG_OBJECT (demux,
976           "sending new segment %" GST_SEGMENT_FORMAT
977           ", scr_adjust: %" G_GINT64_FORMAT "(%" GST_TIME_FORMAT ")",
978           &demux->src_segment, demux->scr_adjust,
979           GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->scr_adjust)));
980 #if 0
981       g_print ("sending new segment: rate %g format %d, start: %"
982           G_GINT64_FORMAT ", stop: %" G_GINT64_FORMAT ", time: %"
983           G_GINT64_FORMAT ", base: %" G_GINT64_FORMAT
984           ", scr_adjust: %" G_GINT64_FORMAT "(%" GST_TIME_FORMAT ")\n",
985           segment->rate, segment->format, start, stop, time, base,
986           demux->scr_adjust,
987           GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (demux->scr_adjust)));
988 #endif
989
990       gst_event_unref (event);
991       event = gst_event_new_segment (&demux->src_segment);
992       gst_flups_demux_send_event (demux, event);
993
994       if (demux->in_still && stop != -1) {
995         /* Generate gap buffers, due to closing segment from a still-frame.
996          * Do this in the new segment with stop time. */
997         GST_DEBUG_OBJECT (demux, "Advancing all streams to stop time %"
998             GST_TIME_FORMAT, GST_TIME_ARGS (stop));
999         gst_flups_demux_send_gap_updates (demux, stop, TRUE);
1000       }
1001
1002       break;
1003     }
1004     case GST_EVENT_EOS:
1005       GST_INFO_OBJECT (demux, "Received EOS");
1006       if (!gst_flups_demux_send_event (demux, event)) {
1007         GST_WARNING_OBJECT (demux, "failed pushing EOS on streams");
1008         GST_ELEMENT_ERROR (demux, STREAM, FAILED,
1009             ("Internal data stream error."), ("Can't push EOS downstream"));
1010       }
1011       break;
1012     case GST_EVENT_CUSTOM_DOWNSTREAM:
1013     case GST_EVENT_CUSTOM_DOWNSTREAM_OOB:
1014     {
1015       const GstStructure *structure = gst_event_get_structure (event);
1016       gboolean in_still;
1017
1018       if (gst_video_event_parse_still_frame (event, &in_still)) {
1019         /* Remember the still-frame state, so we can generate a pre-roll
1020          * GAP event when a segment event arrives */
1021         demux->in_still = in_still;
1022         GST_INFO_OBJECT (demux, "still-state now %d", demux->in_still);
1023         gst_flups_demux_send_event (demux, event);
1024       } else if (structure != NULL
1025           && gst_structure_has_name (structure, "application/x-gst-dvd")) {
1026         res = gst_flups_demux_handle_dvd_event (demux, event);
1027       } else {
1028         gst_flups_demux_send_event (demux, event);
1029       }
1030       break;
1031     }
1032     case GST_EVENT_CAPS:
1033       gst_event_unref (event);
1034       break;
1035     default:
1036       gst_flups_demux_send_event (demux, event);
1037       break;
1038   }
1039
1040   return res;
1041 }
1042
1043 static gboolean
1044 gst_flups_demux_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
1045 {
1046   gboolean res = FALSE;
1047   GstFluPSDemux *demux = GST_FLUPS_DEMUX (parent);
1048
1049   switch (GST_EVENT_TYPE (event)) {
1050     case GST_EVENT_SEEK:
1051     {
1052       gdouble rate;
1053       GstFormat format;
1054       GstSeekFlags flags;
1055       GstSeekType start_type, stop_type;
1056       gint64 start, stop;
1057       gint64 bstart, bstop;
1058       GstEvent *bevent;
1059
1060       gst_event_parse_seek (event, &rate, &format, &flags, &start_type, &start,
1061           &stop_type, &stop);
1062
1063       GST_DEBUG_OBJECT (demux, "seek event, rate: %f start: %" GST_TIME_FORMAT
1064           " stop: %" GST_TIME_FORMAT, rate, GST_TIME_ARGS (start),
1065           GST_TIME_ARGS (stop));
1066
1067       if (format == GST_FORMAT_BYTES) {
1068         GST_DEBUG_OBJECT (demux, "seek not supported on format %d", format);
1069         goto not_supported;
1070       }
1071
1072       GST_DEBUG_OBJECT (demux, "seek - trying directly upstream first");
1073
1074       /* first try original format seek */
1075       (void) gst_event_ref (event);
1076       if ((res = gst_pad_push_event (demux->sinkpad, event)))
1077         goto done;
1078
1079       if (format != GST_FORMAT_TIME) {
1080         /* From here down, we only support time based seeks */
1081         GST_DEBUG_OBJECT (demux, "seek not supported on format %d", format);
1082         goto not_supported;
1083       }
1084
1085       /* We need to convert to byte based seek and we need a scr_rate for that. */
1086       if (demux->scr_rate_n == G_MAXUINT64 || demux->scr_rate_d == G_MAXUINT64) {
1087         GST_DEBUG_OBJECT (demux, "seek not possible, no scr_rate");
1088         goto not_supported;
1089       }
1090
1091       GST_DEBUG_OBJECT (demux, "try with scr_rate interpolation");
1092
1093       bstart = GSTTIME_TO_BYTES (start);
1094       bstop = GSTTIME_TO_BYTES (stop);
1095
1096       GST_DEBUG_OBJECT (demux, "in bytes bstart %" G_GINT64_FORMAT " bstop %"
1097           G_GINT64_FORMAT, bstart, bstop);
1098       bevent = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, start_type,
1099           bstart, stop_type, bstop);
1100
1101       res = gst_pad_push_event (demux->sinkpad, bevent);
1102
1103     done:
1104       gst_event_unref (event);
1105       break;
1106     }
1107     default:
1108       res = gst_pad_push_event (demux->sinkpad, event);
1109       break;
1110   }
1111
1112   return res;
1113
1114 not_supported:
1115   {
1116     gst_event_unref (event);
1117
1118     return FALSE;
1119   }
1120 }
1121
1122 static gboolean
1123 gst_flups_demux_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
1124 {
1125   gboolean res = FALSE;
1126   GstFluPSDemux *demux = GST_FLUPS_DEMUX (parent);
1127
1128   GST_LOG_OBJECT (demux, "Have query of type %d on pad %" GST_PTR_FORMAT,
1129       GST_QUERY_TYPE (query), pad);
1130
1131   switch (GST_QUERY_TYPE (query)) {
1132     case GST_QUERY_POSITION:
1133     {
1134       GstClockTime pos;
1135       GstFormat format;
1136
1137       /* See if upstream can immediately answer */
1138       res = gst_pad_peer_query (demux->sinkpad, query);
1139       if (res)
1140         break;
1141
1142       gst_query_parse_position (query, &format, NULL);
1143
1144       if (format != GST_FORMAT_TIME) {
1145         GST_DEBUG_OBJECT (demux, "position not supported for format: %s",
1146             gst_format_get_name (format));
1147         goto not_supported;
1148       }
1149
1150       pos = demux->base_time;
1151       if (demux->current_scr != G_MAXUINT64 && demux->first_scr != G_MAXUINT64) {
1152         pos +=
1153             MPEGTIME_TO_GSTTIME (demux->current_scr - demux->scr_adjust -
1154             demux->first_scr);
1155       }
1156
1157       GST_LOG_OBJECT (demux, "Position at GStreamer Time:%" GST_TIME_FORMAT,
1158           GST_TIME_ARGS (pos));
1159
1160       gst_query_set_position (query, format, pos);
1161       res = TRUE;
1162       break;
1163     }
1164     case GST_QUERY_DURATION:
1165     {
1166       GstFormat format;
1167       gint64 duration;
1168       GstQuery *byte_query;
1169
1170       gst_query_parse_duration (query, &format, NULL);
1171
1172       if (G_LIKELY (format == GST_FORMAT_TIME &&
1173               GST_CLOCK_TIME_IS_VALID (demux->src_segment.duration))) {
1174         gst_query_set_duration (query, GST_FORMAT_TIME,
1175             demux->src_segment.duration);
1176         res = TRUE;
1177         break;
1178       }
1179
1180       /* For any format other than bytes, see if upstream knows first */
1181       if (format == GST_FORMAT_BYTES) {
1182         GST_DEBUG_OBJECT (demux, "duration not supported for format: %s",
1183             gst_format_get_name (format));
1184         goto not_supported;
1185       }
1186
1187       if (gst_pad_peer_query (demux->sinkpad, query)) {
1188         res = TRUE;
1189         break;
1190       }
1191
1192       /* Upstream didn't know, so we can only answer TIME queries from
1193        * here on */
1194       if (format != GST_FORMAT_TIME) {
1195         GST_DEBUG_OBJECT (demux, "duration not supported for format: %s",
1196             gst_format_get_name (format));
1197         goto not_supported;
1198       }
1199
1200       if (demux->mux_rate == -1) {
1201         GST_DEBUG_OBJECT (demux, "duration not possible, no mux_rate");
1202         goto not_supported;
1203       }
1204
1205       byte_query = gst_query_new_duration (GST_FORMAT_BYTES);
1206
1207       if (!gst_pad_peer_query (demux->sinkpad, byte_query)) {
1208         GST_LOG_OBJECT (demux, "query on peer pad failed");
1209         gst_query_unref (byte_query);
1210         goto not_supported;
1211       }
1212
1213       gst_query_parse_duration (byte_query, &format, &duration);
1214       gst_query_unref (byte_query);
1215
1216       GST_LOG_OBJECT (demux,
1217           "query on peer pad reported bytes %" G_GUINT64_FORMAT, duration);
1218
1219       duration = BYTES_TO_GSTTIME ((guint64) duration);
1220
1221       GST_LOG_OBJECT (demux, "converted to time %" GST_TIME_FORMAT,
1222           GST_TIME_ARGS (duration));
1223
1224       gst_query_set_duration (query, GST_FORMAT_TIME, duration);
1225       res = TRUE;
1226       break;
1227     }
1228     case GST_QUERY_SEEKING:{
1229       /* Just ask upstream */
1230       res = gst_pad_peer_query (demux->sinkpad, query);
1231       break;
1232     }
1233     default:
1234       res = gst_pad_query_default (pad, parent, query);
1235       break;
1236   }
1237
1238   return res;
1239 not_supported:
1240   return FALSE;
1241 }
1242
1243 static void
1244 gst_flups_demux_reset_psm (GstFluPSDemux * demux)
1245 {
1246   gint i;
1247
1248 #define FILL_TYPE(start, stop, type)    \
1249   for (i=start; i <= stop; i++)                 \
1250     demux->psm[i] = type;
1251
1252   FILL_TYPE (0x00, 0x1f, -1);
1253   FILL_TYPE (0x20, 0x3f, ST_PS_DVD_SUBPICTURE);
1254   FILL_TYPE (0x40, 0x7f, -1);
1255   FILL_TYPE (0x80, 0x87, ST_PS_AUDIO_AC3);
1256   FILL_TYPE (0x88, 0x9f, ST_PS_AUDIO_DTS);
1257   FILL_TYPE (0xa0, 0xaf, ST_PS_AUDIO_LPCM);
1258   FILL_TYPE (0xbd, 0xbd, -1);
1259   FILL_TYPE (0xc0, 0xdf, ST_AUDIO_MPEG1);
1260   FILL_TYPE (0xe0, 0xef, ST_GST_VIDEO_MPEG1_OR_2);
1261   FILL_TYPE (0xf0, 0xff, -1);
1262
1263 #undef FILL_TYPE
1264 }
1265
1266 /* ISO/IEC 13818-1:
1267  * pack_header() {
1268  *     pack_start_code                                   32  bslbf  -+
1269  *     '01'                                               2  bslbf   |
1270  *     system_clock_reference_base [32..30]               3  bslbf   |
1271  *     marker_bit                                         1  bslbf   |
1272  *     system_clock_reference_base [29..15]              15  bslbf   |
1273  *     marker_bit                                         1  bslbf   |
1274  *     system_clock_reference_base [14..0]               15  bslbf   |
1275  *     marker_bit                                         1  bslbf   | 112 bits
1276  *     system_clock_reference_extension                   9  ubslbf  |
1277  *     marker_bit                                         1  bslbf   |
1278  *     program_mux_rate                                  22  ubslbf  |
1279  *     marker_bit                                         1  bslbf   |
1280  *     marker_bit                                         1  bslbf   |
1281  *     reserved                                           5  bslbf   |
1282  *     pack_stuffing_length                               3  ubslbf -+
1283  *
1284  *     for (i = 0; i < pack_stuffing_length; i++) {
1285  *         stuffing_byte '1111 1111'                      8  bslbf
1286  *     }
1287  *
1288  * 112 bits = 14 bytes, as max value for pack_stuffing_length is 7, then
1289  * in total it's needed 14 + 7 = 21 bytes.
1290  */
1291 #define PACK_START_SIZE     21
1292
1293 static GstFlowReturn
1294 gst_flups_demux_parse_pack_start (GstFluPSDemux * demux)
1295 {
1296   const guint8 *data;
1297   guint length;
1298   guint32 scr1, scr2;
1299   guint64 scr, scr_adjusted, new_rate;
1300   guint64 scr_rate_n;
1301   guint64 scr_rate_d;
1302   GstClockTime new_time;
1303   guint avail = gst_adapter_available (demux->adapter);
1304
1305   GST_LOG ("parsing pack start");
1306
1307   if (G_UNLIKELY (avail < PACK_START_SIZE))
1308     goto need_more_data;
1309
1310   data = gst_adapter_map (demux->adapter, PACK_START_SIZE);
1311
1312   /* skip start code */
1313   data += 4;
1314
1315   scr1 = GST_READ_UINT32_BE (data);
1316   scr2 = GST_READ_UINT32_BE (data + 4);
1317
1318   /* fixed length to begin with, start code and two scr values */
1319   length = 8 + 4;
1320
1321   /* start parsing the stream */
1322   if ((*data & 0xc0) == 0x40) {
1323     guint32 scr_ext;
1324     guint32 next32;
1325     guint8 stuffing_bytes;
1326
1327     GST_LOG ("Found MPEG2 stream");
1328     demux->is_mpeg2_pack = TRUE;
1329
1330     /* mpeg2 has more data */
1331     length += 2;
1332
1333     /* :2=01 ! scr:3 ! marker:1==1 ! scr:15 ! marker:1==1 ! scr:15 */
1334
1335     /* check markers */
1336     if (G_UNLIKELY ((scr1 & 0xc4000400) != 0x44000400))
1337       goto lost_sync;
1338
1339     scr = ((guint64) scr1 & 0x38000000) << 3;
1340     scr |= ((guint64) scr1 & 0x03fff800) << 4;
1341     scr |= ((guint64) scr1 & 0x000003ff) << 5;
1342     scr |= ((guint64) scr2 & 0xf8000000) >> 27;
1343
1344     /* marker:1==1 ! scr_ext:9 ! marker:1==1 */
1345     if (G_UNLIKELY ((scr2 & 0x04010000) != 0x04010000))
1346       goto lost_sync;
1347
1348     scr_ext = (scr2 & 0x03fe0000) >> 17;
1349     /* We keep the offset of this scr */
1350     demux->cur_scr_offset = demux->adapter_offset + 12;
1351
1352     GST_LOG_OBJECT (demux, "SCR: 0x%08" G_GINT64_MODIFIER "x SCRE: 0x%08x",
1353         scr, scr_ext);
1354
1355     if (scr_ext) {
1356       scr = (scr * 300 + scr_ext % 300) / 300;
1357     }
1358     /* SCR has been converted into units of 90Khz ticks to make it comparable
1359        to DTS/PTS, that also implies 1 tick rounding error */
1360     data += 6;
1361     /* PMR:22 ! :2==11 ! reserved:5 ! stuffing_len:3 */
1362     next32 = GST_READ_UINT32_BE (data);
1363     if (G_UNLIKELY ((next32 & 0x00000300) != 0x00000300))
1364       goto lost_sync;
1365
1366     new_rate = (next32 & 0xfffffc00) >> 10;
1367
1368     stuffing_bytes = (next32 & 0x07);
1369     GST_LOG_OBJECT (demux, "stuffing bytes: %d", stuffing_bytes);
1370
1371     data += 4;
1372     length += stuffing_bytes;
1373     while (stuffing_bytes--) {
1374       if (*data++ != 0xff)
1375         goto lost_sync;
1376     }
1377   } else {
1378     GST_DEBUG ("Found MPEG1 stream");
1379     demux->is_mpeg2_pack = FALSE;
1380
1381     /* check markers */
1382     if (G_UNLIKELY ((scr1 & 0xf1000100) != 0x21000100))
1383       goto lost_sync;
1384
1385     if (G_UNLIKELY ((scr2 & 0x01800001) != 0x01800001))
1386       goto lost_sync;
1387
1388     /* :4=0010 ! scr:3 ! marker:1==1 ! scr:15 ! marker:1==1 ! scr:15 ! marker:1==1 */
1389     scr = ((guint64) scr1 & 0x0e000000) << 5;
1390     scr |= ((guint64) scr1 & 0x00fffe00) << 6;
1391     scr |= ((guint64) scr1 & 0x000000ff) << 7;
1392     scr |= ((guint64) scr2 & 0xfe000000) >> 25;
1393
1394     /* We keep the offset of this scr */
1395     demux->cur_scr_offset = demux->adapter_offset + 8;
1396
1397     /* marker:1==1 ! mux_rate:22 ! marker:1==1 */
1398     new_rate = (scr2 & 0x007ffffe) >> 1;
1399   }
1400   new_rate *= MPEG_MUX_RATE_MULT;
1401
1402   /* scr adjusted is the new scr found + the colected adjustment */
1403   scr_adjusted = scr + demux->scr_adjust;
1404
1405   GST_LOG_OBJECT (demux,
1406       "SCR: %" G_GINT64_FORMAT " (%" G_GINT64_FORMAT "), mux_rate %"
1407       G_GINT64_FORMAT ", GStreamer Time:%" GST_TIME_FORMAT,
1408       scr, scr_adjusted, new_rate,
1409       GST_TIME_ARGS (MPEGTIME_TO_GSTTIME ((guint64) scr)));
1410
1411   /* keep the first src in order to calculate delta time */
1412   if (G_UNLIKELY (demux->first_scr == G_MAXUINT64)) {
1413     demux->first_scr = scr;
1414     demux->first_scr_offset = demux->cur_scr_offset;
1415
1416     if (demux->sink_segment.format == GST_FORMAT_TIME) {
1417       demux->base_time = demux->sink_segment.time;
1418     } else {
1419       demux->base_time = MPEGTIME_TO_GSTTIME (demux->first_scr);
1420     }
1421     /* at begin consider the new_rate as the scr rate, bytes/clock ticks */
1422     scr_rate_n = new_rate;
1423     scr_rate_d = CLOCK_FREQ;
1424   } else if (G_LIKELY (demux->first_scr_offset != demux->cur_scr_offset)) {
1425     /* estimate byte rate related to the SCR */
1426     scr_rate_n = demux->cur_scr_offset - demux->first_scr_offset;
1427     scr_rate_d = scr_adjusted - demux->first_scr;
1428   } else {
1429     scr_rate_n = demux->scr_rate_n;
1430     scr_rate_d = demux->scr_rate_d;
1431   }
1432
1433   GST_DEBUG_OBJECT (demux,
1434       "SCR: %" G_GINT64_FORMAT " (%" G_GINT64_FORMAT "), mux_rate %"
1435       G_GINT64_FORMAT ", GStreamer Time:%" GST_TIME_FORMAT,
1436       scr, scr_adjusted, new_rate,
1437       GST_TIME_ARGS (MPEGTIME_TO_GSTTIME ((guint64) scr - demux->first_scr)));
1438
1439   GST_DEBUG_OBJECT (demux, "%s mode scr: %" G_GUINT64_FORMAT " at %"
1440       G_GUINT64_FORMAT ", first scr: %" G_GUINT64_FORMAT
1441       " at %" G_GUINT64_FORMAT ", scr rate: %" G_GUINT64_FORMAT
1442       "/%" G_GUINT64_FORMAT "(%f)",
1443       ((demux->sink_segment.rate >= 0.0) ? "forward" : "backward"),
1444       scr, demux->cur_scr_offset,
1445       demux->first_scr, demux->first_scr_offset,
1446       scr_rate_n, scr_rate_d, (float) scr_rate_n / scr_rate_d);
1447
1448   /* adjustment of the SCR */
1449   if (G_LIKELY (demux->current_scr != G_MAXUINT64)) {
1450     gint64 diff;
1451     guint64 old_scr, old_mux_rate, bss, adjust = 0;
1452
1453     /* keep SCR of the previous packet */
1454     old_scr = demux->current_scr;
1455     old_mux_rate = demux->mux_rate;
1456
1457     /* Bytes since SCR is the amount we placed in the adapter since then
1458      * (demux->bytes_since_scr) minus the amount remaining in the adapter,
1459      * clamped to >= 0 */
1460     bss = MAX (0, (gint) (demux->bytes_since_scr - avail));
1461
1462     /* estimate the new SCR using the previous one according the notes
1463        on point 2.5.2.2 of the ISO/IEC 13818-1 document */
1464     if (old_mux_rate != 0)
1465       adjust = (bss * CLOCK_FREQ) / old_mux_rate;
1466
1467     if (demux->sink_segment.rate >= 0.0)
1468       demux->next_scr = old_scr + adjust;
1469     else
1470       demux->next_scr = old_scr - adjust;
1471
1472     GST_LOG_OBJECT (demux,
1473         "bss: %" G_GUINT64_FORMAT ", next_scr: %" G_GUINT64_FORMAT
1474         ", old_scr: %" G_GUINT64_FORMAT ", scr: %" G_GUINT64_FORMAT,
1475         bss, demux->next_scr, old_scr, scr_adjusted);
1476
1477     /* calculate the absolute deference between the last scr and
1478        the new one */
1479     if (G_UNLIKELY (old_scr > scr_adjusted))
1480       diff = old_scr - scr_adjusted;
1481     else
1482       diff = scr_adjusted - old_scr;
1483
1484     /* if the difference is more than 1 second we need to reconfigure
1485        adjustment */
1486     if (G_UNLIKELY (diff > CLOCK_FREQ)) {
1487 #if 0
1488       demux->scr_adjust = demux->next_scr - scr;
1489       GST_DEBUG_OBJECT (demux, "discont found, diff: %" G_GINT64_FORMAT
1490           ", adjust %" G_GINT64_FORMAT, diff, demux->scr_adjust);
1491       scr_adjusted = demux->next_scr;
1492 #else
1493       GST_WARNING_OBJECT (demux, "Unexpected SCR diff of %" G_GINT64_FORMAT,
1494           diff);
1495 #endif
1496     } else {
1497       demux->next_scr = scr_adjusted;
1498     }
1499   }
1500
1501   /* update the current_scr and rate members */
1502   demux->mux_rate = new_rate;
1503   demux->current_scr = scr_adjusted;
1504   demux->scr_rate_n = scr_rate_n;
1505   demux->scr_rate_d = scr_rate_d;
1506
1507   new_time = MPEGTIME_TO_GSTTIME (scr_adjusted);
1508   if (new_time != GST_CLOCK_TIME_NONE) {
1509     // g_print ("SCR now %" GST_TIME_FORMAT "\n", GST_TIME_ARGS (new_time));
1510     gst_segment_set_position (&demux->src_segment, GST_FORMAT_TIME, new_time);
1511     gst_flups_demux_send_gap_updates (demux, new_time, FALSE);
1512   }
1513
1514   /* Reset the bytes_since_scr value to count the data remaining in the
1515    * adapter */
1516   demux->bytes_since_scr = avail;
1517
1518   gst_adapter_unmap (demux->adapter);
1519   gst_adapter_flush (demux->adapter, length);
1520   ADAPTER_OFFSET_FLUSH (length);
1521   return GST_FLOW_OK;
1522
1523 lost_sync:
1524   {
1525     GST_DEBUG_OBJECT (demux, "lost sync");
1526     gst_adapter_unmap (demux->adapter);
1527     return GST_FLOW_LOST_SYNC;
1528   }
1529 need_more_data:
1530   {
1531     GST_DEBUG_OBJECT (demux, "need more data");
1532     return GST_FLOW_NEED_MORE_DATA;
1533   }
1534 }
1535
1536 /* ISO/IEC 13818-1:
1537  * system_header () {
1538  *     system_header_start_code                          32  bslbf  -+
1539  *     header_length                                     16  uimsbf  |
1540  *     marker_bit                                         1  bslbf   |
1541  *     rate_bound                                        22  uimsbf  |
1542  *     marker_bit                                         1  bslbf   |
1543  *     audio_bound                                        6  uimsbf  |
1544  *     fixed_flag                                         1  bslbf   |
1545  *     CSPS_flag                                          1  bslbf   | 96 bits
1546  *     system_audio_lock_flag                             1  bslbf   |
1547  *     system_video_lock_flag                             1  bslbf   |
1548  *     marker_bit                                         1  bslbf   |
1549  *     video_bound                                        5  uimsbf  |
1550  *     packet_rate_restriction_flag                       1  bslbf   |
1551  *     reserved_bits                                      7  bslbf  -+
1552  *     while (nextbits () = = '1') {
1553  *         stream_id                                      8  uimsbf -+
1554  *         '11'                                           2  bslbf   | 24 bits
1555  *         P-STD_buffer_bound_scale                       1  bslbf   |
1556  *         P-STD_buffer_size_bound                       13  uimsbf -+
1557  *     }
1558  * }
1559  * 96 bits = 12 bytes, 24 bits = 3 bytes.
1560  */
1561
1562 static GstFlowReturn
1563 gst_flups_demux_parse_sys_head (GstFluPSDemux * demux)
1564 {
1565   guint16 length;
1566   const guint8 *data;
1567 #ifndef GST_DISABLE_GST_DEBUG
1568   gboolean csps;
1569 #endif
1570
1571   if (gst_adapter_available (demux->adapter) < 6)
1572     goto need_more_data;
1573
1574   /* start code + length */
1575   data = gst_adapter_map (demux->adapter, 6);
1576
1577   /* skip start code */
1578   data += 4;
1579
1580   length = GST_READ_UINT16_BE (data);
1581   GST_DEBUG_OBJECT (demux, "length %d", length);
1582
1583   length += 6;
1584
1585   gst_adapter_unmap (demux->adapter);
1586   if (gst_adapter_available (demux->adapter) < length)
1587     goto need_more_data;
1588
1589   data = gst_adapter_map (demux->adapter, length);
1590
1591   /* skip start code and length */
1592   data += 6;
1593
1594   /* marker:1==1 ! rate_bound:22 | marker:1==1 */
1595   if ((*data & 0x80) != 0x80)
1596     goto marker_expected;
1597
1598   {
1599     guint32 rate_bound;
1600
1601     if ((data[2] & 0x01) != 0x01)
1602       goto marker_expected;
1603
1604     rate_bound = ((guint32) data[0] & 0x7f) << 15;
1605     rate_bound |= ((guint32) data[1]) << 7;
1606     rate_bound |= ((guint32) data[2] & 0xfe) >> 1;
1607     rate_bound *= MPEG_MUX_RATE_MULT;
1608
1609     GST_DEBUG_OBJECT (demux, "rate bound %u", rate_bound);
1610
1611     data += 3;
1612   }
1613
1614   /* audio_bound:6==1 ! fixed:1 | constrained:1 */
1615   {
1616 #ifndef GST_DISABLE_GST_DEBUG
1617     guint8 audio_bound;
1618     gboolean fixed;
1619
1620     /* max number of simultaneous audio streams active */
1621     audio_bound = (data[0] & 0xfc) >> 2;
1622     /* fixed or variable bitrate */
1623     fixed = (data[0] & 0x02) == 0x02;
1624     /* meeting constraints */
1625     csps = (data[0] & 0x01) == 0x01;
1626
1627     GST_DEBUG_OBJECT (demux, "audio_bound %d, fixed %d, constrained %d",
1628         audio_bound, fixed, csps);
1629 #endif
1630     data += 1;
1631   }
1632
1633   /* audio_lock:1 | video_lock:1 | marker:1==1 | video_bound:5 */
1634   {
1635 #ifndef GST_DISABLE_GST_DEBUG
1636     gboolean audio_lock;
1637     gboolean video_lock;
1638     guint8 video_bound;
1639
1640     audio_lock = (data[0] & 0x80) == 0x80;
1641     video_lock = (data[0] & 0x40) == 0x40;
1642 #endif
1643
1644     if ((data[0] & 0x20) != 0x20)
1645       goto marker_expected;
1646
1647 #ifndef GST_DISABLE_GST_DEBUG
1648     /* max number of simultaneous video streams active */
1649     video_bound = (data[0] & 0x1f);
1650
1651     GST_DEBUG_OBJECT (demux, "audio_lock %d, video_lock %d, video_bound %d",
1652         audio_lock, video_lock, video_bound);
1653 #endif
1654     data += 1;
1655   }
1656
1657   /* packet_rate_restriction:1 | reserved:7==0x7F */
1658   {
1659 #ifndef GST_DISABLE_GST_DEBUG
1660     gboolean packet_rate_restriction;
1661 #endif
1662     if ((data[0] & 0x7f) != 0x7f)
1663       goto marker_expected;
1664 #ifndef GST_DISABLE_GST_DEBUG
1665     /* only valid if csps is set */
1666     if (csps) {
1667       packet_rate_restriction = (data[0] & 0x80) == 0x80;
1668
1669       GST_DEBUG_OBJECT (demux, "packet_rate_restriction %d",
1670           packet_rate_restriction);
1671     }
1672 #endif
1673   }
1674   data += 1;
1675
1676   {
1677     gint stream_count = (length - 12) / 3;
1678     gint i;
1679
1680     GST_DEBUG_OBJECT (demux, "number of streams: %d ", stream_count);
1681
1682     for (i = 0; i < stream_count; i++) {
1683       guint8 stream_id;
1684 #ifndef GST_DISABLE_GST_DEBUG
1685       gboolean STD_buffer_bound_scale;
1686       guint16 STD_buffer_size_bound;
1687       guint32 buf_byte_size_bound;
1688 #endif
1689       stream_id = *data++;
1690       if (!(stream_id & 0x80))
1691         goto sys_len_error;
1692
1693       /* check marker bits */
1694       if ((*data & 0xC0) != 0xC0)
1695         goto no_placeholder_bits;
1696 #ifndef GST_DISABLE_GST_DEBUG
1697       STD_buffer_bound_scale = *data & 0x20;
1698       STD_buffer_size_bound = ((guint16) (*data++ & 0x1F)) << 8;
1699       STD_buffer_size_bound |= *data++;
1700
1701       if (STD_buffer_bound_scale == 0) {
1702         buf_byte_size_bound = STD_buffer_size_bound * 128;
1703       } else {
1704         buf_byte_size_bound = STD_buffer_size_bound * 1024;
1705       }
1706
1707       GST_DEBUG_OBJECT (demux, "STD_buffer_bound_scale %d",
1708           STD_buffer_bound_scale);
1709       GST_DEBUG_OBJECT (demux, "STD_buffer_size_bound %d or %d bytes",
1710           STD_buffer_size_bound, buf_byte_size_bound);
1711 #endif
1712     }
1713   }
1714
1715   gst_adapter_unmap (demux->adapter);
1716   gst_adapter_flush (demux->adapter, length);
1717   ADAPTER_OFFSET_FLUSH (length);
1718   return GST_FLOW_OK;
1719
1720   /* ERRORS */
1721 marker_expected:
1722   {
1723     GST_DEBUG_OBJECT (demux, "expecting marker");
1724     gst_adapter_unmap (demux->adapter);
1725     return GST_FLOW_LOST_SYNC;
1726   }
1727 no_placeholder_bits:
1728   {
1729     GST_DEBUG_OBJECT (demux, "expecting placeholder bit values"
1730         " '11' after stream id");
1731     gst_adapter_unmap (demux->adapter);
1732     return GST_FLOW_LOST_SYNC;
1733   }
1734 sys_len_error:
1735   {
1736     GST_DEBUG_OBJECT (demux, "error in system header length");
1737     gst_adapter_unmap (demux->adapter);
1738     return GST_FLOW_LOST_SYNC;
1739   }
1740 need_more_data:
1741   {
1742     GST_DEBUG_OBJECT (demux, "need more data");
1743     gst_adapter_unmap (demux->adapter);
1744     return GST_FLOW_NEED_MORE_DATA;
1745   }
1746 }
1747
1748 static GstFlowReturn
1749 gst_flups_demux_parse_psm (GstFluPSDemux * demux)
1750 {
1751   guint16 length = 0, info_length = 0, es_map_length = 0;
1752   guint8 psm_version = 0;
1753   const guint8 *data, *es_map_base;
1754 #ifndef GST_DISABLE_GST_DEBUG
1755   gboolean applicable;
1756 #endif
1757
1758   if (gst_adapter_available (demux->adapter) < 6)
1759     goto need_more_data;
1760
1761   /* start code + length */
1762   data = gst_adapter_map (demux->adapter, 6);
1763
1764   /* skip start code */
1765   data += 4;
1766
1767   length = GST_READ_UINT16_BE (data);
1768   GST_DEBUG_OBJECT (demux, "length %u", length);
1769
1770   if (G_UNLIKELY (length > 0x3FA))
1771     goto psm_len_error;
1772
1773   length += 6;
1774
1775   gst_adapter_unmap (demux->adapter);
1776
1777   if (gst_adapter_available (demux->adapter) < length)
1778     goto need_more_data;
1779
1780   data = gst_adapter_map (demux->adapter, length);
1781
1782   /* skip start code and length */
1783   data += 6;
1784
1785   /* Read PSM applicable bit together with version */
1786   psm_version = GST_READ_UINT8 (data);
1787 #ifndef GST_DISABLE_GST_DEBUG
1788   applicable = (psm_version & 0x80) >> 7;
1789 #endif
1790   psm_version &= 0x1F;
1791   GST_DEBUG_OBJECT (demux, "PSM version %u (applicable now %u)", psm_version,
1792       applicable);
1793
1794   /* Jump over version and marker bit */
1795   data += 2;
1796
1797   /* Read PS info length */
1798   info_length = GST_READ_UINT16_BE (data);
1799   /* Cap it to PSM length - needed bytes for ES map length and CRC */
1800   info_length = MIN (length - 16, info_length);
1801   GST_DEBUG_OBJECT (demux, "PS info length %u bytes", info_length);
1802
1803   /* Jump over that section */
1804   data += (2 + info_length);
1805
1806   /* Read ES map length */
1807   es_map_length = GST_READ_UINT16_BE (data);
1808   /* Cap it to PSM remaining length -  CRC */
1809   es_map_length = MIN (length - (16 + info_length), es_map_length);
1810   GST_DEBUG_OBJECT (demux, "ES map length %u bytes", es_map_length);
1811
1812   /* Jump over the size */
1813   data += 2;
1814
1815   /* Now read the ES map */
1816   es_map_base = data;
1817   while (es_map_base + 4 <= data + es_map_length) {
1818     guint8 stream_type = 0, stream_id = 0;
1819     guint16 stream_info_length = 0;
1820
1821     stream_type = GST_READ_UINT8 (es_map_base);
1822     es_map_base++;
1823     stream_id = GST_READ_UINT8 (es_map_base);
1824     es_map_base++;
1825     stream_info_length = GST_READ_UINT16_BE (es_map_base);
1826     es_map_base += 2;
1827     /* Cap stream_info_length */
1828     stream_info_length = MIN (data + es_map_length - es_map_base,
1829         stream_info_length);
1830
1831     GST_DEBUG_OBJECT (demux, "Stream type %02X with id %02X and %u bytes info",
1832         stream_type, stream_id, stream_info_length);
1833     if (G_LIKELY (stream_id != 0xbd))
1834       demux->psm[stream_id] = stream_type;
1835     else {
1836       /* Ignore stream type for private_stream_1 and discover it looking at
1837        * the stream data.
1838        * Fixes demuxing some clips with lpcm that was wrongly declared as
1839        * mpeg audio */
1840       GST_DEBUG_OBJECT (demux, "stream type for private_stream_1 ignored");
1841     }
1842     es_map_base += stream_info_length;
1843   }
1844
1845   gst_adapter_unmap (demux->adapter);
1846   gst_adapter_flush (demux->adapter, length);
1847   ADAPTER_OFFSET_FLUSH (length);
1848   return GST_FLOW_OK;
1849
1850 psm_len_error:
1851   {
1852     GST_DEBUG_OBJECT (demux, "error in PSM length");
1853     gst_adapter_unmap (demux->adapter);
1854     return GST_FLOW_LOST_SYNC;
1855   }
1856 need_more_data:
1857   {
1858     GST_DEBUG_OBJECT (demux, "need more data");
1859     return GST_FLOW_NEED_MORE_DATA;
1860   }
1861 }
1862
1863 static void
1864 gst_flups_demux_resync_cb (GstPESFilter * filter, GstFluPSDemux * demux)
1865 {
1866 }
1867
1868 static GstFlowReturn
1869 gst_flups_demux_data_cb (GstPESFilter * filter, gboolean first,
1870     GstBuffer * buffer, GstFluPSDemux * demux)
1871 {
1872   GstBuffer *out_buf;
1873   GstFlowReturn ret = GST_FLOW_OK;
1874   gint stream_type;
1875   guint32 start_code;
1876   guint8 id;
1877   GstMapInfo map;
1878   gsize datalen;
1879   guint offset = 0;
1880
1881   gst_buffer_map (buffer, &map, GST_MAP_READ);
1882   datalen = map.size;
1883
1884   start_code = filter->start_code;
1885   id = filter->id;
1886
1887   if (first) {
1888     /* find the stream type */
1889     stream_type = demux->psm[id];
1890     if (stream_type == -1) {
1891       /* no stream type, if PS1, get the new id */
1892       if (start_code == ID_PRIVATE_STREAM_1 && datalen >= 2) {
1893         /* VDR writes A52 streams without any header bytes
1894          * (see ftp://ftp.mplayerhq.hu/MPlayer/samples/MPEG-VOB/vdr-AC3) */
1895         if (datalen >= 4) {
1896           guint hdr = GST_READ_UINT32_BE (map.data);
1897
1898           if (G_UNLIKELY ((hdr & 0xffff0000) == AC3_SYNC_WORD)) {
1899             id = 0x80;
1900             stream_type = demux->psm[id] = ST_GST_AUDIO_RAWA52;
1901             GST_DEBUG_OBJECT (demux, "Found VDR raw A52 stream");
1902           }
1903         }
1904
1905         if (G_LIKELY (stream_type == -1)) {
1906           /* new id is in the first byte */
1907           id = map.data[offset++];
1908           datalen--;
1909
1910           /* and remap */
1911           stream_type = demux->psm[id];
1912
1913           /* Now, if it's a subpicture stream - no more, otherwise
1914            * take the first byte too, since it's the frame count in audio
1915            * streams and our backwards compat convention is to strip it off */
1916           if (stream_type != ST_PS_DVD_SUBPICTURE) {
1917             /* Number of audio frames in this packet */
1918 #ifndef GST_DISABLE_GST_DEBUG
1919             guint8 nframes;
1920
1921             nframes = map.data[offset];
1922             GST_LOG_OBJECT (demux, "private type 0x%02x, %d frames", id,
1923                 nframes);
1924 #endif
1925             offset++;
1926             datalen--;
1927           } else {
1928             GST_LOG_OBJECT (demux, "private type 0x%02x, stream type %d", id,
1929                 stream_type);
1930           }
1931         }
1932       }
1933       if (stream_type == -1)
1934         goto unknown_stream_type;
1935     }
1936     if (filter->pts != -1) {
1937       demux->next_pts = filter->pts + demux->scr_adjust;
1938       GST_LOG_OBJECT (demux, "PTS = %" G_GUINT64_FORMAT
1939           "(%" G_GUINT64_FORMAT ")", filter->pts, demux->next_pts);
1940     } else
1941       demux->next_pts = G_MAXUINT64;
1942
1943     if (filter->dts != -1) {
1944       demux->next_dts = filter->dts + demux->scr_adjust;
1945     } else {
1946       demux->next_dts = demux->next_pts;
1947     }
1948     GST_LOG_OBJECT (demux, "DTS = orig %" G_GUINT64_FORMAT
1949         " (%" G_GUINT64_FORMAT ")", filter->dts, demux->next_dts);
1950
1951     demux->current_stream = gst_flups_demux_get_stream (demux, id, stream_type);
1952   }
1953
1954   if (G_UNLIKELY (demux->current_stream == NULL)) {
1955     GST_DEBUG_OBJECT (demux, "Dropping buffer for unknown stream id 0x%02x",
1956         id);
1957     goto done;
1958   }
1959
1960   /* After 2 seconds of bitstream emit no more pads */
1961   if (demux->need_no_more_pads
1962       && (demux->current_scr - demux->first_scr - demux->scr_adjust) >
1963       2 * CLOCK_FREQ) {
1964     GST_DEBUG_OBJECT (demux, "no more pads, notifying");
1965     gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
1966     demux->need_no_more_pads = FALSE;
1967   }
1968
1969   /* If the stream is not-linked, don't bother creating a sub-buffer
1970    * to send to it, unless we're processing a discont (which resets
1971    * the not-linked status and tries again */
1972   if (demux->current_stream->discont) {
1973     GST_DEBUG_OBJECT (demux, "stream is discont");
1974     demux->current_stream->notlinked = FALSE;
1975   }
1976
1977   if (demux->current_stream->notlinked == FALSE) {
1978     out_buf =
1979         gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, offset, datalen);
1980
1981     ret = gst_flups_demux_send_data (demux, demux->current_stream, out_buf);
1982     if (ret == GST_FLOW_NOT_LINKED) {
1983       demux->current_stream->notlinked = TRUE;
1984       ret = GST_FLOW_OK;
1985     }
1986   }
1987
1988 done:
1989   gst_buffer_unmap (buffer, &map);
1990   gst_buffer_unref (buffer);
1991
1992   return ret;
1993
1994   /* ERRORS */
1995 unknown_stream_type:
1996   {
1997     GST_DEBUG_OBJECT (demux, "unknown stream type %02x", id);
1998     ret = GST_FLOW_OK;
1999     goto done;
2000   }
2001 }
2002
2003 static gboolean
2004 gst_flups_demux_resync (GstFluPSDemux * demux, gboolean save)
2005 {
2006   const guint8 *data;
2007   gint avail;
2008   guint32 code;
2009   gint offset;
2010   gboolean found;
2011
2012   avail = gst_adapter_available (demux->adapter);
2013   if (G_UNLIKELY (avail < 4))
2014     goto need_data;
2015
2016   /* Common case, read 4 bytes an check it */
2017   data = gst_adapter_map (demux->adapter, 4);
2018
2019   /* read currect code */
2020   code = GST_READ_UINT32_BE (data);
2021
2022   /* The common case is that the sync code is at 0 bytes offset */
2023   if (G_LIKELY ((code & 0xffffff00) == 0x100L)) {
2024     GST_LOG_OBJECT (demux, "Found resync code %08x after 0 bytes", code);
2025     demux->last_sync_code = code;
2026     gst_adapter_unmap (demux->adapter);
2027     return TRUE;
2028   }
2029
2030   /* Otherwise, we are starting at byte 4 and we need to search
2031      the sync code in all available data in the adapter */
2032   offset = 4;
2033   if (offset >= avail)
2034     goto need_data;             /* Not enough data to find sync */
2035
2036   data = gst_adapter_map (demux->adapter, avail);
2037
2038   do {
2039     code = (code << 8) | data[offset++];
2040     found = (code & 0xffffff00) == 0x100L;
2041   } while (offset < avail && !found);
2042
2043   gst_adapter_unmap (demux->adapter);
2044
2045   if (!save || demux->sink_segment.rate >= 0.0) {
2046     GST_LOG_OBJECT (demux, "flushing %d bytes", offset - 4);
2047     /* forward playback, we can discard and flush the skipped bytes */
2048     gst_adapter_flush (demux->adapter, offset - 4);
2049     ADAPTER_OFFSET_FLUSH (offset - 4);
2050   } else {
2051     if (found) {
2052       GST_LOG_OBJECT (demux, "reverse saving %d bytes", offset - 4);
2053       /* reverse playback, we keep the flushed bytes and we will append them to
2054        * the next buffer in the chain function, which is the previous buffer in
2055        * the stream. */
2056       gst_adapter_push (demux->rev_adapter,
2057           gst_adapter_take_buffer (demux->adapter, offset - 4));
2058     } else {
2059       GST_LOG_OBJECT (demux, "reverse saving %d bytes", avail);
2060       /* nothing found, keep all bytes */
2061       gst_adapter_push (demux->rev_adapter,
2062           gst_adapter_take_buffer (demux->adapter, avail));
2063     }
2064   }
2065
2066   if (found) {
2067     GST_LOG_OBJECT (demux, "Found resync code %08x after %d bytes",
2068         code, offset - 4);
2069     demux->last_sync_code = code;
2070   } else {
2071     GST_LOG_OBJECT (demux, "No resync after skipping %d", offset);
2072   }
2073
2074   return found;
2075
2076 need_data:
2077   {
2078     GST_LOG_OBJECT (demux, "we need more data for resync %d", avail);
2079     return FALSE;
2080   }
2081 }
2082
2083 static inline gboolean
2084 gst_flups_demux_is_pes_sync (guint32 sync)
2085 {
2086   return ((sync & 0xfc) == 0xbc) ||
2087       ((sync & 0xe0) == 0xc0) || ((sync & 0xf0) == 0xe0);
2088 }
2089
2090 /* If we can pull that's preferred */
2091 static gboolean
2092 gst_flups_demux_sink_activate (GstPad * sinkpad, GstObject * parent)
2093 {
2094   gboolean res = FALSE;
2095   GstQuery *query = gst_query_new_scheduling ();
2096
2097   if (gst_pad_peer_query (sinkpad, query)) {
2098     if (gst_query_has_scheduling_mode_with_flags (query,
2099             GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE)) {
2100       res = gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
2101     } else {
2102       res = gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
2103     }
2104   } else {
2105     res = gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
2106   }
2107
2108   gst_query_unref (query);
2109
2110   return res;
2111 }
2112
2113 /* This function gets called when we activate ourselves in push mode. */
2114 static gboolean
2115 gst_flups_demux_sink_activate_push (GstPad * sinkpad, GstObject * parent,
2116     gboolean active)
2117 {
2118   GstFluPSDemux *demux = GST_FLUPS_DEMUX (parent);
2119
2120   demux->random_access = FALSE;
2121
2122   return TRUE;
2123 }
2124
2125 #if 0
2126 /* this function gets called when we activate ourselves in pull mode.
2127  * We can perform  random access to the resource and we start a task
2128  * to start reading */
2129 static gboolean
2130 gst_flups_demux_sink_activate_pull (GstPad * sinkpad, GstObject * parent,
2131     gboolean active)
2132 {
2133   GstFluPSDemux *demux = GST_FLUPS_DEMUX (parent);
2134
2135   if (active) {
2136     GST_DEBUG ("pull mode activated");
2137     demux->random_access = TRUE;
2138     return gst_pad_start_task (sinkpad, (GstTaskFunction) gst_flups_demux_loop,
2139         sinkpad, NULL);
2140   } else {
2141     demux->random_access = FALSE;
2142     return gst_pad_stop_task (sinkpad);
2143   }
2144 }
2145 #endif
2146
2147 static gboolean
2148 gst_flups_demux_sink_activate_mode (GstPad * pad, GstObject * parent,
2149     GstPadMode mode, gboolean active)
2150 {
2151   if (mode == GST_PAD_MODE_PUSH) {
2152     return gst_flups_demux_sink_activate_push (pad, parent, active);
2153   } else if (mode == GST_PAD_MODE_PULL) {
2154 //    return gst_flups_demux_sink_activate_pull (pad, parent, active);
2155   }
2156   return FALSE;
2157 }
2158
2159 /* EOS and NOT_LINKED need to be combined. This means that we return:
2160 *
2161 *  GST_FLOW_NOT_LINKED: when all pads NOT_LINKED.
2162 *  GST_FLOW_EOS: when all pads EOS or NOT_LINKED.
2163 */
2164 static GstFlowReturn
2165 gst_flups_demux_combine_flows (GstFluPSDemux * demux, GstFlowReturn ret)
2166 {
2167   gint i, count = demux->found_count, streams = 0;
2168   gboolean unexpected = FALSE, not_linked = TRUE;
2169
2170   GST_LOG_OBJECT (demux, "flow return: %s", gst_flow_get_name (ret));
2171
2172   /* only return NOT_LINKED if all other pads returned NOT_LINKED */
2173   for (i = 0; i < count; i++) {
2174     GstFluPSStream *stream = demux->streams_found[i];
2175
2176     if (G_UNLIKELY (!stream))
2177       continue;
2178
2179     ret = stream->last_flow;
2180     streams++;
2181
2182     /* some streams may still have to appear,
2183      * and only those ones may end up linked */
2184     if (G_UNLIKELY (demux->need_no_more_pads && ret == GST_FLOW_NOT_LINKED))
2185       ret = GST_FLOW_OK;
2186
2187     /* no unexpected or unlinked, return */
2188     if (G_LIKELY (ret != GST_FLOW_EOS && ret != GST_FLOW_NOT_LINKED))
2189       goto done;
2190
2191     /* we check to see if we have at least 1 unexpected or all unlinked */
2192     unexpected |= (ret == GST_FLOW_EOS);
2193     not_linked &= (ret == GST_FLOW_NOT_LINKED);
2194   }
2195
2196   /* when we get here, we all have unlinked or unexpected */
2197   if (not_linked && streams)
2198     ret = GST_FLOW_NOT_LINKED;
2199   else if (unexpected)
2200     ret = GST_FLOW_EOS;
2201
2202 done:
2203   GST_LOG_OBJECT (demux, "combined flow return: %s", gst_flow_get_name (ret));
2204   return ret;
2205 }
2206
2207 static GstFlowReturn
2208 gst_flups_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
2209 {
2210   GstFluPSDemux *demux = GST_FLUPS_DEMUX (parent);
2211   GstFlowReturn ret = GST_FLOW_OK;
2212   guint32 avail;
2213   gboolean save, discont;
2214
2215   discont = GST_BUFFER_IS_DISCONT (buffer);
2216
2217   if (discont) {
2218     GST_LOG_OBJECT (demux, "Received buffer with discont flag and"
2219         " offset %" G_GUINT64_FORMAT, GST_BUFFER_OFFSET (buffer));
2220
2221     gst_pes_filter_drain (&demux->filter);
2222     gst_flups_demux_mark_discont (demux, TRUE, FALSE);
2223
2224     /* mark discont on all streams */
2225     if (demux->sink_segment.rate >= 0.0) {
2226       demux->current_scr = G_MAXUINT64;
2227       demux->bytes_since_scr = 0;
2228     }
2229   } else {
2230     GST_LOG_OBJECT (demux, "Received buffer with offset %" G_GUINT64_FORMAT,
2231         GST_BUFFER_OFFSET (buffer));
2232   }
2233
2234   /* We keep the offset to interpolate SCR */
2235   demux->adapter_offset = GST_BUFFER_OFFSET (buffer);
2236
2237   gst_adapter_push (demux->adapter, buffer);
2238   demux->bytes_since_scr += gst_buffer_get_size (buffer);
2239
2240   avail = gst_adapter_available (demux->rev_adapter);
2241   if (avail > 0) {
2242     GST_LOG_OBJECT (demux, "appending %u saved bytes", avail);
2243     /* if we have a previous reverse chunk, append this now */
2244     /* FIXME this code assumes we receive discont buffers all thei
2245      * time */
2246     gst_adapter_push (demux->adapter,
2247         gst_adapter_take_buffer (demux->rev_adapter, avail));
2248   }
2249
2250   avail = gst_adapter_available (demux->adapter);
2251   GST_LOG_OBJECT (demux, "avail now: %d, state %d", avail, demux->filter.state);
2252
2253   switch (demux->filter.state) {
2254     case STATE_DATA_SKIP:
2255     case STATE_DATA_PUSH:
2256       ret = gst_pes_filter_process (&demux->filter);
2257       break;
2258     case STATE_HEADER_PARSE:
2259       break;
2260     default:
2261       break;
2262   }
2263
2264   switch (ret) {
2265     case GST_FLOW_NEED_MORE_DATA:
2266       /* Go and get more data */
2267       ret = GST_FLOW_OK;
2268       goto done;
2269     case GST_FLOW_LOST_SYNC:
2270       /* for FLOW_OK or lost-sync, carry onto resync */
2271       ret = GST_FLOW_OK;
2272       break;
2273     case GST_FLOW_OK:
2274       break;
2275     default:
2276       /* Any other return value should be sent upstream immediately */
2277       goto done;
2278   }
2279
2280   /* align adapter data to sync boundary, we keep the data up to the next sync
2281    * point. */
2282   save = TRUE;
2283   while (gst_flups_demux_resync (demux, save)) {
2284     gboolean ps_sync = TRUE;
2285
2286     /* now switch on last synced byte */
2287     switch (demux->last_sync_code) {
2288       case ID_PS_PACK_START_CODE:
2289         ret = gst_flups_demux_parse_pack_start (demux);
2290         break;
2291       case ID_PS_SYSTEM_HEADER_START_CODE:
2292         ret = gst_flups_demux_parse_sys_head (demux);
2293         break;
2294       case ID_PS_END_CODE:
2295         ret = GST_FLOW_OK;
2296         goto done;
2297       case ID_PS_PROGRAM_STREAM_MAP:
2298         ret = gst_flups_demux_parse_psm (demux);
2299         break;
2300       default:
2301         if (gst_flups_demux_is_pes_sync (demux->last_sync_code)) {
2302           ret = gst_pes_filter_process (&demux->filter);
2303         } else {
2304           GST_DEBUG_OBJECT (demux, "sync_code=%08x, non PES sync found"
2305               ", continuing", demux->last_sync_code);
2306           ps_sync = FALSE;
2307           ret = GST_FLOW_LOST_SYNC;
2308         }
2309         break;
2310     }
2311     /* if we found a ps sync, we stop saving the data, any non-ps sync gets
2312      * saved up to the next ps sync. */
2313     if (ps_sync)
2314       save = FALSE;
2315
2316     switch (ret) {
2317       case GST_FLOW_NEED_MORE_DATA:
2318         GST_DEBUG_OBJECT (demux, "need more data");
2319         ret = GST_FLOW_OK;
2320         goto done;
2321       case GST_FLOW_LOST_SYNC:
2322         if (!save || demux->sink_segment.rate >= 0.0) {
2323           GST_DEBUG_OBJECT (demux, "flushing 3 bytes");
2324           gst_adapter_flush (demux->adapter, 3);
2325           ADAPTER_OFFSET_FLUSH (3);
2326         } else {
2327           GST_DEBUG_OBJECT (demux, "saving 3 bytes");
2328           gst_adapter_push (demux->rev_adapter,
2329               gst_adapter_take_buffer (demux->adapter, 3));
2330         }
2331         ret = GST_FLOW_OK;
2332         break;
2333       default:
2334         ret = gst_flups_demux_combine_flows (demux, ret);
2335         if (ret != GST_FLOW_OK)
2336           goto done;
2337         break;
2338     }
2339   }
2340 done:
2341   return ret;
2342 }
2343
2344 static GstStateChangeReturn
2345 gst_flups_demux_change_state (GstElement * element, GstStateChange transition)
2346 {
2347   GstFluPSDemux *demux = GST_FLUPS_DEMUX (element);
2348   GstStateChangeReturn result;
2349
2350   switch (transition) {
2351     case GST_STATE_CHANGE_NULL_TO_READY:
2352       gst_pes_filter_init (&demux->filter, demux->adapter,
2353           &demux->adapter_offset);
2354       gst_pes_filter_set_callbacks (&demux->filter,
2355           (GstPESFilterData) gst_flups_demux_data_cb,
2356           (GstPESFilterResync) gst_flups_demux_resync_cb, demux);
2357       demux->filter.gather_pes = TRUE;
2358       break;
2359     case GST_STATE_CHANGE_READY_TO_PAUSED:
2360       break;
2361     default:
2362       break;
2363   }
2364
2365   result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
2366
2367   switch (transition) {
2368     case GST_STATE_CHANGE_PAUSED_TO_READY:
2369       gst_flups_demux_reset (demux);
2370       break;
2371     case GST_STATE_CHANGE_READY_TO_NULL:
2372       gst_pes_filter_uninit (&demux->filter);
2373       break;
2374     default:
2375       break;
2376   }
2377
2378   return result;
2379 }
2380
2381 static void
2382 gst_segment_set_position (GstSegment * segment, GstFormat format,
2383     guint64 position)
2384 {
2385   if (segment->format == GST_FORMAT_UNDEFINED) {
2386     segment->format = format;
2387   }
2388   segment->position = position;
2389 }
2390
2391 gboolean
2392 gst_flups_demux_plugin_init (GstPlugin * plugin)
2393 {
2394   GST_DEBUG_CATEGORY_INIT (mpegpspesfilter_debug, "rsnpesfilter", 0,
2395       "MPEG program stream PES filter debug");
2396
2397   GST_DEBUG_CATEGORY_INIT (gstflupsdemux_debug, "rsndvddemux", 0,
2398       "MPEG program stream demuxer debug");
2399
2400   return TRUE;
2401 }