gst: Don't swap start/stop for negative rates in the SEGMENT query
[platform/upstream/gst-plugins-ugly.git] / gst / asfdemux / gstasfdemux.c
1 /* GStreamer ASF/WMV/WMA demuxer
2  * Copyright (C) 1999 Erik Walthinsen <omega@cse.ogi.edu>
3  * Copyright (C) 2006-2009 Tim-Philipp Müller <tim centricular net>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20
21 /* TODO:
22  *
23  * - _loop():
24  *   stop if at end of segment if != end of file, ie. demux->segment.stop
25  *
26  * - fix packet parsing:
27  *   there's something wrong with timestamps for packets with keyframes,
28  *   and durations too.
29  */
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #include <gst/gstutils.h>
36 #include <gst/base/gstbytereader.h>
37 #include <gst/base/gsttypefindhelper.h>
38 #include <gst/riff/riff-media.h>
39 #include <gst/tag/tag.h>
40 #include <gst/gst-i18n-plugin.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44
45 #include "gstasfdemux.h"
46 #include "asfheaders.h"
47 #include "asfpacket.h"
48
49 static GstStaticPadTemplate gst_asf_demux_sink_template =
50 GST_STATIC_PAD_TEMPLATE ("sink",
51     GST_PAD_SINK,
52     GST_PAD_ALWAYS,
53     GST_STATIC_CAPS ("video/x-ms-asf")
54     );
55
56 static GstStaticPadTemplate audio_src_template =
57 GST_STATIC_PAD_TEMPLATE ("audio_%u",
58     GST_PAD_SRC,
59     GST_PAD_SOMETIMES,
60     GST_STATIC_CAPS_ANY);
61
62 static GstStaticPadTemplate video_src_template =
63 GST_STATIC_PAD_TEMPLATE ("video_%u",
64     GST_PAD_SRC,
65     GST_PAD_SOMETIMES,
66     GST_STATIC_CAPS_ANY);
67
68 /* size of an ASF object header, ie. GUID (16 bytes) + object size (8 bytes) */
69 #define ASF_OBJECT_HEADER_SIZE  (16+8)
70
71 /* FIXME: get rid of this */
72 /* abuse this GstFlowReturn enum for internal usage */
73 #define ASF_FLOW_NEED_MORE_DATA  99
74
75 #define gst_asf_get_flow_name(flow)    \
76   (flow == ASF_FLOW_NEED_MORE_DATA) ?  \
77   "need-more-data" : gst_flow_get_name (flow)
78
79 GST_DEBUG_CATEGORY (asfdemux_dbg);
80
81 static GstStateChangeReturn gst_asf_demux_change_state (GstElement * element,
82     GstStateChange transition);
83 static gboolean gst_asf_demux_element_send_event (GstElement * element,
84     GstEvent * event);
85 static gboolean gst_asf_demux_send_event_unlocked (GstASFDemux * demux,
86     GstEvent * event);
87 static gboolean gst_asf_demux_handle_src_query (GstPad * pad,
88     GstObject * parent, GstQuery * query);
89 static GstFlowReturn gst_asf_demux_chain (GstPad * pad, GstObject * parent,
90     GstBuffer * buf);
91 static gboolean gst_asf_demux_sink_event (GstPad * pad, GstObject * parent,
92     GstEvent * event);
93 static GstFlowReturn gst_asf_demux_process_object (GstASFDemux * demux,
94     guint8 ** p_data, guint64 * p_size);
95 static gboolean gst_asf_demux_activate (GstPad * sinkpad, GstObject * parent);
96 static gboolean gst_asf_demux_activate_mode (GstPad * sinkpad,
97     GstObject * parent, GstPadMode mode, gboolean active);
98 static void gst_asf_demux_loop (GstASFDemux * demux);
99 static void
100 gst_asf_demux_process_queued_extended_stream_objects (GstASFDemux * demux);
101 static gboolean gst_asf_demux_pull_headers (GstASFDemux * demux);
102 static void gst_asf_demux_pull_indices (GstASFDemux * demux);
103 static void gst_asf_demux_reset_stream_state_after_discont (GstASFDemux * asf);
104 static gboolean
105 gst_asf_demux_parse_data_object_start (GstASFDemux * demux, guint8 * data);
106 static void gst_asf_demux_descramble_buffer (GstASFDemux * demux,
107     AsfStream * stream, GstBuffer ** p_buffer);
108 static void gst_asf_demux_activate_stream (GstASFDemux * demux,
109     AsfStream * stream);
110 static GstStructure *gst_asf_demux_get_metadata_for_stream (GstASFDemux * d,
111     guint stream_num);
112 static GstFlowReturn gst_asf_demux_push_complete_payloads (GstASFDemux * demux,
113     gboolean force);
114
115 #define gst_asf_demux_parent_class parent_class
116 G_DEFINE_TYPE (GstASFDemux, gst_asf_demux, GST_TYPE_ELEMENT);
117
118 static void
119 gst_asf_demux_class_init (GstASFDemuxClass * klass)
120 {
121   GstElementClass *gstelement_class;
122
123   gstelement_class = (GstElementClass *) klass;
124
125   gst_element_class_set_static_metadata (gstelement_class, "ASF Demuxer",
126       "Codec/Demuxer",
127       "Demultiplexes ASF Streams", "Owen Fraser-Green <owen@discobabe.net>");
128
129   gst_element_class_add_pad_template (gstelement_class,
130       gst_static_pad_template_get (&audio_src_template));
131   gst_element_class_add_pad_template (gstelement_class,
132       gst_static_pad_template_get (&video_src_template));
133   gst_element_class_add_pad_template (gstelement_class,
134       gst_static_pad_template_get (&gst_asf_demux_sink_template));
135
136   gstelement_class->change_state =
137       GST_DEBUG_FUNCPTR (gst_asf_demux_change_state);
138   gstelement_class->send_event =
139       GST_DEBUG_FUNCPTR (gst_asf_demux_element_send_event);
140 }
141
142 static void
143 gst_asf_demux_free_stream (GstASFDemux * demux, AsfStream * stream)
144 {
145   gst_caps_replace (&stream->caps, NULL);
146   if (stream->pending_tags) {
147     gst_tag_list_unref (stream->pending_tags);
148     stream->pending_tags = NULL;
149   }
150   if (stream->pad) {
151     if (stream->active)
152       gst_element_remove_pad (GST_ELEMENT_CAST (demux), stream->pad);
153     else
154       gst_object_unref (stream->pad);
155     stream->pad = NULL;
156   }
157
158   while (stream->payloads->len > 0) {
159     AsfPayload *payload;
160     guint last;
161
162     last = stream->payloads->len - 1;
163     payload = &g_array_index (stream->payloads, AsfPayload, last);
164     gst_buffer_replace (&payload->buf, NULL);
165     g_array_remove_index (stream->payloads, last);
166   }
167   if (stream->payloads) {
168     g_array_free (stream->payloads, TRUE);
169     stream->payloads = NULL;
170   }
171   if (stream->ext_props.valid) {
172     g_free (stream->ext_props.payload_extensions);
173     stream->ext_props.payload_extensions = NULL;
174   }
175 }
176
177 static void
178 gst_asf_demux_reset (GstASFDemux * demux, gboolean chain_reset)
179 {
180   GST_LOG_OBJECT (demux, "resetting");
181
182   gst_segment_init (&demux->segment, GST_FORMAT_UNDEFINED);
183   demux->segment_running = FALSE;
184   if (demux->adapter && !chain_reset) {
185     gst_adapter_clear (demux->adapter);
186     g_object_unref (demux->adapter);
187     demux->adapter = NULL;
188   }
189   if (demux->taglist) {
190     gst_tag_list_unref (demux->taglist);
191     demux->taglist = NULL;
192   }
193   if (demux->metadata) {
194     gst_caps_unref (demux->metadata);
195     demux->metadata = NULL;
196   }
197   if (demux->global_metadata) {
198     gst_structure_free (demux->global_metadata);
199     demux->global_metadata = NULL;
200   }
201
202   demux->state = GST_ASF_DEMUX_STATE_HEADER;
203   g_free (demux->objpath);
204   demux->objpath = NULL;
205   g_strfreev (demux->languages);
206   demux->languages = NULL;
207   demux->num_languages = 0;
208   g_slist_foreach (demux->ext_stream_props, (GFunc) gst_mini_object_unref,
209       NULL);
210   g_slist_free (demux->ext_stream_props);
211   demux->ext_stream_props = NULL;
212
213   while (demux->old_num_streams > 0) {
214     gst_asf_demux_free_stream (demux,
215         &demux->old_stream[demux->old_num_streams - 1]);
216     --demux->old_num_streams;
217   }
218   memset (demux->old_stream, 0, sizeof (demux->old_stream));
219   demux->old_num_streams = 0;
220
221   /* when resetting for a new chained asf, we don't want to remove the pads
222    * before adding the new ones */
223   if (chain_reset) {
224     memcpy (demux->old_stream, demux->stream, sizeof (demux->stream));
225     demux->old_num_streams = demux->num_streams;
226     demux->num_streams = 0;
227   }
228
229   while (demux->num_streams > 0) {
230     gst_asf_demux_free_stream (demux, &demux->stream[demux->num_streams - 1]);
231     --demux->num_streams;
232   }
233   memset (demux->stream, 0, sizeof (demux->stream));
234   if (!chain_reset) {
235     /* do not remove those for not adding pads with same name */
236     demux->num_audio_streams = 0;
237     demux->num_video_streams = 0;
238     demux->have_group_id = FALSE;
239     demux->group_id = G_MAXUINT;
240   }
241   demux->num_streams = 0;
242   demux->activated_streams = FALSE;
243   demux->first_ts = GST_CLOCK_TIME_NONE;
244   demux->segment_ts = GST_CLOCK_TIME_NONE;
245   demux->in_gap = 0;
246   if (!chain_reset)
247     gst_segment_init (&demux->in_segment, GST_FORMAT_UNDEFINED);
248   demux->state = GST_ASF_DEMUX_STATE_HEADER;
249   demux->seekable = FALSE;
250   demux->broadcast = FALSE;
251   demux->sidx_interval = 0;
252   demux->sidx_num_entries = 0;
253   g_free (demux->sidx_entries);
254   demux->sidx_entries = NULL;
255
256   demux->speed_packets = 1;
257
258   if (chain_reset) {
259     GST_LOG_OBJECT (demux, "Restarting");
260     gst_segment_init (&demux->segment, GST_FORMAT_TIME);
261     demux->need_newsegment = TRUE;
262     demux->segment_seqnum = 0;
263     demux->segment_running = FALSE;
264     demux->accurate = FALSE;
265     demux->metadata = gst_caps_new_empty ();
266     demux->global_metadata = gst_structure_new_empty ("metadata");
267     demux->data_size = 0;
268     demux->data_offset = 0;
269     demux->index_offset = 0;
270   } else {
271     demux->base_offset = 0;
272   }
273
274   g_slist_free (demux->other_streams);
275   demux->other_streams = NULL;
276 }
277
278 static void
279 gst_asf_demux_init (GstASFDemux * demux)
280 {
281   demux->sinkpad =
282       gst_pad_new_from_static_template (&gst_asf_demux_sink_template, "sink");
283   gst_pad_set_chain_function (demux->sinkpad,
284       GST_DEBUG_FUNCPTR (gst_asf_demux_chain));
285   gst_pad_set_event_function (demux->sinkpad,
286       GST_DEBUG_FUNCPTR (gst_asf_demux_sink_event));
287   gst_pad_set_activate_function (demux->sinkpad,
288       GST_DEBUG_FUNCPTR (gst_asf_demux_activate));
289   gst_pad_set_activatemode_function (demux->sinkpad,
290       GST_DEBUG_FUNCPTR (gst_asf_demux_activate_mode));
291   gst_element_add_pad (GST_ELEMENT (demux), demux->sinkpad);
292
293   /* set initial state */
294   gst_asf_demux_reset (demux, FALSE);
295 }
296
297 static gboolean
298 gst_asf_demux_activate (GstPad * sinkpad, GstObject * parent)
299 {
300   GstQuery *query;
301   gboolean pull_mode;
302
303   query = gst_query_new_scheduling ();
304
305   if (!gst_pad_peer_query (sinkpad, query)) {
306     gst_query_unref (query);
307     goto activate_push;
308   }
309
310   pull_mode = gst_query_has_scheduling_mode_with_flags (query,
311       GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
312   gst_query_unref (query);
313
314   if (!pull_mode)
315     goto activate_push;
316
317   GST_DEBUG_OBJECT (sinkpad, "activating pull");
318   return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);
319
320 activate_push:
321   {
322     GST_DEBUG_OBJECT (sinkpad, "activating push");
323     return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
324   }
325 }
326
327 static gboolean
328 gst_asf_demux_activate_mode (GstPad * sinkpad, GstObject * parent,
329     GstPadMode mode, gboolean active)
330 {
331   gboolean res;
332   GstASFDemux *demux;
333
334   demux = GST_ASF_DEMUX (parent);
335
336   switch (mode) {
337     case GST_PAD_MODE_PUSH:
338       demux->state = GST_ASF_DEMUX_STATE_HEADER;
339       demux->streaming = TRUE;
340       res = TRUE;
341       break;
342     case GST_PAD_MODE_PULL:
343       if (active) {
344         demux->state = GST_ASF_DEMUX_STATE_HEADER;
345         demux->streaming = FALSE;
346
347         res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_asf_demux_loop,
348             demux, NULL);
349       } else {
350         res = gst_pad_stop_task (sinkpad);
351       }
352       break;
353     default:
354       res = FALSE;
355       break;
356   }
357   return res;
358 }
359
360 static gboolean
361 gst_asf_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
362 {
363   GstASFDemux *demux;
364   gboolean ret = TRUE;
365
366   demux = GST_ASF_DEMUX (parent);
367
368   GST_LOG_OBJECT (demux, "handling %s event", GST_EVENT_TYPE_NAME (event));
369   switch (GST_EVENT_TYPE (event)) {
370     case GST_EVENT_SEGMENT:{
371       const GstSegment *segment;
372
373       gst_event_parse_segment (event, &segment);
374
375       if (segment->format == GST_FORMAT_BYTES) {
376         if (demux->packet_size && segment->start > demux->data_offset)
377           demux->packet = (segment->start - demux->data_offset) /
378               demux->packet_size;
379         else
380           demux->packet = 0;
381       } else if (segment->format == GST_FORMAT_TIME) {
382         /* do not know packet position, not really a problem */
383         demux->packet = -1;
384       } else {
385         GST_WARNING_OBJECT (demux, "unsupported newsegment format, ignoring");
386         gst_event_unref (event);
387         break;
388       }
389
390       /* record upstream segment for interpolation */
391       if (segment->format != demux->in_segment.format)
392         gst_segment_init (&demux->in_segment, GST_FORMAT_UNDEFINED);
393       gst_segment_copy_into (segment, &demux->in_segment);
394
395       /* in either case, clear some state and generate newsegment later on */
396       GST_OBJECT_LOCK (demux);
397       demux->segment_ts = GST_CLOCK_TIME_NONE;
398       demux->in_gap = GST_CLOCK_TIME_NONE;
399       demux->need_newsegment = TRUE;
400       demux->segment_seqnum = gst_event_get_seqnum (event);
401       gst_asf_demux_reset_stream_state_after_discont (demux);
402       GST_OBJECT_UNLOCK (demux);
403
404       gst_event_unref (event);
405       break;
406     }
407     case GST_EVENT_EOS:{
408       GstFlowReturn flow;
409
410       if (demux->state == GST_ASF_DEMUX_STATE_HEADER) {
411         GST_ELEMENT_ERROR (demux, STREAM, DEMUX,
412             (_("This stream contains no data.")),
413             ("got eos and didn't receive a complete header object"));
414         break;
415       }
416       flow = gst_asf_demux_push_complete_payloads (demux, TRUE);
417       if (flow < GST_FLOW_EOS || flow == GST_FLOW_NOT_LINKED) {
418         GST_ELEMENT_ERROR (demux, STREAM, FAILED,
419             (_("Internal data stream error.")),
420             ("streaming stopped, reason %s", gst_flow_get_name (flow)));
421         break;
422       }
423
424       GST_OBJECT_LOCK (demux);
425       gst_adapter_clear (demux->adapter);
426       GST_OBJECT_UNLOCK (demux);
427       gst_asf_demux_send_event_unlocked (demux, event);
428       break;
429     }
430
431     case GST_EVENT_FLUSH_STOP:
432       GST_OBJECT_LOCK (demux);
433       gst_asf_demux_reset_stream_state_after_discont (demux);
434       GST_OBJECT_UNLOCK (demux);
435       gst_asf_demux_send_event_unlocked (demux, event);
436       /* upon activation, latency is no longer introduced, e.g. after seek */
437       if (demux->activated_streams)
438         demux->latency = 0;
439       break;
440
441     default:
442       ret = gst_pad_event_default (pad, parent, event);
443       break;
444   }
445
446   return ret;
447 }
448
449 static gboolean
450 gst_asf_demux_seek_index_lookup (GstASFDemux * demux, guint * packet,
451     GstClockTime seek_time, GstClockTime * p_idx_time, guint * speed,
452     gboolean next, gboolean * eos)
453 {
454   GstClockTime idx_time;
455   guint idx;
456
457   if (eos)
458     *eos = FALSE;
459
460   if (G_UNLIKELY (demux->sidx_num_entries == 0 || demux->sidx_interval == 0))
461     return FALSE;
462
463   idx = (guint) ((seek_time + demux->preroll) / demux->sidx_interval);
464
465   if (next) {
466     /* if we want the next keyframe, we have to go forward till we find
467        a different packet number */
468     guint idx2 = idx;
469     if (idx >= demux->sidx_num_entries - 1) {
470       /* If we get here, we're asking for next keyframe after the last one. There isn't one. */
471       if (eos)
472         *eos = TRUE;
473       return FALSE;
474     }
475     for (idx2 = idx + 1; idx2 < demux->sidx_num_entries; ++idx2) {
476       if (demux->sidx_entries[idx].packet != demux->sidx_entries[idx2].packet) {
477         idx = idx2;
478         break;
479       }
480     }
481   }
482
483   if (G_UNLIKELY (idx >= demux->sidx_num_entries)) {
484     if (eos)
485       *eos = TRUE;
486     return FALSE;
487   }
488
489   *packet = demux->sidx_entries[idx].packet;
490   if (speed)
491     *speed = demux->sidx_entries[idx].count;
492
493   /* so we get closer to the actual time of the packet ... actually, let's not
494    * do this, since we throw away superfluous payloads before the seek position
495    * anyway; this way, our key unit seek 'snap resolution' is a bit better
496    * (ie. same as index resolution) */
497   /*
498      while (idx > 0 && demux->sidx_entries[idx-1] == demux->sidx_entries[idx])
499      --idx;
500    */
501
502   idx_time = demux->sidx_interval * idx;
503   if (G_LIKELY (idx_time >= demux->preroll))
504     idx_time -= demux->preroll;
505
506   GST_DEBUG_OBJECT (demux, "%" GST_TIME_FORMAT " => packet %u at %"
507       GST_TIME_FORMAT, GST_TIME_ARGS (seek_time), *packet,
508       GST_TIME_ARGS (idx_time));
509
510   if (G_LIKELY (p_idx_time))
511     *p_idx_time = idx_time;
512
513   return TRUE;
514 }
515
516 static void
517 gst_asf_demux_reset_stream_state_after_discont (GstASFDemux * demux)
518 {
519   guint n;
520
521   gst_adapter_clear (demux->adapter);
522
523   GST_DEBUG_OBJECT (demux, "reset stream state");
524
525   for (n = 0; n < demux->num_streams; n++) {
526     demux->stream[n].discont = TRUE;
527     demux->stream[n].last_flow = GST_FLOW_OK;
528
529     while (demux->stream[n].payloads->len > 0) {
530       AsfPayload *payload;
531       guint last;
532
533       last = demux->stream[n].payloads->len - 1;
534       payload = &g_array_index (demux->stream[n].payloads, AsfPayload, last);
535       gst_buffer_replace (&payload->buf, NULL);
536       g_array_remove_index (demux->stream[n].payloads, last);
537     }
538   }
539 }
540
541 static void
542 gst_asf_demux_mark_discont (GstASFDemux * demux)
543 {
544   guint n;
545
546   GST_DEBUG_OBJECT (demux, "Mark stream discont");
547
548   for (n = 0; n < demux->num_streams; n++)
549     demux->stream[n].discont = TRUE;
550 }
551
552 /* do a seek in push based mode */
553 static gboolean
554 gst_asf_demux_handle_seek_push (GstASFDemux * demux, GstEvent * event)
555 {
556   gdouble rate;
557   GstFormat format;
558   GstSeekFlags flags;
559   GstSeekType cur_type, stop_type;
560   gint64 cur, stop;
561   guint packet;
562   gboolean res;
563   GstEvent *byte_event;
564
565   gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
566       &stop_type, &stop);
567
568   stop_type = GST_SEEK_TYPE_NONE;
569   stop = -1;
570
571   GST_DEBUG_OBJECT (demux, "seeking to %" GST_TIME_FORMAT, GST_TIME_ARGS (cur));
572
573   /* determine packet, by index or by estimation */
574   if (!gst_asf_demux_seek_index_lookup (demux, &packet, cur, NULL, NULL, FALSE,
575           NULL)) {
576     packet =
577         (guint) gst_util_uint64_scale (demux->num_packets, cur,
578         demux->play_time);
579   }
580
581   if (packet > demux->num_packets) {
582     GST_DEBUG_OBJECT (demux, "could not determine packet to seek to, "
583         "seek aborted.");
584     return FALSE;
585   }
586
587   GST_DEBUG_OBJECT (demux, "seeking to packet %d", packet);
588
589   cur = demux->data_offset + (packet * demux->packet_size);
590
591   GST_DEBUG_OBJECT (demux, "Pushing BYTE seek rate %g, "
592       "start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT, rate, cur, stop);
593   /* BYTE seek event */
594   byte_event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type,
595       cur, stop_type, stop);
596   gst_event_set_seqnum (byte_event, gst_event_get_seqnum (event));
597   res = gst_pad_push_event (demux->sinkpad, byte_event);
598
599   return res;
600 }
601
602 static gboolean
603 gst_asf_demux_handle_seek_event (GstASFDemux * demux, GstEvent * event)
604 {
605   GstClockTime idx_time;
606   GstSegment segment;
607   GstSeekFlags flags;
608   GstSeekType cur_type, stop_type;
609   GstFormat format;
610   gboolean only_need_update;
611   gboolean keyunit_sync, after, before, next;
612   gboolean flush;
613   gdouble rate;
614   gint64 cur, stop;
615   gint64 seek_time;
616   guint packet, speed_count = 1;
617   gboolean eos;
618   guint32 seqnum;
619   GstEvent *fevent;
620
621   if (G_UNLIKELY (demux->seekable == FALSE || demux->packet_size == 0 ||
622           demux->num_packets == 0 || demux->play_time == 0)) {
623     GST_LOG_OBJECT (demux, "stream is not seekable");
624     return FALSE;
625   }
626
627   if (G_UNLIKELY (!demux->activated_streams)) {
628     GST_LOG_OBJECT (demux, "streams not yet activated, ignoring seek");
629     return FALSE;
630   }
631
632   gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
633       &stop_type, &stop);
634   seqnum = gst_event_get_seqnum (event);
635
636   if (G_UNLIKELY (format != GST_FORMAT_TIME)) {
637     GST_LOG_OBJECT (demux, "seeking is only supported in TIME format");
638     return FALSE;
639   }
640
641   if (G_UNLIKELY (rate <= 0.0)) {
642     GST_LOG_OBJECT (demux, "backward playback is not supported yet");
643     return FALSE;
644   }
645
646   flush = ((flags & GST_SEEK_FLAG_FLUSH) == GST_SEEK_FLAG_FLUSH);
647   demux->accurate =
648       ((flags & GST_SEEK_FLAG_ACCURATE) == GST_SEEK_FLAG_ACCURATE);
649   keyunit_sync = ((flags & GST_SEEK_FLAG_KEY_UNIT) == GST_SEEK_FLAG_KEY_UNIT);
650   after = ((flags & GST_SEEK_FLAG_SNAP_AFTER) == GST_SEEK_FLAG_SNAP_AFTER);
651   before = ((flags & GST_SEEK_FLAG_SNAP_BEFORE) == GST_SEEK_FLAG_SNAP_BEFORE);
652   next = after && !before;
653
654   if (G_UNLIKELY (demux->streaming)) {
655     /* support it safely needs more segment handling, e.g. closing etc */
656     if (!flush) {
657       GST_LOG_OBJECT (demux, "streaming; non-flushing seek not supported");
658       return FALSE;
659     }
660     /* we can (re)construct the start later on, but not the end */
661     if (stop_type != GST_SEEK_TYPE_NONE &&
662         (stop_type != GST_SEEK_TYPE_SET || GST_CLOCK_TIME_IS_VALID (stop))) {
663       GST_LOG_OBJECT (demux, "streaming; end position must be NONE");
664       return FALSE;
665     }
666     gst_event_ref (event);
667     /* upstream might handle TIME seek, e.g. mms or rtsp,
668      * or not, e.g. http, then we give it a hand */
669     if (!gst_pad_push_event (demux->sinkpad, event))
670       return gst_asf_demux_handle_seek_push (demux, event);
671     else
672       return TRUE;
673   }
674
675   /* unlock the streaming thread */
676   if (G_LIKELY (flush)) {
677     fevent = gst_event_new_flush_start ();
678
679     gst_event_set_seqnum (fevent, seqnum);
680     gst_pad_push_event (demux->sinkpad, gst_event_ref (fevent));
681     gst_asf_demux_send_event_unlocked (demux, fevent);
682   } else {
683     gst_pad_pause_task (demux->sinkpad);
684   }
685
686   /* grab the stream lock so that streaming cannot continue, for
687    * non flushing seeks when the element is in PAUSED this could block
688    * forever */
689   GST_PAD_STREAM_LOCK (demux->sinkpad);
690
691   /* we now can stop flushing, since we have the stream lock now */
692   fevent = gst_event_new_flush_stop (TRUE);
693   gst_event_set_seqnum (fevent, seqnum);
694   gst_pad_push_event (demux->sinkpad, gst_event_ref (fevent));
695
696   if (G_LIKELY (flush))
697     gst_asf_demux_send_event_unlocked (demux, fevent);
698   else
699     gst_event_unref (fevent);
700
701   /* operating on copy of segment until we know the seek worked */
702   segment = demux->segment;
703
704   if (G_UNLIKELY (demux->segment_running && !flush)) {
705     GstSegment newsegment;
706     GstEvent *newseg;
707
708     /* create the segment event to close the current segment */
709     gst_segment_copy_into (&segment, &newsegment);
710     newseg = gst_event_new_segment (&newsegment);
711     gst_event_set_seqnum (newseg, seqnum);
712
713     gst_asf_demux_send_event_unlocked (demux, newseg);
714   }
715
716   gst_segment_do_seek (&segment, rate, format, flags, cur_type,
717       cur, stop_type, stop, &only_need_update);
718
719   GST_DEBUG_OBJECT (demux, "seeking to time %" GST_TIME_FORMAT ", segment: "
720       "%" GST_SEGMENT_FORMAT, GST_TIME_ARGS (segment.start), &segment);
721
722   seek_time = segment.start;
723
724   /* FIXME: should check the KEY_UNIT flag; need to adjust position to
725    * real start of data and segment_start to indexed time for key unit seek*/
726   if (G_UNLIKELY (!gst_asf_demux_seek_index_lookup (demux, &packet, seek_time,
727               &idx_time, &speed_count, next, &eos))) {
728     gint64 offset;
729
730     if (eos) {
731       demux->packet = demux->num_packets;
732       goto skip;
733     }
734
735     /* First try to query our source to see if it can convert for us. This is
736        the case when our source is an mms stream, notice that in this case
737        gstmms will do a time based seek to get the byte offset, this is not a
738        problem as the seek to this offset needs to happen anway. */
739     if (gst_pad_peer_query_convert (demux->sinkpad, GST_FORMAT_TIME, seek_time,
740             GST_FORMAT_BYTES, &offset)) {
741       packet = (offset - demux->data_offset) / demux->packet_size;
742       GST_LOG_OBJECT (demux, "convert %" GST_TIME_FORMAT
743           " to bytes query result: %" G_GINT64_FORMAT ", data_ofset: %"
744           G_GINT64_FORMAT ", packet_size: %u," " resulting packet: %u\n",
745           GST_TIME_ARGS (seek_time), offset, demux->data_offset,
746           demux->packet_size, packet);
747     } else {
748       /* FIXME: For streams containing video, seek to an earlier position in
749        * the hope of hitting a keyframe and let the sinks throw away the stuff
750        * before the segment start. For audio-only this is unnecessary as every
751        * frame is 'key'. */
752       if (flush && (demux->accurate || (keyunit_sync && !next))
753           && demux->num_video_streams > 0) {
754         seek_time -= 5 * GST_SECOND;
755         if (seek_time < 0)
756           seek_time = 0;
757       }
758
759       packet = (guint) gst_util_uint64_scale (demux->num_packets,
760           seek_time, demux->play_time);
761
762       if (packet > demux->num_packets)
763         packet = demux->num_packets;
764     }
765   } else {
766     if (G_LIKELY (keyunit_sync)) {
767       GST_DEBUG_OBJECT (demux, "key unit seek, adjust seek_time = %"
768           GST_TIME_FORMAT " to index_time = %" GST_TIME_FORMAT,
769           GST_TIME_ARGS (seek_time), GST_TIME_ARGS (idx_time));
770       segment.start = idx_time;
771       segment.position = idx_time;
772       segment.time = idx_time;
773     }
774   }
775
776   GST_DEBUG_OBJECT (demux, "seeking to packet %u (%d)", packet, speed_count);
777
778   GST_OBJECT_LOCK (demux);
779   demux->segment = segment;
780   demux->packet = packet;
781   demux->need_newsegment = TRUE;
782   demux->segment_seqnum = seqnum;
783   demux->speed_packets = speed_count;
784   gst_asf_demux_reset_stream_state_after_discont (demux);
785   GST_OBJECT_UNLOCK (demux);
786
787 skip:
788   /* restart our task since it might have been stopped when we did the flush */
789   gst_pad_start_task (demux->sinkpad, (GstTaskFunction) gst_asf_demux_loop,
790       demux, NULL);
791
792   /* streaming can continue now */
793   GST_PAD_STREAM_UNLOCK (demux->sinkpad);
794
795   return TRUE;
796 }
797
798 static gboolean
799 gst_asf_demux_handle_src_event (GstPad * pad, GstObject * parent,
800     GstEvent * event)
801 {
802   GstASFDemux *demux;
803   gboolean ret;
804
805   demux = GST_ASF_DEMUX (parent);
806
807   switch (GST_EVENT_TYPE (event)) {
808     case GST_EVENT_SEEK:
809       GST_LOG_OBJECT (pad, "seek event");
810       ret = gst_asf_demux_handle_seek_event (demux, event);
811       gst_event_unref (event);
812       break;
813     case GST_EVENT_QOS:
814     case GST_EVENT_NAVIGATION:
815       /* just drop these two silently */
816       gst_event_unref (event);
817       ret = FALSE;
818       break;
819     default:
820       GST_LOG_OBJECT (pad, "%s event", GST_EVENT_TYPE_NAME (event));
821       ret = gst_pad_event_default (pad, parent, event);
822       break;
823   }
824
825   return ret;
826 }
827
828 static inline guint32
829 gst_asf_demux_identify_guid (const ASFGuidHash * guids, ASFGuid * guid)
830 {
831   guint32 ret;
832
833   ret = gst_asf_identify_guid (guids, guid);
834
835   GST_LOG ("%s  0x%08x-0x%08x-0x%08x-0x%08x",
836       gst_asf_get_guid_nick (guids, ret),
837       guid->v1, guid->v2, guid->v3, guid->v4);
838
839   return ret;
840 }
841
842 typedef struct
843 {
844   AsfObjectID id;
845   guint64 size;
846 } AsfObject;
847
848
849 /* expect is true when the user is expeting an object,
850  * when false, it will give no warnings if the object
851  * is not identified
852  */
853 static gboolean
854 asf_demux_peek_object (GstASFDemux * demux, const guint8 * data,
855     guint data_len, AsfObject * object, gboolean expect)
856 {
857   ASFGuid guid;
858
859   if (data_len < ASF_OBJECT_HEADER_SIZE)
860     return FALSE;
861
862   guid.v1 = GST_READ_UINT32_LE (data + 0);
863   guid.v2 = GST_READ_UINT32_LE (data + 4);
864   guid.v3 = GST_READ_UINT32_LE (data + 8);
865   guid.v4 = GST_READ_UINT32_LE (data + 12);
866
867   object->size = GST_READ_UINT64_LE (data + 16);
868
869   /* FIXME: make asf_demux_identify_object_guid() */
870   object->id = gst_asf_demux_identify_guid (asf_object_guids, &guid);
871   if (object->id == ASF_OBJ_UNDEFINED && expect) {
872     GST_WARNING_OBJECT (demux, "Unknown object %08x-%08x-%08x-%08x",
873         guid.v1, guid.v2, guid.v3, guid.v4);
874   }
875
876   return TRUE;
877 }
878
879 static void
880 gst_asf_demux_release_old_pads (GstASFDemux * demux)
881 {
882   GST_DEBUG_OBJECT (demux, "Releasing old pads");
883
884   while (demux->old_num_streams > 0) {
885     gst_pad_push_event (demux->old_stream[demux->old_num_streams - 1].pad,
886         gst_event_new_eos ());
887     gst_asf_demux_free_stream (demux,
888         &demux->old_stream[demux->old_num_streams - 1]);
889     --demux->old_num_streams;
890   }
891   memset (demux->old_stream, 0, sizeof (demux->old_stream));
892   demux->old_num_streams = 0;
893 }
894
895 static GstFlowReturn
896 gst_asf_demux_chain_headers (GstASFDemux * demux)
897 {
898   GstFlowReturn flow;
899   AsfObject obj;
900   guint8 *header_data, *data = NULL;
901   const guint8 *cdata = NULL;
902   guint64 header_size;
903
904   cdata = (guint8 *) gst_adapter_map (demux->adapter, ASF_OBJECT_HEADER_SIZE);
905   if (cdata == NULL)
906     goto need_more_data;
907
908   asf_demux_peek_object (demux, cdata, ASF_OBJECT_HEADER_SIZE, &obj, TRUE);
909   if (obj.id != ASF_OBJ_HEADER)
910     goto wrong_type;
911
912   GST_LOG_OBJECT (demux, "header size = %u", (guint) obj.size);
913
914   /* + 50 for non-packet data at beginning of ASF_OBJ_DATA */
915   if (gst_adapter_available (demux->adapter) < obj.size + 50)
916     goto need_more_data;
917
918   data = gst_adapter_take (demux->adapter, obj.size + 50);
919
920   header_data = data;
921   header_size = obj.size;
922   flow = gst_asf_demux_process_object (demux, &header_data, &header_size);
923   if (flow != GST_FLOW_OK)
924     goto parse_failed;
925
926   /* calculate where the packet data starts */
927   demux->data_offset = obj.size + 50;
928
929   /* now parse the beginning of the ASF_OBJ_DATA object */
930   if (!gst_asf_demux_parse_data_object_start (demux, data + obj.size))
931     goto wrong_type;
932
933   if (demux->num_streams == 0)
934     goto no_streams;
935
936   g_free (data);
937   return GST_FLOW_OK;
938
939 /* NON-FATAL */
940 need_more_data:
941   {
942     GST_LOG_OBJECT (demux, "not enough data in adapter yet");
943     return GST_FLOW_OK;
944   }
945
946 /* ERRORS */
947 wrong_type:
948   {
949     GST_ELEMENT_ERROR (demux, STREAM, WRONG_TYPE, (NULL),
950         ("This doesn't seem to be an ASF file"));
951     g_free (data);
952     return GST_FLOW_ERROR;
953   }
954 no_streams:
955 parse_failed:
956   {
957     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
958         ("header parsing failed, or no streams found, flow = %s",
959             gst_flow_get_name (flow)));
960     g_free (data);
961     return GST_FLOW_ERROR;
962   }
963 }
964
965 static GstFlowReturn
966 gst_asf_demux_aggregate_flow_return (GstASFDemux * demux, AsfStream * stream,
967     GstFlowReturn flow)
968 {
969   int i;
970
971   GST_DEBUG_OBJECT (demux, "Aggregating");
972
973   /* Store the value */
974   stream->last_flow = flow;
975
976   /* any other error that is not not-linked can be returned right away */
977   if (flow != GST_FLOW_NOT_LINKED)
978     goto done;
979
980   for (i = 0; i < demux->num_streams; i++) {
981     if (demux->stream[i].active) {
982       flow = demux->stream[i].last_flow;
983       GST_DEBUG_OBJECT (demux, "Aggregating: flow %i return %s", i,
984           gst_flow_get_name (flow));
985       if (flow != GST_FLOW_NOT_LINKED)
986         goto done;
987     }
988   }
989
990   /* If we got here, then all our active streams are not linked */
991 done:
992   return flow;
993 }
994
995 static gboolean
996 gst_asf_demux_pull_data (GstASFDemux * demux, guint64 offset, guint size,
997     GstBuffer ** p_buf, GstFlowReturn * p_flow)
998 {
999   gsize buffer_size;
1000   GstFlowReturn flow;
1001
1002   GST_LOG_OBJECT (demux, "pulling buffer at %" G_GUINT64_FORMAT "+%u",
1003       offset, size);
1004
1005   flow = gst_pad_pull_range (demux->sinkpad, offset, size, p_buf);
1006
1007   if (G_LIKELY (p_flow))
1008     *p_flow = flow;
1009
1010   if (G_UNLIKELY (flow != GST_FLOW_OK)) {
1011     GST_DEBUG_OBJECT (demux, "flow %s pulling buffer at %" G_GUINT64_FORMAT
1012         "+%u", gst_flow_get_name (flow), offset, size);
1013     *p_buf = NULL;
1014     return FALSE;
1015   }
1016
1017   g_assert (*p_buf != NULL);
1018
1019   buffer_size = gst_buffer_get_size (*p_buf);
1020   if (G_UNLIKELY (buffer_size < size)) {
1021     GST_DEBUG_OBJECT (demux, "short read pulling buffer at %" G_GUINT64_FORMAT
1022         "+%u (got only %" G_GSIZE_FORMAT " bytes)", offset, size, buffer_size);
1023     gst_buffer_unref (*p_buf);
1024     if (G_LIKELY (p_flow))
1025       *p_flow = GST_FLOW_EOS;
1026     *p_buf = NULL;
1027     return FALSE;
1028   }
1029
1030   return TRUE;
1031 }
1032
1033 static void
1034 gst_asf_demux_pull_indices (GstASFDemux * demux)
1035 {
1036   GstBuffer *buf = NULL;
1037   guint64 offset;
1038   guint num_read = 0;
1039
1040   offset = demux->index_offset;
1041
1042   if (G_UNLIKELY (offset == 0)) {
1043     GST_DEBUG_OBJECT (demux, "can't read indices, don't know index offset");
1044     return;
1045   }
1046
1047   while (gst_asf_demux_pull_data (demux, offset, 16 + 8, &buf, NULL)) {
1048     GstFlowReturn flow;
1049     AsfObject obj;
1050     GstMapInfo map;
1051     guint8 *bufdata;
1052
1053     gst_buffer_map (buf, &map, GST_MAP_READ);
1054     g_assert (map.size >= 16 + 8);
1055     asf_demux_peek_object (demux, map.data, 16 + 8, &obj, TRUE);
1056     gst_buffer_unmap (buf, &map);
1057     gst_buffer_replace (&buf, NULL);
1058
1059     /* check for sanity */
1060     if (G_UNLIKELY (obj.size > (5 * 1024 * 1024))) {
1061       GST_DEBUG_OBJECT (demux, "implausible index object size, bailing out");
1062       break;
1063     }
1064
1065     if (G_UNLIKELY (!gst_asf_demux_pull_data (demux, offset, obj.size, &buf,
1066                 NULL)))
1067       break;
1068
1069     GST_LOG_OBJECT (demux, "index object at offset 0x%" G_GINT64_MODIFIER "X"
1070         ", size %u", offset, (guint) obj.size);
1071
1072     offset += obj.size;         /* increase before _process_object changes it */
1073
1074     gst_buffer_map (buf, &map, GST_MAP_READ);
1075     g_assert (map.size >= obj.size);
1076     bufdata = (guint8 *) map.data;
1077     flow = gst_asf_demux_process_object (demux, &bufdata, &obj.size);
1078     gst_buffer_unmap (buf, &map);
1079     gst_buffer_replace (&buf, NULL);
1080
1081     if (G_UNLIKELY (flow != GST_FLOW_OK))
1082       break;
1083
1084     ++num_read;
1085   }
1086   GST_DEBUG_OBJECT (demux, "read %u index objects", num_read);
1087 }
1088
1089 static gboolean
1090 gst_asf_demux_parse_data_object_start (GstASFDemux * demux, guint8 * data)
1091 {
1092   AsfObject obj;
1093
1094   asf_demux_peek_object (demux, data, 50, &obj, TRUE);
1095   if (obj.id != ASF_OBJ_DATA) {
1096     GST_WARNING_OBJECT (demux, "headers not followed by a DATA object");
1097     return FALSE;
1098   }
1099
1100   demux->state = GST_ASF_DEMUX_STATE_DATA;
1101
1102   if (!demux->broadcast && obj.size > 50) {
1103     demux->data_size = obj.size - 50;
1104     /* CHECKME: for at least one file this is off by +158 bytes?! */
1105     demux->index_offset = demux->data_offset + demux->data_size;
1106   } else {
1107     demux->data_size = 0;
1108     demux->index_offset = 0;
1109   }
1110
1111   demux->packet = 0;
1112
1113   if (!demux->broadcast) {
1114     /* skip object header (24 bytes) and file GUID (16 bytes) */
1115     demux->num_packets = GST_READ_UINT64_LE (data + (16 + 8) + 16);
1116   } else {
1117     demux->num_packets = 0;
1118   }
1119
1120   if (demux->num_packets == 0)
1121     demux->seekable = FALSE;
1122
1123   /* fallback in the unlikely case that headers are inconsistent, can't hurt */
1124   if (demux->data_size == 0 && demux->num_packets > 0) {
1125     demux->data_size = demux->num_packets * demux->packet_size;
1126     demux->index_offset = demux->data_offset + demux->data_size;
1127   }
1128
1129   /* process pending stream objects and create pads for those */
1130   gst_asf_demux_process_queued_extended_stream_objects (demux);
1131
1132   GST_INFO_OBJECT (demux, "Stream has %" G_GUINT64_FORMAT " packets, "
1133       "data_offset=%" G_GINT64_FORMAT ", data_size=%" G_GINT64_FORMAT
1134       ", index_offset=%" G_GUINT64_FORMAT, demux->num_packets,
1135       demux->data_offset, demux->data_size, demux->index_offset);
1136
1137   return TRUE;
1138 }
1139
1140 static gboolean
1141 gst_asf_demux_pull_headers (GstASFDemux * demux)
1142 {
1143   GstFlowReturn flow;
1144   AsfObject obj;
1145   GstBuffer *buf = NULL;
1146   guint64 size;
1147   GstMapInfo map;
1148   guint8 *bufdata;
1149
1150   GST_LOG_OBJECT (demux, "reading headers");
1151
1152   /* pull HEADER object header, so we know its size */
1153   if (!gst_asf_demux_pull_data (demux, demux->base_offset, 16 + 8, &buf, NULL))
1154     goto read_failed;
1155
1156   gst_buffer_map (buf, &map, GST_MAP_READ);
1157   g_assert (map.size >= 16 + 8);
1158   asf_demux_peek_object (demux, map.data, 16 + 8, &obj, TRUE);
1159   gst_buffer_unmap (buf, &map);
1160   gst_buffer_replace (&buf, NULL);
1161
1162   if (obj.id != ASF_OBJ_HEADER)
1163     goto wrong_type;
1164
1165   GST_LOG_OBJECT (demux, "header size = %u", (guint) obj.size);
1166
1167   /* pull HEADER object */
1168   if (!gst_asf_demux_pull_data (demux, demux->base_offset, obj.size, &buf,
1169           NULL))
1170     goto read_failed;
1171
1172   size = obj.size;              /* don't want obj.size changed */
1173   gst_buffer_map (buf, &map, GST_MAP_READ);
1174   g_assert (map.size >= size);
1175   bufdata = (guint8 *) map.data;
1176   flow = gst_asf_demux_process_object (demux, &bufdata, &size);
1177   gst_buffer_unmap (buf, &map);
1178   gst_buffer_replace (&buf, NULL);
1179
1180   if (flow != GST_FLOW_OK) {
1181     GST_WARNING_OBJECT (demux, "process_object: %s", gst_flow_get_name (flow));
1182     goto parse_failed;
1183   }
1184
1185   /* calculate where the packet data starts */
1186   demux->data_offset = demux->base_offset + obj.size + 50;
1187
1188   /* now pull beginning of DATA object before packet data */
1189   if (!gst_asf_demux_pull_data (demux, demux->base_offset + obj.size, 50, &buf,
1190           NULL))
1191     goto read_failed;
1192
1193   gst_buffer_map (buf, &map, GST_MAP_READ);
1194   g_assert (map.size >= size);
1195   bufdata = (guint8 *) map.data;
1196   if (!gst_asf_demux_parse_data_object_start (demux, bufdata))
1197     goto wrong_type;
1198
1199   if (demux->num_streams == 0)
1200     goto no_streams;
1201
1202   gst_buffer_unmap (buf, &map);
1203   gst_buffer_replace (&buf, NULL);
1204
1205   return TRUE;
1206
1207 /* ERRORS */
1208 wrong_type:
1209   {
1210     if (buf != NULL) {
1211       gst_buffer_unmap (buf, &map);
1212       gst_buffer_replace (&buf, NULL);
1213     }
1214     GST_ELEMENT_ERROR (demux, STREAM, WRONG_TYPE, (NULL),
1215         ("This doesn't seem to be an ASF file"));
1216     return FALSE;
1217   }
1218
1219 no_streams:
1220 read_failed:
1221 parse_failed:
1222   {
1223     if (buf)
1224       gst_buffer_unmap (buf, &map);
1225     gst_buffer_replace (&buf, NULL);
1226     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), (NULL));
1227     return FALSE;
1228   }
1229 }
1230
1231 static gboolean
1232 all_streams_prerolled (GstASFDemux * demux)
1233 {
1234   GstClockTime preroll_time;
1235   guint i, num_no_data = 0;
1236
1237   /* Allow at least 500ms of preroll_time  */
1238   preroll_time = MAX (demux->preroll, 500 * GST_MSECOND);
1239
1240   /* returns TRUE as long as there isn't a stream which (a) has data queued
1241    * and (b) the timestamp of last piece of data queued is < demux->preroll
1242    * AND there is at least one other stream with data queued */
1243   for (i = 0; i < demux->num_streams; ++i) {
1244     AsfPayload *last_payload = NULL;
1245     AsfStream *stream;
1246     gint last_idx;
1247
1248     stream = &demux->stream[i];
1249     if (G_UNLIKELY (stream->payloads->len == 0)) {
1250       ++num_no_data;
1251       GST_LOG_OBJECT (stream->pad, "no data queued");
1252       continue;
1253     }
1254
1255     /* find last payload with timestamp */
1256     for (last_idx = stream->payloads->len - 1;
1257         last_idx >= 0 && (last_payload == NULL
1258             || !GST_CLOCK_TIME_IS_VALID (last_payload->ts)); --last_idx) {
1259       last_payload = &g_array_index (stream->payloads, AsfPayload, last_idx);
1260     }
1261
1262     GST_LOG_OBJECT (stream->pad, "checking if %" GST_TIME_FORMAT " > %"
1263         GST_TIME_FORMAT, GST_TIME_ARGS (last_payload->ts),
1264         GST_TIME_ARGS (preroll_time));
1265     if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (last_payload->ts)
1266             || last_payload->ts <= preroll_time)) {
1267       GST_LOG_OBJECT (stream->pad, "not beyond preroll point yet");
1268       return FALSE;
1269     }
1270   }
1271
1272   if (G_UNLIKELY (num_no_data > 0))
1273     return FALSE;
1274
1275   return TRUE;
1276 }
1277
1278 #if 0
1279 static gboolean
1280 gst_asf_demux_have_mutually_exclusive_active_stream (GstASFDemux * demux,
1281     AsfStream * stream)
1282 {
1283   GSList *l;
1284
1285   for (l = demux->mut_ex_streams; l != NULL; l = l->next) {
1286     guint8 *mes;
1287
1288     /* check for each mutual exclusion group whether it affects this stream */
1289     for (mes = (guint8 *) l->data; mes != NULL && *mes != 0xff; ++mes) {
1290       if (*mes == stream->id) {
1291         /* we are in this group; let's check if we've already activated streams
1292          * that are in the same group (and hence mutually exclusive to this
1293          * one) */
1294         for (mes = (guint8 *) l->data; mes != NULL && *mes != 0xff; ++mes) {
1295           guint i;
1296
1297           for (i = 0; i < demux->num_streams; ++i) {
1298             if (demux->stream[i].id == *mes && demux->stream[i].active) {
1299               GST_LOG_OBJECT (demux, "stream with ID %d is mutually exclusive "
1300                   "to already active stream with ID %d", stream->id,
1301                   demux->stream[i].id);
1302               return TRUE;
1303             }
1304           }
1305         }
1306         /* we can only be in this group once, let's break out and move on to
1307          * the next mutual exclusion group */
1308         break;
1309       }
1310     }
1311   }
1312
1313   return FALSE;
1314 }
1315 #endif
1316
1317 static gboolean
1318 gst_asf_demux_check_first_ts (GstASFDemux * demux, gboolean force)
1319 {
1320   if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (demux->first_ts))) {
1321     GstClockTime first_ts = GST_CLOCK_TIME_NONE;
1322     int i;
1323
1324     /* go trhough each stream, find smallest timestamp */
1325     for (i = 0; i < demux->num_streams; ++i) {
1326       AsfStream *stream;
1327       int j;
1328       GstClockTime stream_min_ts = GST_CLOCK_TIME_NONE;
1329       stream = &demux->stream[i];
1330
1331       for (j = 0; j < stream->payloads->len; ++j) {
1332         AsfPayload *payload = &g_array_index (stream->payloads, AsfPayload, j);
1333         if (GST_CLOCK_TIME_IS_VALID (payload->ts) &&
1334             (!GST_CLOCK_TIME_IS_VALID (stream_min_ts)
1335                 || stream_min_ts > payload->ts))
1336           stream_min_ts = payload->ts;
1337       }
1338
1339       /* if we don't have timestamp for this stream, wait for more data */
1340       if (!GST_CLOCK_TIME_IS_VALID (stream_min_ts) && !force)
1341         return FALSE;
1342
1343       if (GST_CLOCK_TIME_IS_VALID (stream_min_ts) &&
1344           (!GST_CLOCK_TIME_IS_VALID (first_ts) || first_ts > stream_min_ts))
1345         first_ts = stream_min_ts;
1346     }
1347
1348     if (!GST_CLOCK_TIME_IS_VALID (first_ts))    /* can happen with force = TRUE */
1349       first_ts = 0;
1350
1351     demux->first_ts = first_ts;
1352
1353     /* update packets queued before we knew first timestamp */
1354     for (i = 0; i < demux->num_streams; ++i) {
1355       AsfStream *stream;
1356       int j;
1357       stream = &demux->stream[i];
1358
1359       for (j = 0; j < stream->payloads->len; ++j) {
1360         AsfPayload *payload = &g_array_index (stream->payloads, AsfPayload, j);
1361         if (GST_CLOCK_TIME_IS_VALID (payload->ts)) {
1362           if (payload->ts > first_ts)
1363             payload->ts -= first_ts;
1364           else
1365             payload->ts = 0;
1366         }
1367       }
1368     }
1369
1370     /* remember the first queued timestamp for the segment */
1371     if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (demux->segment_ts))) {
1372       GST_DEBUG_OBJECT (demux, "segment ts: %" GST_TIME_FORMAT,
1373           GST_TIME_ARGS (first_ts));
1374       demux->segment_ts = first_ts;
1375       /* always note, but only determines segment when streaming */
1376       if (demux->streaming)
1377         gst_segment_do_seek (&demux->segment, demux->in_segment.rate,
1378             GST_FORMAT_TIME, (GstSeekFlags) demux->segment.flags,
1379             GST_SEEK_TYPE_SET, demux->segment_ts, GST_SEEK_TYPE_NONE, 0, NULL);
1380     }
1381   }
1382
1383   return TRUE;
1384 }
1385
1386 static gboolean
1387 gst_asf_demux_update_caps_from_payload (GstASFDemux * demux, AsfStream * stream)
1388 {
1389   /* try to determine whether the stream is AC-3 or MPEG; In dvr-ms the codecTag is unreliable
1390      and often set wrong, inspecting the data is the only way that seem to be working */
1391   GstTypeFindProbability prob = GST_TYPE_FIND_NONE;
1392   GstCaps *caps = NULL;
1393   GstAdapter *adapter = gst_adapter_new ();
1394
1395   for (int i = 0; i < stream->payloads->len && prob < GST_TYPE_FIND_LIKELY; ++i) {
1396     const guint8 *data;
1397     AsfPayload *payload;
1398     int len;
1399
1400     payload = &g_array_index (stream->payloads, AsfPayload, i);
1401     gst_adapter_push (adapter, gst_buffer_ref (payload->buf));
1402     len = gst_adapter_available (adapter);
1403     data = gst_adapter_map (adapter, len);
1404
1405   again:
1406
1407 #define MIN_LENGTH 128
1408
1409     /* look for the sync points */
1410     while (TRUE) {
1411       if (len < MIN_LENGTH ||   /* give typefind something to work on */
1412           (data[0] == 0x0b && data[1] == 0x77) ||       /* AC-3 sync point */
1413           (data[0] == 0xFF && ((data[1] & 0xF0) >> 4) == 0xF))  /* MPEG sync point */
1414         break;
1415       ++data;
1416       --len;
1417     }
1418
1419     gst_caps_take (&caps, gst_type_find_helper_for_data (GST_OBJECT (demux),
1420             data, len, &prob));
1421
1422     if (prob < GST_TYPE_FIND_LIKELY) {
1423       ++data;
1424       --len;
1425       if (len > MIN_LENGTH)
1426         /* this wasn't it, look for another sync point */
1427         goto again;
1428     }
1429
1430     gst_adapter_unmap (adapter);
1431   }
1432
1433   gst_object_unref (adapter);
1434
1435   if (caps) {
1436     gst_caps_take (&stream->caps, caps);
1437     return TRUE;
1438   } else {
1439     return FALSE;
1440   }
1441 }
1442
1443 static gboolean
1444 gst_asf_demux_check_activate_streams (GstASFDemux * demux, gboolean force)
1445 {
1446   guint i;
1447
1448   if (demux->activated_streams)
1449     return TRUE;
1450
1451   if (G_UNLIKELY (!gst_asf_demux_check_first_ts (demux, force)))
1452     return FALSE;
1453
1454   if (!all_streams_prerolled (demux) && !force) {
1455     GST_DEBUG_OBJECT (demux, "not all streams with data beyond preroll yet");
1456     return FALSE;
1457   }
1458
1459   for (i = 0; i < demux->num_streams; ++i) {
1460     AsfStream *stream = &demux->stream[i];
1461
1462     if (stream->payloads->len > 0) {
1463
1464       if (stream->inspect_payload &&    /* dvr-ms required payload inspection */
1465           !stream->active &&    /* do not inspect active streams (caps were already set) */
1466           !gst_asf_demux_update_caps_from_payload (demux, stream) &&    /* failed to determine caps */
1467           stream->payloads->len < 20) { /* if we couldn't determine the caps from 20 packets then just give up and use whatever was in codecTag */
1468         /* try to gather some more data  */
1469         return FALSE;
1470       }
1471       /* we don't check mutual exclusion stuff here; either we have data for
1472        * a stream, then we active it, or we don't, then we'll ignore it */
1473       GST_LOG_OBJECT (stream->pad, "is prerolled - activate!");
1474       gst_asf_demux_activate_stream (demux, stream);
1475     } else {
1476       GST_LOG_OBJECT (stream->pad, "no data, ignoring stream");
1477     }
1478   }
1479
1480   gst_asf_demux_release_old_pads (demux);
1481
1482   demux->activated_streams = TRUE;
1483   GST_LOG_OBJECT (demux, "signalling no more pads");
1484   gst_element_no_more_pads (GST_ELEMENT (demux));
1485   return TRUE;
1486 }
1487
1488 /* returns the stream that has a complete payload with the lowest timestamp
1489  * queued, or NULL (we push things by timestamp because during the internal
1490  * prerolling we might accumulate more data then the external queues can take,
1491  * so we'd lock up if we pushed all accumulated data for stream N in one go) */
1492 static AsfStream *
1493 gst_asf_demux_find_stream_with_complete_payload (GstASFDemux * demux)
1494 {
1495   AsfPayload *best_payload = NULL;
1496   AsfStream *best_stream = NULL;
1497   guint i;
1498
1499   for (i = 0; i < demux->num_streams; ++i) {
1500     AsfStream *stream;
1501     int j;
1502
1503     stream = &demux->stream[i];
1504
1505     /* Don't push any data until we have at least one payload that falls within
1506      * the current segment. This way we can remove out-of-segment payloads that
1507      * don't need to be decoded after a seek, sending only data from the
1508      * keyframe directly before our segment start */
1509     if (stream->payloads->len > 0) {
1510       AsfPayload *payload = NULL;
1511       gint last_idx;
1512
1513       /* find last payload with timestamp */
1514       for (last_idx = stream->payloads->len - 1;
1515           last_idx >= 0 && (payload == NULL
1516               || !GST_CLOCK_TIME_IS_VALID (payload->ts)); --last_idx) {
1517         payload = &g_array_index (stream->payloads, AsfPayload, last_idx);
1518       }
1519       if (G_UNLIKELY (GST_CLOCK_TIME_IS_VALID (payload->ts) &&
1520               (payload->ts < demux->segment.start))) {
1521         if (G_UNLIKELY ((!demux->accurate) && payload->keyframe)) {
1522           GST_DEBUG_OBJECT (stream->pad,
1523               "Found keyframe, updating segment start to %" GST_TIME_FORMAT,
1524               GST_TIME_ARGS (payload->ts));
1525           demux->segment.start = payload->ts;
1526           demux->segment.time = payload->ts;
1527         } else {
1528           GST_DEBUG_OBJECT (stream->pad, "Last queued payload has timestamp %"
1529               GST_TIME_FORMAT " which is before our segment start %"
1530               GST_TIME_FORMAT ", not pushing yet", GST_TIME_ARGS (payload->ts),
1531               GST_TIME_ARGS (demux->segment.start));
1532           continue;
1533         }
1534       }
1535
1536       /* Now see if there's a complete payload queued for this stream */
1537
1538       payload = NULL;
1539       /* find first complete payload with timestamp */
1540       for (j = 0;
1541           j < stream->payloads->len && (payload == NULL
1542               || !GST_CLOCK_TIME_IS_VALID (payload->ts)); ++j) {
1543         payload = &g_array_index (stream->payloads, AsfPayload, j);
1544       }
1545
1546       if (!gst_asf_payload_is_complete (payload))
1547         continue;
1548
1549       /* ... and whether its timestamp is lower than the current best */
1550       if (best_stream == NULL || best_payload->ts > payload->ts) {
1551         best_stream = stream;
1552         best_payload = payload;
1553       }
1554     }
1555   }
1556
1557   return best_stream;
1558 }
1559
1560 static GstFlowReturn
1561 gst_asf_demux_push_complete_payloads (GstASFDemux * demux, gboolean force)
1562 {
1563   AsfStream *stream;
1564   GstFlowReturn ret = GST_FLOW_OK;
1565
1566   if (G_UNLIKELY (!demux->activated_streams)) {
1567     if (!gst_asf_demux_check_activate_streams (demux, force))
1568       return GST_FLOW_OK;
1569     /* streams are now activated */
1570   }
1571
1572   /* wait until we had a chance to "lock on" some payload's timestamp */
1573   if (G_UNLIKELY (demux->need_newsegment
1574           && !GST_CLOCK_TIME_IS_VALID (demux->segment_ts)))
1575     return GST_FLOW_OK;
1576
1577   while ((stream = gst_asf_demux_find_stream_with_complete_payload (demux))) {
1578     AsfPayload *payload;
1579
1580     payload = &g_array_index (stream->payloads, AsfPayload, 0);
1581
1582     /* do we need to send a newsegment event */
1583     if ((G_UNLIKELY (demux->need_newsegment))) {
1584       GstEvent *segment_event;
1585
1586       /* safe default if insufficient upstream info */
1587       if (!GST_CLOCK_TIME_IS_VALID (demux->in_gap))
1588         demux->in_gap = 0;
1589
1590       if (demux->segment.stop == GST_CLOCK_TIME_NONE &&
1591           demux->segment.duration > 0) {
1592         /* slight HACK; prevent clipping of last bit */
1593         demux->segment.stop = demux->segment.duration + demux->in_gap;
1594       }
1595
1596       /* FIXME : only if ACCURATE ! */
1597       if (G_LIKELY (!demux->accurate
1598               && (GST_CLOCK_TIME_IS_VALID (payload->ts)))) {
1599         GST_DEBUG ("Adjusting newsegment start to %" GST_TIME_FORMAT,
1600             GST_TIME_ARGS (payload->ts));
1601         demux->segment.start = payload->ts;
1602         demux->segment.time = payload->ts;
1603       }
1604
1605       GST_DEBUG_OBJECT (demux, "sending new-segment event %" GST_SEGMENT_FORMAT,
1606           &demux->segment);
1607
1608       /* note: we fix up all timestamps to start from 0, so this should be ok */
1609       segment_event = gst_event_new_segment (&demux->segment);
1610       if (demux->segment_seqnum)
1611         gst_event_set_seqnum (segment_event, demux->segment_seqnum);
1612       gst_asf_demux_send_event_unlocked (demux, segment_event);
1613
1614       /* now post any global tags we may have found */
1615       if (demux->taglist == NULL) {
1616         demux->taglist = gst_tag_list_new_empty ();
1617         gst_tag_list_set_scope (demux->taglist, GST_TAG_SCOPE_GLOBAL);
1618       }
1619
1620       gst_tag_list_add (demux->taglist, GST_TAG_MERGE_REPLACE,
1621           GST_TAG_CONTAINER_FORMAT, "ASF", NULL);
1622
1623       GST_DEBUG_OBJECT (demux, "global tags: %" GST_PTR_FORMAT, demux->taglist);
1624       gst_asf_demux_send_event_unlocked (demux,
1625           gst_event_new_tag (demux->taglist));
1626       demux->taglist = NULL;
1627
1628       demux->need_newsegment = FALSE;
1629       demux->segment_seqnum = 0;
1630       demux->segment_running = TRUE;
1631     }
1632
1633     /* Do we have tags pending for this stream? */
1634     if (G_UNLIKELY (stream->pending_tags)) {
1635       GST_LOG_OBJECT (stream->pad, "%" GST_PTR_FORMAT, stream->pending_tags);
1636       gst_pad_push_event (stream->pad,
1637           gst_event_new_tag (stream->pending_tags));
1638       stream->pending_tags = NULL;
1639     }
1640
1641     /* We have the whole packet now so we should push the packet to
1642      * the src pad now. First though we should check if we need to do
1643      * descrambling */
1644     if (G_UNLIKELY (demux->span > 1)) {
1645       gst_asf_demux_descramble_buffer (demux, stream, &payload->buf);
1646     }
1647
1648     payload->buf = gst_buffer_make_writable (payload->buf);
1649
1650     if (G_LIKELY (!payload->keyframe)) {
1651       GST_BUFFER_FLAG_SET (payload->buf, GST_BUFFER_FLAG_DELTA_UNIT);
1652     }
1653
1654     if (G_UNLIKELY (stream->discont)) {
1655       GST_DEBUG_OBJECT (stream->pad, "marking DISCONT on stream");
1656       GST_BUFFER_FLAG_SET (payload->buf, GST_BUFFER_FLAG_DISCONT);
1657       stream->discont = FALSE;
1658     }
1659
1660     if (G_UNLIKELY (stream->is_video && payload->par_x && payload->par_y &&
1661             (payload->par_x != stream->par_x) &&
1662             (payload->par_y != stream->par_y))) {
1663       GST_DEBUG ("Updating PAR (%d/%d => %d/%d)",
1664           stream->par_x, stream->par_y, payload->par_x, payload->par_y);
1665       stream->par_x = payload->par_x;
1666       stream->par_y = payload->par_y;
1667       stream->caps = gst_caps_make_writable (stream->caps);
1668       gst_caps_set_simple (stream->caps, "pixel-aspect-ratio",
1669           GST_TYPE_FRACTION, stream->par_x, stream->par_y, NULL);
1670       gst_pad_set_caps (stream->pad, stream->caps);
1671     }
1672
1673     if (G_UNLIKELY (stream->interlaced != payload->interlaced)) {
1674       GST_DEBUG ("Updating interlaced status (%d => %d)", stream->interlaced,
1675           payload->interlaced);
1676       stream->interlaced = payload->interlaced;
1677       stream->caps = gst_caps_make_writable (stream->caps);
1678       gst_caps_set_simple (stream->caps, "interlace-mode", G_TYPE_BOOLEAN,
1679           (stream->interlaced ? "mixed" : "progressive"), NULL);
1680       gst_pad_set_caps (stream->pad, stream->caps);
1681     }
1682
1683     /* (sort of) interpolate timestamps using upstream "frame of reference",
1684      * typically useful for live src, but might (unavoidably) mess with
1685      * position reporting if a live src is playing not so live content
1686      * (e.g. rtspsrc taking some time to fall back to tcp) */
1687     GST_BUFFER_PTS (payload->buf) = payload->ts;
1688     if (GST_BUFFER_PTS_IS_VALID (payload->buf)) {
1689       GST_BUFFER_PTS (payload->buf) += demux->in_gap;
1690     }
1691     if (payload->duration == GST_CLOCK_TIME_NONE
1692         && stream->ext_props.avg_time_per_frame != 0)
1693       GST_BUFFER_DURATION (payload->buf) =
1694           stream->ext_props.avg_time_per_frame * 100;
1695     else
1696       GST_BUFFER_DURATION (payload->buf) = payload->duration;
1697
1698     /* FIXME: we should really set durations on buffers if we can */
1699
1700     GST_LOG_OBJECT (stream->pad, "pushing buffer, ts=%" GST_TIME_FORMAT
1701         ", dur=%" GST_TIME_FORMAT " size=%" G_GSIZE_FORMAT,
1702         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (payload->buf)),
1703         GST_TIME_ARGS (GST_BUFFER_DURATION (payload->buf)),
1704         gst_buffer_get_size (payload->buf));
1705
1706     if (stream->active) {
1707       ret = gst_pad_push (stream->pad, payload->buf);
1708       ret = gst_asf_demux_aggregate_flow_return (demux, stream, ret);
1709     } else {
1710       gst_buffer_unref (payload->buf);
1711       ret = GST_FLOW_OK;
1712     }
1713     payload->buf = NULL;
1714     g_array_remove_index (stream->payloads, 0);
1715
1716     /* Break out as soon as we have an issue */
1717     if (G_UNLIKELY (ret != GST_FLOW_OK))
1718       break;
1719   }
1720
1721   return ret;
1722 }
1723
1724 static gboolean
1725 gst_asf_demux_check_buffer_is_header (GstASFDemux * demux, GstBuffer * buf)
1726 {
1727   AsfObject obj;
1728   GstMapInfo map;
1729   g_assert (buf != NULL);
1730
1731   GST_LOG_OBJECT (demux, "Checking if buffer is a header");
1732
1733   gst_buffer_map (buf, &map, GST_MAP_READ);
1734
1735   /* we return false on buffer too small */
1736   if (map.size < ASF_OBJECT_HEADER_SIZE) {
1737     gst_buffer_unmap (buf, &map);
1738     return FALSE;
1739   }
1740
1741   /* check if it is a header */
1742   asf_demux_peek_object (demux, map.data, ASF_OBJECT_HEADER_SIZE, &obj, TRUE);
1743   gst_buffer_unmap (buf, &map);
1744   if (obj.id == ASF_OBJ_HEADER) {
1745     return TRUE;
1746   }
1747   return FALSE;
1748 }
1749
1750 static gboolean
1751 gst_asf_demux_check_chained_asf (GstASFDemux * demux)
1752 {
1753   guint64 off = demux->data_offset + (demux->packet * demux->packet_size);
1754   GstFlowReturn ret = GST_FLOW_OK;
1755   GstBuffer *buf = NULL;
1756   gboolean header = FALSE;
1757
1758   /* TODO maybe we should skip index objects after the data and look
1759    * further for a new header */
1760   if (gst_asf_demux_pull_data (demux, off, ASF_OBJECT_HEADER_SIZE, &buf, &ret)) {
1761     g_assert (buf != NULL);
1762     /* check if it is a header */
1763     if (gst_asf_demux_check_buffer_is_header (demux, buf)) {
1764       GST_DEBUG_OBJECT (demux, "new base offset: %" G_GUINT64_FORMAT, off);
1765       demux->base_offset = off;
1766       header = TRUE;
1767     }
1768
1769     gst_buffer_unref (buf);
1770   }
1771
1772   return header;
1773 }
1774
1775 static void
1776 gst_asf_demux_loop (GstASFDemux * demux)
1777 {
1778   GstFlowReturn flow = GST_FLOW_OK;
1779   GstBuffer *buf = NULL;
1780   guint64 off;
1781   gboolean sent_eos = FALSE;
1782
1783   if (G_UNLIKELY (demux->state == GST_ASF_DEMUX_STATE_HEADER)) {
1784     if (!gst_asf_demux_pull_headers (demux)) {
1785       flow = GST_FLOW_ERROR;
1786       goto pause;
1787     }
1788
1789     gst_asf_demux_pull_indices (demux);
1790   }
1791
1792   g_assert (demux->state == GST_ASF_DEMUX_STATE_DATA);
1793
1794   if (G_UNLIKELY (demux->num_packets != 0
1795           && demux->packet >= demux->num_packets))
1796     goto eos;
1797
1798   GST_LOG_OBJECT (demux, "packet %u/%u", (guint) demux->packet + 1,
1799       (guint) demux->num_packets);
1800
1801   off = demux->data_offset + (demux->packet * demux->packet_size);
1802
1803   if (G_UNLIKELY (!gst_asf_demux_pull_data (demux, off,
1804               demux->packet_size * demux->speed_packets, &buf, &flow))) {
1805     GST_DEBUG_OBJECT (demux, "got flow %s", gst_flow_get_name (flow));
1806     if (flow == GST_FLOW_EOS)
1807       goto eos;
1808     else if (flow == GST_FLOW_FLUSHING) {
1809       GST_DEBUG_OBJECT (demux, "Not fatal");
1810       goto pause;
1811     } else
1812       goto read_failed;
1813   }
1814
1815   if (G_LIKELY (demux->speed_packets == 1)) {
1816     GstAsfDemuxParsePacketError err;
1817     err = gst_asf_demux_parse_packet (demux, buf);
1818     if (G_UNLIKELY (err != GST_ASF_DEMUX_PARSE_PACKET_ERROR_NONE)) {
1819       /* when we don't know when the data object ends, we should check
1820        * for a chained asf */
1821       if (demux->num_packets == 0) {
1822         if (gst_asf_demux_check_buffer_is_header (demux, buf)) {
1823           GST_INFO_OBJECT (demux, "Chained asf found");
1824           demux->base_offset = off;
1825           gst_asf_demux_reset (demux, TRUE);
1826           gst_buffer_unref (buf);
1827           return;
1828         }
1829       }
1830       /* FIXME: We should tally up fatal errors and error out only
1831        * after a few broken packets in a row? */
1832
1833       GST_INFO_OBJECT (demux, "Ignoring recoverable parse error");
1834       gst_buffer_unref (buf);
1835       ++demux->packet;
1836       return;
1837     }
1838
1839     flow = gst_asf_demux_push_complete_payloads (demux, FALSE);
1840
1841     ++demux->packet;
1842
1843   } else {
1844     guint n;
1845     for (n = 0; n < demux->speed_packets; n++) {
1846       GstBuffer *sub;
1847       GstAsfDemuxParsePacketError err;
1848
1849       sub =
1850           gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL,
1851           n * demux->packet_size, demux->packet_size);
1852       err = gst_asf_demux_parse_packet (demux, sub);
1853       if (G_UNLIKELY (err != GST_ASF_DEMUX_PARSE_PACKET_ERROR_NONE)) {
1854         /* when we don't know when the data object ends, we should check
1855          * for a chained asf */
1856         if (demux->num_packets == 0) {
1857           if (gst_asf_demux_check_buffer_is_header (demux, sub)) {
1858             GST_INFO_OBJECT (demux, "Chained asf found");
1859             demux->base_offset = off + n * demux->packet_size;
1860             gst_asf_demux_reset (demux, TRUE);
1861             gst_buffer_unref (sub);
1862             gst_buffer_unref (buf);
1863             return;
1864           }
1865         }
1866         /* FIXME: We should tally up fatal errors and error out only
1867          * after a few broken packets in a row? */
1868
1869         GST_INFO_OBJECT (demux, "Ignoring recoverable parse error");
1870         flow = GST_FLOW_OK;
1871       }
1872
1873       gst_buffer_unref (sub);
1874
1875       if (err == GST_ASF_DEMUX_PARSE_PACKET_ERROR_NONE)
1876         flow = gst_asf_demux_push_complete_payloads (demux, FALSE);
1877
1878       ++demux->packet;
1879
1880     }
1881
1882     /* reset speed pull */
1883     demux->speed_packets = 1;
1884   }
1885
1886   gst_buffer_unref (buf);
1887
1888   if (G_UNLIKELY (demux->num_packets > 0
1889           && demux->packet >= demux->num_packets)) {
1890     GST_LOG_OBJECT (demux, "reached EOS");
1891     goto eos;
1892   }
1893
1894   if (G_UNLIKELY (flow != GST_FLOW_OK)) {
1895     GST_DEBUG_OBJECT (demux, "pushing complete payloads failed");
1896     goto pause;
1897   }
1898
1899   /* check if we're at the end of the configured segment */
1900   /* FIXME: check if segment end reached etc. */
1901
1902   return;
1903
1904 eos:
1905   {
1906     /* if we haven't activated our streams yet, this might be because we have
1907      * less data queued than required for preroll; force stream activation and
1908      * send any pending payloads before sending EOS */
1909     if (!demux->activated_streams)
1910       gst_asf_demux_push_complete_payloads (demux, TRUE);
1911
1912     /* we want to push an eos or post a segment-done in any case */
1913     if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) {
1914       gint64 stop;
1915
1916       /* for segment playback we need to post when (in stream time)
1917        * we stopped, this is either stop (when set) or the duration. */
1918       if ((stop = demux->segment.stop) == -1)
1919         stop = demux->segment.duration;
1920
1921       GST_INFO_OBJECT (demux, "Posting segment-done, at end of segment");
1922       gst_element_post_message (GST_ELEMENT_CAST (demux),
1923           gst_message_new_segment_done (GST_OBJECT (demux), GST_FORMAT_TIME,
1924               stop));
1925       gst_asf_demux_send_event_unlocked (demux,
1926           gst_event_new_segment_done (GST_FORMAT_TIME, stop));
1927     } else if (flow != GST_FLOW_EOS) {
1928       /* check if we have a chained asf, in case, we don't eos yet */
1929       if (gst_asf_demux_check_chained_asf (demux)) {
1930         GST_INFO_OBJECT (demux, "Chained ASF starting");
1931         gst_asf_demux_reset (demux, TRUE);
1932         return;
1933       }
1934     }
1935     /* normal playback, send EOS to all linked pads */
1936     GST_INFO_OBJECT (demux, "Sending EOS, at end of stream");
1937     gst_asf_demux_send_event_unlocked (demux, gst_event_new_eos ());
1938     sent_eos = TRUE;
1939     /* ... and fall through to pause */
1940   }
1941 pause:
1942   {
1943     GST_DEBUG_OBJECT (demux, "pausing task, flow return: %s",
1944         gst_flow_get_name (flow));
1945     demux->segment_running = FALSE;
1946     gst_pad_pause_task (demux->sinkpad);
1947
1948     /* For the error cases (not EOS) */
1949     if (!sent_eos) {
1950       if (flow == GST_FLOW_EOS)
1951         gst_asf_demux_send_event_unlocked (demux, gst_event_new_eos ());
1952       else if (flow < GST_FLOW_EOS || flow == GST_FLOW_NOT_LINKED) {
1953         /* Post an error. Hopefully something else already has, but if not... */
1954         GST_ELEMENT_ERROR (demux, STREAM, FAILED,
1955             (_("Internal data stream error.")),
1956             ("streaming stopped, reason %s", gst_flow_get_name (flow)));
1957       }
1958     }
1959     return;
1960   }
1961
1962 /* ERRORS */
1963 read_failed:
1964   {
1965     GST_DEBUG_OBJECT (demux, "Read failed, doh");
1966     gst_asf_demux_send_event_unlocked (demux, gst_event_new_eos ());
1967     flow = GST_FLOW_EOS;
1968     goto pause;
1969   }
1970 #if 0
1971   /* See FIXMEs above */
1972 parse_error:
1973   {
1974     gst_buffer_unref (buf);
1975     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
1976         ("Error parsing ASF packet %u", (guint) demux->packet));
1977     gst_asf_demux_send_event_unlocked (demux, gst_event_new_eos ());
1978     flow = GST_FLOW_ERROR;
1979     goto pause;
1980   }
1981 #endif
1982 }
1983
1984 #define GST_ASF_DEMUX_CHECK_HEADER_YES       0
1985 #define GST_ASF_DEMUX_CHECK_HEADER_NO        1
1986 #define GST_ASF_DEMUX_CHECK_HEADER_NEED_DATA 2
1987
1988 static gint
1989 gst_asf_demux_check_header (GstASFDemux * demux)
1990 {
1991   AsfObject obj;
1992   guint8 *cdata = (guint8 *) gst_adapter_map (demux->adapter,
1993       ASF_OBJECT_HEADER_SIZE);
1994   if (cdata == NULL)            /* need more data */
1995     return GST_ASF_DEMUX_CHECK_HEADER_NEED_DATA;
1996
1997   asf_demux_peek_object (demux, cdata, ASF_OBJECT_HEADER_SIZE, &obj, FALSE);
1998   if (obj.id != ASF_OBJ_HEADER) {
1999     return GST_ASF_DEMUX_CHECK_HEADER_NO;
2000   } else {
2001     return GST_ASF_DEMUX_CHECK_HEADER_YES;
2002   }
2003 }
2004
2005 static GstFlowReturn
2006 gst_asf_demux_chain (GstPad * pad, GstObject * parent, GstBuffer * buf)
2007 {
2008   GstFlowReturn ret = GST_FLOW_OK;
2009   GstASFDemux *demux;
2010
2011   demux = GST_ASF_DEMUX (parent);
2012
2013   GST_LOG_OBJECT (demux,
2014       "buffer: size=%" G_GSIZE_FORMAT ", offset=%" G_GINT64_FORMAT ", time=%"
2015       GST_TIME_FORMAT, gst_buffer_get_size (buf), GST_BUFFER_OFFSET (buf),
2016       GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)));
2017
2018   if (G_UNLIKELY (GST_BUFFER_IS_DISCONT (buf))) {
2019     GST_DEBUG_OBJECT (demux, "received DISCONT");
2020     gst_asf_demux_mark_discont (demux);
2021   }
2022
2023   if (G_UNLIKELY ((!GST_CLOCK_TIME_IS_VALID (demux->in_gap) &&
2024               GST_BUFFER_TIMESTAMP_IS_VALID (buf)))) {
2025     demux->in_gap = GST_BUFFER_TIMESTAMP (buf) - demux->in_segment.start;
2026     GST_DEBUG_OBJECT (demux, "upstream segment start %" GST_TIME_FORMAT
2027         ", interpolation gap: %" GST_TIME_FORMAT,
2028         GST_TIME_ARGS (demux->in_segment.start), GST_TIME_ARGS (demux->in_gap));
2029   }
2030
2031   gst_adapter_push (demux->adapter, buf);
2032
2033   switch (demux->state) {
2034     case GST_ASF_DEMUX_STATE_INDEX:{
2035       gint result = gst_asf_demux_check_header (demux);
2036       if (result == GST_ASF_DEMUX_CHECK_HEADER_NEED_DATA)       /* need more data */
2037         break;
2038
2039       if (result == GST_ASF_DEMUX_CHECK_HEADER_NO) {
2040         /* we don't care about this, probably an index */
2041         /* TODO maybe would be smarter to skip all the indices
2042          * until we got a new header or EOS to decide */
2043         GST_LOG_OBJECT (demux, "Received index object, its EOS");
2044         goto eos;
2045       } else {
2046         GST_INFO_OBJECT (demux, "Chained asf starting");
2047         /* cleanup and get ready for a chained asf */
2048         gst_asf_demux_reset (demux, TRUE);
2049         /* fall through */
2050       }
2051     }
2052     case GST_ASF_DEMUX_STATE_HEADER:{
2053       ret = gst_asf_demux_chain_headers (demux);
2054       if (demux->state != GST_ASF_DEMUX_STATE_DATA)
2055         break;
2056       /* otherwise fall through */
2057     }
2058     case GST_ASF_DEMUX_STATE_DATA:
2059     {
2060       guint64 data_size;
2061
2062       data_size = demux->packet_size;
2063
2064       while (gst_adapter_available (demux->adapter) >= data_size) {
2065         GstBuffer *buf;
2066         GstAsfDemuxParsePacketError err;
2067
2068         /* we don't know the length of the stream
2069          * check for a chained asf everytime */
2070         if (demux->num_packets == 0) {
2071           gint result = gst_asf_demux_check_header (demux);
2072
2073           if (result == GST_ASF_DEMUX_CHECK_HEADER_YES) {
2074             GST_INFO_OBJECT (demux, "Chained asf starting");
2075             /* cleanup and get ready for a chained asf */
2076             gst_asf_demux_reset (demux, TRUE);
2077             break;
2078           }
2079         } else if (G_UNLIKELY (demux->num_packets != 0 && demux->packet >= 0
2080                 && demux->packet >= demux->num_packets)) {
2081           /* do not overshoot data section when streaming */
2082           break;
2083         }
2084
2085         buf = gst_adapter_take_buffer (demux->adapter, data_size);
2086
2087         /* FIXME: We should tally up fatal errors and error out only
2088          * after a few broken packets in a row? */
2089         err = gst_asf_demux_parse_packet (demux, buf);
2090
2091         gst_buffer_unref (buf);
2092
2093         if (G_LIKELY (err == GST_ASF_DEMUX_PARSE_PACKET_ERROR_NONE))
2094           ret = gst_asf_demux_push_complete_payloads (demux, FALSE);
2095         else
2096           GST_WARNING_OBJECT (demux, "Parse error");
2097
2098         if (demux->packet >= 0)
2099           ++demux->packet;
2100       }
2101       if (G_UNLIKELY (demux->num_packets != 0 && demux->packet >= 0
2102               && demux->packet >= demux->num_packets)) {
2103         demux->state = GST_ASF_DEMUX_STATE_INDEX;
2104       }
2105       break;
2106     }
2107     default:
2108       g_assert_not_reached ();
2109   }
2110
2111 done:
2112   if (ret != GST_FLOW_OK)
2113     GST_DEBUG_OBJECT (demux, "flow: %s", gst_flow_get_name (ret));
2114
2115   return ret;
2116
2117 eos:
2118   {
2119     GST_DEBUG_OBJECT (demux, "Handled last packet, setting EOS");
2120     ret = GST_FLOW_EOS;
2121     goto done;
2122   }
2123 }
2124
2125 static inline gboolean
2126 gst_asf_demux_skip_bytes (guint num_bytes, guint8 ** p_data, guint64 * p_size)
2127 {
2128   if (*p_size < num_bytes)
2129     return FALSE;
2130
2131   *p_data += num_bytes;
2132   *p_size -= num_bytes;
2133   return TRUE;
2134 }
2135
2136 static inline guint8
2137 gst_asf_demux_get_uint8 (guint8 ** p_data, guint64 * p_size)
2138 {
2139   guint8 ret;
2140
2141   g_assert (*p_size >= 1);
2142   ret = GST_READ_UINT8 (*p_data);
2143   *p_data += sizeof (guint8);
2144   *p_size -= sizeof (guint8);
2145   return ret;
2146 }
2147
2148 static inline guint16
2149 gst_asf_demux_get_uint16 (guint8 ** p_data, guint64 * p_size)
2150 {
2151   guint16 ret;
2152
2153   g_assert (*p_size >= 2);
2154   ret = GST_READ_UINT16_LE (*p_data);
2155   *p_data += sizeof (guint16);
2156   *p_size -= sizeof (guint16);
2157   return ret;
2158 }
2159
2160 static inline guint32
2161 gst_asf_demux_get_uint32 (guint8 ** p_data, guint64 * p_size)
2162 {
2163   guint32 ret;
2164
2165   g_assert (*p_size >= 4);
2166   ret = GST_READ_UINT32_LE (*p_data);
2167   *p_data += sizeof (guint32);
2168   *p_size -= sizeof (guint32);
2169   return ret;
2170 }
2171
2172 static inline guint64
2173 gst_asf_demux_get_uint64 (guint8 ** p_data, guint64 * p_size)
2174 {
2175   guint64 ret;
2176
2177   g_assert (*p_size >= 8);
2178   ret = GST_READ_UINT64_LE (*p_data);
2179   *p_data += sizeof (guint64);
2180   *p_size -= sizeof (guint64);
2181   return ret;
2182 }
2183
2184 static inline guint32
2185 gst_asf_demux_get_var_length (guint8 type, guint8 ** p_data, guint64 * p_size)
2186 {
2187   switch (type) {
2188     case 0:
2189       return 0;
2190
2191     case 1:
2192       g_assert (*p_size >= 1);
2193       return gst_asf_demux_get_uint8 (p_data, p_size);
2194
2195     case 2:
2196       g_assert (*p_size >= 2);
2197       return gst_asf_demux_get_uint16 (p_data, p_size);
2198
2199     case 3:
2200       g_assert (*p_size >= 4);
2201       return gst_asf_demux_get_uint32 (p_data, p_size);
2202
2203     default:
2204       g_assert_not_reached ();
2205       break;
2206   }
2207   return 0;
2208 }
2209
2210 static gboolean
2211 gst_asf_demux_get_buffer (GstBuffer ** p_buf, guint num_bytes_to_read,
2212     guint8 ** p_data, guint64 * p_size)
2213 {
2214   *p_buf = NULL;
2215
2216   if (*p_size < num_bytes_to_read)
2217     return FALSE;
2218
2219   *p_buf = gst_buffer_new_and_alloc (num_bytes_to_read);
2220   gst_buffer_fill (*p_buf, 0, *p_data, num_bytes_to_read);
2221
2222   *p_data += num_bytes_to_read;
2223   *p_size -= num_bytes_to_read;
2224
2225   return TRUE;
2226 }
2227
2228 static gboolean
2229 gst_asf_demux_get_bytes (guint8 ** p_buf, guint num_bytes_to_read,
2230     guint8 ** p_data, guint64 * p_size)
2231 {
2232   *p_buf = NULL;
2233
2234   if (*p_size < num_bytes_to_read)
2235     return FALSE;
2236
2237   *p_buf = g_memdup (*p_data, num_bytes_to_read);
2238   *p_data += num_bytes_to_read;
2239   *p_size -= num_bytes_to_read;
2240   return TRUE;
2241 }
2242
2243 static gboolean
2244 gst_asf_demux_get_string (gchar ** p_str, guint16 * p_strlen,
2245     guint8 ** p_data, guint64 * p_size)
2246 {
2247   guint16 s_length;
2248   guint8 *s;
2249
2250   *p_str = NULL;
2251
2252   if (*p_size < 2)
2253     return FALSE;
2254
2255   s_length = gst_asf_demux_get_uint16 (p_data, p_size);
2256
2257   if (p_strlen)
2258     *p_strlen = s_length;
2259
2260   if (s_length == 0) {
2261     GST_WARNING ("zero-length string");
2262     *p_str = g_strdup ("");
2263     return TRUE;
2264   }
2265
2266   if (!gst_asf_demux_get_bytes (&s, s_length, p_data, p_size))
2267     return FALSE;
2268
2269   g_assert (s != NULL);
2270
2271   /* just because They don't exist doesn't
2272    * mean They are not out to get you ... */
2273   if (s[s_length - 1] != '\0') {
2274     s = g_realloc (s, s_length + 1);
2275     s[s_length] = '\0';
2276   }
2277
2278   *p_str = (gchar *) s;
2279   return TRUE;
2280 }
2281
2282
2283 static void
2284 gst_asf_demux_get_guid (ASFGuid * guid, guint8 ** p_data, guint64 * p_size)
2285 {
2286   g_assert (*p_size >= 4 * sizeof (guint32));
2287
2288   guid->v1 = gst_asf_demux_get_uint32 (p_data, p_size);
2289   guid->v2 = gst_asf_demux_get_uint32 (p_data, p_size);
2290   guid->v3 = gst_asf_demux_get_uint32 (p_data, p_size);
2291   guid->v4 = gst_asf_demux_get_uint32 (p_data, p_size);
2292 }
2293
2294 static gboolean
2295 gst_asf_demux_get_stream_audio (asf_stream_audio * audio, guint8 ** p_data,
2296     guint64 * p_size)
2297 {
2298   if (*p_size < (2 + 2 + 4 + 4 + 2 + 2 + 2))
2299     return FALSE;
2300
2301   /* WAVEFORMATEX Structure */
2302   audio->codec_tag = gst_asf_demux_get_uint16 (p_data, p_size);
2303   audio->channels = gst_asf_demux_get_uint16 (p_data, p_size);
2304   audio->sample_rate = gst_asf_demux_get_uint32 (p_data, p_size);
2305   audio->byte_rate = gst_asf_demux_get_uint32 (p_data, p_size);
2306   audio->block_align = gst_asf_demux_get_uint16 (p_data, p_size);
2307   audio->word_size = gst_asf_demux_get_uint16 (p_data, p_size);
2308   /* Codec specific data size */
2309   audio->size = gst_asf_demux_get_uint16 (p_data, p_size);
2310   return TRUE;
2311 }
2312
2313 static gboolean
2314 gst_asf_demux_get_stream_video (asf_stream_video * video, guint8 ** p_data,
2315     guint64 * p_size)
2316 {
2317   if (*p_size < (4 + 4 + 1 + 2))
2318     return FALSE;
2319
2320   video->width = gst_asf_demux_get_uint32 (p_data, p_size);
2321   video->height = gst_asf_demux_get_uint32 (p_data, p_size);
2322   video->unknown = gst_asf_demux_get_uint8 (p_data, p_size);
2323   video->size = gst_asf_demux_get_uint16 (p_data, p_size);
2324   return TRUE;
2325 }
2326
2327 static gboolean
2328 gst_asf_demux_get_stream_video_format (asf_stream_video_format * fmt,
2329     guint8 ** p_data, guint64 * p_size)
2330 {
2331   if (*p_size < (4 + 4 + 4 + 2 + 2 + 4 + 4 + 4 + 4 + 4 + 4))
2332     return FALSE;
2333
2334   fmt->size = gst_asf_demux_get_uint32 (p_data, p_size);
2335   fmt->width = gst_asf_demux_get_uint32 (p_data, p_size);
2336   fmt->height = gst_asf_demux_get_uint32 (p_data, p_size);
2337   fmt->planes = gst_asf_demux_get_uint16 (p_data, p_size);
2338   fmt->depth = gst_asf_demux_get_uint16 (p_data, p_size);
2339   fmt->tag = gst_asf_demux_get_uint32 (p_data, p_size);
2340   fmt->image_size = gst_asf_demux_get_uint32 (p_data, p_size);
2341   fmt->xpels_meter = gst_asf_demux_get_uint32 (p_data, p_size);
2342   fmt->ypels_meter = gst_asf_demux_get_uint32 (p_data, p_size);
2343   fmt->num_colors = gst_asf_demux_get_uint32 (p_data, p_size);
2344   fmt->imp_colors = gst_asf_demux_get_uint32 (p_data, p_size);
2345   return TRUE;
2346 }
2347
2348 AsfStream *
2349 gst_asf_demux_get_stream (GstASFDemux * demux, guint16 id)
2350 {
2351   guint i;
2352
2353   for (i = 0; i < demux->num_streams; i++) {
2354     if (demux->stream[i].id == id)
2355       return &demux->stream[i];
2356   }
2357
2358   if (gst_asf_demux_is_unknown_stream (demux, id))
2359     GST_WARNING ("Segment found for undefined stream: (%d)", id);
2360   return NULL;
2361 }
2362
2363 static void
2364 gst_asf_demux_setup_pad (GstASFDemux * demux, GstPad * src_pad,
2365     GstCaps * caps, guint16 id, gboolean is_video, GstTagList * tags)
2366 {
2367   AsfStream *stream;
2368
2369   gst_pad_use_fixed_caps (src_pad);
2370   gst_pad_set_caps (src_pad, caps);
2371
2372   gst_pad_set_event_function (src_pad,
2373       GST_DEBUG_FUNCPTR (gst_asf_demux_handle_src_event));
2374   gst_pad_set_query_function (src_pad,
2375       GST_DEBUG_FUNCPTR (gst_asf_demux_handle_src_query));
2376
2377   stream = &demux->stream[demux->num_streams];
2378   stream->caps = caps;
2379   stream->pad = src_pad;
2380   stream->id = id;
2381   stream->fps_known = !is_video;        /* bit hacky for audio */
2382   stream->is_video = is_video;
2383   stream->pending_tags = tags;
2384   stream->discont = TRUE;
2385   if (is_video) {
2386     GstStructure *st;
2387     gint par_x, par_y;
2388     st = gst_caps_get_structure (caps, 0);
2389     if (gst_structure_get_fraction (st, "pixel-aspect-ratio", &par_x, &par_y) &&
2390         par_x > 0 && par_y > 0) {
2391       GST_DEBUG ("PAR %d/%d", par_x, par_y);
2392       stream->par_x = par_x;
2393       stream->par_y = par_y;
2394     }
2395   }
2396
2397   stream->payloads = g_array_new (FALSE, FALSE, sizeof (AsfPayload));
2398
2399   GST_INFO ("Created pad %s for stream %u with caps %" GST_PTR_FORMAT,
2400       GST_PAD_NAME (src_pad), demux->num_streams, caps);
2401
2402   ++demux->num_streams;
2403
2404   stream->active = FALSE;
2405 }
2406
2407 static void
2408 gst_asf_demux_add_audio_stream (GstASFDemux * demux,
2409     asf_stream_audio * audio, guint16 id, guint8 ** p_data, guint64 * p_size)
2410 {
2411   GstTagList *tags = NULL;
2412   GstBuffer *extradata = NULL;
2413   GstPad *src_pad;
2414   GstCaps *caps;
2415   guint16 size_left = 0;
2416   gchar *codec_name = NULL;
2417   gchar *name = NULL;
2418
2419   size_left = audio->size;
2420
2421   /* Create the audio pad */
2422   name = g_strdup_printf ("audio_%u", demux->num_audio_streams);
2423
2424   src_pad = gst_pad_new_from_static_template (&audio_src_template, name);
2425   g_free (name);
2426
2427   /* Swallow up any left over data and set up the 
2428    * standard properties from the header info */
2429   if (size_left) {
2430     GST_INFO_OBJECT (demux, "Audio header contains %d bytes of "
2431         "codec specific data", size_left);
2432
2433     g_assert (size_left <= *p_size);
2434     gst_asf_demux_get_buffer (&extradata, size_left, p_data, p_size);
2435   }
2436
2437   /* asf_stream_audio is the same as gst_riff_strf_auds, but with an
2438    * additional two bytes indicating extradata. */
2439   /* FIXME: Handle the channel reorder map here */
2440   caps = gst_riff_create_audio_caps (audio->codec_tag, NULL,
2441       (gst_riff_strf_auds *) audio, extradata, NULL, &codec_name, NULL);
2442
2443   if (caps == NULL) {
2444     caps = gst_caps_new_simple ("audio/x-asf-unknown", "codec_id",
2445         G_TYPE_INT, (gint) audio->codec_tag, NULL);
2446   }
2447
2448   /* Informing about that audio format we just added */
2449   if (codec_name) {
2450     tags = gst_tag_list_new (GST_TAG_AUDIO_CODEC, codec_name, NULL);
2451     g_free (codec_name);
2452   }
2453
2454   if (extradata)
2455     gst_buffer_unref (extradata);
2456
2457   GST_INFO ("Adding audio stream #%u, id %u codec %u (0x%04x), tags=%"
2458       GST_PTR_FORMAT, demux->num_audio_streams, id, audio->codec_tag,
2459       audio->codec_tag, tags);
2460
2461   ++demux->num_audio_streams;
2462
2463   gst_asf_demux_setup_pad (demux, src_pad, caps, id, FALSE, tags);
2464 }
2465
2466 static void
2467 gst_asf_demux_add_video_stream (GstASFDemux * demux,
2468     asf_stream_video_format * video, guint16 id,
2469     guint8 ** p_data, guint64 * p_size)
2470 {
2471   GstTagList *tags = NULL;
2472   GstBuffer *extradata = NULL;
2473   GstPad *src_pad;
2474   GstCaps *caps;
2475   gchar *str;
2476   gchar *name = NULL;
2477   gchar *codec_name = NULL;
2478   gint size_left = video->size - 40;
2479
2480   /* Create the video pad */
2481   name = g_strdup_printf ("video_%u", demux->num_video_streams);
2482   src_pad = gst_pad_new_from_static_template (&video_src_template, name);
2483   g_free (name);
2484
2485   /* Now try some gstreamer formatted MIME types (from gst_avi_demux_strf_vids) */
2486   if (size_left) {
2487     GST_LOG ("Video header has %d bytes of codec specific data", size_left);
2488     g_assert (size_left <= *p_size);
2489     gst_asf_demux_get_buffer (&extradata, size_left, p_data, p_size);
2490   }
2491
2492   GST_DEBUG ("video codec %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (video->tag));
2493
2494   /* yes, asf_stream_video_format and gst_riff_strf_vids are the same */
2495   caps = gst_riff_create_video_caps (video->tag, NULL,
2496       (gst_riff_strf_vids *) video, extradata, NULL, &codec_name);
2497
2498   if (caps == NULL) {
2499     caps = gst_caps_new_simple ("video/x-asf-unknown", "fourcc",
2500         G_TYPE_UINT, video->tag, NULL);
2501   } else {
2502     GstStructure *s;
2503     gint ax, ay;
2504
2505     s = gst_asf_demux_get_metadata_for_stream (demux, id);
2506     if (gst_structure_get_int (s, "AspectRatioX", &ax) &&
2507         gst_structure_get_int (s, "AspectRatioY", &ay) && (ax > 0 && ay > 0)) {
2508       gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
2509           ax, ay, NULL);
2510
2511     } else {
2512       guint ax, ay;
2513       /* retry with the global metadata */
2514       GST_DEBUG ("Retrying with global metadata %" GST_PTR_FORMAT,
2515           demux->global_metadata);
2516       s = demux->global_metadata;
2517       if (gst_structure_get_uint (s, "AspectRatioX", &ax) &&
2518           gst_structure_get_uint (s, "AspectRatioY", &ay)) {
2519         GST_DEBUG ("ax:%d, ay:%d", ax, ay);
2520         if (ax > 0 && ay > 0)
2521           gst_caps_set_simple (caps, "pixel-aspect-ratio", GST_TYPE_FRACTION,
2522               ax, ay, NULL);
2523       }
2524     }
2525     s = gst_caps_get_structure (caps, 0);
2526     gst_structure_remove_field (s, "framerate");
2527   }
2528
2529   /* add fourcc format to caps, some proprietary decoders seem to need it */
2530   str = g_strdup_printf ("%" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (video->tag));
2531   gst_caps_set_simple (caps, "format", G_TYPE_STRING, str, NULL);
2532   g_free (str);
2533
2534   if (codec_name) {
2535     tags = gst_tag_list_new (GST_TAG_VIDEO_CODEC, codec_name, NULL);
2536     g_free (codec_name);
2537   }
2538
2539   if (extradata)
2540     gst_buffer_unref (extradata);
2541
2542   GST_INFO ("Adding video stream #%u, id %u, codec %"
2543       GST_FOURCC_FORMAT " (0x%08x)", demux->num_video_streams, id,
2544       GST_FOURCC_ARGS (video->tag), video->tag);
2545
2546   ++demux->num_video_streams;
2547
2548   gst_asf_demux_setup_pad (demux, src_pad, caps, id, TRUE, tags);
2549 }
2550
2551 static void
2552 gst_asf_demux_activate_stream (GstASFDemux * demux, AsfStream * stream)
2553 {
2554   if (!stream->active) {
2555     GstEvent *event;
2556     gchar *stream_id;
2557
2558     GST_INFO_OBJECT (demux, "Activating stream %2u, pad %s, caps %"
2559         GST_PTR_FORMAT, stream->id, GST_PAD_NAME (stream->pad), stream->caps);
2560     gst_pad_set_active (stream->pad, TRUE);
2561
2562     stream_id =
2563         gst_pad_create_stream_id_printf (stream->pad, GST_ELEMENT_CAST (demux),
2564         "%03u", stream->id);
2565
2566     event =
2567         gst_pad_get_sticky_event (demux->sinkpad, GST_EVENT_STREAM_START, 0);
2568     if (event) {
2569       if (gst_event_parse_group_id (event, &demux->group_id))
2570         demux->have_group_id = TRUE;
2571       else
2572         demux->have_group_id = FALSE;
2573       gst_event_unref (event);
2574     } else if (!demux->have_group_id) {
2575       demux->have_group_id = TRUE;
2576       demux->group_id = gst_util_group_id_next ();
2577     }
2578
2579     event = gst_event_new_stream_start (stream_id);
2580     if (demux->have_group_id)
2581       gst_event_set_group_id (event, demux->group_id);
2582
2583     gst_pad_push_event (stream->pad, event);
2584     g_free (stream_id);
2585     gst_pad_set_caps (stream->pad, stream->caps);
2586
2587     gst_element_add_pad (GST_ELEMENT_CAST (demux), stream->pad);
2588     stream->active = TRUE;
2589   }
2590 }
2591
2592 static AsfStream *
2593 gst_asf_demux_parse_stream_object (GstASFDemux * demux, guint8 * data,
2594     guint64 size)
2595 {
2596   AsfCorrectionType correction_type;
2597   AsfStreamType stream_type;
2598   GstClockTime time_offset;
2599   gboolean is_encrypted G_GNUC_UNUSED;
2600   guint16 stream_id;
2601   guint16 flags;
2602   ASFGuid guid;
2603   guint stream_specific_size;
2604   guint type_specific_size G_GNUC_UNUSED;
2605   guint unknown G_GNUC_UNUSED;
2606   gboolean inspect_payload = FALSE;
2607   AsfStream *stream;
2608
2609   /* Get the rest of the header's header */
2610   if (size < (16 + 16 + 8 + 4 + 4 + 2 + 4))
2611     goto not_enough_data;
2612
2613   gst_asf_demux_get_guid (&guid, &data, &size);
2614   stream_type = gst_asf_demux_identify_guid (asf_stream_guids, &guid);
2615
2616   gst_asf_demux_get_guid (&guid, &data, &size);
2617   correction_type = gst_asf_demux_identify_guid (asf_correction_guids, &guid);
2618
2619   time_offset = gst_asf_demux_get_uint64 (&data, &size) * 100;
2620
2621   type_specific_size = gst_asf_demux_get_uint32 (&data, &size);
2622   stream_specific_size = gst_asf_demux_get_uint32 (&data, &size);
2623
2624   flags = gst_asf_demux_get_uint16 (&data, &size);
2625   stream_id = flags & 0x7f;
2626   is_encrypted = ! !((flags & 0x8000) << 15);
2627   unknown = gst_asf_demux_get_uint32 (&data, &size);
2628
2629   GST_DEBUG_OBJECT (demux, "Found stream %u, time_offset=%" GST_TIME_FORMAT,
2630       stream_id, GST_TIME_ARGS (time_offset));
2631
2632   /* dvr-ms has audio stream declared in stream specific data */
2633   if (stream_type == ASF_STREAM_EXT_EMBED_HEADER) {
2634     AsfExtStreamType ext_stream_type;
2635     gst_asf_demux_get_guid (&guid, &data, &size);
2636     ext_stream_type = gst_asf_demux_identify_guid (asf_ext_stream_guids, &guid);
2637
2638     if (ext_stream_type == ASF_EXT_STREAM_AUDIO) {
2639       inspect_payload = TRUE;
2640
2641       gst_asf_demux_get_guid (&guid, &data, &size);
2642       gst_asf_demux_get_uint32 (&data, &size);
2643       gst_asf_demux_get_uint32 (&data, &size);
2644       gst_asf_demux_get_uint32 (&data, &size);
2645       gst_asf_demux_get_guid (&guid, &data, &size);
2646       gst_asf_demux_get_uint32 (&data, &size);
2647       stream_type = ASF_STREAM_AUDIO;
2648     }
2649   }
2650
2651   switch (stream_type) {
2652     case ASF_STREAM_AUDIO:{
2653       asf_stream_audio audio_object;
2654
2655       if (!gst_asf_demux_get_stream_audio (&audio_object, &data, &size))
2656         goto not_enough_data;
2657
2658       GST_INFO ("Object is an audio stream with %u bytes of additional data",
2659           audio_object.size);
2660
2661       gst_asf_demux_add_audio_stream (demux, &audio_object, stream_id,
2662           &data, &size);
2663
2664       switch (correction_type) {
2665         case ASF_CORRECTION_ON:{
2666           guint span, packet_size, chunk_size, data_size, silence_data;
2667
2668           GST_INFO ("Using error correction");
2669
2670           if (size < (1 + 2 + 2 + 2 + 1))
2671             goto not_enough_data;
2672
2673           span = gst_asf_demux_get_uint8 (&data, &size);
2674           packet_size = gst_asf_demux_get_uint16 (&data, &size);
2675           chunk_size = gst_asf_demux_get_uint16 (&data, &size);
2676           data_size = gst_asf_demux_get_uint16 (&data, &size);
2677           silence_data = gst_asf_demux_get_uint8 (&data, &size);
2678
2679           /* FIXME: shouldn't this be per-stream? */
2680           demux->span = span;
2681
2682           GST_DEBUG_OBJECT (demux, "Descrambling ps:%u cs:%u ds:%u s:%u sd:%u",
2683               packet_size, chunk_size, data_size, span, silence_data);
2684
2685           if (demux->span > 1) {
2686             if (chunk_size == 0 || ((packet_size / chunk_size) <= 1)) {
2687               /* Disable descrambling */
2688               demux->span = 0;
2689             } else {
2690               /* FIXME: this else branch was added for
2691                * weird_al_yankovic - the saga begins.asf */
2692               demux->ds_packet_size = packet_size;
2693               demux->ds_chunk_size = chunk_size;
2694             }
2695           } else {
2696             /* Descambling is enabled */
2697             demux->ds_packet_size = packet_size;
2698             demux->ds_chunk_size = chunk_size;
2699           }
2700 #if 0
2701           /* Now skip the rest of the silence data */
2702           if (data_size > 1)
2703             gst_bytestream_flush (demux->bs, data_size - 1);
2704 #else
2705           /* FIXME: CHECKME. And why -1? */
2706           if (data_size > 1) {
2707             if (!gst_asf_demux_skip_bytes (data_size - 1, &data, &size)) {
2708               goto not_enough_data;
2709             }
2710           }
2711 #endif
2712           break;
2713         }
2714         case ASF_CORRECTION_OFF:{
2715           GST_INFO ("Error correction off");
2716           if (!gst_asf_demux_skip_bytes (stream_specific_size, &data, &size))
2717             goto not_enough_data;
2718           break;
2719         }
2720         default:
2721           GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
2722               ("Audio stream using unknown error correction"));
2723           return NULL;
2724       }
2725
2726       break;
2727     }
2728
2729     case ASF_STREAM_VIDEO:{
2730       asf_stream_video_format video_format_object;
2731       asf_stream_video video_object;
2732       guint16 vsize;
2733
2734       if (!gst_asf_demux_get_stream_video (&video_object, &data, &size))
2735         goto not_enough_data;
2736
2737       vsize = video_object.size - 40;   /* Byte order gets offset by single byte */
2738
2739       GST_INFO ("object is a video stream with %u bytes of "
2740           "additional data", vsize);
2741
2742       if (!gst_asf_demux_get_stream_video_format (&video_format_object,
2743               &data, &size)) {
2744         goto not_enough_data;
2745       }
2746
2747       gst_asf_demux_add_video_stream (demux, &video_format_object, stream_id,
2748           &data, &size);
2749
2750       break;
2751     }
2752
2753     default:
2754       GST_WARNING_OBJECT (demux, "Unknown stream type for stream %u",
2755           stream_id);
2756       demux->other_streams =
2757           g_slist_append (demux->other_streams, GINT_TO_POINTER (stream_id));
2758       break;
2759   }
2760
2761   stream = gst_asf_demux_get_stream (demux, stream_id);
2762   if (stream)
2763     stream->inspect_payload = inspect_payload;
2764   return stream;
2765
2766 not_enough_data:
2767   {
2768     GST_WARNING_OBJECT (demux, "Unexpected end of data parsing stream object");
2769     /* we'll error out later if we found no streams */
2770     return NULL;
2771   }
2772 }
2773
2774 static const gchar *
2775 gst_asf_demux_get_gst_tag_from_tag_name (const gchar * name_utf8)
2776 {
2777   const struct
2778   {
2779     const gchar *asf_name;
2780     const gchar *gst_name;
2781   } tags[] = {
2782     {
2783     "WM/Genre", GST_TAG_GENRE}, {
2784     "WM/AlbumTitle", GST_TAG_ALBUM}, {
2785     "WM/AlbumArtist", GST_TAG_ARTIST}, {
2786     "WM/Picture", GST_TAG_IMAGE}, {
2787     "WM/Track", GST_TAG_TRACK_NUMBER}, {
2788     "WM/TrackNumber", GST_TAG_TRACK_NUMBER}, {
2789     "WM/Year", GST_TAG_DATE_TIME}
2790     /* { "WM/Composer", GST_TAG_COMPOSER } */
2791   };
2792   gsize out;
2793   guint i;
2794
2795   if (name_utf8 == NULL) {
2796     GST_WARNING ("Failed to convert name to UTF8, skipping");
2797     return NULL;
2798   }
2799
2800   out = strlen (name_utf8);
2801
2802   for (i = 0; i < G_N_ELEMENTS (tags); ++i) {
2803     if (strncmp (tags[i].asf_name, name_utf8, out) == 0) {
2804       GST_LOG ("map tagname '%s' -> '%s'", name_utf8, tags[i].gst_name);
2805       return tags[i].gst_name;
2806     }
2807   }
2808
2809   return NULL;
2810 }
2811
2812 /* gst_asf_demux_add_global_tags() takes ownership of taglist! */
2813 static void
2814 gst_asf_demux_add_global_tags (GstASFDemux * demux, GstTagList * taglist)
2815 {
2816   GstTagList *t;
2817
2818   GST_DEBUG_OBJECT (demux, "adding global tags: %" GST_PTR_FORMAT, taglist);
2819
2820   if (taglist == NULL)
2821     return;
2822
2823   if (gst_tag_list_is_empty (taglist)) {
2824     gst_tag_list_unref (taglist);
2825     return;
2826   }
2827
2828   t = gst_tag_list_merge (demux->taglist, taglist, GST_TAG_MERGE_APPEND);
2829   gst_tag_list_set_scope (t, GST_TAG_SCOPE_GLOBAL);
2830   if (demux->taglist)
2831     gst_tag_list_unref (demux->taglist);
2832   gst_tag_list_unref (taglist);
2833   demux->taglist = t;
2834   GST_LOG_OBJECT (demux, "global tags now: %" GST_PTR_FORMAT, demux->taglist);
2835 }
2836
2837 #define ASF_DEMUX_DATA_TYPE_UTF16LE_STRING  0
2838 #define ASF_DEMUX_DATA_TYPE_BYTE_ARRAY      1
2839 #define ASF_DEMUX_DATA_TYPE_DWORD           3
2840
2841 static void
2842 asf_demux_parse_picture_tag (GstTagList * tags, const guint8 * tag_data,
2843     guint tag_data_len)
2844 {
2845   GstByteReader r;
2846   const guint8 *img_data = NULL;
2847   guint32 img_data_len = 0;
2848   guint8 pic_type = 0;
2849
2850   gst_byte_reader_init (&r, tag_data, tag_data_len);
2851
2852   /* skip mime type string (we don't trust it and do our own typefinding),
2853    * and also skip the description string, since we don't use it */
2854   if (!gst_byte_reader_get_uint8 (&r, &pic_type) ||
2855       !gst_byte_reader_get_uint32_le (&r, &img_data_len) ||
2856       !gst_byte_reader_skip_string_utf16 (&r) ||
2857       !gst_byte_reader_skip_string_utf16 (&r) ||
2858       !gst_byte_reader_get_data (&r, img_data_len, &img_data)) {
2859     goto not_enough_data;
2860   }
2861
2862
2863   if (!gst_tag_list_add_id3_image (tags, img_data, img_data_len, pic_type))
2864     GST_DEBUG ("failed to add image extracted from WM/Picture tag to taglist");
2865
2866   return;
2867
2868 not_enough_data:
2869   {
2870     GST_DEBUG ("Failed to read WM/Picture tag: not enough data");
2871     GST_MEMDUMP ("WM/Picture data", tag_data, tag_data_len);
2872     return;
2873   }
2874 }
2875
2876 /* Extended Content Description Object */
2877 static GstFlowReturn
2878 gst_asf_demux_process_ext_content_desc (GstASFDemux * demux, guint8 * data,
2879     guint64 size)
2880 {
2881   /* Other known (and unused) 'text/unicode' metadata available :
2882    *
2883    *   WM/Lyrics =
2884    *   WM/MediaPrimaryClassID = {D1607DBC-E323-4BE2-86A1-48A42A28441E}
2885    *   WMFSDKVersion = 9.00.00.2980
2886    *   WMFSDKNeeded = 0.0.0.0000
2887    *   WM/UniqueFileIdentifier = AMGa_id=R    15334;AMGp_id=P     5149;AMGt_id=T  2324984
2888    *   WM/Publisher = 4AD
2889    *   WM/Provider = AMG
2890    *   WM/ProviderRating = 8
2891    *   WM/ProviderStyle = Rock (similar to WM/Genre)
2892    *   WM/GenreID (similar to WM/Genre)
2893    *   WM/TrackNumber (same as WM/Track but as a string)
2894    *
2895    * Other known (and unused) 'non-text' metadata available :
2896    *
2897    *   WM/EncodingTime
2898    *   WM/MCDI
2899    *   IsVBR
2900    *
2901    * We might want to read WM/TrackNumber and use atoi() if we don't have
2902    * WM/Track
2903    */
2904
2905   GstTagList *taglist;
2906   guint16 blockcount, i;
2907
2908   GST_INFO_OBJECT (demux, "object is an extended content description");
2909
2910   taglist = gst_tag_list_new_empty ();
2911
2912   /* Content Descriptor Count */
2913   if (size < 2)
2914     goto not_enough_data;
2915
2916   blockcount = gst_asf_demux_get_uint16 (&data, &size);
2917
2918   for (i = 1; i <= blockcount; ++i) {
2919     const gchar *gst_tag_name;
2920     guint16 datatype;
2921     guint16 value_len;
2922     guint16 name_len;
2923     GValue tag_value = { 0, };
2924     gsize in, out;
2925     gchar *name;
2926     gchar *name_utf8 = NULL;
2927     gchar *value;
2928
2929     /* Descriptor */
2930     if (!gst_asf_demux_get_string (&name, &name_len, &data, &size))
2931       goto not_enough_data;
2932
2933     if (size < 2) {
2934       g_free (name);
2935       goto not_enough_data;
2936     }
2937     /* Descriptor Value Data Type */
2938     datatype = gst_asf_demux_get_uint16 (&data, &size);
2939
2940     /* Descriptor Value (not really a string, but same thing reading-wise) */
2941     if (!gst_asf_demux_get_string (&value, &value_len, &data, &size)) {
2942       g_free (name);
2943       goto not_enough_data;
2944     }
2945
2946     name_utf8 =
2947         g_convert (name, name_len, "UTF-8", "UTF-16LE", &in, &out, NULL);
2948
2949     if (name_utf8 != NULL) {
2950       GST_DEBUG ("Found tag/metadata %s", name_utf8);
2951
2952       gst_tag_name = gst_asf_demux_get_gst_tag_from_tag_name (name_utf8);
2953       GST_DEBUG ("gst_tag_name %s", GST_STR_NULL (gst_tag_name));
2954
2955       switch (datatype) {
2956         case ASF_DEMUX_DATA_TYPE_UTF16LE_STRING:{
2957           gchar *value_utf8;
2958
2959           value_utf8 = g_convert (value, value_len, "UTF-8", "UTF-16LE",
2960               &in, &out, NULL);
2961
2962           /* get rid of tags with empty value */
2963           if (value_utf8 != NULL && *value_utf8 != '\0') {
2964             GST_DEBUG ("string value %s", value_utf8);
2965
2966             value_utf8[out] = '\0';
2967
2968             if (gst_tag_name != NULL) {
2969               if (strcmp (gst_tag_name, GST_TAG_DATE_TIME) == 0) {
2970                 guint year = atoi (value_utf8);
2971
2972                 if (year > 0) {
2973                   g_value_init (&tag_value, GST_TYPE_DATE_TIME);
2974                   g_value_take_boxed (&tag_value, gst_date_time_new_y (year));
2975                 }
2976               } else if (strcmp (gst_tag_name, GST_TAG_GENRE) == 0) {
2977                 guint id3v1_genre_id;
2978                 const gchar *genre_str;
2979
2980                 if (sscanf (value_utf8, "(%u)", &id3v1_genre_id) == 1 &&
2981                     ((genre_str = gst_tag_id3_genre_get (id3v1_genre_id)))) {
2982                   GST_DEBUG ("Genre: %s -> %s", value_utf8, genre_str);
2983                   g_free (value_utf8);
2984                   value_utf8 = g_strdup (genre_str);
2985                 }
2986               } else {
2987                 GType tag_type;
2988
2989                 /* convert tag from string to other type if required */
2990                 tag_type = gst_tag_get_type (gst_tag_name);
2991                 g_value_init (&tag_value, tag_type);
2992                 if (!gst_value_deserialize (&tag_value, value_utf8)) {
2993                   GValue from_val = { 0, };
2994
2995                   g_value_init (&from_val, G_TYPE_STRING);
2996                   g_value_set_string (&from_val, value_utf8);
2997                   if (!g_value_transform (&from_val, &tag_value)) {
2998                     GST_WARNING_OBJECT (demux,
2999                         "Could not transform string tag to " "%s tag type %s",
3000                         gst_tag_name, g_type_name (tag_type));
3001                     g_value_unset (&tag_value);
3002                   }
3003                   g_value_unset (&from_val);
3004                 }
3005               }
3006             } else {
3007               /* metadata ! */
3008               GST_DEBUG ("Setting metadata");
3009               g_value_init (&tag_value, G_TYPE_STRING);
3010               g_value_set_string (&tag_value, value_utf8);
3011             }
3012           } else if (value_utf8 == NULL) {
3013             GST_WARNING ("Failed to convert string value to UTF8, skipping");
3014           } else {
3015             GST_DEBUG ("Skipping empty string value for %s",
3016                 GST_STR_NULL (gst_tag_name));
3017           }
3018           g_free (value_utf8);
3019           break;
3020         }
3021         case ASF_DEMUX_DATA_TYPE_BYTE_ARRAY:{
3022           if (gst_tag_name) {
3023             if (!g_str_equal (gst_tag_name, GST_TAG_IMAGE)) {
3024               GST_FIXME ("Unhandled byte array tag %s",
3025                   GST_STR_NULL (gst_tag_name));
3026               break;
3027             } else {
3028               asf_demux_parse_picture_tag (taglist, (guint8 *) value,
3029                   value_len);
3030             }
3031           }
3032           break;
3033         }
3034         case ASF_DEMUX_DATA_TYPE_DWORD:{
3035           guint uint_val = GST_READ_UINT32_LE (value);
3036
3037           /* this is the track number */
3038           g_value_init (&tag_value, G_TYPE_UINT);
3039
3040           /* WM/Track counts from 0 */
3041           if (!strcmp (name_utf8, "WM/Track"))
3042             ++uint_val;
3043
3044           g_value_set_uint (&tag_value, uint_val);
3045           break;
3046         }
3047         default:{
3048           GST_DEBUG ("Skipping tag %s of type %d", gst_tag_name, datatype);
3049           break;
3050         }
3051       }
3052
3053       if (G_IS_VALUE (&tag_value)) {
3054         if (gst_tag_name) {
3055           GstTagMergeMode merge_mode = GST_TAG_MERGE_APPEND;
3056
3057           /* WM/TrackNumber is more reliable than WM/Track, since the latter
3058            * is supposed to have a 0 base but is often wrongly written to start
3059            * from 1 as well, so prefer WM/TrackNumber when we have it: either
3060            * replace the value added earlier from WM/Track or put it first in
3061            * the list, so that it will get picked up by _get_uint() */
3062           if (strcmp (name_utf8, "WM/TrackNumber") == 0)
3063             merge_mode = GST_TAG_MERGE_REPLACE;
3064
3065           gst_tag_list_add_values (taglist, merge_mode, gst_tag_name,
3066               &tag_value, NULL);
3067         } else {
3068           GST_DEBUG ("Setting global metadata %s", name_utf8);
3069           gst_structure_set_value (demux->global_metadata, name_utf8,
3070               &tag_value);
3071         }
3072
3073         g_value_unset (&tag_value);
3074       }
3075     }
3076
3077     g_free (name);
3078     g_free (value);
3079     g_free (name_utf8);
3080   }
3081
3082   gst_asf_demux_add_global_tags (demux, taglist);
3083
3084   return GST_FLOW_OK;
3085
3086   /* Errors */
3087 not_enough_data:
3088   {
3089     GST_WARNING ("Unexpected end of data parsing ext content desc object");
3090     gst_tag_list_unref (taglist);
3091     return GST_FLOW_OK;         /* not really fatal */
3092   }
3093 }
3094
3095 static GstStructure *
3096 gst_asf_demux_get_metadata_for_stream (GstASFDemux * demux, guint stream_num)
3097 {
3098   gchar sname[32];
3099   guint i;
3100
3101   g_snprintf (sname, sizeof (sname), "stream-%u", stream_num);
3102
3103   for (i = 0; i < gst_caps_get_size (demux->metadata); ++i) {
3104     GstStructure *s;
3105
3106     s = gst_caps_get_structure (demux->metadata, i);
3107     if (gst_structure_has_name (s, sname))
3108       return s;
3109   }
3110
3111   gst_caps_append_structure (demux->metadata, gst_structure_new_empty (sname));
3112
3113   /* try lookup again; demux->metadata took ownership of the structure, so we
3114    * can't really make any assumptions about what happened to it, so we can't
3115    * just return it directly after appending it */
3116   return gst_asf_demux_get_metadata_for_stream (demux, stream_num);
3117 }
3118
3119 static GstFlowReturn
3120 gst_asf_demux_process_metadata (GstASFDemux * demux, guint8 * data,
3121     guint64 size)
3122 {
3123   guint16 blockcount, i;
3124
3125   GST_INFO_OBJECT (demux, "object is a metadata object");
3126
3127   /* Content Descriptor Count */
3128   if (size < 2)
3129     goto not_enough_data;
3130
3131   blockcount = gst_asf_demux_get_uint16 (&data, &size);
3132
3133   for (i = 0; i < blockcount; ++i) {
3134     GstStructure *s;
3135     guint16 stream_num, name_len, data_type, lang_idx G_GNUC_UNUSED;
3136     guint32 data_len, ival;
3137     gchar *name_utf8;
3138
3139     if (size < (2 + 2 + 2 + 2 + 4))
3140       goto not_enough_data;
3141
3142     lang_idx = gst_asf_demux_get_uint16 (&data, &size);
3143     stream_num = gst_asf_demux_get_uint16 (&data, &size);
3144     name_len = gst_asf_demux_get_uint16 (&data, &size);
3145     data_type = gst_asf_demux_get_uint16 (&data, &size);
3146     data_len = gst_asf_demux_get_uint32 (&data, &size);
3147
3148     if (size < name_len + data_len)
3149       goto not_enough_data;
3150
3151     /* convert name to UTF-8 */
3152     name_utf8 = g_convert ((gchar *) data, name_len, "UTF-8", "UTF-16LE",
3153         NULL, NULL, NULL);
3154     gst_asf_demux_skip_bytes (name_len, &data, &size);
3155
3156     if (name_utf8 == NULL) {
3157       GST_WARNING ("Failed to convert value name to UTF8, skipping");
3158       gst_asf_demux_skip_bytes (data_len, &data, &size);
3159       continue;
3160     }
3161
3162     if (data_type != ASF_DEMUX_DATA_TYPE_DWORD) {
3163       gst_asf_demux_skip_bytes (data_len, &data, &size);
3164       g_free (name_utf8);
3165       continue;
3166     }
3167
3168     /* read DWORD */
3169     if (size < 4) {
3170       g_free (name_utf8);
3171       goto not_enough_data;
3172     }
3173
3174     ival = gst_asf_demux_get_uint32 (&data, &size);
3175
3176     /* skip anything else there may be, just in case */
3177     gst_asf_demux_skip_bytes (data_len - 4, &data, &size);
3178
3179     s = gst_asf_demux_get_metadata_for_stream (demux, stream_num);
3180     gst_structure_set (s, name_utf8, G_TYPE_INT, ival, NULL);
3181     g_free (name_utf8);
3182   }
3183
3184   GST_INFO_OBJECT (demux, "metadata = %" GST_PTR_FORMAT, demux->metadata);
3185   return GST_FLOW_OK;
3186
3187   /* Errors */
3188 not_enough_data:
3189   {
3190     GST_WARNING ("Unexpected end of data parsing metadata object");
3191     return GST_FLOW_OK;         /* not really fatal */
3192   }
3193 }
3194
3195 static GstFlowReturn
3196 gst_asf_demux_process_header (GstASFDemux * demux, guint8 * data, guint64 size)
3197 {
3198   GstFlowReturn ret = GST_FLOW_OK;
3199   guint32 i, num_objects;
3200   guint8 unknown G_GNUC_UNUSED;
3201
3202   /* Get the rest of the header's header */
3203   if (size < (4 + 1 + 1))
3204     goto not_enough_data;
3205
3206   num_objects = gst_asf_demux_get_uint32 (&data, &size);
3207   unknown = gst_asf_demux_get_uint8 (&data, &size);
3208   unknown = gst_asf_demux_get_uint8 (&data, &size);
3209
3210   GST_INFO_OBJECT (demux, "object is a header with %u parts", num_objects);
3211
3212   /* Loop through the header's objects, processing those */
3213   for (i = 0; i < num_objects; ++i) {
3214     GST_INFO_OBJECT (demux, "reading header part %u", i);
3215     ret = gst_asf_demux_process_object (demux, &data, &size);
3216     if (ret != GST_FLOW_OK) {
3217       GST_WARNING ("process_object returned %s", gst_asf_get_flow_name (ret));
3218       break;
3219     }
3220   }
3221
3222   return ret;
3223
3224 not_enough_data:
3225   {
3226     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3227         ("short read parsing HEADER object"));
3228     return GST_FLOW_ERROR;
3229   }
3230 }
3231
3232 static GstFlowReturn
3233 gst_asf_demux_process_file (GstASFDemux * demux, guint8 * data, guint64 size)
3234 {
3235   guint64 creation_time G_GNUC_UNUSED;
3236   guint64 file_size G_GNUC_UNUSED;
3237   guint64 send_time G_GNUC_UNUSED;
3238   guint64 packets_count, play_time, preroll;
3239   guint32 flags, min_pktsize, max_pktsize, min_bitrate G_GNUC_UNUSED;
3240
3241   if (size < (16 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + 4 + 4))
3242     goto not_enough_data;
3243
3244   gst_asf_demux_skip_bytes (16, &data, &size);  /* skip GUID */
3245   file_size = gst_asf_demux_get_uint64 (&data, &size);
3246   creation_time = gst_asf_demux_get_uint64 (&data, &size);
3247   packets_count = gst_asf_demux_get_uint64 (&data, &size);
3248   play_time = gst_asf_demux_get_uint64 (&data, &size);
3249   send_time = gst_asf_demux_get_uint64 (&data, &size);
3250   preroll = gst_asf_demux_get_uint64 (&data, &size);
3251   flags = gst_asf_demux_get_uint32 (&data, &size);
3252   min_pktsize = gst_asf_demux_get_uint32 (&data, &size);
3253   max_pktsize = gst_asf_demux_get_uint32 (&data, &size);
3254   min_bitrate = gst_asf_demux_get_uint32 (&data, &size);
3255
3256   demux->broadcast = ! !(flags & 0x01);
3257   demux->seekable = ! !(flags & 0x02);
3258
3259   GST_DEBUG_OBJECT (demux, "min_pktsize = %u", min_pktsize);
3260   GST_DEBUG_OBJECT (demux, "flags::broadcast = %d", demux->broadcast);
3261   GST_DEBUG_OBJECT (demux, "flags::seekable  = %d", demux->seekable);
3262
3263   if (demux->broadcast) {
3264     /* these fields are invalid if the broadcast flag is set */
3265     play_time = 0;
3266     file_size = 0;
3267   }
3268
3269   if (min_pktsize != max_pktsize)
3270     goto non_fixed_packet_size;
3271
3272   demux->packet_size = max_pktsize;
3273
3274   /* FIXME: do we need send_time as well? what is it? */
3275   if ((play_time * 100) >= (preroll * GST_MSECOND))
3276     demux->play_time = (play_time * 100) - (preroll * GST_MSECOND);
3277   else
3278     demux->play_time = 0;
3279
3280   demux->preroll = preroll * GST_MSECOND;
3281
3282   /* initial latency */
3283   demux->latency = demux->preroll;
3284
3285   if (demux->play_time == 0)
3286     demux->seekable = FALSE;
3287
3288   GST_DEBUG_OBJECT (demux, "play_time %" GST_TIME_FORMAT,
3289       GST_TIME_ARGS (demux->play_time));
3290   GST_DEBUG_OBJECT (demux, "preroll   %" GST_TIME_FORMAT,
3291       GST_TIME_ARGS (demux->preroll));
3292
3293   if (demux->play_time > 0) {
3294     demux->segment.duration = demux->play_time;
3295   }
3296
3297   GST_INFO ("object is a file with %" G_GUINT64_FORMAT " data packets",
3298       packets_count);
3299   GST_INFO ("preroll = %" G_GUINT64_FORMAT, demux->preroll);
3300
3301   return GST_FLOW_OK;
3302
3303 /* ERRORS */
3304 non_fixed_packet_size:
3305   {
3306     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3307         ("packet size must be fixed"));
3308     return GST_FLOW_ERROR;
3309   }
3310 not_enough_data:
3311   {
3312     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3313         ("short read parsing FILE object"));
3314     return GST_FLOW_ERROR;
3315   }
3316 }
3317
3318 /* Content Description Object */
3319 static GstFlowReturn
3320 gst_asf_demux_process_comment (GstASFDemux * demux, guint8 * data, guint64 size)
3321 {
3322   struct
3323   {
3324     const gchar *gst_tag;
3325     guint16 val_length;
3326     gchar *val_utf8;
3327   } tags[5] = {
3328     {
3329     GST_TAG_TITLE, 0, NULL}, {
3330     GST_TAG_ARTIST, 0, NULL}, {
3331     GST_TAG_COPYRIGHT, 0, NULL}, {
3332     GST_TAG_DESCRIPTION, 0, NULL}, {
3333     GST_TAG_COMMENT, 0, NULL}
3334   };
3335   GstTagList *taglist;
3336   GValue value = { 0 };
3337   gsize in, out;
3338   gint i = -1;
3339
3340   GST_INFO_OBJECT (demux, "object is a comment");
3341
3342   if (size < (2 + 2 + 2 + 2 + 2))
3343     goto not_enough_data;
3344
3345   tags[0].val_length = gst_asf_demux_get_uint16 (&data, &size);
3346   tags[1].val_length = gst_asf_demux_get_uint16 (&data, &size);
3347   tags[2].val_length = gst_asf_demux_get_uint16 (&data, &size);
3348   tags[3].val_length = gst_asf_demux_get_uint16 (&data, &size);
3349   tags[4].val_length = gst_asf_demux_get_uint16 (&data, &size);
3350
3351   GST_DEBUG_OBJECT (demux, "Comment lengths: title=%d author=%d copyright=%d "
3352       "description=%d rating=%d", tags[0].val_length, tags[1].val_length,
3353       tags[2].val_length, tags[3].val_length, tags[4].val_length);
3354
3355   for (i = 0; i < G_N_ELEMENTS (tags); ++i) {
3356     if (size < tags[i].val_length)
3357       goto not_enough_data;
3358
3359     /* might be just '/0', '/0'... */
3360     if (tags[i].val_length > 2 && tags[i].val_length % 2 == 0) {
3361       /* convert to UTF-8 */
3362       tags[i].val_utf8 = g_convert ((gchar *) data, tags[i].val_length,
3363           "UTF-8", "UTF-16LE", &in, &out, NULL);
3364     }
3365     gst_asf_demux_skip_bytes (tags[i].val_length, &data, &size);
3366   }
3367
3368   /* parse metadata into taglist */
3369   taglist = gst_tag_list_new_empty ();
3370   g_value_init (&value, G_TYPE_STRING);
3371   for (i = 0; i < G_N_ELEMENTS (tags); ++i) {
3372     if (tags[i].val_utf8 && strlen (tags[i].val_utf8) > 0 && tags[i].gst_tag) {
3373       g_value_set_string (&value, tags[i].val_utf8);
3374       gst_tag_list_add_values (taglist, GST_TAG_MERGE_APPEND,
3375           tags[i].gst_tag, &value, NULL);
3376     }
3377   }
3378   g_value_unset (&value);
3379
3380   gst_asf_demux_add_global_tags (demux, taglist);
3381
3382   for (i = 0; i < G_N_ELEMENTS (tags); ++i)
3383     g_free (tags[i].val_utf8);
3384
3385   return GST_FLOW_OK;
3386
3387 not_enough_data:
3388   {
3389     GST_WARNING_OBJECT (demux, "unexpectedly short of data while processing "
3390         "comment tag section %d, skipping comment object", i);
3391     for (i = 0; i < G_N_ELEMENTS (tags); i++)
3392       g_free (tags[i].val_utf8);
3393     return GST_FLOW_OK;         /* not really fatal */
3394   }
3395 }
3396
3397 static GstFlowReturn
3398 gst_asf_demux_process_bitrate_props_object (GstASFDemux * demux, guint8 * data,
3399     guint64 size)
3400 {
3401   guint16 num_streams, i;
3402   AsfStream *stream;
3403
3404   if (size < 2)
3405     goto not_enough_data;
3406
3407   num_streams = gst_asf_demux_get_uint16 (&data, &size);
3408
3409   GST_INFO ("object is a bitrate properties object with %u streams",
3410       num_streams);
3411
3412   if (size < (num_streams * (2 + 4)))
3413     goto not_enough_data;
3414
3415   for (i = 0; i < num_streams; ++i) {
3416     guint32 bitrate;
3417     guint16 stream_id;
3418
3419     stream_id = gst_asf_demux_get_uint16 (&data, &size);
3420     bitrate = gst_asf_demux_get_uint32 (&data, &size);
3421
3422     if (stream_id < GST_ASF_DEMUX_NUM_STREAM_IDS) {
3423       GST_DEBUG_OBJECT (demux, "bitrate of stream %u = %u", stream_id, bitrate);
3424       stream = gst_asf_demux_get_stream (demux, stream_id);
3425       if (stream) {
3426         if (stream->pending_tags == NULL) {
3427           stream->pending_tags =
3428               gst_tag_list_new (GST_TAG_BITRATE, bitrate, NULL);
3429         }
3430       } else {
3431         GST_WARNING_OBJECT (demux, "Stream id %u wasn't found", stream_id);
3432       }
3433     } else {
3434       GST_WARNING ("stream id %u is too large", stream_id);
3435     }
3436   }
3437
3438   return GST_FLOW_OK;
3439
3440 not_enough_data:
3441   {
3442     GST_WARNING_OBJECT (demux, "short read parsing bitrate props object!");
3443     return GST_FLOW_OK;         /* not really fatal */
3444   }
3445 }
3446
3447 static GstFlowReturn
3448 gst_asf_demux_process_header_ext (GstASFDemux * demux, guint8 * data,
3449     guint64 size)
3450 {
3451   GstFlowReturn ret = GST_FLOW_OK;
3452   guint64 hdr_size;
3453
3454   /* Get the rest of the header's header */
3455   if (size < (16 + 2 + 4))
3456     goto not_enough_data;
3457
3458   /* skip GUID and two other bytes */
3459   gst_asf_demux_skip_bytes (16 + 2, &data, &size);
3460   hdr_size = gst_asf_demux_get_uint32 (&data, &size);
3461
3462   GST_INFO ("extended header object with a size of %u bytes", (guint) size);
3463
3464   /* FIXME: does data_size include the rest of the header that we have read? */
3465   if (hdr_size > size)
3466     goto not_enough_data;
3467
3468   while (hdr_size > 0) {
3469     ret = gst_asf_demux_process_object (demux, &data, &hdr_size);
3470     if (ret != GST_FLOW_OK)
3471       break;
3472   }
3473
3474   return ret;
3475
3476 not_enough_data:
3477   {
3478     GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL),
3479         ("short read parsing extended header object"));
3480     return GST_FLOW_ERROR;
3481   }
3482 }
3483
3484 static GstFlowReturn
3485 gst_asf_demux_process_language_list (GstASFDemux * demux, guint8 * data,
3486     guint64 size)
3487 {
3488   guint i;
3489
3490   if (size < 2)
3491     goto not_enough_data;
3492
3493   if (demux->languages) {
3494     GST_WARNING ("More than one LANGUAGE_LIST object in stream");
3495     g_strfreev (demux->languages);
3496     demux->languages = NULL;
3497     demux->num_languages = 0;
3498   }
3499
3500   demux->num_languages = gst_asf_demux_get_uint16 (&data, &size);
3501   GST_LOG ("%u languages:", demux->num_languages);
3502
3503   demux->languages = g_new0 (gchar *, demux->num_languages + 1);
3504   for (i = 0; i < demux->num_languages; ++i) {
3505     guint8 len, *lang_data = NULL;
3506
3507     if (size < 1)
3508       goto not_enough_data;
3509     len = gst_asf_demux_get_uint8 (&data, &size);
3510     if (gst_asf_demux_get_bytes (&lang_data, len, &data, &size)) {
3511       gchar *utf8;
3512
3513       utf8 = g_convert ((gchar *) lang_data, len, "UTF-8", "UTF-16LE", NULL,
3514           NULL, NULL);
3515
3516       /* truncate "en-us" etc. to just "en" */
3517       if (utf8 && strlen (utf8) >= 5 && (utf8[2] == '-' || utf8[2] == '_')) {
3518         utf8[2] = '\0';
3519       }
3520       GST_DEBUG ("[%u] %s", i, GST_STR_NULL (utf8));
3521       demux->languages[i] = utf8;
3522       g_free (lang_data);
3523     } else {
3524       goto not_enough_data;
3525     }
3526   }
3527
3528   return GST_FLOW_OK;
3529
3530 not_enough_data:
3531   {
3532     GST_WARNING_OBJECT (demux, "short read parsing language list object!");
3533     g_free (demux->languages);
3534     demux->languages = NULL;
3535     return GST_FLOW_OK;         /* not fatal */
3536   }
3537 }
3538
3539 static GstFlowReturn
3540 gst_asf_demux_process_simple_index (GstASFDemux * demux, guint8 * data,
3541     guint64 size)
3542 {
3543   GstClockTime interval;
3544   guint32 count, i;
3545
3546   if (size < (16 + 8 + 4 + 4))
3547     goto not_enough_data;
3548
3549   /* skip file id */
3550   gst_asf_demux_skip_bytes (16, &data, &size);
3551   interval = gst_asf_demux_get_uint64 (&data, &size) * (GstClockTime) 100;
3552   gst_asf_demux_skip_bytes (4, &data, &size);
3553   count = gst_asf_demux_get_uint32 (&data, &size);
3554   if (count > 0) {
3555     demux->sidx_interval = interval;
3556     demux->sidx_num_entries = count;
3557     g_free (demux->sidx_entries);
3558     demux->sidx_entries = g_new0 (AsfSimpleIndexEntry, count);
3559
3560     for (i = 0; i < count; ++i) {
3561       if (G_UNLIKELY (size <= 6))
3562         break;
3563       demux->sidx_entries[i].packet = gst_asf_demux_get_uint32 (&data, &size);
3564       demux->sidx_entries[i].count = gst_asf_demux_get_uint16 (&data, &size);
3565       GST_LOG_OBJECT (demux, "%" GST_TIME_FORMAT " = packet %4u  count : %2d",
3566           GST_TIME_ARGS (i * interval), demux->sidx_entries[i].packet,
3567           demux->sidx_entries[i].count);
3568     }
3569   } else {
3570     GST_DEBUG_OBJECT (demux, "simple index object with 0 entries");
3571   }
3572
3573   return GST_FLOW_OK;
3574
3575 not_enough_data:
3576   {
3577     GST_WARNING_OBJECT (demux, "short read parsing simple index object!");
3578     return GST_FLOW_OK;         /* not fatal */
3579   }
3580 }
3581
3582 static GstFlowReturn
3583 gst_asf_demux_process_advanced_mutual_exclusion (GstASFDemux * demux,
3584     guint8 * data, guint64 size)
3585 {
3586   ASFGuid guid;
3587   guint16 num, i;
3588   guint8 *mes;
3589
3590   if (size < 16 + 2 + (2 * 2))
3591     goto not_enough_data;
3592
3593   gst_asf_demux_get_guid (&guid, &data, &size);
3594   num = gst_asf_demux_get_uint16 (&data, &size);
3595
3596   if (num < 2) {
3597     GST_WARNING_OBJECT (demux, "nonsensical mutually exclusive streams count");
3598     return GST_FLOW_OK;
3599   }
3600
3601   if (size < (num * sizeof (guint16)))
3602     goto not_enough_data;
3603
3604   /* read mutually exclusive stream numbers */
3605   mes = g_new (guint8, num + 1);
3606   for (i = 0; i < num; ++i) {
3607     mes[i] = gst_asf_demux_get_uint16 (&data, &size) & 0x7f;
3608     GST_LOG_OBJECT (demux, "mutually exclusive: stream #%d", mes[i]);
3609   }
3610
3611   /* add terminator so we can easily get the count or know when to stop */
3612   mes[i] = (guint8) - 1;
3613
3614   demux->mut_ex_streams = g_slist_append (demux->mut_ex_streams, mes);
3615
3616   return GST_FLOW_OK;
3617
3618   /* Errors */
3619 not_enough_data:
3620   {
3621     GST_WARNING_OBJECT (demux, "short read parsing advanced mutual exclusion");
3622     return GST_FLOW_OK;         /* not absolutely fatal */
3623   }
3624 }
3625
3626 gboolean
3627 gst_asf_demux_is_unknown_stream (GstASFDemux * demux, guint stream_num)
3628 {
3629   return g_slist_find (demux->other_streams,
3630       GINT_TO_POINTER (stream_num)) == NULL;
3631 }
3632
3633 static GstFlowReturn
3634 gst_asf_demux_process_ext_stream_props (GstASFDemux * demux, guint8 * data,
3635     guint64 size)
3636 {
3637   AsfStreamExtProps esp;
3638   AsfStream *stream = NULL;
3639   AsfObject stream_obj;
3640   guint16 stream_name_count;
3641   guint16 num_payload_ext;
3642   guint64 len;
3643   guint8 *stream_obj_data = NULL;
3644   guint8 *data_start;
3645   guint obj_size;
3646   guint i, stream_num;
3647
3648   data_start = data;
3649   obj_size = (guint) size;
3650
3651   if (size < 64)
3652     goto not_enough_data;
3653
3654   esp.valid = TRUE;
3655   esp.start_time = gst_asf_demux_get_uint64 (&data, &size) * GST_MSECOND;
3656   esp.end_time = gst_asf_demux_get_uint64 (&data, &size) * GST_MSECOND;
3657   esp.data_bitrate = gst_asf_demux_get_uint32 (&data, &size);
3658   esp.buffer_size = gst_asf_demux_get_uint32 (&data, &size);
3659   esp.intial_buf_fullness = gst_asf_demux_get_uint32 (&data, &size);
3660   esp.data_bitrate2 = gst_asf_demux_get_uint32 (&data, &size);
3661   esp.buffer_size2 = gst_asf_demux_get_uint32 (&data, &size);
3662   esp.intial_buf_fullness2 = gst_asf_demux_get_uint32 (&data, &size);
3663   esp.max_obj_size = gst_asf_demux_get_uint32 (&data, &size);
3664   esp.flags = gst_asf_demux_get_uint32 (&data, &size);
3665   stream_num = gst_asf_demux_get_uint16 (&data, &size);
3666   esp.lang_idx = gst_asf_demux_get_uint16 (&data, &size);
3667   esp.avg_time_per_frame = gst_asf_demux_get_uint64 (&data, &size);
3668   stream_name_count = gst_asf_demux_get_uint16 (&data, &size);
3669   num_payload_ext = gst_asf_demux_get_uint16 (&data, &size);
3670
3671   GST_INFO ("start_time             = %" GST_TIME_FORMAT,
3672       GST_TIME_ARGS (esp.start_time));
3673   GST_INFO ("end_time               = %" GST_TIME_FORMAT,
3674       GST_TIME_ARGS (esp.end_time));
3675   GST_INFO ("flags                  = %08x", esp.flags);
3676   GST_INFO ("average time per frame = %" GST_TIME_FORMAT,
3677       GST_TIME_ARGS (esp.avg_time_per_frame * 100));
3678   GST_INFO ("stream number          = %u", stream_num);
3679   GST_INFO ("stream language ID idx = %u (%s)", esp.lang_idx,
3680       (esp.lang_idx < demux->num_languages) ?
3681       GST_STR_NULL (demux->languages[esp.lang_idx]) : "??");
3682   GST_INFO ("stream name count      = %u", stream_name_count);
3683
3684   /* read stream names */
3685   for (i = 0; i < stream_name_count; ++i) {
3686     guint16 stream_lang_idx G_GNUC_UNUSED;
3687     gchar *stream_name = NULL;
3688
3689     if (size < 2)
3690       goto not_enough_data;
3691     stream_lang_idx = gst_asf_demux_get_uint16 (&data, &size);
3692     if (!gst_asf_demux_get_string (&stream_name, NULL, &data, &size))
3693       goto not_enough_data;
3694     GST_INFO ("stream name %d: %s", i, GST_STR_NULL (stream_name));
3695     g_free (stream_name);       /* TODO: store names in struct */
3696   }
3697
3698   /* read payload extension systems stuff */
3699   GST_LOG ("payload extension systems count = %u", num_payload_ext);
3700
3701   if (num_payload_ext > 0)
3702     esp.payload_extensions = g_new0 (AsfPayloadExtension, num_payload_ext + 1);
3703   else
3704     esp.payload_extensions = NULL;
3705
3706   for (i = 0; i < num_payload_ext; ++i) {
3707     AsfPayloadExtension ext;
3708     ASFGuid ext_guid;
3709     guint32 sys_info_len;
3710
3711     if (size < 16 + 2 + 4)
3712       goto not_enough_data;
3713
3714     gst_asf_demux_get_guid (&ext_guid, &data, &size);
3715     ext.id = gst_asf_demux_identify_guid (asf_payload_ext_guids, &ext_guid);
3716     ext.len = gst_asf_demux_get_uint16 (&data, &size);
3717
3718     sys_info_len = gst_asf_demux_get_uint32 (&data, &size);
3719     GST_LOG ("payload systems info len = %u", sys_info_len);
3720     if (!gst_asf_demux_skip_bytes (sys_info_len, &data, &size))
3721       goto not_enough_data;
3722
3723     esp.payload_extensions[i] = ext;
3724   }
3725
3726   GST_LOG ("bytes read: %u/%u", (guint) (data - data_start), obj_size);
3727
3728   /* there might be an optional STREAM_INFO object here now; if not, we
3729    * should have parsed the corresponding stream info object already (since
3730    * we are parsing the extended stream properties objects delayed) */
3731   if (size == 0) {
3732     stream = gst_asf_demux_get_stream (demux, stream_num);
3733     goto done;
3734   }
3735
3736   /* get size of the stream object */
3737   if (!asf_demux_peek_object (demux, data, size, &stream_obj, TRUE))
3738     goto not_enough_data;
3739
3740   if (stream_obj.id != ASF_OBJ_STREAM)
3741     goto expected_stream_object;
3742
3743   if (stream_obj.size < ASF_OBJECT_HEADER_SIZE ||
3744       stream_obj.size > (10 * 1024 * 1024))
3745     goto not_enough_data;
3746
3747   gst_asf_demux_skip_bytes (ASF_OBJECT_HEADER_SIZE, &data, &size);
3748
3749   /* process this stream object later after all the other 'normal' ones
3750    * have been processed (since the others are more important/non-hidden) */
3751   len = stream_obj.size - ASF_OBJECT_HEADER_SIZE;
3752   if (!gst_asf_demux_get_bytes (&stream_obj_data, len, &data, &size))
3753     goto not_enough_data;
3754
3755   /* parse stream object */
3756   stream = gst_asf_demux_parse_stream_object (demux, stream_obj_data, len);
3757   g_free (stream_obj_data);
3758
3759 done:
3760
3761   if (stream) {
3762     stream->ext_props = esp;
3763
3764     /* try to set the framerate */
3765     if (stream->is_video && stream->caps) {
3766       GValue framerate = { 0 };
3767       GstStructure *s;
3768       gint num, denom;
3769
3770       g_value_init (&framerate, GST_TYPE_FRACTION);
3771
3772       num = GST_SECOND / 100;
3773       denom = esp.avg_time_per_frame;
3774       if (denom == 0) {
3775         /* avoid division by 0, assume 25/1 framerate */
3776         denom = GST_SECOND / 2500;
3777       }
3778
3779       gst_value_set_fraction (&framerate, num, denom);
3780
3781       stream->caps = gst_caps_make_writable (stream->caps);
3782       s = gst_caps_get_structure (stream->caps, 0);
3783       gst_structure_set_value (s, "framerate", &framerate);
3784       g_value_unset (&framerate);
3785       GST_DEBUG_OBJECT (demux, "setting framerate of %d/%d = %f",
3786           num, denom, ((gdouble) num) / denom);
3787     }
3788
3789     /* add language info now if we have it */
3790     if (stream->ext_props.lang_idx < demux->num_languages) {
3791       if (stream->pending_tags == NULL)
3792         stream->pending_tags = gst_tag_list_new_empty ();
3793       GST_LOG_OBJECT (demux, "stream %u has language '%s'", stream->id,
3794           demux->languages[stream->ext_props.lang_idx]);
3795       gst_tag_list_add (stream->pending_tags, GST_TAG_MERGE_APPEND,
3796           GST_TAG_LANGUAGE_CODE, demux->languages[stream->ext_props.lang_idx],
3797           NULL);
3798     }
3799   } else if (gst_asf_demux_is_unknown_stream (demux, stream_num)) {
3800     GST_WARNING_OBJECT (demux, "Ext. stream properties for unknown stream");
3801   }
3802
3803   return GST_FLOW_OK;
3804
3805   /* Errors */
3806 not_enough_data:
3807   {
3808     GST_WARNING_OBJECT (demux, "short read parsing ext stream props object!");
3809     return GST_FLOW_OK;         /* not absolutely fatal */
3810   }
3811 expected_stream_object:
3812   {
3813     GST_WARNING_OBJECT (demux, "error parsing extended stream properties "
3814         "object: expected embedded stream object, but got %s object instead!",
3815         gst_asf_get_guid_nick (asf_object_guids, stream_obj.id));
3816     return GST_FLOW_OK;         /* not absolutely fatal */
3817   }
3818 }
3819
3820 static const gchar *
3821 gst_asf_demux_push_obj (GstASFDemux * demux, guint32 obj_id)
3822 {
3823   const gchar *nick;
3824
3825   nick = gst_asf_get_guid_nick (asf_object_guids, obj_id);
3826   if (g_str_has_prefix (nick, "ASF_OBJ_"))
3827     nick += strlen ("ASF_OBJ_");
3828
3829   if (demux->objpath == NULL) {
3830     demux->objpath = g_strdup (nick);
3831   } else {
3832     gchar *newpath;
3833
3834     newpath = g_strdup_printf ("%s/%s", demux->objpath, nick);
3835     g_free (demux->objpath);
3836     demux->objpath = newpath;
3837   }
3838
3839   return (const gchar *) demux->objpath;
3840 }
3841
3842 static void
3843 gst_asf_demux_pop_obj (GstASFDemux * demux)
3844 {
3845   gchar *s;
3846
3847   if ((s = g_strrstr (demux->objpath, "/"))) {
3848     *s = '\0';
3849   } else {
3850     g_free (demux->objpath);
3851     demux->objpath = NULL;
3852   }
3853 }
3854
3855 static void
3856 gst_asf_demux_process_queued_extended_stream_objects (GstASFDemux * demux)
3857 {
3858   GSList *l;
3859   guint i;
3860
3861   /* Parse the queued extended stream property objects and add the info
3862    * to the existing streams or add the new embedded streams, but without
3863    * activating them yet */
3864   GST_LOG_OBJECT (demux, "%u queued extended stream properties objects",
3865       g_slist_length (demux->ext_stream_props));
3866
3867   for (l = demux->ext_stream_props, i = 0; l != NULL; l = l->next, ++i) {
3868     GstBuffer *buf = GST_BUFFER (l->data);
3869     GstMapInfo map;
3870
3871     gst_buffer_map (buf, &map, GST_MAP_READ);
3872
3873     GST_LOG_OBJECT (demux, "parsing ext. stream properties object #%u", i);
3874     gst_asf_demux_process_ext_stream_props (demux, map.data, map.size);
3875     gst_buffer_unmap (buf, &map);
3876     gst_buffer_unref (buf);
3877   }
3878   g_slist_free (demux->ext_stream_props);
3879   demux->ext_stream_props = NULL;
3880 }
3881
3882 #if 0
3883 static void
3884 gst_asf_demux_activate_ext_props_streams (GstASFDemux * demux)
3885 {
3886   guint i, j;
3887
3888   for (i = 0; i < demux->num_streams; ++i) {
3889     AsfStream *stream;
3890     gboolean is_hidden;
3891     GSList *x;
3892
3893     stream = &demux->stream[i];
3894
3895     GST_LOG_OBJECT (demux, "checking  stream %2u", stream->id);
3896
3897     if (stream->active) {
3898       GST_LOG_OBJECT (demux, "stream %2u is already activated", stream->id);
3899       continue;
3900     }
3901
3902     is_hidden = FALSE;
3903     for (x = demux->mut_ex_streams; x != NULL; x = x->next) {
3904       guint8 *mes;
3905
3906       /* check for each mutual exclusion whether it affects this stream */
3907       for (mes = (guint8 *) x->data; mes != NULL && *mes != 0xff; ++mes) {
3908         if (*mes == stream->id) {
3909           /* if yes, check if we've already added streams that are mutually
3910            * exclusive with the stream we're about to add */
3911           for (mes = (guint8 *) x->data; mes != NULL && *mes != 0xff; ++mes) {
3912             for (j = 0; j < demux->num_streams; ++j) {
3913               /* if the broadcast flag is set, assume the hidden streams aren't
3914                * actually streamed and hide them (or playbin won't work right),
3915                * otherwise assume their data is available */
3916               if (demux->stream[j].id == *mes && demux->broadcast) {
3917                 is_hidden = TRUE;
3918                 GST_LOG_OBJECT (demux, "broadcast stream ID %d to be added is "
3919                     "mutually exclusive with already existing stream ID %d, "
3920                     "hiding stream", stream->id, demux->stream[j].id);
3921                 goto next;
3922               }
3923             }
3924           }
3925           break;
3926         }
3927       }
3928     }
3929
3930   next:
3931
3932     /* FIXME: we should do stream activation based on preroll data in
3933      * streaming mode too */
3934     if (demux->streaming && !is_hidden)
3935       gst_asf_demux_activate_stream (demux, stream);
3936   }
3937 }
3938 #endif
3939
3940 static GstFlowReturn
3941 gst_asf_demux_process_object (GstASFDemux * demux, guint8 ** p_data,
3942     guint64 * p_size)
3943 {
3944   GstFlowReturn ret = GST_FLOW_OK;
3945   AsfObject obj;
3946   guint64 obj_data_size;
3947
3948   if (*p_size < ASF_OBJECT_HEADER_SIZE)
3949     return ASF_FLOW_NEED_MORE_DATA;
3950
3951   asf_demux_peek_object (demux, *p_data, ASF_OBJECT_HEADER_SIZE, &obj, TRUE);
3952   gst_asf_demux_skip_bytes (ASF_OBJECT_HEADER_SIZE, p_data, p_size);
3953
3954   obj_data_size = obj.size - ASF_OBJECT_HEADER_SIZE;
3955
3956   if (*p_size < obj_data_size)
3957     return ASF_FLOW_NEED_MORE_DATA;
3958
3959   gst_asf_demux_push_obj (demux, obj.id);
3960
3961   GST_INFO ("%s: size %" G_GUINT64_FORMAT, demux->objpath, obj.size);
3962
3963   switch (obj.id) {
3964     case ASF_OBJ_STREAM:
3965       gst_asf_demux_parse_stream_object (demux, *p_data, obj_data_size);
3966       ret = GST_FLOW_OK;
3967       break;
3968     case ASF_OBJ_FILE:
3969       ret = gst_asf_demux_process_file (demux, *p_data, obj_data_size);
3970       break;
3971     case ASF_OBJ_HEADER:
3972       ret = gst_asf_demux_process_header (demux, *p_data, obj_data_size);
3973       break;
3974     case ASF_OBJ_COMMENT:
3975       ret = gst_asf_demux_process_comment (demux, *p_data, obj_data_size);
3976       break;
3977     case ASF_OBJ_HEAD1:
3978       ret = gst_asf_demux_process_header_ext (demux, *p_data, obj_data_size);
3979       break;
3980     case ASF_OBJ_BITRATE_PROPS:
3981       ret =
3982           gst_asf_demux_process_bitrate_props_object (demux, *p_data,
3983           obj_data_size);
3984       break;
3985     case ASF_OBJ_EXT_CONTENT_DESC:
3986       ret =
3987           gst_asf_demux_process_ext_content_desc (demux, *p_data,
3988           obj_data_size);
3989       break;
3990     case ASF_OBJ_METADATA_OBJECT:
3991       ret = gst_asf_demux_process_metadata (demux, *p_data, obj_data_size);
3992       break;
3993     case ASF_OBJ_EXTENDED_STREAM_PROPS:{
3994       GstBuffer *buf;
3995
3996       /* process these later, we might not have parsed the corresponding
3997        * stream object yet */
3998       GST_LOG ("%s: queued for later parsing", demux->objpath);
3999       buf = gst_buffer_new_and_alloc (obj_data_size);
4000       gst_buffer_fill (buf, 0, *p_data, obj_data_size);
4001       demux->ext_stream_props = g_slist_append (demux->ext_stream_props, buf);
4002       ret = GST_FLOW_OK;
4003       break;
4004     }
4005     case ASF_OBJ_LANGUAGE_LIST:
4006       ret = gst_asf_demux_process_language_list (demux, *p_data, obj_data_size);
4007       break;
4008     case ASF_OBJ_ADVANCED_MUTUAL_EXCLUSION:
4009       ret = gst_asf_demux_process_advanced_mutual_exclusion (demux, *p_data,
4010           obj_data_size);
4011       break;
4012     case ASF_OBJ_SIMPLE_INDEX:
4013       ret = gst_asf_demux_process_simple_index (demux, *p_data, obj_data_size);
4014       break;
4015     case ASF_OBJ_CONTENT_ENCRYPTION:
4016     case ASF_OBJ_EXT_CONTENT_ENCRYPTION:
4017     case ASF_OBJ_DIGITAL_SIGNATURE_OBJECT:
4018     case ASF_OBJ_UNKNOWN_ENCRYPTION_OBJECT:
4019       goto error_encrypted;
4020     case ASF_OBJ_CONCEAL_NONE:
4021     case ASF_OBJ_HEAD2:
4022     case ASF_OBJ_UNDEFINED:
4023     case ASF_OBJ_CODEC_COMMENT:
4024     case ASF_OBJ_INDEX:
4025     case ASF_OBJ_PADDING:
4026     case ASF_OBJ_BITRATE_MUTEX:
4027     case ASF_OBJ_COMPATIBILITY:
4028     case ASF_OBJ_INDEX_PLACEHOLDER:
4029     case ASF_OBJ_INDEX_PARAMETERS:
4030     case ASF_OBJ_STREAM_PRIORITIZATION:
4031     case ASF_OBJ_SCRIPT_COMMAND:
4032     default:
4033       /* Unknown/unhandled object, skip it and hope for the best */
4034       GST_INFO ("%s: skipping object", demux->objpath);
4035       ret = GST_FLOW_OK;
4036       break;
4037   }
4038
4039   /* this can't fail, we checked the number of bytes available before */
4040   gst_asf_demux_skip_bytes (obj_data_size, p_data, p_size);
4041
4042   GST_LOG ("%s: ret = %s", demux->objpath, gst_asf_get_flow_name (ret));
4043
4044   gst_asf_demux_pop_obj (demux);
4045
4046   return ret;
4047
4048 /* ERRORS */
4049 error_encrypted:
4050   {
4051     GST_ELEMENT_ERROR (demux, STREAM, DECRYPT, (NULL), (NULL));
4052     return GST_FLOW_ERROR;
4053   }
4054 }
4055
4056 static void
4057 gst_asf_demux_descramble_buffer (GstASFDemux * demux, AsfStream * stream,
4058     GstBuffer ** p_buffer)
4059 {
4060   GstBuffer *descrambled_buffer;
4061   GstBuffer *scrambled_buffer;
4062   GstBuffer *sub_buffer;
4063   guint offset;
4064   guint off;
4065   guint row;
4066   guint col;
4067   guint idx;
4068
4069   /* descrambled_buffer is initialised in the first iteration */
4070   descrambled_buffer = NULL;
4071   scrambled_buffer = *p_buffer;
4072
4073   if (gst_buffer_get_size (scrambled_buffer) <
4074       demux->ds_packet_size * demux->span)
4075     return;
4076
4077   for (offset = 0; offset < gst_buffer_get_size (scrambled_buffer);
4078       offset += demux->ds_chunk_size) {
4079     off = offset / demux->ds_chunk_size;
4080     row = off / demux->span;
4081     col = off % demux->span;
4082     idx = row + col * demux->ds_packet_size / demux->ds_chunk_size;
4083     GST_DEBUG ("idx=%u, row=%u, col=%u, off=%u, ds_chunk_size=%u", idx, row,
4084         col, off, demux->ds_chunk_size);
4085     GST_DEBUG ("scrambled buffer size=%" G_GSIZE_FORMAT
4086         ", span=%u, packet_size=%u", gst_buffer_get_size (scrambled_buffer),
4087         demux->span, demux->ds_packet_size);
4088     GST_DEBUG ("gst_buffer_get_size (scrambled_buffer) = %" G_GSIZE_FORMAT,
4089         gst_buffer_get_size (scrambled_buffer));
4090     sub_buffer =
4091         gst_buffer_copy_region (scrambled_buffer, GST_BUFFER_COPY_NONE,
4092         idx * demux->ds_chunk_size, demux->ds_chunk_size);
4093     if (!offset) {
4094       descrambled_buffer = sub_buffer;
4095     } else {
4096       descrambled_buffer = gst_buffer_append (descrambled_buffer, sub_buffer);
4097     }
4098   }
4099
4100   GST_BUFFER_TIMESTAMP (descrambled_buffer) =
4101       GST_BUFFER_TIMESTAMP (scrambled_buffer);
4102   GST_BUFFER_DURATION (descrambled_buffer) =
4103       GST_BUFFER_DURATION (scrambled_buffer);
4104   GST_BUFFER_OFFSET (descrambled_buffer) = GST_BUFFER_OFFSET (scrambled_buffer);
4105   GST_BUFFER_OFFSET_END (descrambled_buffer) =
4106       GST_BUFFER_OFFSET_END (scrambled_buffer);
4107
4108   /* FIXME/CHECK: do we need to transfer buffer flags here too? */
4109
4110   gst_buffer_unref (scrambled_buffer);
4111   *p_buffer = descrambled_buffer;
4112 }
4113
4114 static gboolean
4115 gst_asf_demux_element_send_event (GstElement * element, GstEvent * event)
4116 {
4117   GstASFDemux *demux = GST_ASF_DEMUX (element);
4118   gint i;
4119
4120   GST_DEBUG ("handling element event of type %s", GST_EVENT_TYPE_NAME (event));
4121
4122   for (i = 0; i < demux->num_streams; ++i) {
4123     gst_event_ref (event);
4124     if (gst_asf_demux_handle_src_event (demux->stream[i].pad,
4125             GST_OBJECT_CAST (element), event)) {
4126       gst_event_unref (event);
4127       return TRUE;
4128     }
4129   }
4130
4131   gst_event_unref (event);
4132   return FALSE;
4133 }
4134
4135 /* takes ownership of the passed event */
4136 static gboolean
4137 gst_asf_demux_send_event_unlocked (GstASFDemux * demux, GstEvent * event)
4138 {
4139   gboolean ret = TRUE;
4140   gint i;
4141
4142   GST_DEBUG_OBJECT (demux, "sending %s event to all source pads",
4143       GST_EVENT_TYPE_NAME (event));
4144
4145   for (i = 0; i < demux->num_streams; ++i) {
4146     gst_event_ref (event);
4147     ret &= gst_pad_push_event (demux->stream[i].pad, event);
4148   }
4149   gst_event_unref (event);
4150   return ret;
4151 }
4152
4153 static gboolean
4154 gst_asf_demux_handle_src_query (GstPad * pad, GstObject * parent,
4155     GstQuery * query)
4156 {
4157   GstASFDemux *demux;
4158   gboolean res = FALSE;
4159
4160   demux = GST_ASF_DEMUX (parent);
4161
4162   GST_DEBUG ("handling %s query",
4163       gst_query_type_get_name (GST_QUERY_TYPE (query)));
4164
4165   switch (GST_QUERY_TYPE (query)) {
4166     case GST_QUERY_DURATION:
4167     {
4168       GstFormat format;
4169
4170       gst_query_parse_duration (query, &format, NULL);
4171
4172       if (format != GST_FORMAT_TIME) {
4173         GST_LOG ("only support duration queries in TIME format");
4174         break;
4175       }
4176
4177       GST_OBJECT_LOCK (demux);
4178
4179       if (demux->segment.duration != GST_CLOCK_TIME_NONE) {
4180         GST_LOG ("returning duration: %" GST_TIME_FORMAT,
4181             GST_TIME_ARGS (demux->segment.duration));
4182
4183         gst_query_set_duration (query, GST_FORMAT_TIME,
4184             demux->segment.duration);
4185
4186         res = TRUE;
4187       } else {
4188         GST_LOG ("duration not known yet");
4189       }
4190
4191       GST_OBJECT_UNLOCK (demux);
4192       break;
4193     }
4194
4195     case GST_QUERY_POSITION:{
4196       GstFormat format;
4197
4198       gst_query_parse_position (query, &format, NULL);
4199
4200       if (format != GST_FORMAT_TIME) {
4201         GST_LOG ("only support position queries in TIME format");
4202         break;
4203       }
4204
4205       GST_OBJECT_LOCK (demux);
4206
4207       if (demux->segment.position != GST_CLOCK_TIME_NONE) {
4208         GST_LOG ("returning position: %" GST_TIME_FORMAT,
4209             GST_TIME_ARGS (demux->segment.position));
4210
4211         gst_query_set_position (query, GST_FORMAT_TIME,
4212             demux->segment.position);
4213
4214         res = TRUE;
4215       } else {
4216         GST_LOG ("position not known yet");
4217       }
4218
4219       GST_OBJECT_UNLOCK (demux);
4220       break;
4221     }
4222
4223     case GST_QUERY_SEEKING:{
4224       GstFormat format;
4225
4226       gst_query_parse_seeking (query, &format, NULL, NULL, NULL);
4227       if (format == GST_FORMAT_TIME) {
4228         gint64 duration;
4229
4230         GST_OBJECT_LOCK (demux);
4231         duration = demux->segment.duration;
4232         GST_OBJECT_UNLOCK (demux);
4233
4234         if (!demux->streaming || !demux->seekable) {
4235           gst_query_set_seeking (query, GST_FORMAT_TIME, demux->seekable, 0,
4236               duration);
4237           res = TRUE;
4238         } else {
4239           GstFormat fmt;
4240           gboolean seekable;
4241
4242           /* try downstream first in TIME */
4243           res = gst_pad_query_default (pad, parent, query);
4244
4245           gst_query_parse_seeking (query, &fmt, &seekable, NULL, NULL);
4246           GST_LOG_OBJECT (demux, "upstream %s seekable %d",
4247               GST_STR_NULL (gst_format_get_name (fmt)), seekable);
4248           /* if no luck, maybe in BYTES */
4249           if (!seekable || fmt != GST_FORMAT_TIME) {
4250             GstQuery *q;
4251
4252             q = gst_query_new_seeking (GST_FORMAT_BYTES);
4253             if ((res = gst_pad_peer_query (demux->sinkpad, q))) {
4254               gst_query_parse_seeking (q, &fmt, &seekable, NULL, NULL);
4255               GST_LOG_OBJECT (demux, "upstream %s seekable %d",
4256                   GST_STR_NULL (gst_format_get_name (fmt)), seekable);
4257               if (fmt != GST_FORMAT_BYTES)
4258                 seekable = FALSE;
4259             }
4260             gst_query_unref (q);
4261             gst_query_set_seeking (query, GST_FORMAT_TIME, seekable, 0,
4262                 duration);
4263             res = TRUE;
4264           }
4265         }
4266       } else
4267         GST_LOG_OBJECT (demux, "only support seeking in TIME format");
4268       break;
4269     }
4270
4271     case GST_QUERY_LATENCY:
4272     {
4273       gboolean live;
4274       GstClockTime min, max;
4275
4276       /* preroll delay does not matter in non-live pipeline,
4277        * but we might end up in a live (rtsp) one ... */
4278
4279       /* first forward */
4280       res = gst_pad_query_default (pad, parent, query);
4281       if (!res)
4282         break;
4283
4284       gst_query_parse_latency (query, &live, &min, &max);
4285
4286       GST_DEBUG_OBJECT (demux, "Peer latency: live %d, min %"
4287           GST_TIME_FORMAT " max %" GST_TIME_FORMAT, live,
4288           GST_TIME_ARGS (min), GST_TIME_ARGS (max));
4289
4290       GST_OBJECT_LOCK (demux);
4291       if (min != -1)
4292         min += demux->latency;
4293       if (max != -1)
4294         max += demux->latency;
4295       GST_OBJECT_UNLOCK (demux);
4296
4297       gst_query_set_latency (query, live, min, max);
4298       break;
4299     }
4300     case GST_QUERY_SEGMENT:
4301     {
4302       GstFormat format;
4303       gint64 start, stop;
4304
4305       format = demux->segment.format;
4306
4307       start =
4308           gst_segment_to_stream_time (&demux->segment, format,
4309           demux->segment.start);
4310       if ((stop = demux->segment.stop) == -1)
4311         stop = demux->segment.duration;
4312       else
4313         stop = gst_segment_to_stream_time (&demux->segment, format, stop);
4314
4315       gst_query_set_segment (query, demux->segment.rate, format, start, stop);
4316       res = TRUE;
4317       break;
4318     }
4319     default:
4320       res = gst_pad_query_default (pad, parent, query);
4321       break;
4322   }
4323
4324   return res;
4325 }
4326
4327 static GstStateChangeReturn
4328 gst_asf_demux_change_state (GstElement * element, GstStateChange transition)
4329 {
4330   GstASFDemux *demux = GST_ASF_DEMUX (element);
4331   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
4332
4333   switch (transition) {
4334     case GST_STATE_CHANGE_NULL_TO_READY:{
4335       gst_segment_init (&demux->segment, GST_FORMAT_TIME);
4336       demux->need_newsegment = TRUE;
4337       demux->segment_running = FALSE;
4338       demux->accurate = FALSE;
4339       demux->adapter = gst_adapter_new ();
4340       demux->metadata = gst_caps_new_empty ();
4341       demux->global_metadata = gst_structure_new_empty ("metadata");
4342       demux->data_size = 0;
4343       demux->data_offset = 0;
4344       demux->index_offset = 0;
4345       demux->base_offset = 0;
4346       break;
4347     }
4348     default:
4349       break;
4350   }
4351
4352   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
4353   if (ret == GST_STATE_CHANGE_FAILURE)
4354     return ret;
4355
4356   switch (transition) {
4357     case GST_STATE_CHANGE_PAUSED_TO_READY:
4358     case GST_STATE_CHANGE_READY_TO_NULL:
4359       gst_asf_demux_reset (demux, FALSE);
4360       break;
4361     default:
4362       break;
4363   }
4364
4365   return ret;
4366 }