Merging gst-ci
[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   "creation_time", GST_TAG_DATE_TIME}, {
1110     /* Need to convert ISO 8601 to GDateTime: */
1111   "date", GST_TAG_DATE_TIME}, {
1112   "disc", GST_TAG_ALBUM_VOLUME_NUMBER}, {
1113   "encoder", GST_TAG_ENCODER}, {
1114   "encoded_by", GST_TAG_ENCODED_BY}, {
1115   "genre", GST_TAG_GENRE}, {
1116   "language", GST_TAG_LANGUAGE_CODE}, {
1117   "performer", GST_TAG_PERFORMER}, {
1118   "publisher", GST_TAG_PUBLISHER}, {
1119   "title", GST_TAG_TITLE}, {
1120   "track", GST_TAG_TRACK_NUMBER}
1121 };
1122
1123 static const gchar *
1124 match_tag_name (gchar * ffmpeg_tag_name)
1125 {
1126   gint i;
1127   for (i = 0; i < G_N_ELEMENTS (tagmapping); i++) {
1128     if (!g_strcmp0 (tagmapping[i].ffmpeg_tag_name, ffmpeg_tag_name))
1129       return tagmapping[i].gst_tag_name;
1130   }
1131   return NULL;
1132 }
1133
1134 static GstTagList *
1135 gst_ffmpeg_metadata_to_tag_list (AVDictionary * metadata)
1136 {
1137   AVDictionaryEntry *tag = NULL;
1138   GstTagList *list;
1139   list = gst_tag_list_new_empty ();
1140
1141   while ((tag = av_dict_get (metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
1142     const gchar *gsttag = match_tag_name (tag->key);
1143     GType t;
1144     GST_LOG ("mapping tag %s=%s\n", tag->key, tag->value);
1145     if (gsttag == NULL) {
1146       GST_LOG ("Ignoring unknown metadata tag %s", tag->key);
1147       continue;
1148     }
1149     /* Special case, track and disc numbers may be x/n in libav, split
1150      * them */
1151     if (g_str_equal (gsttag, GST_TAG_TRACK_NUMBER)) {
1152       guint track, trackcount;
1153       if (sscanf (tag->value, "%u/%u", &track, &trackcount) == 2) {
1154         gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1155             gsttag, track, GST_TAG_TRACK_COUNT, trackcount, NULL);
1156         continue;
1157       }
1158       /* Fall through and handle as a single uint below */
1159     } else if (g_str_equal (gsttag, GST_TAG_ALBUM_VOLUME_NUMBER)) {
1160       guint disc, disc_count;
1161       if (sscanf (tag->value, "%u/%u", &disc, &disc_count) == 2) {
1162         gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
1163             gsttag, disc, GST_TAG_ALBUM_VOLUME_COUNT, disc_count, NULL);
1164         continue;
1165       }
1166       /* Fall through and handle as a single uint below */
1167     }
1168
1169     t = gst_tag_get_type (gsttag);
1170     if (t == G_TYPE_STRING) {
1171       gchar *s = safe_utf8_copy (tag->value);
1172       gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, gsttag, s, NULL);
1173       g_free (s);
1174     } else if (t == G_TYPE_UINT || t == G_TYPE_INT) {
1175       gchar *end;
1176       gint v = strtol (tag->value, &end, 10);
1177       if (end == tag->value)
1178         continue;               /* Failed to parse */
1179       gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, gsttag, v, NULL);
1180     } else if (t == G_TYPE_DATE) {
1181       guint year, month, day;
1182       GDate *date = NULL;
1183       if (sscanf (tag->value, "%04u-%02u-%02u", &year, &month, &day) == 3) {
1184         date = g_date_new_dmy (day, month, year);
1185       } else {
1186         /* Try interpreting just as a year */
1187         gchar *end;
1188
1189         year = strtol (tag->value, &end, 10);
1190         if (end != tag->value)
1191           date = g_date_new_dmy (1, 1, year);
1192       }
1193       if (date) {
1194         gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, gsttag, date, NULL);
1195         g_date_free (date);
1196       }
1197     } else if (t == GST_TYPE_DATE_TIME) {
1198       gchar *s = safe_utf8_copy (tag->value);
1199       GstDateTime *d = gst_date_time_new_from_iso8601_string (s);
1200
1201       g_free (s);
1202       if (d) {
1203         gst_tag_list_add (list, GST_TAG_MERGE_REPLACE, gsttag, d, NULL);
1204         gst_date_time_unref (d);
1205       }
1206     } else {
1207       GST_FIXME ("Unhandled tag %s", gsttag);
1208     }
1209   }
1210
1211   if (gst_tag_list_is_empty (list)) {
1212     gst_tag_list_unref (list);
1213     return NULL;
1214   }
1215
1216   return list;
1217 }
1218
1219 static gboolean
1220 gst_ffmpegdemux_open (GstFFMpegDemux * demux)
1221 {
1222   AVIOContext *iocontext = NULL;
1223   GstFFMpegDemuxClass *oclass =
1224       (GstFFMpegDemuxClass *) G_OBJECT_GET_CLASS (demux);
1225   gint res, n_streams, i;
1226   GstTagList *tags;
1227   GstEvent *event;
1228   GList *cached_events;
1229   GstQuery *query;
1230   gchar *uri = NULL;
1231
1232   /* to be sure... */
1233   gst_ffmpegdemux_close (demux);
1234
1235   /* open via our input protocol hack */
1236   if (demux->seekable)
1237     res = gst_ffmpegdata_open (demux->sinkpad, AVIO_FLAG_READ, &iocontext);
1238   else
1239     res = gst_ffmpeg_pipe_open (&demux->ffpipe, AVIO_FLAG_READ, &iocontext);
1240
1241   if (res < 0)
1242     goto beach;
1243
1244   query = gst_query_new_uri ();
1245   if (gst_pad_peer_query (demux->sinkpad, query)) {
1246     gchar *query_uri, *redirect_uri;
1247     gboolean permanent;
1248
1249     gst_query_parse_uri (query, &query_uri);
1250     gst_query_parse_uri_redirection (query, &redirect_uri);
1251     gst_query_parse_uri_redirection_permanent (query, &permanent);
1252
1253     if (permanent && redirect_uri) {
1254       uri = redirect_uri;
1255       g_free (query_uri);
1256     } else {
1257       uri = query_uri;
1258       g_free (redirect_uri);
1259     }
1260   }
1261   gst_query_unref (query);
1262
1263   GST_DEBUG_OBJECT (demux, "Opening context with URI %s", GST_STR_NULL (uri));
1264
1265   demux->context = avformat_alloc_context ();
1266   demux->context->pb = iocontext;
1267   res = avformat_open_input (&demux->context, uri, oclass->in_plugin, NULL);
1268
1269   g_free (uri);
1270
1271   GST_DEBUG_OBJECT (demux, "av_open_input returned %d", res);
1272   if (res < 0)
1273     goto beach;
1274
1275   res = gst_ffmpeg_av_find_stream_info (demux->context);
1276   GST_DEBUG_OBJECT (demux, "av_find_stream_info returned %d", res);
1277   if (res < 0)
1278     goto beach;
1279
1280   n_streams = demux->context->nb_streams;
1281   GST_DEBUG_OBJECT (demux, "we have %d streams", n_streams);
1282
1283   /* open_input_file() automatically reads the header. We can now map each
1284    * created AVStream to a GstPad to make GStreamer handle it. */
1285   for (i = 0; i < n_streams; i++) {
1286     gst_ffmpegdemux_get_stream (demux, demux->context->streams[i]);
1287   }
1288
1289   gst_element_no_more_pads (GST_ELEMENT (demux));
1290
1291   /* transform some useful info to GstClockTime and remember */
1292   demux->start_time = gst_util_uint64_scale_int (demux->context->start_time,
1293       GST_SECOND, AV_TIME_BASE);
1294   GST_DEBUG_OBJECT (demux, "start time: %" GST_TIME_FORMAT,
1295       GST_TIME_ARGS (demux->start_time));
1296   if (demux->context->duration > 0)
1297     demux->duration = gst_util_uint64_scale_int (demux->context->duration,
1298         GST_SECOND, AV_TIME_BASE);
1299   else
1300     demux->duration = GST_CLOCK_TIME_NONE;
1301
1302   GST_DEBUG_OBJECT (demux, "duration: %" GST_TIME_FORMAT,
1303       GST_TIME_ARGS (demux->duration));
1304
1305   /* store duration in the segment as well */
1306   demux->segment.duration = demux->duration;
1307
1308   GST_OBJECT_LOCK (demux);
1309   demux->opened = TRUE;
1310   event = demux->seek_event;
1311   demux->seek_event = NULL;
1312   cached_events = demux->cached_events;
1313   demux->cached_events = NULL;
1314   GST_OBJECT_UNLOCK (demux);
1315
1316   if (event) {
1317     gst_ffmpegdemux_perform_seek (demux, event);
1318     gst_event_unref (event);
1319   } else {
1320     GST_DEBUG_OBJECT (demux, "Sending segment %" GST_SEGMENT_FORMAT,
1321         &demux->segment);
1322     gst_ffmpegdemux_push_event (demux, gst_event_new_segment (&demux->segment));
1323   }
1324
1325   while (cached_events) {
1326     event = cached_events->data;
1327     GST_INFO_OBJECT (demux, "pushing cached event: %" GST_PTR_FORMAT, event);
1328     gst_ffmpegdemux_push_event (demux, event);
1329     cached_events = g_list_delete_link (cached_events, cached_events);
1330   }
1331
1332   /* grab the global tags */
1333   tags = gst_ffmpeg_metadata_to_tag_list (demux->context->metadata);
1334   if (tags) {
1335     GST_INFO_OBJECT (demux, "global tags: %" GST_PTR_FORMAT, tags);
1336   }
1337
1338   /* now handle the stream tags */
1339   for (i = 0; i < n_streams; i++) {
1340     GstFFStream *stream;
1341
1342     stream = gst_ffmpegdemux_get_stream (demux, demux->context->streams[i]);
1343     if (stream->pad != NULL) {
1344
1345       /* Global tags */
1346       if (tags)
1347         gst_pad_push_event (stream->pad,
1348             gst_event_new_tag (gst_tag_list_ref (tags)));
1349
1350       /* Per-stream tags */
1351       if (stream->tags != NULL) {
1352         GST_INFO_OBJECT (stream->pad, "stream tags: %" GST_PTR_FORMAT,
1353             stream->tags);
1354         gst_pad_push_event (stream->pad,
1355             gst_event_new_tag (gst_tag_list_ref (stream->tags)));
1356       }
1357     }
1358   }
1359   if (tags)
1360     gst_tag_list_unref (tags);
1361   return TRUE;
1362
1363   /* ERRORS */
1364 beach:
1365   {
1366     GST_ELEMENT_ERROR (demux, LIBRARY, FAILED, (NULL),
1367         ("%s", gst_ffmpegdemux_averror (res)));
1368     return FALSE;
1369   }
1370 }
1371
1372 #define GST_FFMPEG_TYPE_FIND_SIZE 4096
1373 #define GST_FFMPEG_TYPE_FIND_MIN_SIZE 256
1374
1375 static void
1376 gst_ffmpegdemux_type_find (GstTypeFind * tf, gpointer priv)
1377 {
1378   const guint8 *data;
1379   AVInputFormat *in_plugin = (AVInputFormat *) priv;
1380   gint res = 0;
1381   guint64 length;
1382   GstCaps *sinkcaps;
1383
1384   /* We want GST_FFMPEG_TYPE_FIND_SIZE bytes, but if the file is shorter than
1385    * that we'll give it a try... */
1386   length = gst_type_find_get_length (tf);
1387   if (length == 0 || length > GST_FFMPEG_TYPE_FIND_SIZE)
1388     length = GST_FFMPEG_TYPE_FIND_SIZE;
1389
1390   /* The ffmpeg typefinders assume there's a certain minimum amount of data
1391    * and will happily do invalid memory access if there isn't, so let's just
1392    * skip the ffmpeg typefinders if the data available is too short
1393    * (in which case it's unlikely to be a media file anyway) */
1394   if (length < GST_FFMPEG_TYPE_FIND_MIN_SIZE) {
1395     GST_LOG ("not typefinding %" G_GUINT64_FORMAT " bytes, too short", length);
1396     return;
1397   }
1398
1399   GST_LOG ("typefinding %" G_GUINT64_FORMAT " bytes", length);
1400   if (in_plugin->read_probe &&
1401       (data = gst_type_find_peek (tf, 0, length)) != NULL) {
1402     AVProbeData probe_data;
1403
1404     probe_data.filename = "";
1405     probe_data.buf = (guint8 *) data;
1406     probe_data.buf_size = length;
1407
1408     res = in_plugin->read_probe (&probe_data);
1409     if (res > 0) {
1410       res = MAX (1, res * GST_TYPE_FIND_MAXIMUM / AVPROBE_SCORE_MAX);
1411       /* Restrict the probability for MPEG-TS streams, because there is
1412        * probably a better version in plugins-base, if the user has a recent
1413        * plugins-base (in fact we shouldn't even get here for ffmpeg mpegts or
1414        * mpegtsraw typefinders, since we blacklist them) */
1415       if (g_str_has_prefix (in_plugin->name, "mpegts"))
1416         res = MIN (res, GST_TYPE_FIND_POSSIBLE);
1417
1418       sinkcaps = gst_ffmpeg_formatid_to_caps (in_plugin->name);
1419
1420       GST_LOG ("libav typefinder '%s' suggests %" GST_PTR_FORMAT ", p=%u%%",
1421           in_plugin->name, sinkcaps, res);
1422
1423       gst_type_find_suggest (tf, res, sinkcaps);
1424       gst_caps_unref (sinkcaps);
1425     }
1426   }
1427 }
1428
1429 /* Task */
1430 static void
1431 gst_ffmpegdemux_loop (GstFFMpegDemux * demux)
1432 {
1433   GstFlowReturn ret;
1434   gint res = -1;
1435   AVPacket pkt;
1436   GstPad *srcpad;
1437   GstFFStream *stream;
1438   AVStream *avstream;
1439   GstBuffer *outbuf = NULL;
1440   GstClockTime timestamp, duration;
1441   gint outsize;
1442   gboolean rawvideo;
1443   GstFlowReturn stream_last_flow;
1444   gint64 pts;
1445
1446   /* open file if we didn't so already */
1447   if (!demux->opened)
1448     if (!gst_ffmpegdemux_open (demux))
1449       goto open_failed;
1450
1451   GST_DEBUG_OBJECT (demux, "about to read a frame");
1452
1453   /* read a frame */
1454   res = av_read_frame (demux->context, &pkt);
1455   if (res < 0)
1456     goto read_failed;
1457
1458   /* get the stream */
1459   stream =
1460       gst_ffmpegdemux_get_stream (demux,
1461       demux->context->streams[pkt.stream_index]);
1462
1463   /* check if we know the stream */
1464   if (stream->unknown)
1465     goto done;
1466
1467   /* get more stuff belonging to this stream */
1468   avstream = stream->avstream;
1469
1470   /* do timestamps, we do this first so that we can know when we
1471    * stepped over the segment stop position. */
1472   pts = pkt.pts;
1473   if (G_UNLIKELY (pts < 0)) {
1474     /* some streams have pts such this:
1475      * 0
1476      * -2
1477      * -1
1478      * 1
1479      *
1480      * we reset pts to 0 since for us timestamp are unsigned
1481      */
1482     GST_WARNING_OBJECT (demux,
1483         "negative pts detected: %" G_GINT64_FORMAT " resetting to 0", pts);
1484     pts = 0;
1485   }
1486   timestamp = gst_ffmpeg_time_ff_to_gst (pts, avstream->time_base);
1487   if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
1488     stream->last_ts = timestamp;
1489   }
1490   duration = gst_ffmpeg_time_ff_to_gst (pkt.duration, avstream->time_base);
1491   if (G_UNLIKELY (!duration)) {
1492     GST_WARNING_OBJECT (demux, "invalid buffer duration, setting to NONE");
1493     duration = GST_CLOCK_TIME_NONE;
1494   }
1495
1496
1497   GST_DEBUG_OBJECT (demux,
1498       "pkt pts:%" GST_TIME_FORMAT
1499       " / size:%d / stream_index:%d / flags:%d / duration:%" GST_TIME_FORMAT
1500       " / pos:%" G_GINT64_FORMAT, GST_TIME_ARGS (timestamp), pkt.size,
1501       pkt.stream_index, pkt.flags, GST_TIME_ARGS (duration), (gint64) pkt.pos);
1502
1503   /* check start_time */
1504 #if 0
1505   if (demux->start_time != -1 && demux->start_time > timestamp)
1506     goto drop;
1507 #endif
1508
1509   if (GST_CLOCK_TIME_IS_VALID (timestamp)) {
1510     /* start_time should be the ts of the first frame but it may actually be
1511      * higher because of rounding when converting to gst ts. */
1512     if (demux->start_time >= timestamp)
1513       timestamp = 0;
1514     else
1515       timestamp -= demux->start_time;
1516   }
1517
1518   /* check if we ran outside of the segment */
1519   if (demux->segment.stop != -1 && timestamp > demux->segment.stop)
1520     goto drop;
1521
1522   /* prepare to push packet to peer */
1523   srcpad = stream->pad;
1524
1525   rawvideo = (avstream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
1526       avstream->codecpar->codec_id == AV_CODEC_ID_RAWVIDEO);
1527
1528   if (rawvideo)
1529     outsize = gst_ffmpeg_avpicture_get_size (avstream->codecpar->format,
1530         avstream->codecpar->width, avstream->codecpar->height);
1531   else
1532     outsize = pkt.size;
1533
1534   outbuf = gst_buffer_new_and_alloc (outsize);
1535
1536   /* copy the data from packet into the target buffer
1537    * and do conversions for raw video packets */
1538   if (rawvideo) {
1539     AVFrame src, dst;
1540     const gchar *plugin_name =
1541         ((GstFFMpegDemuxClass *) (G_OBJECT_GET_CLASS (demux)))->in_plugin->name;
1542     GstMapInfo map;
1543
1544     GST_WARNING ("Unknown demuxer %s, no idea what to do", plugin_name);
1545     gst_ffmpeg_avpicture_fill (&src, pkt.data,
1546         avstream->codecpar->format, avstream->codecpar->width,
1547         avstream->codecpar->height);
1548
1549     gst_buffer_map (outbuf, &map, GST_MAP_WRITE);
1550     gst_ffmpeg_avpicture_fill (&dst, map.data,
1551         avstream->codecpar->format, avstream->codecpar->width,
1552         avstream->codecpar->height);
1553
1554     av_image_copy (dst.data, dst.linesize, (const uint8_t **) src.data,
1555         src.linesize, avstream->codecpar->format, avstream->codecpar->width,
1556         avstream->codecpar->height);
1557     gst_buffer_unmap (outbuf, &map);
1558   } else {
1559     gst_buffer_fill (outbuf, 0, pkt.data, outsize);
1560   }
1561
1562   GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
1563   GST_BUFFER_DURATION (outbuf) = duration;
1564
1565   /* mark keyframes */
1566   if (!(pkt.flags & AV_PKT_FLAG_KEY)) {
1567     GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
1568   }
1569
1570   /* Mark discont */
1571   if (stream->discont) {
1572     GST_DEBUG_OBJECT (demux, "marking DISCONT");
1573     GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
1574     stream->discont = FALSE;
1575   }
1576
1577   GST_DEBUG_OBJECT (demux,
1578       "Sending out buffer time:%" GST_TIME_FORMAT " size:%" G_GSIZE_FORMAT,
1579       GST_TIME_ARGS (timestamp), gst_buffer_get_size (outbuf));
1580
1581   ret = stream_last_flow = gst_pad_push (srcpad, outbuf);
1582
1583   /* if a pad is in e.g. WRONG_STATE, we want to pause to unlock the STREAM_LOCK */
1584   if (((ret = gst_flow_combiner_update_flow (demux->flowcombiner,
1585                   ret)) != GST_FLOW_OK)) {
1586     GST_WARNING_OBJECT (demux, "stream_movi flow: %s / %s",
1587         gst_flow_get_name (stream_last_flow), gst_flow_get_name (ret));
1588     goto pause;
1589   }
1590
1591 done:
1592   /* can destroy the packet now */
1593   if (res == 0) {
1594     av_packet_unref (&pkt);
1595   }
1596
1597   return;
1598
1599   /* ERRORS */
1600 pause:
1601   {
1602     GST_LOG_OBJECT (demux, "pausing task, reason %d (%s)", ret,
1603         gst_flow_get_name (ret));
1604     if (demux->seekable)
1605       gst_pad_pause_task (demux->sinkpad);
1606     else {
1607       GstFFMpegPipe *ffpipe = &demux->ffpipe;
1608
1609       GST_FFMPEG_PIPE_MUTEX_LOCK (ffpipe);
1610       /* pause task and make sure loop stops */
1611       gst_task_pause (demux->task);
1612       g_rec_mutex_lock (&demux->task_lock);
1613       g_rec_mutex_unlock (&demux->task_lock);
1614       demux->ffpipe.srcresult = ret;
1615       GST_FFMPEG_PIPE_MUTEX_UNLOCK (ffpipe);
1616     }
1617
1618     if (ret == GST_FLOW_EOS) {
1619       if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
1620         gint64 stop;
1621
1622         if ((stop = demux->segment.stop) == -1)
1623           stop = demux->segment.duration;
1624
1625         GST_LOG_OBJECT (demux, "posting segment done");
1626         gst_element_post_message (GST_ELEMENT (demux),
1627             gst_message_new_segment_done (GST_OBJECT (demux),
1628                 demux->segment.format, stop));
1629         gst_ffmpegdemux_push_event (demux,
1630             gst_event_new_segment_done (demux->segment.format, stop));
1631       } else {
1632         GST_LOG_OBJECT (demux, "pushing eos");
1633         gst_ffmpegdemux_push_event (demux, gst_event_new_eos ());
1634       }
1635     } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
1636       GST_ELEMENT_FLOW_ERROR (demux, ret);
1637       gst_ffmpegdemux_push_event (demux, gst_event_new_eos ());
1638     }
1639     goto done;
1640   }
1641 open_failed:
1642   {
1643     ret = GST_FLOW_ERROR;
1644     goto pause;
1645   }
1646 read_failed:
1647   {
1648     /* something went wrong... */
1649     GST_WARNING_OBJECT (demux, "av_read_frame returned %d", res);
1650
1651     GST_OBJECT_LOCK (demux);
1652     /* pause appropriatly based on if we are flushing or not */
1653     if (demux->flushing)
1654       ret = GST_FLOW_FLUSHING;
1655     else if (gst_ffmpegdemux_has_outputted (demux)
1656         || gst_ffmpegdemux_is_eos (demux)) {
1657       GST_DEBUG_OBJECT (demux, "We are EOS");
1658       ret = GST_FLOW_EOS;
1659     } else
1660       ret = GST_FLOW_ERROR;
1661     GST_OBJECT_UNLOCK (demux);
1662
1663     goto pause;
1664   }
1665 drop:
1666   {
1667     GST_DEBUG_OBJECT (demux, "dropping buffer out of segment, stream eos");
1668     stream->eos = TRUE;
1669     if (gst_ffmpegdemux_is_eos (demux)) {
1670       av_packet_unref (&pkt);
1671       GST_DEBUG_OBJECT (demux, "we are eos");
1672       ret = GST_FLOW_EOS;
1673       goto pause;
1674     } else {
1675       GST_DEBUG_OBJECT (demux, "some streams are not yet eos");
1676       goto done;
1677     }
1678   }
1679 }
1680
1681
1682 static gboolean
1683 gst_ffmpegdemux_sink_event (GstPad * sinkpad, GstObject * parent,
1684     GstEvent * event)
1685 {
1686   GstFFMpegDemux *demux;
1687   GstFFMpegPipe *ffpipe;
1688   gboolean result = TRUE;
1689
1690   demux = (GstFFMpegDemux *) parent;
1691   ffpipe = &(demux->ffpipe);
1692
1693   GST_LOG_OBJECT (demux, "event: %" GST_PTR_FORMAT, event);
1694
1695   switch (GST_EVENT_TYPE (event)) {
1696     case GST_EVENT_FLUSH_START:
1697       /* forward event */
1698       gst_pad_event_default (sinkpad, parent, event);
1699
1700       /* now unblock the chain function */
1701       GST_FFMPEG_PIPE_MUTEX_LOCK (ffpipe);
1702       ffpipe->srcresult = GST_FLOW_FLUSHING;
1703       GST_FFMPEG_PIPE_SIGNAL (ffpipe);
1704       GST_FFMPEG_PIPE_MUTEX_UNLOCK (ffpipe);
1705
1706       /* loop might run into WRONG_STATE and end itself,
1707        * but may also be waiting in a ffmpeg read
1708        * trying to break that would make ffmpeg believe eos,
1709        * so no harm to have the loop 'pausing' there ... */
1710       goto done;
1711     case GST_EVENT_FLUSH_STOP:
1712       /* forward event */
1713       gst_pad_event_default (sinkpad, parent, event);
1714
1715       GST_OBJECT_LOCK (demux);
1716       g_list_foreach (demux->cached_events, (GFunc) gst_mini_object_unref,
1717           NULL);
1718       g_list_free (demux->cached_events);
1719       GST_OBJECT_UNLOCK (demux);
1720       GST_FFMPEG_PIPE_MUTEX_LOCK (ffpipe);
1721       gst_adapter_clear (ffpipe->adapter);
1722       ffpipe->srcresult = GST_FLOW_OK;
1723       /* loop may have decided to end itself as a result of flush WRONG_STATE */
1724       gst_task_start (demux->task);
1725       demux->flushing = FALSE;
1726       GST_LOG_OBJECT (demux, "loop started");
1727       GST_FFMPEG_PIPE_MUTEX_UNLOCK (ffpipe);
1728       goto done;
1729     case GST_EVENT_EOS:
1730       /* inform the src task that it can stop now */
1731       GST_FFMPEG_PIPE_MUTEX_LOCK (ffpipe);
1732       ffpipe->eos = TRUE;
1733       GST_FFMPEG_PIPE_SIGNAL (ffpipe);
1734       GST_FFMPEG_PIPE_MUTEX_UNLOCK (ffpipe);
1735
1736       /* eat this event for now, task will send eos when finished */
1737       gst_event_unref (event);
1738       goto done;
1739     case GST_EVENT_STREAM_START:
1740     case GST_EVENT_CAPS:
1741       GST_LOG_OBJECT (demux, "dropping %s event", GST_EVENT_TYPE_NAME (event));
1742       gst_event_unref (event);
1743       goto done;
1744     default:
1745       /* for a serialized event, wait until an earlier data is gone,
1746        * though this is no guarantee as to when task is done with it.
1747        *
1748        * If the demuxer isn't opened, push straight away, since we'll
1749        * be waiting against a cond that will never be signalled. */
1750       if (GST_EVENT_IS_SERIALIZED (event)) {
1751         if (demux->opened) {
1752           GST_FFMPEG_PIPE_MUTEX_LOCK (ffpipe);
1753           while (!ffpipe->needed)
1754             GST_FFMPEG_PIPE_WAIT (ffpipe);
1755           GST_FFMPEG_PIPE_MUTEX_UNLOCK (ffpipe);
1756         } else {
1757           /* queue events and send them later (esp. tag events) */
1758           GST_OBJECT_LOCK (demux);
1759           demux->cached_events = g_list_append (demux->cached_events, event);
1760           GST_OBJECT_UNLOCK (demux);
1761           goto done;
1762         }
1763       }
1764       break;
1765   }
1766
1767   result = gst_pad_event_default (sinkpad, parent, event);
1768
1769 done:
1770
1771   return result;
1772 }
1773
1774 static GstFlowReturn
1775 gst_ffmpegdemux_chain (GstPad * sinkpad, GstObject * parent, GstBuffer * buffer)
1776 {
1777   GstFFMpegDemux *demux;
1778   GstFFMpegPipe *ffpipe;
1779
1780   demux = (GstFFMpegDemux *) parent;
1781   ffpipe = &demux->ffpipe;
1782
1783   GST_FFMPEG_PIPE_MUTEX_LOCK (ffpipe);
1784
1785   if (G_UNLIKELY (ffpipe->eos))
1786     goto eos;
1787
1788   if (G_UNLIKELY (ffpipe->srcresult != GST_FLOW_OK))
1789     goto ignore;
1790
1791   GST_DEBUG ("Giving a buffer of %" G_GSIZE_FORMAT " bytes",
1792       gst_buffer_get_size (buffer));
1793   gst_adapter_push (ffpipe->adapter, buffer);
1794   buffer = NULL;
1795   while (gst_adapter_available (ffpipe->adapter) >= ffpipe->needed) {
1796     GST_DEBUG ("Adapter has more that requested (ffpipe->needed:%d)",
1797         ffpipe->needed);
1798     GST_FFMPEG_PIPE_SIGNAL (ffpipe);
1799     GST_FFMPEG_PIPE_WAIT (ffpipe);
1800     /* may have become flushing */
1801     if (G_UNLIKELY (ffpipe->srcresult != GST_FLOW_OK))
1802       goto ignore;
1803   }
1804
1805   GST_FFMPEG_PIPE_MUTEX_UNLOCK (ffpipe);
1806
1807   return GST_FLOW_OK;
1808
1809 /* special cases */
1810 eos:
1811   {
1812     GST_DEBUG_OBJECT (demux, "ignoring buffer at end-of-stream");
1813     GST_FFMPEG_PIPE_MUTEX_UNLOCK (ffpipe);
1814
1815     gst_buffer_unref (buffer);
1816     return GST_FLOW_EOS;
1817   }
1818 ignore:
1819   {
1820     GST_DEBUG_OBJECT (demux, "ignoring buffer because src task encountered %s",
1821         gst_flow_get_name (ffpipe->srcresult));
1822     GST_FFMPEG_PIPE_MUTEX_UNLOCK (ffpipe);
1823
1824     if (buffer)
1825       gst_buffer_unref (buffer);
1826     return GST_FLOW_FLUSHING;
1827   }
1828 }
1829
1830 static gboolean
1831 gst_ffmpegdemux_sink_activate (GstPad * sinkpad, GstObject * parent)
1832 {
1833   GstQuery *query;
1834   gboolean pull_mode;
1835   GstSchedulingFlags flags;
1836
1837   query = gst_query_new_scheduling ();
1838
1839   if (!gst_pad_peer_query (sinkpad, query)) {
1840     gst_query_unref (query);
1841     goto activate_push;
1842   }
1843
1844   pull_mode = gst_query_has_scheduling_mode_with_flags (query,
1845       GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
1846
1847   gst_query_parse_scheduling (query, &flags, NULL, NULL, NULL);
1848   if (flags & GST_SCHEDULING_FLAG_SEQUENTIAL)
1849     pull_mode = FALSE;
1850
1851   gst_query_unref (query);
1852
1853   if (!pull_mode)
1854     goto activate_push;
1855
1856   GST_DEBUG_OBJECT (sinkpad, "activating pull");
1857   return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
1858
1859 activate_push:
1860   {
1861     GST_DEBUG_OBJECT (sinkpad, "activating push");
1862     return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
1863   }
1864 }
1865
1866 /* push mode:
1867  * - not seekable
1868  * - use gstpipe protocol, like ffmpeg's pipe protocol
1869  * - (independently managed) task driving ffmpeg
1870  */
1871 static gboolean
1872 gst_ffmpegdemux_sink_activate_push (GstPad * sinkpad, GstObject * parent,
1873     gboolean active)
1874 {
1875   GstFFMpegDemux *demux;
1876   gboolean res = FALSE;
1877
1878   demux = (GstFFMpegDemux *) (parent);
1879
1880   if (active) {
1881     if (demux->can_push == FALSE) {
1882       GST_WARNING_OBJECT (demux, "Demuxer can't reliably operate in push-mode");
1883       goto beach;
1884     }
1885     demux->ffpipe.eos = FALSE;
1886     demux->ffpipe.srcresult = GST_FLOW_OK;
1887     demux->ffpipe.needed = 0;
1888     demux->seekable = FALSE;
1889     res = gst_task_start (demux->task);
1890   } else {
1891     GstFFMpegPipe *ffpipe = &demux->ffpipe;
1892
1893     /* release chain and loop */
1894     GST_FFMPEG_PIPE_MUTEX_LOCK (ffpipe);
1895     demux->ffpipe.srcresult = GST_FLOW_FLUSHING;
1896     /* end streaming by making ffmpeg believe eos */
1897     demux->ffpipe.eos = TRUE;
1898     GST_FFMPEG_PIPE_SIGNAL (ffpipe);
1899     GST_FFMPEG_PIPE_MUTEX_UNLOCK (ffpipe);
1900
1901     /* make sure streaming ends */
1902     gst_task_stop (demux->task);
1903     g_rec_mutex_lock (&demux->task_lock);
1904     g_rec_mutex_unlock (&demux->task_lock);
1905     res = gst_task_join (demux->task);
1906     demux->seekable = FALSE;
1907   }
1908
1909 beach:
1910   return res;
1911 }
1912
1913 /* pull mode:
1914  * - seekable
1915  * - use gstreamer protocol, like ffmpeg's file protocol
1916  * - task driving ffmpeg based on sink pad
1917  */
1918 static gboolean
1919 gst_ffmpegdemux_sink_activate_pull (GstPad * sinkpad, GstObject * parent,
1920     gboolean active)
1921 {
1922   GstFFMpegDemux *demux;
1923   gboolean res;
1924
1925   demux = (GstFFMpegDemux *) parent;
1926
1927   if (active) {
1928     demux->seekable = TRUE;
1929     res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_ffmpegdemux_loop,
1930         demux, NULL);
1931   } else {
1932     res = gst_pad_stop_task (sinkpad);
1933     demux->seekable = FALSE;
1934   }
1935
1936   return res;
1937 }
1938
1939 static gboolean
1940 gst_ffmpegdemux_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
1941     GstPadMode mode, gboolean active)
1942 {
1943   gboolean res;
1944
1945   switch (mode) {
1946     case GST_PAD_MODE_PUSH:
1947       res = gst_ffmpegdemux_sink_activate_push (sinkpad, parent, active);
1948       break;
1949     case GST_PAD_MODE_PULL:
1950       res = gst_ffmpegdemux_sink_activate_pull (sinkpad, parent, active);
1951       break;
1952     default:
1953       res = FALSE;
1954       break;
1955   }
1956   return res;
1957 }
1958
1959 static GstStateChangeReturn
1960 gst_ffmpegdemux_change_state (GstElement * element, GstStateChange transition)
1961 {
1962   GstFFMpegDemux *demux = (GstFFMpegDemux *) (element);
1963   GstStateChangeReturn ret;
1964
1965   switch (transition) {
1966     case GST_STATE_CHANGE_READY_TO_PAUSED:
1967 #if 0
1968       /* test seek in READY here */
1969       gst_element_send_event (element, gst_event_new_seek (1.0,
1970               GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
1971               GST_SEEK_TYPE_SET, 10 * GST_SECOND,
1972               GST_SEEK_TYPE_SET, 13 * GST_SECOND));
1973 #endif
1974       break;
1975     default:
1976       break;
1977   }
1978
1979   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1980
1981   switch (transition) {
1982     case GST_STATE_CHANGE_PAUSED_TO_READY:
1983       gst_ffmpegdemux_close (demux);
1984       gst_adapter_clear (demux->ffpipe.adapter);
1985       g_list_foreach (demux->cached_events, (GFunc) gst_mini_object_unref,
1986           NULL);
1987       g_list_free (demux->cached_events);
1988       demux->cached_events = NULL;
1989       demux->have_group_id = FALSE;
1990       demux->group_id = G_MAXUINT;
1991       break;
1992     default:
1993       break;
1994   }
1995
1996   return ret;
1997 }
1998
1999 gboolean
2000 gst_ffmpegdemux_register (GstPlugin * plugin)
2001 {
2002   GType type;
2003   const AVInputFormat *in_plugin;
2004   gchar *extensions;
2005   GTypeInfo typeinfo = {
2006     sizeof (GstFFMpegDemuxClass),
2007     (GBaseInitFunc) gst_ffmpegdemux_base_init,
2008     NULL,
2009     (GClassInitFunc) gst_ffmpegdemux_class_init,
2010     NULL,
2011     NULL,
2012     sizeof (GstFFMpegDemux),
2013     0,
2014     (GInstanceInitFunc) gst_ffmpegdemux_init,
2015   };
2016
2017   void *i = 0;
2018
2019   GST_LOG ("Registering demuxers");
2020
2021   while ((in_plugin = av_demuxer_iterate (&i))) {
2022     gchar *type_name, *typefind_name;
2023     gint rank;
2024     gboolean register_typefind_func = TRUE;
2025
2026     GST_LOG ("Attempting to handle libav demuxer plugin %s [%s]",
2027         in_plugin->name, in_plugin->long_name);
2028
2029     /* no emulators */
2030     if (in_plugin->long_name != NULL) {
2031       if (!strncmp (in_plugin->long_name, "raw ", 4) ||
2032           !strncmp (in_plugin->long_name, "pcm ", 4)
2033           )
2034         continue;
2035     }
2036
2037     if (!strcmp (in_plugin->name, "audio_device") ||
2038         !strncmp (in_plugin->name, "image", 5) ||
2039         !strcmp (in_plugin->name, "mpegvideo") ||
2040         !strcmp (in_plugin->name, "mjpeg") ||
2041         !strcmp (in_plugin->name, "redir") ||
2042         !strncmp (in_plugin->name, "u8", 2) ||
2043         !strncmp (in_plugin->name, "u16", 3) ||
2044         !strncmp (in_plugin->name, "u24", 3) ||
2045         !strncmp (in_plugin->name, "u32", 3) ||
2046         !strncmp (in_plugin->name, "s8", 2) ||
2047         !strncmp (in_plugin->name, "s16", 3) ||
2048         !strncmp (in_plugin->name, "s24", 3) ||
2049         !strncmp (in_plugin->name, "s32", 3) ||
2050         !strncmp (in_plugin->name, "f32", 3) ||
2051         !strncmp (in_plugin->name, "f64", 3) ||
2052         !strcmp (in_plugin->name, "mulaw") || !strcmp (in_plugin->name, "alaw")
2053         )
2054       continue;
2055
2056     /* no network demuxers */
2057     if (!strcmp (in_plugin->name, "sdp") ||
2058         !strcmp (in_plugin->name, "rtsp") ||
2059         !strcmp (in_plugin->name, "applehttp")
2060         )
2061       continue;
2062
2063     /* these don't do what one would expect or
2064      * are only partially functional/useful */
2065     if (!strcmp (in_plugin->name, "aac") ||
2066         !strcmp (in_plugin->name, "wv") ||
2067         !strcmp (in_plugin->name, "ass") ||
2068         !strcmp (in_plugin->name, "ffmetadata"))
2069       continue;
2070
2071     /* Don't use the typefind functions of formats for which we already have
2072      * better typefind functions */
2073     if (!strcmp (in_plugin->name, "mov,mp4,m4a,3gp,3g2,mj2") ||
2074         !strcmp (in_plugin->name, "ass") ||
2075         !strcmp (in_plugin->name, "avi") ||
2076         !strcmp (in_plugin->name, "asf") ||
2077         !strcmp (in_plugin->name, "mpegvideo") ||
2078         !strcmp (in_plugin->name, "mp3") ||
2079         !strcmp (in_plugin->name, "matroska") ||
2080         !strcmp (in_plugin->name, "matroska_webm") ||
2081         !strcmp (in_plugin->name, "matroska,webm") ||
2082         !strcmp (in_plugin->name, "mpeg") ||
2083         !strcmp (in_plugin->name, "wav") ||
2084         !strcmp (in_plugin->name, "au") ||
2085         !strcmp (in_plugin->name, "tta") ||
2086         !strcmp (in_plugin->name, "rm") ||
2087         !strcmp (in_plugin->name, "amr") ||
2088         !strcmp (in_plugin->name, "ogg") ||
2089         !strcmp (in_plugin->name, "aiff") ||
2090         !strcmp (in_plugin->name, "ape") ||
2091         !strcmp (in_plugin->name, "dv") ||
2092         !strcmp (in_plugin->name, "flv") ||
2093         !strcmp (in_plugin->name, "mpc") ||
2094         !strcmp (in_plugin->name, "mpc8") ||
2095         !strcmp (in_plugin->name, "mpegts") ||
2096         !strcmp (in_plugin->name, "mpegtsraw") ||
2097         !strcmp (in_plugin->name, "mxf") ||
2098         !strcmp (in_plugin->name, "nuv") ||
2099         !strcmp (in_plugin->name, "swf") ||
2100         !strcmp (in_plugin->name, "voc") ||
2101         !strcmp (in_plugin->name, "pva") ||
2102         !strcmp (in_plugin->name, "gif") ||
2103         !strcmp (in_plugin->name, "vc1test") ||
2104         !strcmp (in_plugin->name, "ivf"))
2105       register_typefind_func = FALSE;
2106
2107     /* Set the rank of demuxers known to work to MARGINAL.
2108      * Set demuxers for which we already have another implementation to NONE
2109      * Set All others to NONE*/
2110     /**
2111      * element-avdemux_xwma
2112      *
2113      * Since: 1.20
2114      */
2115     if (!strcmp (in_plugin->name, "wsvqa") ||
2116         !strcmp (in_plugin->name, "wsaud") ||
2117         !strcmp (in_plugin->name, "wc3movie") ||
2118         !strcmp (in_plugin->name, "voc") ||
2119         !strcmp (in_plugin->name, "tta") ||
2120         !strcmp (in_plugin->name, "sol") ||
2121         !strcmp (in_plugin->name, "smk") ||
2122         !strcmp (in_plugin->name, "vmd") ||
2123         !strcmp (in_plugin->name, "film_cpk") ||
2124         !strcmp (in_plugin->name, "ingenient") ||
2125         !strcmp (in_plugin->name, "psxstr") ||
2126         !strcmp (in_plugin->name, "nuv") ||
2127         !strcmp (in_plugin->name, "nut") ||
2128         !strcmp (in_plugin->name, "nsv") ||
2129         !strcmp (in_plugin->name, "mxf") ||
2130         !strcmp (in_plugin->name, "mmf") ||
2131         !strcmp (in_plugin->name, "mm") ||
2132         !strcmp (in_plugin->name, "ipmovie") ||
2133         !strcmp (in_plugin->name, "ape") ||
2134         !strcmp (in_plugin->name, "RoQ") ||
2135         !strcmp (in_plugin->name, "idcin") ||
2136         !strcmp (in_plugin->name, "gxf") ||
2137         !strcmp (in_plugin->name, "ffm") ||
2138         !strcmp (in_plugin->name, "ea") ||
2139         !strcmp (in_plugin->name, "daud") ||
2140         !strcmp (in_plugin->name, "avs") ||
2141         !strcmp (in_plugin->name, "aiff") ||
2142         !strcmp (in_plugin->name, "xwma") ||
2143         !strcmp (in_plugin->name, "4xm") ||
2144         !strcmp (in_plugin->name, "yuv4mpegpipe") ||
2145         !strcmp (in_plugin->name, "pva") ||
2146         !strcmp (in_plugin->name, "mpc") ||
2147         !strcmp (in_plugin->name, "mpc8") ||
2148         !strcmp (in_plugin->name, "ivf") ||
2149         !strcmp (in_plugin->name, "brstm") ||
2150         !strcmp (in_plugin->name, "bfstm") ||
2151         !strcmp (in_plugin->name, "gif") ||
2152         !strcmp (in_plugin->name, "dsf") || !strcmp (in_plugin->name, "iff"))
2153       rank = GST_RANK_MARGINAL;
2154     else {
2155       GST_DEBUG ("ignoring %s", in_plugin->name);
2156       rank = GST_RANK_NONE;
2157       continue;
2158     }
2159
2160     /* construct the type */
2161     type_name = g_strdup_printf ("avdemux_%s", in_plugin->name);
2162     g_strdelimit (type_name, ".,|-<> ", '_');
2163
2164     /* if it's already registered, drop it */
2165     if (g_type_from_name (type_name)) {
2166       g_free (type_name);
2167       continue;
2168     }
2169
2170     typefind_name = g_strdup_printf ("avtype_%s", in_plugin->name);
2171     g_strdelimit (typefind_name, ".,|-<> ", '_');
2172
2173     /* create the type now */
2174     type = g_type_register_static (GST_TYPE_ELEMENT, type_name, &typeinfo, 0);
2175     g_type_set_qdata (type, GST_FFDEMUX_PARAMS_QDATA, (gpointer) in_plugin);
2176
2177     if (in_plugin->extensions)
2178       extensions = g_strdelimit (g_strdup (in_plugin->extensions), " ", ',');
2179     else
2180       extensions = NULL;
2181
2182     if (!gst_element_register (plugin, type_name, rank, type) ||
2183         (register_typefind_func == TRUE &&
2184             !gst_type_find_register (plugin, typefind_name, rank,
2185                 gst_ffmpegdemux_type_find, extensions, NULL,
2186                 (gpointer) in_plugin, NULL))) {
2187       g_warning ("Registration of type %s failed", type_name);
2188       g_free (type_name);
2189       g_free (typefind_name);
2190       g_free (extensions);
2191       return FALSE;
2192     }
2193
2194     g_free (type_name);
2195     g_free (typefind_name);
2196     g_free (extensions);
2197   }
2198
2199   GST_LOG ("Finished registering demuxers");
2200
2201   return TRUE;
2202 }