rtsp-server:wfd: Fix build error for gcc upgrade
[platform/upstream/gstreamer.git] / subprojects / gst-libav / ext / libav / gstavdemux.c
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>,
3  *               <2006> Edward Hervey <bilboed@bilboed.com>
4  *               <2006> Wim Taymans <wim@fluendo.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <string.h>
27
28 #include <libavformat/avformat.h>
29 #include <libavutil/imgutils.h>
30 /* #include <ffmpeg/avi.h> */
31 #include <gst/gst.h>
32 #include <gst/base/gstflowcombiner.h>
33
34 #include "gstav.h"
35 #include "gstavcodecmap.h"
36 #include "gstavutils.h"
37 #include "gstavprotocol.h"
38
39 #define MAX_STREAMS 20
40
41 typedef struct _GstFFMpegDemux GstFFMpegDemux;
42 typedef struct _GstFFStream GstFFStream;
43
44 struct _GstFFStream
45 {
46   GstPad *pad;
47
48   AVStream *avstream;
49
50   gboolean unknown;
51   GstClockTime last_ts;
52   gboolean discont;
53   gboolean eos;
54
55   GstTagList *tags;             /* stream tags */
56 };
57
58 struct _GstFFMpegDemux
59 {
60   GstElement element;
61
62   /* We need to keep track of our pads, so we do so here. */
63   GstPad *sinkpad;
64
65   gboolean have_group_id;
66   guint group_id;
67
68   AVFormatContext *context;
69   gboolean opened;
70
71   GstFFStream *streams[MAX_STREAMS];
72
73   GstFlowCombiner *flowcombiner;
74
75   gint videopads, audiopads;
76
77   GstClockTime start_time;
78   GstClockTime duration;
79
80   /* TRUE if working in pull-mode */
81   gboolean seekable;
82
83   /* TRUE if the avformat demuxer can reliably handle streaming mode */
84   gboolean can_push;
85
86   gboolean flushing;
87
88   /* segment stuff */
89   GstSegment segment;
90
91   /* cached seek in READY */
92   GstEvent *seek_event;
93
94   /* cached upstream events */
95   GList *cached_events;
96
97   /* push mode data */
98   GstFFMpegPipe ffpipe;
99   GstTask *task;
100   GRecMutex task_lock;
101 };
102
103 typedef struct _GstFFMpegDemuxClass GstFFMpegDemuxClass;
104
105 struct _GstFFMpegDemuxClass
106 {
107   GstElementClass parent_class;
108
109   AVInputFormat *in_plugin;
110   GstPadTemplate *sinktempl;
111   GstPadTemplate *videosrctempl;
112   GstPadTemplate *audiosrctempl;
113 };
114
115 /* A number of function prototypes are given so we can refer to them later. */
116 static void gst_ffmpegdemux_class_init (GstFFMpegDemuxClass * klass);
117 static void gst_ffmpegdemux_base_init (GstFFMpegDemuxClass * klass);
118 static void gst_ffmpegdemux_init (GstFFMpegDemux * demux);
119 static void gst_ffmpegdemux_finalize (GObject * object);
120
121 static gboolean gst_ffmpegdemux_sink_event (GstPad * sinkpad,
122     GstObject * parent, GstEvent * event);
123 static GstFlowReturn gst_ffmpegdemux_chain (GstPad * sinkpad,
124     GstObject * parent, GstBuffer * buf);
125
126 static void gst_ffmpegdemux_loop (GstFFMpegDemux * demux);
127 static gboolean gst_ffmpegdemux_sink_activate (GstPad * sinkpad,
128     GstObject * parent);
129 static gboolean gst_ffmpegdemux_sink_activate_mode (GstPad * sinkpad,
130     GstObject * parent, GstPadMode mode, gboolean active);
131 static GstTagList *gst_ffmpeg_metadata_to_tag_list (AVDictionary * metadata);
132
133 #if 0
134 static gboolean
135 gst_ffmpegdemux_src_convert (GstPad * pad,
136     GstFormat src_fmt,
137     gint64 src_value, GstFormat * dest_fmt, gint64 * dest_value);
138 #endif
139 static gboolean
140 gst_ffmpegdemux_send_event (GstElement * element, GstEvent * event);
141 static GstStateChangeReturn
142 gst_ffmpegdemux_change_state (GstElement * element, GstStateChange transition);
143
144 #define GST_FFDEMUX_PARAMS_QDATA g_quark_from_static_string("avdemux-params")
145
146 static GstElementClass *parent_class = NULL;
147
148 static const gchar *
149 gst_ffmpegdemux_averror (gint av_errno)
150 {
151   const gchar *message = NULL;
152
153   switch (av_errno) {
154     case AVERROR (EINVAL):
155       message = "Unknown error";
156       break;
157     case AVERROR (EIO):
158       message = "Input/output error";
159       break;
160     case AVERROR (EDOM):
161       message = "Number syntax expected in filename";
162       break;
163     case AVERROR (ENOMEM):
164       message = "Not enough memory";
165       break;
166     case AVERROR (EILSEQ):
167       message = "Unknown format";
168       break;
169     case AVERROR (ENOSYS):
170       message = "Operation not supported";
171       break;
172     default:
173       message = "Unhandled error code received";
174       break;
175   }
176
177   return message;
178 }
179
180 static void
181 gst_ffmpegdemux_base_init (GstFFMpegDemuxClass * klass)
182 {
183   GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
184   AVInputFormat *in_plugin;
185   GstCaps *sinkcaps;
186   GstPadTemplate *sinktempl, *audiosrctempl, *videosrctempl;
187   gchar *longname, *description, *name;
188
189   in_plugin = (AVInputFormat *)
190       g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass), GST_FFDEMUX_PARAMS_QDATA);
191   g_assert (in_plugin != NULL);
192
193   name = g_strdup (in_plugin->name);
194   g_strdelimit (name, ".,|-<> ", '_');
195
196   /* construct the element details struct */
197   longname = g_strdup_printf ("libav %s demuxer", in_plugin->long_name);
198   description = g_strdup_printf ("libav %s demuxer", in_plugin->long_name);
199   gst_element_class_set_metadata (element_class, longname,
200       "Codec/Demuxer", description,
201       "Wim Taymans <wim@fluendo.com>, "
202       "Ronald Bultje <rbultje@ronald.bitfreak.net>, "
203       "Edward Hervey <bilboed@bilboed.com>");
204   g_free (longname);
205   g_free (description);
206
207   /* pad templates */
208   sinkcaps = gst_ffmpeg_formatid_to_caps (name);
209   sinktempl = gst_pad_template_new ("sink",
210       GST_PAD_SINK, GST_PAD_ALWAYS, sinkcaps);
211   g_free (name);
212   videosrctempl = gst_pad_template_new ("video_%u",
213       GST_PAD_SRC, GST_PAD_SOMETIMES, GST_CAPS_ANY);
214   audiosrctempl = gst_pad_template_new ("audio_%u",
215       GST_PAD_SRC, GST_PAD_SOMETIMES, GST_CAPS_ANY);
216
217   gst_element_class_add_pad_template (element_class, videosrctempl);
218   gst_element_class_add_pad_template (element_class, audiosrctempl);
219   gst_element_class_add_pad_template (element_class, sinktempl);
220
221   gst_caps_unref (sinkcaps);
222
223   klass->in_plugin = in_plugin;
224   klass->videosrctempl = videosrctempl;
225   klass->audiosrctempl = audiosrctempl;
226   klass->sinktempl = sinktempl;
227 }
228
229 static void
230 gst_ffmpegdemux_class_init (GstFFMpegDemuxClass * klass)
231 {
232   GObjectClass *gobject_class;
233   GstElementClass *gstelement_class;
234
235   gobject_class = (GObjectClass *) klass;
236   gstelement_class = (GstElementClass *) klass;
237
238   parent_class = g_type_class_peek_parent (klass);
239
240   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_ffmpegdemux_finalize);
241
242   gstelement_class->change_state = gst_ffmpegdemux_change_state;
243   gstelement_class->send_event = gst_ffmpegdemux_send_event;
244 }
245
246 static void
247 gst_ffmpegdemux_init (GstFFMpegDemux * demux)
248 {
249   GstFFMpegDemuxClass *oclass =
250       (GstFFMpegDemuxClass *) (G_OBJECT_GET_CLASS (demux));
251   gint n;
252
253   demux->sinkpad = gst_pad_new_from_template (oclass->sinktempl, "sink");
254   gst_pad_set_activate_function (demux->sinkpad,
255       GST_DEBUG_FUNCPTR (gst_ffmpegdemux_sink_activate));
256   gst_pad_set_activatemode_function (demux->sinkpad,
257       GST_DEBUG_FUNCPTR (gst_ffmpegdemux_sink_activate_mode));
258   gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);
259
260   /* push based setup */
261   /* the following are not used in pull-based mode, so safe to set anyway */
262   gst_pad_set_event_function (demux->sinkpad,
263       GST_DEBUG_FUNCPTR (gst_ffmpegdemux_sink_event));
264   gst_pad_set_chain_function (demux->sinkpad,
265       GST_DEBUG_FUNCPTR (gst_ffmpegdemux_chain));
266   /* task for driving ffmpeg in loop function */
267   demux->task =
268       gst_task_new ((GstTaskFunction) gst_ffmpegdemux_loop, demux, NULL);
269   g_rec_mutex_init (&demux->task_lock);
270   gst_task_set_lock (demux->task, &demux->task_lock);
271
272   demux->have_group_id = FALSE;
273   demux->group_id = G_MAXUINT;
274
275   demux->opened = FALSE;
276   demux->context = NULL;
277
278   for (n = 0; n < MAX_STREAMS; n++) {
279     demux->streams[n] = NULL;
280   }
281   demux->videopads = 0;
282   demux->audiopads = 0;
283
284   demux->seek_event = NULL;
285   gst_segment_init (&demux->segment, GST_FORMAT_TIME);
286
287   demux->flowcombiner = gst_flow_combiner_new ();
288
289   /* push based data */
290   g_mutex_init (&demux->ffpipe.tlock);
291   g_cond_init (&demux->ffpipe.cond);
292   demux->ffpipe.adapter = gst_adapter_new ();
293
294   /* blacklist unreliable push-based demuxers */
295   if (strcmp (oclass->in_plugin->name, "ape"))
296     demux->can_push = TRUE;
297   else
298     demux->can_push = FALSE;
299 }
300
301 static void
302 gst_ffmpegdemux_finalize (GObject * object)
303 {
304   GstFFMpegDemux *demux;
305
306   demux = (GstFFMpegDemux *) object;
307
308   gst_flow_combiner_free (demux->flowcombiner);
309
310   g_mutex_clear (&demux->ffpipe.tlock);
311   g_cond_clear (&demux->ffpipe.cond);
312   gst_object_unref (demux->ffpipe.adapter);
313
314   gst_object_unref (demux->task);
315   g_rec_mutex_clear (&demux->task_lock);
316
317   G_OBJECT_CLASS (parent_class)->finalize (object);
318 }
319
320 static void
321 gst_ffmpegdemux_close (GstFFMpegDemux * demux)
322 {
323   gint n;
324   GstEvent **event_p;
325
326   if (!demux->opened)
327     return;
328
329   /* remove pads from ourselves */
330   for (n = 0; n < MAX_STREAMS; n++) {
331     GstFFStream *stream;
332
333     stream = demux->streams[n];
334     if (stream) {
335       if (stream->pad) {
336         gst_flow_combiner_remove_pad (demux->flowcombiner, stream->pad);
337         gst_element_remove_pad (GST_ELEMENT (demux), stream->pad);
338       }
339       if (stream->tags)
340         gst_tag_list_unref (stream->tags);
341       g_free (stream);
342     }
343     demux->streams[n] = NULL;
344   }
345   demux->videopads = 0;
346   demux->audiopads = 0;
347
348   /* close demuxer context from ffmpeg */
349   if (demux->seekable)
350     gst_ffmpegdata_close (demux->context->pb);
351   else
352     gst_ffmpeg_pipe_close (demux->context->pb);
353   demux->context->pb = NULL;
354   avformat_close_input (&demux->context);
355   if (demux->context)
356     avformat_free_context (demux->context);
357   demux->context = NULL;
358
359   GST_OBJECT_LOCK (demux);
360   demux->opened = FALSE;
361   event_p = &demux->seek_event;
362   gst_event_replace (event_p, NULL);
363   GST_OBJECT_UNLOCK (demux);
364
365   gst_segment_init (&demux->segment, GST_FORMAT_TIME);
366 }
367
368 /* send an event to all the source pads .
369  * Takes ownership of the event.
370  *
371  * Returns FALSE if none of the source pads handled the event.
372  */
373 static gboolean
374 gst_ffmpegdemux_push_event (GstFFMpegDemux * demux, GstEvent * event)
375 {
376   gboolean res;
377   gint n;
378
379   res = TRUE;
380
381   for (n = 0; n < MAX_STREAMS; n++) {
382     GstFFStream *s = demux->streams[n];
383
384     if (s && s->pad) {
385       gst_event_ref (event);
386       res &= gst_pad_push_event (s->pad, event);
387     }
388   }
389   gst_event_unref (event);
390
391   return res;
392 }
393
394 /* set flags on all streams */
395 static void
396 gst_ffmpegdemux_set_flags (GstFFMpegDemux * demux, gboolean discont,
397     gboolean eos)
398 {
399   GstFFStream *s;
400   gint n;
401
402   for (n = 0; n < MAX_STREAMS; n++) {
403     if ((s = demux->streams[n])) {
404       s->discont = discont;
405       s->eos = eos;
406     }
407   }
408 }
409
410 /* check if all streams are eos */
411 static gboolean
412 gst_ffmpegdemux_is_eos (GstFFMpegDemux * demux)
413 {
414   GstFFStream *s;
415   gint n;
416
417   for (n = 0; n < MAX_STREAMS; n++) {
418     if ((s = demux->streams[n])) {
419       GST_DEBUG ("stream %d %p eos:%d", n, s, s->eos);
420       if (!s->eos)
421         return FALSE;
422     }
423   }
424   return TRUE;
425 }
426
427 /* Returns True if we at least outputted one buffer */
428 static gboolean
429 gst_ffmpegdemux_has_outputted (GstFFMpegDemux * demux)
430 {
431   GstFFStream *s;
432   gint n;
433
434   for (n = 0; n < MAX_STREAMS; n++) {
435     if ((s = demux->streams[n])) {
436       if (GST_CLOCK_TIME_IS_VALID (s->last_ts))
437         return TRUE;
438     }
439   }
440   return FALSE;
441 }
442
443 static gboolean
444 gst_ffmpegdemux_do_seek (GstFFMpegDemux * demux, GstSegment * segment)
445 {
446   gboolean ret;
447   gint seekret;
448   gint64 target;
449   gint64 fftarget;
450   AVStream *stream;
451   gint index;
452
453   /* find default index and fail if none is present */
454   index = av_find_default_stream_index (demux->context);
455   GST_LOG_OBJECT (demux, "default stream index %d", index);
456   if (index < 0)
457     return FALSE;
458
459   ret = TRUE;
460
461   /* get the stream for seeking */
462   stream = demux->context->streams[index];
463   /* initial seek position */
464   target = segment->position + demux->start_time;
465   /* convert target to ffmpeg time */
466   fftarget = gst_ffmpeg_time_gst_to_ff (target, stream->time_base);
467
468   GST_LOG_OBJECT (demux, "do seek to time %" GST_TIME_FORMAT,
469       GST_TIME_ARGS (target));
470
471   /* if we need to land on a keyframe, try to do so, we don't try to do a
472    * keyframe seek if we are not absolutely sure we have an index.*/
473   if (segment->flags & GST_SEEK_FLAG_KEY_UNIT) {
474     gint keyframeidx;
475
476     GST_LOG_OBJECT (demux, "looking for keyframe in ffmpeg for time %"
477         GST_TIME_FORMAT, GST_TIME_ARGS (target));
478
479     /* search in the index for the previous keyframe */
480     keyframeidx =
481         av_index_search_timestamp (stream, fftarget, AVSEEK_FLAG_BACKWARD);
482
483     GST_LOG_OBJECT (demux, "keyframeidx: %d", keyframeidx);
484
485     if (keyframeidx >= 0) {
486 #if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(58,78,0)
487       fftarget = avformat_index_get_entry (stream, keyframeidx)->timestamp;
488 #else
489       fftarget = stream->index_entries[keyframeidx].timestamp;
490 #endif
491       target = gst_ffmpeg_time_ff_to_gst (fftarget, stream->time_base);
492
493       GST_LOG_OBJECT (demux,
494           "Found a keyframe at ffmpeg idx: %d timestamp :%" GST_TIME_FORMAT,
495           keyframeidx, GST_TIME_ARGS (target));
496     }
497   }
498
499   GST_DEBUG_OBJECT (demux,
500       "About to call av_seek_frame (context, %d, %" G_GINT64_FORMAT
501       ", 0) for time %" GST_TIME_FORMAT, index, fftarget,
502       GST_TIME_ARGS (target));
503
504   if ((seekret =
505           av_seek_frame (demux->context, index, fftarget,
506               AVSEEK_FLAG_BACKWARD)) < 0)
507     goto seek_failed;
508
509   GST_DEBUG_OBJECT (demux, "seek success, returned %d", seekret);
510
511   if (target > demux->start_time)
512     target -= demux->start_time;
513   else
514     target = 0;
515
516   segment->position = target;
517   segment->time = target;
518   segment->start = target;
519
520   return ret;
521
522   /* ERRORS */
523 seek_failed:
524   {
525     GST_WARNING_OBJECT (demux, "Call to av_seek_frame failed : %d", seekret);
526     return FALSE;
527   }
528 }
529
530 static gboolean
531 gst_ffmpegdemux_perform_seek (GstFFMpegDemux * demux, GstEvent * event)
532 {
533   gboolean res;
534   gdouble rate;
535   GstFormat format;
536   GstSeekFlags flags;
537   GstSeekType cur_type, stop_type;
538   gint64 cur, stop;
539   gboolean flush;
540   gboolean update;
541   GstSegment seeksegment;
542
543   if (!demux->seekable) {
544     GST_DEBUG_OBJECT (demux, "in push mode; ignoring seek");
545     return FALSE;
546   }
547
548   GST_DEBUG_OBJECT (demux, "starting seek");
549
550   if (event) {
551     gst_event_parse_seek (event, &rate, &format, &flags,
552         &cur_type, &cur, &stop_type, &stop);
553
554     /* we have to have a format as the segment format. Try to convert
555      * if not. */
556     if (demux->segment.format != format) {
557       GstFormat fmt;
558
559       fmt = demux->segment.format;
560       res = TRUE;
561       /* FIXME, use source pad */
562       if (cur_type != GST_SEEK_TYPE_NONE && cur != -1)
563         res = gst_pad_query_convert (demux->sinkpad, format, cur, fmt, &cur);
564       if (res && stop_type != GST_SEEK_TYPE_NONE && stop != -1)
565         res = gst_pad_query_convert (demux->sinkpad, format, stop, fmt, &stop);
566       if (!res)
567         goto no_format;
568
569       format = fmt;
570     }
571   } else {
572     flags = 0;
573   }
574
575   flush = flags & GST_SEEK_FLAG_FLUSH;
576
577   /* send flush start */
578   if (flush) {
579     /* mark flushing so that the streaming thread can react on it */
580     GST_OBJECT_LOCK (demux);
581     demux->flushing = TRUE;
582     GST_OBJECT_UNLOCK (demux);
583     gst_pad_push_event (demux->sinkpad, gst_event_new_flush_start ());
584     gst_ffmpegdemux_push_event (demux, gst_event_new_flush_start ());
585   } else {
586     gst_pad_pause_task (demux->sinkpad);
587   }
588
589   /* grab streaming lock, this should eventually be possible, either
590    * because the task is paused or our streaming thread stopped
591    * because our peer is flushing. */
592   GST_PAD_STREAM_LOCK (demux->sinkpad);
593
594   /* make copy into temp structure, we can only update the main one
595    * when we actually could do the seek. */
596   memcpy (&seeksegment, &demux->segment, sizeof (GstSegment));
597
598   /* now configure the seek segment */
599   if (event) {
600     gst_segment_do_seek (&seeksegment, rate, format, flags,
601         cur_type, cur, stop_type, stop, &update);
602   }
603
604   GST_DEBUG_OBJECT (demux, "segment configured from %" G_GINT64_FORMAT
605       " to %" G_GINT64_FORMAT ", position %" G_GINT64_FORMAT,
606       seeksegment.start, seeksegment.stop, seeksegment.position);
607
608   /* make the sinkpad available for data passing since we might need
609    * it when doing the seek */
610   if (flush) {
611     GST_OBJECT_LOCK (demux);
612     demux->flushing = FALSE;
613     GST_OBJECT_UNLOCK (demux);
614     gst_pad_push_event (demux->sinkpad, gst_event_new_flush_stop (TRUE));
615   }
616
617   /* do the seek, segment.position contains new position. */
618   res = gst_ffmpegdemux_do_seek (demux, &seeksegment);
619
620   /* and prepare to continue streaming */
621   if (flush) {
622     /* send flush stop, peer will accept data and events again. We
623      * are not yet providing data as we still have the STREAM_LOCK. */
624     gst_ffmpegdemux_push_event (demux, gst_event_new_flush_stop (TRUE));
625   }
626   /* if successfull seek, we update our real segment and push
627    * out the new segment. */
628   if (res) {
629     memcpy (&demux->segment, &seeksegment, sizeof (GstSegment));
630
631     if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
632       gst_element_post_message (GST_ELEMENT (demux),
633           gst_message_new_segment_start (GST_OBJECT (demux),
634               demux->segment.format, demux->segment.position));
635     }
636
637     /* now send the newsegment, FIXME, do this from the streaming thread */
638     GST_DEBUG_OBJECT (demux, "Sending newsegment %" GST_SEGMENT_FORMAT,
639         &demux->segment);
640
641     gst_ffmpegdemux_push_event (demux, gst_event_new_segment (&demux->segment));
642   }
643
644   /* Mark discont on all srcpads and remove eos */
645   gst_ffmpegdemux_set_flags (demux, TRUE, FALSE);
646   gst_flow_combiner_reset (demux->flowcombiner);
647
648   /* and restart the task in case it got paused explicitely or by
649    * the FLUSH_START event we pushed out. */
650   gst_pad_start_task (demux->sinkpad, (GstTaskFunction) gst_ffmpegdemux_loop,
651       demux->sinkpad, NULL);
652
653   /* and release the lock again so we can continue streaming */
654   GST_PAD_STREAM_UNLOCK (demux->sinkpad);
655
656   return res;
657
658   /* ERROR */
659 no_format:
660   {
661     GST_DEBUG_OBJECT (demux, "undefined format given, seek aborted.");
662     return FALSE;
663   }
664 }
665
666 static gboolean
667 gst_ffmpegdemux_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
668 {
669   GstFFMpegDemux *demux;
670   gboolean res = TRUE;
671
672   demux = (GstFFMpegDemux *) parent;
673
674   switch (GST_EVENT_TYPE (event)) {
675     case GST_EVENT_SEEK:
676       res = gst_ffmpegdemux_perform_seek (demux, event);
677       gst_event_unref (event);
678       break;
679     case GST_EVENT_LATENCY:
680       res = gst_pad_push_event (demux->sinkpad, event);
681       break;
682     case GST_EVENT_NAVIGATION:
683     case GST_EVENT_QOS:
684     default:
685       res = FALSE;
686       gst_event_unref (event);
687       break;
688   }
689
690   return res;
691 }
692
693 static gboolean
694 gst_ffmpegdemux_send_event (GstElement * element, GstEvent * event)
695 {
696   GstFFMpegDemux *demux = (GstFFMpegDemux *) (element);
697   gboolean res;
698
699   switch (GST_EVENT_TYPE (event)) {
700     case GST_EVENT_SEEK:
701       GST_OBJECT_LOCK (demux);
702       if (!demux->opened) {
703         GstEvent **event_p;
704
705         GST_DEBUG_OBJECT (demux, "caching seek event");
706         event_p = &demux->seek_event;
707         gst_event_replace (event_p, event);
708         GST_OBJECT_UNLOCK (demux);
709
710         res = TRUE;
711       } else {
712         GST_OBJECT_UNLOCK (demux);
713         res = gst_ffmpegdemux_perform_seek (demux, event);
714         gst_event_unref (event);
715       }
716       break;
717     default:
718       res = FALSE;
719       break;
720   }
721
722   return res;
723 }
724
725 static gboolean
726 gst_ffmpegdemux_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
727 {
728   GstFFMpegDemux *demux;
729   GstFFStream *stream;
730   AVStream *avstream;
731   gboolean res = FALSE;
732
733   if (!(stream = gst_pad_get_element_private (pad)))
734     return FALSE;
735
736   avstream = stream->avstream;
737
738   demux = (GstFFMpegDemux *) parent;
739
740   switch (GST_QUERY_TYPE (query)) {
741     case GST_QUERY_POSITION:
742     {
743       GstFormat format;
744       gint64 timeposition;
745
746       gst_query_parse_position (query, &format, NULL);
747
748       timeposition = stream->last_ts;
749       if (!(GST_CLOCK_TIME_IS_VALID (timeposition)))
750         break;
751
752       switch (format) {
753         case GST_FORMAT_TIME:
754           gst_query_set_position (query, GST_FORMAT_TIME, timeposition);
755           res = TRUE;
756           break;
757         case GST_FORMAT_DEFAULT:
758           gst_query_set_position (query, GST_FORMAT_DEFAULT,
759               gst_util_uint64_scale (timeposition, avstream->avg_frame_rate.num,
760                   GST_SECOND * avstream->avg_frame_rate.den));
761           res = TRUE;
762           break;
763         case GST_FORMAT_BYTES:
764           if (demux->videopads + demux->audiopads == 1 &&
765               GST_PAD_PEER (demux->sinkpad) != NULL)
766             res = gst_pad_query_default (pad, parent, query);
767           break;
768         default:
769           break;
770       }
771     }
772       break;
773     case GST_QUERY_DURATION:
774     {
775       GstFormat format;
776       gint64 timeduration;
777
778       gst_query_parse_duration (query, &format, NULL);
779
780       timeduration =
781           gst_ffmpeg_time_ff_to_gst (avstream->duration, avstream->time_base);
782       if (!(GST_CLOCK_TIME_IS_VALID (timeduration))) {
783         /* use duration of complete file if the stream duration is not known */
784         timeduration = demux->duration;
785         if (!(GST_CLOCK_TIME_IS_VALID (timeduration)))
786           break;
787       }
788
789       switch (format) {
790         case GST_FORMAT_TIME:
791           gst_query_set_duration (query, GST_FORMAT_TIME, timeduration);
792           res = TRUE;
793           break;
794         case GST_FORMAT_DEFAULT:
795           gst_query_set_duration (query, GST_FORMAT_DEFAULT,
796               gst_util_uint64_scale (timeduration, avstream->avg_frame_rate.num,
797                   GST_SECOND * avstream->avg_frame_rate.den));
798           res = TRUE;
799           break;
800         case GST_FORMAT_BYTES:
801           if (demux->videopads + demux->audiopads == 1 &&
802               GST_PAD_PEER (demux->sinkpad) != NULL)
803             res = gst_pad_query_default (pad, parent, query);
804           break;
805         default:
806           break;
807       }
808     }
809       break;
810     case GST_QUERY_SEEKING:{
811       GstFormat format;
812       gboolean seekable;
813       gint64 dur = -1;
814
815       gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
816       seekable = demux->seekable;
817       if (!gst_pad_query_duration (pad, format, &dur)) {
818         /* unlikely that we don't know duration but can seek */
819         seekable = FALSE;
820         dur = -1;
821       }
822       gst_query_set_seeking (query, format, seekable, 0, dur);
823       res = TRUE;
824       break;
825     }
826     case GST_QUERY_SEGMENT:{
827       GstFormat format;
828       gint64 start, stop;
829
830       format = demux->segment.format;
831
832       start =
833           gst_segment_to_stream_time (&demux->segment, format,
834           demux->segment.start);
835       if ((stop = demux->segment.stop) == -1)
836         stop = demux->segment.duration;
837       else
838         stop = gst_segment_to_stream_time (&demux->segment, format, stop);
839
840       gst_query_set_segment (query, demux->segment.rate, format, start, stop);
841       res = TRUE;
842       break;
843     }
844     default:
845       /* FIXME : ADD GST_QUERY_CONVERT */
846       res = gst_pad_query_default (pad, parent, query);
847       break;
848   }
849
850   return res;
851 }
852
853 #if 0
854 /* FIXME, reenable me */
855 static gboolean
856 gst_ffmpegdemux_src_convert (GstPad * pad,
857     GstFormat src_fmt,
858     gint64 src_value, GstFormat * dest_fmt, gint64 * dest_value)
859 {
860   GstFFStream *stream;
861   gboolean res = TRUE;
862   AVStream *avstream;
863
864   if (!(stream = gst_pad_get_element_private (pad)))
865     return FALSE;
866
867   avstream = stream->avstream;
868   if (avstream->codec->codec_type != AVMEDIA_TYPE_VIDEO)
869     return FALSE;
870
871   switch (src_fmt) {
872     case GST_FORMAT_TIME:
873       switch (*dest_fmt) {
874         case GST_FORMAT_DEFAULT:
875           *dest_value = gst_util_uint64_scale (src_value,
876               avstream->avg_frame_rate.num,
877               GST_SECOND * avstream->avg_frame_rate.den);
878           break;
879         default:
880           res = FALSE;
881           break;
882       }
883       break;
884     case GST_FORMAT_DEFAULT:
885       switch (*dest_fmt) {
886         case GST_FORMAT_TIME:
887           *dest_value = gst_util_uint64_scale (src_value,
888               GST_SECOND * avstream->avg_frame_rate.num,
889               avstream->avg_frame_rate.den);
890           break;
891         default:
892           res = FALSE;
893           break;
894       }
895       break;
896     default:
897       res = FALSE;
898       break;
899   }
900
901   return res;
902 }
903 #endif
904
905 static gchar *
906 gst_ffmpegdemux_create_padname (const gchar * templ, gint n)
907 {
908   GString *string;
909
910   /* FIXME, we just want to printf the number according to the template but
911    * then the format string is not a literal and we can't check arguments and
912    * this generates a compiler error */
913   string = g_string_new (templ);
914   g_string_truncate (string, string->len - 2);
915   g_string_append_printf (string, "%u", n);
916
917   return g_string_free (string, FALSE);
918 }
919
920 static GstFFStream *
921 gst_ffmpegdemux_get_stream (GstFFMpegDemux * demux, AVStream * avstream)
922 {
923   GstFFMpegDemuxClass *oclass;
924   GstPadTemplate *templ = NULL;
925   GstPad *pad;
926   GstCaps *caps;
927   gint num;
928   gchar *padname;
929   const gchar *codec;
930   AVCodecContext *ctx = NULL;
931   GstFFStream *stream;
932   GstEvent *event;
933   gchar *stream_id;
934
935   oclass = (GstFFMpegDemuxClass *) G_OBJECT_GET_CLASS (demux);
936
937   if (demux->streams[avstream->index] != NULL)
938     goto exists;
939
940   ctx = avcodec_alloc_context3 (NULL);
941   avcodec_parameters_to_context (ctx, avstream->codecpar);
942
943   /* create new stream */
944   stream = g_new0 (GstFFStream, 1);
945   demux->streams[avstream->index] = stream;
946
947   /* mark stream as unknown */
948   stream->unknown = TRUE;
949   stream->discont = TRUE;
950   stream->avstream = avstream;
951   stream->last_ts = GST_CLOCK_TIME_NONE;
952   stream->tags = NULL;
953
954   switch (ctx->codec_type) {
955     case AVMEDIA_TYPE_VIDEO:
956       templ = oclass->videosrctempl;
957       num = demux->videopads++;
958       /* These are not part of the codec parameters we built the
959        * context from */
960       ctx->framerate.num = avstream->r_frame_rate.num;
961       ctx->framerate.den = avstream->r_frame_rate.den;
962       break;
963     case AVMEDIA_TYPE_AUDIO:
964       templ = oclass->audiosrctempl;
965       num = demux->audiopads++;
966       break;
967     default:
968       goto unknown_type;
969   }
970
971   /* get caps that belongs to this stream */
972   caps = gst_ffmpeg_codecid_to_caps (ctx->codec_id, ctx, TRUE);
973   if (caps == NULL)
974     goto unknown_caps;
975
976   /* stream is known now */
977   stream->unknown = FALSE;
978
979   /* create new pad for this stream */
980   padname =
981       gst_ffmpegdemux_create_padname (GST_PAD_TEMPLATE_NAME_TEMPLATE (templ),
982       num);
983   pad = gst_pad_new_from_template (templ, padname);
984   g_free (padname);
985
986   gst_pad_use_fixed_caps (pad);
987   gst_pad_set_active (pad, TRUE);
988
989   gst_pad_set_query_function (pad, gst_ffmpegdemux_src_query);
990   gst_pad_set_event_function (pad, gst_ffmpegdemux_src_event);
991
992   /* store pad internally */
993   stream->pad = pad;
994   gst_pad_set_element_private (pad, stream);
995
996   /* transform some useful info to GstClockTime and remember */
997   {
998     GstClockTime tmp;
999
1000     /* FIXME, actually use the start_time in some way */
1001     tmp = gst_ffmpeg_time_ff_to_gst (avstream->start_time, avstream->time_base);
1002     GST_DEBUG_OBJECT (demux, "stream %d: start time: %" GST_TIME_FORMAT,
1003         avstream->index, GST_TIME_ARGS (tmp));
1004
1005     tmp = gst_ffmpeg_time_ff_to_gst (avstream->duration, avstream->time_base);
1006     GST_DEBUG_OBJECT (demux, "stream %d: duration: %" GST_TIME_FORMAT,
1007         avstream->index, GST_TIME_ARGS (tmp));
1008   }
1009
1010   demux->streams[avstream->index] = stream;
1011
1012
1013   stream_id =
1014       gst_pad_create_stream_id_printf (pad, GST_ELEMENT_CAST (demux), "%03u",
1015       avstream->index);
1016
1017   event = gst_pad_get_sticky_event (demux->sinkpad, GST_EVENT_STREAM_START, 0);
1018   if (event) {
1019     if (gst_event_parse_group_id (event, &demux->group_id))
1020       demux->have_group_id = TRUE;
1021     else
1022       demux->have_group_id = FALSE;
1023     gst_event_unref (event);
1024   } else if (!demux->have_group_id) {
1025     demux->have_group_id = TRUE;
1026     demux->group_id = gst_util_group_id_next ();
1027   }
1028   event = gst_event_new_stream_start (stream_id);
1029   if (demux->have_group_id)
1030     gst_event_set_group_id (event, demux->group_id);
1031
1032   gst_pad_push_event (pad, event);
1033   g_free (stream_id);
1034
1035   GST_INFO_OBJECT (pad, "adding pad with caps %" GST_PTR_FORMAT, caps);
1036   gst_pad_set_caps (pad, caps);
1037   gst_caps_unref (caps);
1038
1039   /* activate and add */
1040   gst_element_add_pad (GST_ELEMENT (demux), pad);
1041   gst_flow_combiner_add_pad (demux->flowcombiner, pad);
1042
1043   /* metadata */
1044   if ((codec = gst_ffmpeg_get_codecid_longname (ctx->codec_id))) {
1045     stream->tags = gst_ffmpeg_metadata_to_tag_list (avstream->metadata);
1046
1047     if (stream->tags == NULL)
1048       stream->tags = gst_tag_list_new_empty ();
1049
1050     gst_tag_list_add (stream->tags, GST_TAG_MERGE_REPLACE,
1051         (ctx->codec_type == AVMEDIA_TYPE_VIDEO) ?
1052         GST_TAG_VIDEO_CODEC : GST_TAG_AUDIO_CODEC, codec, NULL);
1053   }
1054
1055 done:
1056   if (ctx)
1057     avcodec_free_context (&ctx);
1058   return stream;
1059
1060   /* ERRORS */
1061 exists:
1062   {
1063     GST_DEBUG_OBJECT (demux, "Pad existed (stream %d)", avstream->index);
1064     stream = demux->streams[avstream->index];
1065     goto done;
1066   }
1067 unknown_type:
1068   {
1069     GST_WARNING_OBJECT (demux, "Unknown pad type %d", ctx->codec_type);
1070     goto done;
1071   }
1072 unknown_caps:
1073   {
1074     GST_WARNING_OBJECT (demux, "Unknown caps for codec %d", ctx->codec_id);
1075     goto done;
1076   }
1077 }
1078
1079 static gchar *
1080 safe_utf8_copy (gchar * input)
1081 {
1082   gchar *output;
1083
1084   if (!(g_utf8_validate (input, -1, NULL))) {
1085     output = g_convert (input, strlen (input),
1086         "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
1087   } else {
1088     output = g_strdup (input);
1089   }
1090
1091   return output;
1092 }
1093
1094 /* This is a list of standard tag keys taken from the avformat.h
1095  * header, without handling any variants. */
1096 static const struct
1097 {
1098   const gchar *ffmpeg_tag_name;
1099   const gchar *gst_tag_name;
1100 } tagmapping[] = {
1101   {
1102   "album", GST_TAG_ALBUM}, {
1103   "album_artist", GST_TAG_ALBUM_ARTIST}, {
1104   "artist", GST_TAG_ARTIST}, {
1105   "comment", GST_TAG_COMMENT}, {
1106   "composer", GST_TAG_COMPOSER}, {
1107   "copyright", GST_TAG_COPYRIGHT},
1108       /* Need to convert ISO 8601 to GstDateTime: */
1109   {
1110   "creation_time", GST_TAG_DATE_TIME},
1111       /* Need to convert ISO 8601 to GDateTime: */
1112   {
1113   "date", GST_TAG_DATE_TIME}, {
1114   "disc", GST_TAG_ALBUM_VOLUME_NUMBER}, {
1115   "encoder", GST_TAG_ENCODER}, {
1116   "encoded_by", GST_TAG_ENCODED_BY}, {
1117   "genre", GST_TAG_GENRE}, {
1118   "language", GST_TAG_LANGUAGE_CODE}, {
1119   "performer", GST_TAG_PERFORMER}, {
1120   "publisher", GST_TAG_PUBLISHER}, {
1121   "title", GST_TAG_TITLE}, {
1122   "track", GST_TAG_TRACK_NUMBER}
1123 };
1124
1125 static const gchar *
1126 match_tag_name (gchar * ffmpeg_tag_name)
1127 {
1128   gint i;
1129   for (i = 0; i < G_N_ELEMENTS (tagmapping); i++) {
1130     if (!g_strcmp0 (tagmapping[i].ffmpeg_tag_name, ffmpeg_tag_name))
1131       return tagmapping[i].gst_tag_name;
1132   }
1133   return NULL;
1134 }
1135
1136 static GstTagList *
1137 gst_ffmpeg_metadata_to_tag_list (AVDictionary * metadata)
1138 {
1139   AVDictionaryEntry *tag = NULL;
1140   GstTagList *list;
1141   list = gst_tag_list_new_empty ();
1142
1143   while ((tag = av_dict_get (metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
1144     const gchar *gsttag = match_tag_name (tag->key);
1145     GType t;
1146     GST_LOG ("mapping tag %s=%s\n", tag->key, tag->value);
1147     if (gsttag == NULL) {
1148       GST_LOG ("Ignoring unknown metadata tag %s", tag->key);
1149       continue;
1150     }
1151     /* Special case, track and disc numbers may be x/n in libav, split
1152      * them */
1153     if (g_str_equal (gsttag, GST_TAG_TRACK_NUMBER)) {
1154       guint track, trackcount;
1155       if (sscanf (tag->value, "%u/%u", &track, &trackcount) == 2) {
1156         gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1157             gsttag, track, GST_TAG_TRACK_COUNT, trackcount, NULL);
1158         continue;
1159       }
1160       /* Fall through and handle as a single uint below */
1161     } else if (g_str_equal (gsttag, GST_TAG_ALBUM_VOLUME_NUMBER)) {
1162       guint disc, disc_count;
1163       if (sscanf (tag->value, "%u/%u", &disc, &disc_count) == 2) {
1164         gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1165             gsttag, disc, GST_TAG_ALBUM_VOLUME_COUNT, disc_count, NULL);
1166         continue;
1167       }
1168       /* Fall through and handle as a single uint below */
1169     }
1170
1171     t = gst_tag_get_type (gsttag);
1172     if (t == G_TYPE_STRING) {
1173       gchar *s = safe_utf8_copy (tag->value);
1174       gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, gsttag, s, NULL);
1175       g_free (s);
1176     } else if (t == G_TYPE_UINT || t == G_TYPE_INT) {
1177       gchar *end;
1178       gint v = strtol (tag->value, &end, 10);
1179       if (end == tag->value)
1180         continue;               /* Failed to parse */
1181       gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, gsttag, v, NULL);
1182     } else if (t == G_TYPE_DATE) {
1183       guint year, month, day;
1184       GDate *date = NULL;
1185       if (sscanf (tag->value, "%04u-%02u-%02u", &year, &month, &day) == 3) {
1186         date = g_date_new_dmy (day, month, year);
1187       } else {
1188         /* Try interpreting just as a year */
1189         gchar *end;
1190
1191         year = strtol (tag->value, &end, 10);
1192         if (end != tag->value)
1193           date = g_date_new_dmy (1, 1, year);
1194       }
1195       if (date) {
1196         gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, gsttag, date, NULL);
1197         g_date_free (date);
1198       }
1199     } else if (t == GST_TYPE_DATE_TIME) {
1200       gchar *s = safe_utf8_copy (tag->value);
1201       GstDateTime *d = gst_date_time_new_from_iso8601_string (s);
1202
1203       g_free (s);
1204       if (d) {
1205         gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, gsttag, d, NULL);
1206         gst_date_time_unref (d);
1207       }
1208     } else {
1209       GST_FIXME ("Unhandled tag %s", gsttag);
1210     }
1211   }
1212
1213   if (gst_tag_list_is_empty (list)) {
1214     gst_tag_list_unref (list);
1215     return NULL;
1216   }
1217
1218   return list;
1219 }
1220
1221 static gboolean
1222 gst_ffmpegdemux_open (GstFFMpegDemux * demux)
1223 {
1224   AVIOContext *iocontext = NULL;
1225   GstFFMpegDemuxClass *oclass =
1226       (GstFFMpegDemuxClass *) G_OBJECT_GET_CLASS (demux);
1227   gint res, n_streams, i;
1228   GstTagList *tags;
1229   GstEvent *event;
1230   GList *cached_events;
1231   GstQuery *query;
1232   gchar *uri = NULL;
1233
1234   /* to be sure... */
1235   gst_ffmpegdemux_close (demux);
1236
1237   /* open via our input protocol hack */
1238   if (demux->seekable)
1239     res = gst_ffmpegdata_open (demux->sinkpad, AVIO_FLAG_READ, &iocontext);
1240   else
1241     res = gst_ffmpeg_pipe_open (&demux->ffpipe, AVIO_FLAG_READ, &iocontext);
1242
1243   if (res < 0)
1244     goto beach;
1245
1246   query = gst_query_new_uri ();
1247   if (gst_pad_peer_query (demux->sinkpad, query)) {
1248     gchar *query_uri, *redirect_uri;
1249     gboolean permanent;
1250
1251     gst_query_parse_uri (query, &query_uri);
1252     gst_query_parse_uri_redirection (query, &redirect_uri);
1253     gst_query_parse_uri_redirection_permanent (query, &permanent);
1254
1255     if (permanent && redirect_uri) {
1256       uri = redirect_uri;
1257       g_free (query_uri);
1258     } else {
1259       uri = query_uri;
1260       g_free (redirect_uri);
1261     }
1262   }
1263   gst_query_unref (query);
1264
1265   GST_DEBUG_OBJECT (demux, "Opening context with URI %s", GST_STR_NULL (uri));
1266
1267   demux->context = avformat_alloc_context ();
1268   demux->context->pb = iocontext;
1269   res = avformat_open_input (&demux->context, uri, oclass->in_plugin, NULL);
1270
1271   g_free (uri);
1272
1273   GST_DEBUG_OBJECT (demux, "av_open_input returned %d", res);
1274   if (res < 0)
1275     goto beach;
1276
1277   res = gst_ffmpeg_av_find_stream_info (demux->context);
1278   GST_DEBUG_OBJECT (demux, "av_find_stream_info returned %d", res);
1279   if (res < 0)
1280     goto beach;
1281
1282   n_streams = demux->context->nb_streams;
1283   GST_DEBUG_OBJECT (demux, "we have %d streams", n_streams);
1284
1285   /* open_input_file() automatically reads the header. We can now map each
1286    * created AVStream to a GstPad to make GStreamer handle it. */
1287   for (i = 0; i < n_streams; i++) {
1288     gst_ffmpegdemux_get_stream (demux, demux->context->streams[i]);
1289   }
1290
1291   gst_element_no_more_pads (GST_ELEMENT (demux));
1292
1293   /* transform some useful info to GstClockTime and remember */
1294   demux->start_time = gst_util_uint64_scale_int (demux->context->start_time,
1295       GST_SECOND, AV_TIME_BASE);
1296   GST_DEBUG_OBJECT (demux, "start time: %" GST_TIME_FORMAT,
1297       GST_TIME_ARGS (demux->start_time));
1298   if (demux->context->duration > 0)
1299     demux->duration = gst_util_uint64_scale_int (demux->context->duration,
1300         GST_SECOND, AV_TIME_BASE);
1301   else
1302     demux->duration = GST_CLOCK_TIME_NONE;
1303
1304   GST_DEBUG_OBJECT (demux, "duration: %" GST_TIME_FORMAT,
1305       GST_TIME_ARGS (demux->duration));
1306
1307   /* store duration in the segment as well */
1308   demux->segment.duration = demux->duration;
1309
1310   GST_OBJECT_LOCK (demux);
1311   demux->opened = TRUE;
1312   event = demux->seek_event;
1313   demux->seek_event = NULL;
1314   cached_events = demux->cached_events;
1315   demux->cached_events = NULL;
1316   GST_OBJECT_UNLOCK (demux);
1317
1318   if (event) {
1319     gst_ffmpegdemux_perform_seek (demux, event);
1320     gst_event_unref (event);
1321   } else {
1322     GST_DEBUG_OBJECT (demux, "Sending segment %" GST_SEGMENT_FORMAT,
1323         &demux->segment);
1324     gst_ffmpegdemux_push_event (demux, gst_event_new_segment (&demux->segment));
1325   }
1326
1327   while (cached_events) {
1328     event = cached_events->data;
1329     GST_INFO_OBJECT (demux, "pushing cached event: %" GST_PTR_FORMAT, event);
1330     gst_ffmpegdemux_push_event (demux, event);
1331     cached_events = g_list_delete_link (cached_events, cached_events);
1332   }
1333
1334   /* grab the global tags */
1335   tags = gst_ffmpeg_metadata_to_tag_list (demux->context->metadata);
1336   if (tags) {
1337     GST_INFO_OBJECT (demux, "global tags: %" GST_PTR_FORMAT, tags);
1338   }
1339
1340   /* now handle the stream tags */
1341   for (i = 0; i < n_streams; i++) {
1342     GstFFStream *stream;
1343
1344     stream = gst_ffmpegdemux_get_stream (demux, demux->context->streams[i]);
1345     if (stream->pad != NULL) {
1346
1347       /* Global tags */
1348       if (tags)
1349         gst_pad_push_event (stream->pad,
1350             gst_event_new_tag (gst_tag_list_ref (tags)));
1351
1352       /* Per-stream tags */
1353       if (stream->tags != NULL) {
1354         GST_INFO_OBJECT (stream->pad, "stream tags: %" GST_PTR_FORMAT,
1355             stream->tags);
1356         gst_pad_push_event (stream->pad,
1357             gst_event_new_tag (gst_tag_list_ref (stream->tags)));
1358       }
1359     }
1360   }
1361   if (tags)
1362     gst_tag_list_unref (tags);
1363   return TRUE;
1364
1365   /* ERRORS */
1366 beach:
1367   {
1368     GST_ELEMENT_ERROR (demux, LIBRARY, FAILED, (NULL),
1369         ("%s", gst_ffmpegdemux_averror (res)));
1370     return FALSE;
1371   }
1372 }
1373
1374 #define GST_FFMPEG_TYPE_FIND_SIZE 4096
1375 #define GST_FFMPEG_TYPE_FIND_MIN_SIZE 256
1376
1377 static void
1378 gst_ffmpegdemux_type_find (GstTypeFind * tf, gpointer priv)
1379 {
1380   const guint8 *data;
1381   AVInputFormat *in_plugin = (AVInputFormat *) priv;
1382   gint res = 0;
1383   guint64 length;
1384   GstCaps *sinkcaps;
1385
1386   /* We want GST_FFMPEG_TYPE_FIND_SIZE bytes, but if the file is shorter than
1387    * that we'll give it a try... */
1388   length = gst_type_find_get_length (tf);
1389   if (length == 0 || length > GST_FFMPEG_TYPE_FIND_SIZE)
1390     length = GST_FFMPEG_TYPE_FIND_SIZE;
1391
1392   /* The ffmpeg typefinders assume there's a certain minimum amount of data
1393    * and will happily do invalid memory access if there isn't, so let's just
1394    * skip the ffmpeg typefinders if the data available is too short
1395    * (in which case it's unlikely to be a media file anyway) */
1396   if (length < GST_FFMPEG_TYPE_FIND_MIN_SIZE) {
1397     GST_LOG ("not typefinding %" G_GUINT64_FORMAT " bytes, too short", length);
1398     return;
1399   }
1400
1401   GST_LOG ("typefinding %" G_GUINT64_FORMAT " bytes", length);
1402   if (in_plugin->read_probe &&
1403       (data = gst_type_find_peek (tf, 0, length)) != NULL) {
1404     AVProbeData probe_data;
1405
1406     probe_data.filename = "";
1407     probe_data.buf = (guint8 *) data;
1408     probe_data.buf_size = length;
1409
1410     res = in_plugin->read_probe (&probe_data);
1411     if (res > 0) {
1412       res = MAX (1, res * GST_TYPE_FIND_MAXIMUM / AVPROBE_SCORE_MAX);
1413       /* Restrict the probability for MPEG-TS streams, because there is
1414        * probably a better version in plugins-base, if the user has a recent
1415        * plugins-base (in fact we shouldn't even get here for ffmpeg mpegts or
1416        * mpegtsraw typefinders, since we blacklist them) */
1417       if (g_str_has_prefix (in_plugin->name, "mpegts"))
1418         res = MIN (res, GST_TYPE_FIND_POSSIBLE);
1419
1420       sinkcaps = gst_ffmpeg_formatid_to_caps (in_plugin->name);
1421
1422       GST_LOG ("libav typefinder '%s' suggests %" GST_PTR_FORMAT ", p=%u%%",
1423           in_plugin->name, sinkcaps, res);
1424
1425       gst_type_find_suggest (tf, res, sinkcaps);
1426       gst_caps_unref (sinkcaps);
1427     }
1428   }
1429 }
1430
1431 /* Task */
1432 static void
1433 gst_ffmpegdemux_loop (GstFFMpegDemux * demux)
1434 {
1435   GstFlowReturn ret;
1436   gint res = -1;
1437   AVPacket pkt;
1438   GstPad *srcpad;
1439   GstFFStream *stream;
1440   AVStream *avstream;
1441   GstBuffer *outbuf = NULL;
1442   GstClockTime timestamp, duration;
1443   gint outsize;
1444   gboolean rawvideo;
1445   GstFlowReturn stream_last_flow;
1446   gint64 pts;
1447
1448   /* open file if we didn't so already */
1449   if (!demux->opened)
1450     if (!gst_ffmpegdemux_open (demux))
1451       goto open_failed;
1452
1453   GST_DEBUG_OBJECT (demux, "about to read a frame");
1454
1455   /* read a frame */
1456   res = av_read_frame (demux->context, &pkt);
1457   if (res < 0)
1458     goto read_failed;
1459
1460   /* get the stream */
1461   stream =
1462       gst_ffmpegdemux_get_stream (demux,
1463       demux->context->streams[pkt.stream_index]);
1464
1465   /* check if we know the stream */
1466   if (stream->unknown)
1467     goto done;
1468
1469   /* get more stuff belonging to this stream */
1470   avstream = stream->avstream;
1471
1472   /* do timestamps, we do this first so that we can know when we
1473    * stepped over the segment stop position. */
1474   pts = pkt.pts;
1475   if (G_UNLIKELY (pts < 0)) {
1476     /* some streams have pts such this:
1477      * 0
1478      * -2
1479      * -1
1480      * 1
1481      *
1482      * we reset pts to 0 since for us timestamp are unsigned
1483      */
1484     GST_WARNING_OBJECT (demux,
1485         "negative pts detected: %" G_GINT64_FORMAT " resetting to 0", pts);
1486     pts = 0;
1487   }
1488   timestamp = gst_ffmpeg_time_ff_to_gst (pts, avstream->time_base);
1489   if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
1490     stream->last_ts = timestamp;
1491   }
1492   duration = gst_ffmpeg_time_ff_to_gst (pkt.duration, avstream->time_base);
1493   if (G_UNLIKELY (!duration)) {
1494     GST_WARNING_OBJECT (demux, "invalid buffer duration, setting to NONE");
1495     duration = GST_CLOCK_TIME_NONE;
1496   }
1497
1498
1499   GST_DEBUG_OBJECT (demux,
1500       "pkt pts:%" GST_TIME_FORMAT
1501       " / size:%d / stream_index:%d / flags:%d / duration:%" GST_TIME_FORMAT
1502       " / pos:%" G_GINT64_FORMAT, GST_TIME_ARGS (timestamp), pkt.size,
1503       pkt.stream_index, pkt.flags, GST_TIME_ARGS (duration), (gint64) pkt.pos);
1504
1505   /* check start_time */
1506 #if 0
1507   if (demux->start_time != -1 && demux->start_time > timestamp)
1508     goto drop;
1509 #endif
1510
1511   if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
1512     /* start_time should be the ts of the first frame but it may actually be
1513      * higher because of rounding when converting to gst ts. */
1514     if (demux->start_time >= timestamp)
1515       timestamp = 0;
1516     else
1517       timestamp -= demux->start_time;
1518   }
1519
1520   /* check if we ran outside of the segment */
1521   if (demux->segment.stop != -1 && timestamp > demux->segment.stop)
1522     goto drop;
1523
1524   /* prepare to push packet to peer */
1525   srcpad = stream->pad;
1526
1527   rawvideo = (avstream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
1528       avstream->codecpar->codec_id == AV_CODEC_ID_RAWVIDEO);
1529
1530   if (rawvideo)
1531     outsize = gst_ffmpeg_avpicture_get_size (avstream->codecpar->format,
1532         avstream->codecpar->width, avstream->codecpar->height);
1533   else
1534     outsize = pkt.size;
1535
1536   outbuf = gst_buffer_new_and_alloc (outsize);
1537
1538   /* copy the data from packet into the target buffer
1539    * and do conversions for raw video packets */
1540   if (rawvideo) {
1541     AVFrame src, dst;
1542     const gchar *plugin_name =
1543         ((GstFFMpegDemuxClass *) (G_OBJECT_GET_CLASS (demux)))->in_plugin->name;
1544     GstMapInfo map;
1545
1546     GST_WARNING ("Unknown demuxer %s, no idea what to do", plugin_name);
1547     gst_ffmpeg_avpicture_fill (&src, pkt.data,
1548         avstream->codecpar->format, avstream->codecpar->width,
1549         avstream->codecpar->height);
1550
1551     gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
1552     gst_ffmpeg_avpicture_fill (&dst, map.data,
1553         avstream->codecpar->format, avstream->codecpar->width,
1554         avstream->codecpar->height);
1555
1556     av_image_copy (dst.data, dst.linesize, (const uint8_t **) src.data,
1557         src.linesize, avstream->codecpar->format, avstream->codecpar->width,
1558         avstream->codecpar->height);
1559     gst_buffer_unmap (outbuf, &map);
1560   } else {
1561     gst_buffer_fill (outbuf, 0, pkt.data, outsize);
1562   }
1563
1564   GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
1565   GST_BUFFER_DURATION (outbuf) = duration;
1566
1567   /* mark keyframes */
1568   if (!(pkt.flags & AV_PKT_FLAG_KEY)) {
1569     GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
1570   }
1571
1572   /* Mark discont */
1573   if (stream->discont) {
1574     GST_DEBUG_OBJECT (demux, "marking DISCONT");
1575     GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
1576     stream->discont = FALSE;
1577   }
1578
1579   GST_DEBUG_OBJECT (demux,
1580       "Sending out buffer time:%" GST_TIME_FORMAT " size:%" G_GSIZE_FORMAT,
1581       GST_TIME_ARGS (timestamp), gst_buffer_get_size (outbuf));
1582
1583   ret = stream_last_flow = gst_pad_push (srcpad, outbuf);
1584
1585   /* if a pad is in e.g. WRONG_STATE, we want to pause to unlock the STREAM_LOCK */
1586   if (((ret = gst_flow_combiner_update_flow (demux->flowcombiner,
1587                   ret)) != GST_FLOW_OK)) {
1588     GST_WARNING_OBJECT (demux, "stream_movi flow: %s / %s",
1589         gst_flow_get_name (stream_last_flow), gst_flow_get_name (ret));
1590     goto pause;
1591   }
1592
1593 done:
1594   /* can destroy the packet now */
1595   if (res == 0) {
1596     av_packet_unref (&pkt);
1597   }
1598
1599   return;
1600
1601   /* ERRORS */
1602 pause:
1603   {
1604     GST_LOG_OBJECT (demux, "pausing task, reason %d (%s)", ret,
1605         gst_flow_get_name (ret));
1606     if (demux->seekable)
1607       gst_pad_pause_task (demux->sinkpad);
1608     else {
1609       GstFFMpegPipe *ffpipe = &demux->ffpipe;
1610
1611       GST_FFMPEG_PIPE_MUTEX_LOCK (ffpipe);
1612       /* pause task and make sure loop stops */
1613       gst_task_pause (demux->task);
1614       g_rec_mutex_lock (&demux->task_lock);
1615       g_rec_mutex_unlock (&demux->task_lock);
1616       demux->ffpipe.srcresult = ret;
1617       GST_FFMPEG_PIPE_MUTEX_UNLOCK (ffpipe);
1618     }
1619
1620     if (ret == GST_FLOW_EOS) {
1621       if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
1622         gint64 stop;
1623
1624         if ((stop = demux->segment.stop) == -1)
1625           stop = demux->segment.duration;
1626
1627         GST_LOG_OBJECT (demux, "posting segment done");
1628         gst_element_post_message (GST_ELEMENT (demux),
1629             gst_message_new_segment_done (GST_OBJECT (demux),
1630                 demux->segment.format, stop));
1631         gst_ffmpegdemux_push_event (demux,
1632             gst_event_new_segment_done (demux->segment.format, stop));
1633       } else {
1634         GST_LOG_OBJECT (demux, "pushing eos");
1635         gst_ffmpegdemux_push_event (demux, gst_event_new_eos ());
1636       }
1637     } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
1638       GST_ELEMENT_FLOW_ERROR (demux, ret);
1639       gst_ffmpegdemux_push_event (demux, gst_event_new_eos ());
1640     }
1641     goto done;
1642   }
1643 open_failed:
1644   {
1645     ret = GST_FLOW_ERROR;
1646     goto pause;
1647   }
1648 read_failed:
1649   {
1650     /* something went wrong... */
1651     GST_WARNING_OBJECT (demux, "av_read_frame returned %d", res);
1652
1653     GST_OBJECT_LOCK (demux);
1654     /* pause appropriatly based on if we are flushing or not */
1655     if (demux->flushing)
1656       ret = GST_FLOW_FLUSHING;
1657     else if (gst_ffmpegdemux_has_outputted (demux)
1658         || gst_ffmpegdemux_is_eos (demux)) {
1659       GST_DEBUG_OBJECT (demux, "We are EOS");
1660       ret = GST_FLOW_EOS;
1661     } else
1662       ret = GST_FLOW_ERROR;
1663     GST_OBJECT_UNLOCK (demux);
1664
1665     goto pause;
1666   }
1667 drop:
1668   {
1669     GST_DEBUG_OBJECT (demux, "dropping buffer out of segment, stream eos");
1670     stream->eos = TRUE;
1671     if (gst_ffmpegdemux_is_eos (demux)) {
1672       av_packet_unref (&pkt);
1673       GST_DEBUG_OBJECT (demux, "we are eos");
1674       ret = GST_FLOW_EOS;
1675       goto pause;
1676     } else {
1677       GST_DEBUG_OBJECT (demux, "some streams are not yet eos");
1678       goto done;
1679     }
1680   }
1681 }
1682
1683
1684 static gboolean
1685 gst_ffmpegdemux_sink_event (GstPad * sinkpad, GstObject * parent,
1686     GstEvent * event)
1687 {
1688   GstFFMpegDemux *demux;
1689   GstFFMpegPipe *ffpipe;
1690   gboolean result = TRUE;
1691
1692   demux = (GstFFMpegDemux *) parent;
1693   ffpipe = &(demux->ffpipe);
1694
1695   GST_LOG_OBJECT (demux, "event: %" GST_PTR_FORMAT, event);
1696
1697   switch (GST_EVENT_TYPE (event)) {
1698     case GST_EVENT_FLUSH_START:
1699       /* forward event */
1700       gst_pad_event_default (sinkpad, parent, event);
1701
1702       /* now unblock the chain function */
1703       GST_FFMPEG_PIPE_MUTEX_LOCK (ffpipe);
1704       ffpipe->srcresult = GST_FLOW_FLUSHING;
1705       GST_FFMPEG_PIPE_SIGNAL (ffpipe);
1706       GST_FFMPEG_PIPE_MUTEX_UNLOCK (ffpipe);
1707
1708       /* loop might run into WRONG_STATE and end itself,
1709        * but may also be waiting in a ffmpeg read
1710        * trying to break that would make ffmpeg believe eos,
1711        * so no harm to have the loop 'pausing' there ... */
1712       goto done;
1713     case GST_EVENT_FLUSH_STOP:
1714       /* forward event */
1715       gst_pad_event_default (sinkpad, parent, event);
1716
1717       GST_OBJECT_LOCK (demux);
1718       g_list_foreach (demux->cached_events, (GFunc) gst_mini_object_unref,
1719           NULL);
1720       g_list_free (demux->cached_events);
1721       GST_OBJECT_UNLOCK (demux);
1722       GST_FFMPEG_PIPE_MUTEX_LOCK (ffpipe);
1723       gst_adapter_clear (ffpipe->adapter);
1724       ffpipe->srcresult = GST_FLOW_OK;
1725       /* loop may have decided to end itself as a result of flush WRONG_STATE */
1726       gst_task_start (demux->task);
1727       demux->flushing = FALSE;
1728       GST_LOG_OBJECT (demux, "loop started");
1729       GST_FFMPEG_PIPE_MUTEX_UNLOCK (ffpipe);
1730       goto done;
1731     case GST_EVENT_EOS:
1732       /* inform the src task that it can stop now */
1733       GST_FFMPEG_PIPE_MUTEX_LOCK (ffpipe);
1734       ffpipe->eos = TRUE;
1735       GST_FFMPEG_PIPE_SIGNAL (ffpipe);
1736       GST_FFMPEG_PIPE_MUTEX_UNLOCK (ffpipe);
1737
1738       /* eat this event for now, task will send eos when finished */
1739       gst_event_unref (event);
1740       goto done;
1741     case GST_EVENT_STREAM_START:
1742     case GST_EVENT_CAPS:
1743     case GST_EVENT_SEGMENT:
1744       GST_LOG_OBJECT (demux, "dropping %s event", GST_EVENT_TYPE_NAME (event));
1745       gst_event_unref (event);
1746       goto done;
1747     default:
1748       /* for a serialized event, wait until an earlier data is gone,
1749        * though this is no guarantee as to when task is done with it.
1750        *
1751        * If the demuxer isn't opened, push straight away, since we'll
1752        * be waiting against a cond that will never be signalled. */
1753       if (GST_EVENT_IS_SERIALIZED (event)) {
1754         if (demux->opened) {
1755           GST_FFMPEG_PIPE_MUTEX_LOCK (ffpipe);
1756           while (!ffpipe->needed)
1757             GST_FFMPEG_PIPE_WAIT (ffpipe);
1758           GST_FFMPEG_PIPE_MUTEX_UNLOCK (ffpipe);
1759         } else {
1760           /* queue events and send them later (esp. tag events) */
1761           GST_OBJECT_LOCK (demux);
1762           demux->cached_events = g_list_append (demux->cached_events, event);
1763           GST_OBJECT_UNLOCK (demux);
1764           goto done;
1765         }
1766       }
1767       break;
1768   }
1769
1770   result = gst_pad_event_default (sinkpad, parent, event);
1771
1772 done:
1773
1774   return result;
1775 }
1776
1777 static GstFlowReturn
1778 gst_ffmpegdemux_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * buffer)
1779 {
1780   GstFFMpegDemux *demux;
1781   GstFFMpegPipe *ffpipe;
1782
1783   demux = (GstFFMpegDemux *) parent;
1784   ffpipe = &demux->ffpipe;
1785
1786   GST_FFMPEG_PIPE_MUTEX_LOCK (ffpipe);
1787
1788   if (G_UNLIKELY (ffpipe->eos))
1789     goto eos;
1790
1791   if (G_UNLIKELY (ffpipe->srcresult != GST_FLOW_OK))
1792     goto ignore;
1793
1794   GST_DEBUG ("Giving a buffer of %" G_GSIZE_FORMAT " bytes",
1795       gst_buffer_get_size (buffer));
1796   gst_adapter_push (ffpipe->adapter, buffer);
1797   buffer = NULL;
1798   while (gst_adapter_available (ffpipe->adapter) >= ffpipe->needed) {
1799     GST_DEBUG ("Adapter has more that requested (ffpipe->needed:%d)",
1800         ffpipe->needed);
1801     GST_FFMPEG_PIPE_SIGNAL (ffpipe);
1802     GST_FFMPEG_PIPE_WAIT (ffpipe);
1803     /* may have become flushing */
1804     if (G_UNLIKELY (ffpipe->srcresult != GST_FLOW_OK))
1805       goto ignore;
1806   }
1807
1808   GST_FFMPEG_PIPE_MUTEX_UNLOCK (ffpipe);
1809
1810   return GST_FLOW_OK;
1811
1812 /* special cases */
1813 eos:
1814   {
1815     GST_DEBUG_OBJECT (demux, "ignoring buffer at end-of-stream");
1816     GST_FFMPEG_PIPE_MUTEX_UNLOCK (ffpipe);
1817
1818     gst_buffer_unref (buffer);
1819     return GST_FLOW_EOS;
1820   }
1821 ignore:
1822   {
1823     GST_DEBUG_OBJECT (demux, "ignoring buffer because src task encountered %s",
1824         gst_flow_get_name (ffpipe->srcresult));
1825     GST_FFMPEG_PIPE_MUTEX_UNLOCK (ffpipe);
1826
1827     if (buffer)
1828       gst_buffer_unref (buffer);
1829     return GST_FLOW_FLUSHING;
1830   }
1831 }
1832
1833 static gboolean
1834 gst_ffmpegdemux_sink_activate (GstPad * sinkpad, GstObject * parent)
1835 {
1836   GstQuery *query;
1837   gboolean pull_mode;
1838   GstSchedulingFlags flags;
1839
1840   query = gst_query_new_scheduling ();
1841
1842   if (!gst_pad_peer_query (sinkpad, query)) {
1843     gst_query_unref (query);
1844     goto activate_push;
1845   }
1846
1847   pull_mode = gst_query_has_scheduling_mode_with_flags (query,
1848       GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
1849
1850   gst_query_parse_scheduling (query, &flags, NULL, NULL, NULL);
1851   if (flags & GST_SCHEDULING_FLAG_SEQUENTIAL)
1852     pull_mode = FALSE;
1853
1854   gst_query_unref (query);
1855
1856   if (!pull_mode)
1857     goto activate_push;
1858
1859   GST_DEBUG_OBJECT (sinkpad, "activating pull");
1860   return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
1861
1862 activate_push:
1863   {
1864     GST_DEBUG_OBJECT (sinkpad, "activating push");
1865     return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
1866   }
1867 }
1868
1869 /* push mode:
1870  * - not seekable
1871  * - use gstpipe protocol, like ffmpeg's pipe protocol
1872  * - (independently managed) task driving ffmpeg
1873  */
1874 static gboolean
1875 gst_ffmpegdemux_sink_activate_push (GstPad * sinkpad, GstObject * parent,
1876     gboolean active)
1877 {
1878   GstFFMpegDemux *demux;
1879   gboolean res = FALSE;
1880
1881   demux = (GstFFMpegDemux *) (parent);
1882
1883   if (active) {
1884     if (demux->can_push == FALSE) {
1885       GST_WARNING_OBJECT (demux, "Demuxer can't reliably operate in push-mode");
1886       goto beach;
1887     }
1888     demux->ffpipe.eos = FALSE;
1889     demux->ffpipe.srcresult = GST_FLOW_OK;
1890     demux->ffpipe.needed = 0;
1891     demux->seekable = FALSE;
1892     res = gst_task_start (demux->task);
1893   } else {
1894     GstFFMpegPipe *ffpipe = &demux->ffpipe;
1895
1896     /* release chain and loop */
1897     GST_FFMPEG_PIPE_MUTEX_LOCK (ffpipe);
1898     demux->ffpipe.srcresult = GST_FLOW_FLUSHING;
1899     /* end streaming by making ffmpeg believe eos */
1900     demux->ffpipe.eos = TRUE;
1901     GST_FFMPEG_PIPE_SIGNAL (ffpipe);
1902     GST_FFMPEG_PIPE_MUTEX_UNLOCK (ffpipe);
1903
1904     /* make sure streaming ends */
1905     gst_task_stop (demux->task);
1906     g_rec_mutex_lock (&demux->task_lock);
1907     g_rec_mutex_unlock (&demux->task_lock);
1908     res = gst_task_join (demux->task);
1909     demux->seekable = FALSE;
1910   }
1911
1912 beach:
1913   return res;
1914 }
1915
1916 /* pull mode:
1917  * - seekable
1918  * - use gstreamer protocol, like ffmpeg's file protocol
1919  * - task driving ffmpeg based on sink pad
1920  */
1921 static gboolean
1922 gst_ffmpegdemux_sink_activate_pull (GstPad * sinkpad, GstObject * parent,
1923     gboolean active)
1924 {
1925   GstFFMpegDemux *demux;
1926   gboolean res;
1927
1928   demux = (GstFFMpegDemux *) parent;
1929
1930   if (active) {
1931     demux->seekable = TRUE;
1932     res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_ffmpegdemux_loop,
1933         demux, NULL);
1934   } else {
1935     res = gst_pad_stop_task (sinkpad);
1936     demux->seekable = FALSE;
1937   }
1938
1939   return res;
1940 }
1941
1942 static gboolean
1943 gst_ffmpegdemux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
1944     GstPadMode mode, gboolean active)
1945 {
1946   gboolean res;
1947
1948   switch (mode) {
1949     case GST_PAD_MODE_PUSH:
1950       res = gst_ffmpegdemux_sink_activate_push (sinkpad, parent, active);
1951       break;
1952     case GST_PAD_MODE_PULL:
1953       res = gst_ffmpegdemux_sink_activate_pull (sinkpad, parent, active);
1954       break;
1955     default:
1956       res = FALSE;
1957       break;
1958   }
1959   return res;
1960 }
1961
1962 static GstStateChangeReturn
1963 gst_ffmpegdemux_change_state (GstElement * element, GstStateChange transition)
1964 {
1965   GstFFMpegDemux *demux = (GstFFMpegDemux *) (element);
1966   GstStateChangeReturn ret;
1967
1968   switch (transition) {
1969     case GST_STATE_CHANGE_READY_TO_PAUSED:
1970 #if 0
1971       /* test seek in READY here */
1972       gst_element_send_event (element, gst_event_new_seek (1.0,
1973               GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
1974               GST_SEEK_TYPE_SET, 10 * GST_SECOND,
1975               GST_SEEK_TYPE_SET, 13 * GST_SECOND));
1976 #endif
1977       break;
1978     default:
1979       break;
1980   }
1981
1982   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1983
1984   switch (transition) {
1985     case GST_STATE_CHANGE_PAUSED_TO_READY:
1986       gst_ffmpegdemux_close (demux);
1987       gst_adapter_clear (demux->ffpipe.adapter);
1988       g_list_foreach (demux->cached_events, (GFunc) gst_mini_object_unref,
1989           NULL);
1990       g_list_free (demux->cached_events);
1991       demux->cached_events = NULL;
1992       demux->have_group_id = FALSE;
1993       demux->group_id = G_MAXUINT;
1994       break;
1995     default:
1996       break;
1997   }
1998
1999   return ret;
2000 }
2001
2002 gboolean
2003 gst_ffmpegdemux_register (GstPlugin * plugin)
2004 {
2005   GType type;
2006   const AVInputFormat *in_plugin;
2007   gchar *extensions;
2008   GTypeInfo typeinfo = {
2009     sizeof (GstFFMpegDemuxClass),
2010     (GBaseInitFunc) gst_ffmpegdemux_base_init,
2011     NULL,
2012     (GClassInitFunc) gst_ffmpegdemux_class_init,
2013     NULL,
2014     NULL,
2015     sizeof (GstFFMpegDemux),
2016     0,
2017     (GInstanceInitFunc) gst_ffmpegdemux_init,
2018   };
2019
2020   void *i = 0;
2021
2022   GST_LOG ("Registering demuxers");
2023
2024   while ((in_plugin = av_demuxer_iterate (&i))) {
2025     gchar *type_name, *typefind_name;
2026     gint rank;
2027     gboolean register_typefind_func = TRUE;
2028
2029     GST_LOG ("Attempting to handle libav demuxer plugin %s [%s]",
2030         in_plugin->name, in_plugin->long_name);
2031
2032     /* no emulators */
2033     if (in_plugin->long_name != NULL) {
2034       if (!strncmp (in_plugin->long_name, "raw ", 4) ||
2035           !strncmp (in_plugin->long_name, "pcm ", 4)
2036           )
2037         continue;
2038     }
2039
2040     if (!strcmp (in_plugin->name, "audio_device") ||
2041         !strncmp (in_plugin->name, "image", 5) ||
2042         !strcmp (in_plugin->name, "mpegvideo") ||
2043         !strcmp (in_plugin->name, "mjpeg") ||
2044         !strcmp (in_plugin->name, "redir") ||
2045         !strncmp (in_plugin->name, "u8", 2) ||
2046         !strncmp (in_plugin->name, "u16", 3) ||
2047         !strncmp (in_plugin->name, "u24", 3) ||
2048         !strncmp (in_plugin->name, "u32", 3) ||
2049         !strncmp (in_plugin->name, "s8", 2) ||
2050         !strncmp (in_plugin->name, "s16", 3) ||
2051         !strncmp (in_plugin->name, "s24", 3) ||
2052         !strncmp (in_plugin->name, "s32", 3) ||
2053         !strncmp (in_plugin->name, "f32", 3) ||
2054         !strncmp (in_plugin->name, "f64", 3) ||
2055         !strcmp (in_plugin->name, "mulaw") || !strcmp (in_plugin->name, "alaw")
2056         )
2057       continue;
2058
2059     /* no network demuxers */
2060     if (!strcmp (in_plugin->name, "sdp") ||
2061         !strcmp (in_plugin->name, "rtsp") ||
2062         !strcmp (in_plugin->name, "applehttp")
2063         )
2064       continue;
2065
2066     /* these don't do what one would expect or
2067      * are only partially functional/useful */
2068     if (!strcmp (in_plugin->name, "aac") ||
2069         !strcmp (in_plugin->name, "wv") ||
2070         !strcmp (in_plugin->name, "ass") ||
2071         !strcmp (in_plugin->name, "ffmetadata"))
2072       continue;
2073
2074     /* Don't use the typefind functions of formats for which we already have
2075      * better typefind functions */
2076     if (!strcmp (in_plugin->name, "mov,mp4,m4a,3gp,3g2,mj2") ||
2077         !strcmp (in_plugin->name, "ass") ||
2078         !strcmp (in_plugin->name, "avi") ||
2079         !strcmp (in_plugin->name, "asf") ||
2080         !strcmp (in_plugin->name, "mpegvideo") ||
2081         !strcmp (in_plugin->name, "mp3") ||
2082         !strcmp (in_plugin->name, "matroska") ||
2083         !strcmp (in_plugin->name, "matroska_webm") ||
2084         !strcmp (in_plugin->name, "matroska,webm") ||
2085         !strcmp (in_plugin->name, "mpeg") ||
2086         !strcmp (in_plugin->name, "wav") ||
2087         !strcmp (in_plugin->name, "au") ||
2088         !strcmp (in_plugin->name, "tta") ||
2089         !strcmp (in_plugin->name, "rm") ||
2090         !strcmp (in_plugin->name, "amr") ||
2091         !strcmp (in_plugin->name, "ogg") ||
2092         !strcmp (in_plugin->name, "aiff") ||
2093         !strcmp (in_plugin->name, "ape") ||
2094         !strcmp (in_plugin->name, "dv") ||
2095         !strcmp (in_plugin->name, "flv") ||
2096         !strcmp (in_plugin->name, "mpc") ||
2097         !strcmp (in_plugin->name, "mpc8") ||
2098         !strcmp (in_plugin->name, "mpegts") ||
2099         !strcmp (in_plugin->name, "mpegtsraw") ||
2100         !strcmp (in_plugin->name, "mxf") ||
2101         !strcmp (in_plugin->name, "nuv") ||
2102         !strcmp (in_plugin->name, "swf") ||
2103         !strcmp (in_plugin->name, "voc") ||
2104         !strcmp (in_plugin->name, "pva") ||
2105         !strcmp (in_plugin->name, "gif") ||
2106         !strcmp (in_plugin->name, "vc1test") ||
2107         !strcmp (in_plugin->name, "ivf"))
2108       register_typefind_func = FALSE;
2109
2110     /* Set the rank of demuxers known to work to MARGINAL.
2111      * Set demuxers for which we already have another implementation to NONE
2112      * Set All others to NONE*/
2113     /**
2114      * element-avdemux_xwma
2115      *
2116      * Since: 1.20
2117      */
2118     if (!strcmp (in_plugin->name, "wsvqa") ||
2119         !strcmp (in_plugin->name, "wsaud") ||
2120         !strcmp (in_plugin->name, "wc3movie") ||
2121         !strcmp (in_plugin->name, "voc") ||
2122         !strcmp (in_plugin->name, "tta") ||
2123         !strcmp (in_plugin->name, "sol") ||
2124         !strcmp (in_plugin->name, "smk") ||
2125         !strcmp (in_plugin->name, "vmd") ||
2126         !strcmp (in_plugin->name, "film_cpk") ||
2127         !strcmp (in_plugin->name, "ingenient") ||
2128         !strcmp (in_plugin->name, "psxstr") ||
2129         !strcmp (in_plugin->name, "nuv") ||
2130         !strcmp (in_plugin->name, "nut") ||
2131         !strcmp (in_plugin->name, "nsv") ||
2132         !strcmp (in_plugin->name, "mxf") ||
2133         !strcmp (in_plugin->name, "mmf") ||
2134         !strcmp (in_plugin->name, "mm") ||
2135         !strcmp (in_plugin->name, "ipmovie") ||
2136         !strcmp (in_plugin->name, "ape") ||
2137         !strcmp (in_plugin->name, "RoQ") ||
2138         !strcmp (in_plugin->name, "idcin") ||
2139         !strcmp (in_plugin->name, "gxf") ||
2140         !strcmp (in_plugin->name, "ffm") ||
2141         !strcmp (in_plugin->name, "ea") ||
2142         !strcmp (in_plugin->name, "daud") ||
2143         !strcmp (in_plugin->name, "avs") ||
2144         !strcmp (in_plugin->name, "aiff") ||
2145         !strcmp (in_plugin->name, "xwma") ||
2146         !strcmp (in_plugin->name, "4xm") ||
2147         !strcmp (in_plugin->name, "yuv4mpegpipe") ||
2148         !strcmp (in_plugin->name, "pva") ||
2149         !strcmp (in_plugin->name, "mpc") ||
2150         !strcmp (in_plugin->name, "mpc8") ||
2151         !strcmp (in_plugin->name, "ivf") ||
2152         !strcmp (in_plugin->name, "brstm") ||
2153         !strcmp (in_plugin->name, "bfstm") ||
2154         !strcmp (in_plugin->name, "gif") ||
2155         !strcmp (in_plugin->name, "dsf") || !strcmp (in_plugin->name, "iff"))
2156       rank = GST_RANK_MARGINAL;
2157     else {
2158       GST_DEBUG ("ignoring %s", in_plugin->name);
2159       rank = GST_RANK_NONE;
2160       continue;
2161     }
2162
2163     /* construct the type */
2164     type_name = g_strdup_printf ("avdemux_%s", in_plugin->name);
2165     g_strdelimit (type_name, ".,|-<> ", '_');
2166
2167     /* if it's already registered, drop it */
2168     if (g_type_from_name (type_name)) {
2169       g_free (type_name);
2170       continue;
2171     }
2172
2173     typefind_name = g_strdup_printf ("avtype_%s", in_plugin->name);
2174     g_strdelimit (typefind_name, ".,|-<> ", '_');
2175
2176     /* create the type now */
2177     type = g_type_register_static (GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
2178     g_type_set_qdata (type, GST_FFDEMUX_PARAMS_QDATA, (gpointer) in_plugin);
2179
2180     if (in_plugin->extensions)
2181       extensions = g_strdelimit (g_strdup (in_plugin->extensions), " ", ',');
2182     else
2183       extensions = NULL;
2184
2185     if (!gst_element_register (plugin, type_name, rank, type) ||
2186         (register_typefind_func == TRUE &&
2187             !gst_type_find_register (plugin, typefind_name, rank,
2188                 gst_ffmpegdemux_type_find, extensions, NULL,
2189                 (gpointer) in_plugin, NULL))) {
2190       g_warning ("Registration of type %s failed", type_name);
2191       g_free (type_name);
2192       g_free (typefind_name);
2193       g_free (extensions);
2194       return FALSE;
2195     }
2196
2197     g_free (type_name);
2198     g_free (typefind_name);
2199     g_free (extensions);
2200   }
2201
2202   GST_LOG ("Finished registering demuxers");
2203
2204   return TRUE;
2205 }