aboutsummaryrefslogtreecommitdiff
path: root/gst/asfdemux/gstasfdemux.c
diff options
context:
space:
mode:
Diffstat (limited to 'gst/asfdemux/gstasfdemux.c')
-rw-r--r--gst/asfdemux/gstasfdemux.c334
1 files changed, 301 insertions, 33 deletions
diff --git a/gst/asfdemux/gstasfdemux.c b/gst/asfdemux/gstasfdemux.c
index caa4d3c..ec44035 100644
--- a/gst/asfdemux/gstasfdemux.c
+++ b/gst/asfdemux/gstasfdemux.c
@@ -14,8 +14,8 @@
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*/
/* TODO:
@@ -34,6 +34,7 @@
#include <gst/gstutils.h>
#include <gst/base/gstbytereader.h>
+#include <gst/base/gsttypefindhelper.h>
#include <gst/riff/riff-media.h>
#include <gst/tag/tag.h>
#include <gst/gst-i18n-plugin.h>
@@ -234,6 +235,8 @@ gst_asf_demux_reset (GstASFDemux * demux, gboolean chain_reset)
/* do not remove those for not adding pads with same name */
demux->num_audio_streams = 0;
demux->num_video_streams = 0;
+ demux->have_group_id = FALSE;
+ demux->group_id = G_MAXUINT;
}
demux->num_streams = 0;
demux->activated_streams = FALSE;
@@ -256,6 +259,7 @@ gst_asf_demux_reset (GstASFDemux * demux, gboolean chain_reset)
GST_LOG_OBJECT (demux, "Restarting");
gst_segment_init (&demux->segment, GST_FORMAT_TIME);
demux->need_newsegment = TRUE;
+ demux->segment_seqnum = 0;
demux->segment_running = FALSE;
demux->accurate = FALSE;
demux->metadata = gst_caps_new_empty ();
@@ -266,6 +270,9 @@ gst_asf_demux_reset (GstASFDemux * demux, gboolean chain_reset)
} else {
demux->base_offset = 0;
}
+
+ g_slist_free (demux->other_streams);
+ demux->other_streams = NULL;
}
static void
@@ -390,6 +397,7 @@ gst_asf_demux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
demux->segment_ts = GST_CLOCK_TIME_NONE;
demux->in_gap = GST_CLOCK_TIME_NONE;
demux->need_newsegment = TRUE;
+ demux->segment_seqnum = gst_event_get_seqnum (event);
gst_asf_demux_reset_stream_state_after_discont (demux);
GST_OBJECT_UNLOCK (demux);
@@ -552,6 +560,7 @@ gst_asf_demux_handle_seek_push (GstASFDemux * demux, GstEvent * event)
gint64 cur, stop;
guint packet;
gboolean res;
+ GstEvent *byte_event;
gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
&stop_type, &stop);
@@ -582,9 +591,10 @@ gst_asf_demux_handle_seek_push (GstASFDemux * demux, GstEvent * event)
GST_DEBUG_OBJECT (demux, "Pushing BYTE seek rate %g, "
"start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT, rate, cur, stop);
/* BYTE seek event */
- event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type, cur,
- stop_type, stop);
- res = gst_pad_push_event (demux->sinkpad, event);
+ byte_event = gst_event_new_seek (rate, GST_FORMAT_BYTES, flags, cur_type,
+ cur, stop_type, stop);
+ gst_event_set_seqnum (byte_event, gst_event_get_seqnum (event));
+ res = gst_pad_push_event (demux->sinkpad, byte_event);
return res;
}
@@ -605,6 +615,8 @@ gst_asf_demux_handle_seek_event (GstASFDemux * demux, GstEvent * event)
gint64 seek_time;
guint packet, speed_count = 1;
gboolean eos;
+ guint32 seqnum;
+ GstEvent *fevent;
if (G_UNLIKELY (demux->seekable == FALSE || demux->packet_size == 0 ||
demux->num_packets == 0 || demux->play_time == 0)) {
@@ -619,6 +631,7 @@ gst_asf_demux_handle_seek_event (GstASFDemux * demux, GstEvent * event)
gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
&stop_type, &stop);
+ seqnum = gst_event_get_seqnum (event);
if (G_UNLIKELY (format != GST_FORMAT_TIME)) {
GST_LOG_OBJECT (demux, "seeking is only supported in TIME format");
@@ -661,8 +674,11 @@ gst_asf_demux_handle_seek_event (GstASFDemux * demux, GstEvent * event)
/* unlock the streaming thread */
if (G_LIKELY (flush)) {
- gst_pad_push_event (demux->sinkpad, gst_event_new_flush_start ());
- gst_asf_demux_send_event_unlocked (demux, gst_event_new_flush_start ());
+ fevent = gst_event_new_flush_start ();
+
+ gst_event_set_seqnum (fevent, seqnum);
+ gst_pad_push_event (demux->sinkpad, gst_event_ref (fevent));
+ gst_asf_demux_send_event_unlocked (demux, fevent);
} else {
gst_pad_pause_task (demux->sinkpad);
}
@@ -673,10 +689,14 @@ gst_asf_demux_handle_seek_event (GstASFDemux * demux, GstEvent * event)
GST_PAD_STREAM_LOCK (demux->sinkpad);
/* we now can stop flushing, since we have the stream lock now */
- gst_pad_push_event (demux->sinkpad, gst_event_new_flush_stop (TRUE));
+ fevent = gst_event_new_flush_stop (TRUE);
+ gst_event_set_seqnum (fevent, seqnum);
+ gst_pad_push_event (demux->sinkpad, gst_event_ref (fevent));
if (G_LIKELY (flush))
- gst_asf_demux_send_event_unlocked (demux, gst_event_new_flush_stop (TRUE));
+ gst_asf_demux_send_event_unlocked (demux, fevent);
+ else
+ gst_event_unref (fevent);
/* operating on copy of segment until we know the seek worked */
segment = demux->segment;
@@ -688,6 +708,7 @@ gst_asf_demux_handle_seek_event (GstASFDemux * demux, GstEvent * event)
/* create the segment event to close the current segment */
gst_segment_copy_into (&segment, &newsegment);
newseg = gst_event_new_segment (&newsegment);
+ gst_event_set_seqnum (newseg, seqnum);
gst_asf_demux_send_event_unlocked (demux, newseg);
}
@@ -758,6 +779,7 @@ gst_asf_demux_handle_seek_event (GstASFDemux * demux, GstEvent * event)
demux->segment = segment;
demux->packet = packet;
demux->need_newsegment = TRUE;
+ demux->segment_seqnum = seqnum;
demux->speed_packets = speed_count;
gst_asf_demux_reset_stream_state_after_discont (demux);
GST_OBJECT_UNLOCK (demux);
@@ -1219,9 +1241,9 @@ all_streams_prerolled (GstASFDemux * demux)
* and (b) the timestamp of last piece of data queued is < demux->preroll
* AND there is at least one other stream with data queued */
for (i = 0; i < demux->num_streams; ++i) {
- AsfPayload *last_payload;
+ AsfPayload *last_payload = NULL;
AsfStream *stream;
- guint last_idx;
+ gint last_idx;
stream = &demux->stream[i];
if (G_UNLIKELY (stream->payloads->len == 0)) {
@@ -1230,19 +1252,24 @@ all_streams_prerolled (GstASFDemux * demux)
continue;
}
- last_idx = stream->payloads->len - 1;
- last_payload = &g_array_index (stream->payloads, AsfPayload, last_idx);
+ /* find last payload with timestamp */
+ for (last_idx = stream->payloads->len - 1;
+ last_idx >= 0 && (last_payload == NULL
+ || !GST_CLOCK_TIME_IS_VALID (last_payload->ts)); --last_idx) {
+ last_payload = &g_array_index (stream->payloads, AsfPayload, last_idx);
+ }
GST_LOG_OBJECT (stream->pad, "checking if %" GST_TIME_FORMAT " > %"
GST_TIME_FORMAT, GST_TIME_ARGS (last_payload->ts),
GST_TIME_ARGS (preroll_time));
- if (G_UNLIKELY (last_payload->ts <= preroll_time)) {
+ if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (last_payload->ts)
+ || last_payload->ts <= preroll_time)) {
GST_LOG_OBJECT (stream->pad, "not beyond preroll point yet");
return FALSE;
}
}
- if (G_UNLIKELY (num_no_data == demux->num_streams))
+ if (G_UNLIKELY (num_no_data > 0))
return FALSE;
return TRUE;
@@ -1287,6 +1314,140 @@ gst_asf_demux_have_mutually_exclusive_active_stream (GstASFDemux * demux,
}
#endif
+static void
+gst_asf_demux_check_segment_ts (GstASFDemux * demux, GstClockTime payload_ts)
+{
+ /* remember the first queued timestamp for the segment */
+ if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (demux->segment_ts) &&
+ GST_CLOCK_TIME_IS_VALID (demux->first_ts))) {
+ GST_DEBUG_OBJECT (demux, "segment ts: %" GST_TIME_FORMAT,
+ GST_TIME_ARGS (demux->first_ts));
+ demux->segment_ts = payload_ts;
+ /* always note, but only determines segment when streaming */
+ if (demux->streaming)
+ gst_segment_do_seek (&demux->segment, demux->in_segment.rate,
+ GST_FORMAT_TIME, (GstSeekFlags) demux->segment.flags,
+ GST_SEEK_TYPE_SET, demux->segment_ts, GST_SEEK_TYPE_NONE, 0, NULL);
+ }
+}
+
+static gboolean
+gst_asf_demux_check_first_ts (GstASFDemux * demux, gboolean force)
+{
+ if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (demux->first_ts))) {
+ GstClockTime first_ts = GST_CLOCK_TIME_NONE;
+ int i;
+
+ /* go trhough each stream, find smallest timestamp */
+ for (i = 0; i < demux->num_streams; ++i) {
+ AsfStream *stream;
+ int j;
+ GstClockTime stream_min_ts = GST_CLOCK_TIME_NONE;
+ stream = &demux->stream[i];
+
+ for (j = 0; j < stream->payloads->len; ++j) {
+ AsfPayload *payload = &g_array_index (stream->payloads, AsfPayload, j);
+ if (GST_CLOCK_TIME_IS_VALID (payload->ts) &&
+ (!GST_CLOCK_TIME_IS_VALID (stream_min_ts)
+ || stream_min_ts > payload->ts))
+ stream_min_ts = payload->ts;
+ }
+
+ /* if we don't have timestamp for this stream, wait for more data */
+ if (!GST_CLOCK_TIME_IS_VALID (stream_min_ts) && !force)
+ return FALSE;
+
+ if (GST_CLOCK_TIME_IS_VALID (stream_min_ts) &&
+ (!GST_CLOCK_TIME_IS_VALID (first_ts) || first_ts > stream_min_ts))
+ first_ts = stream_min_ts;
+ }
+
+ if (!GST_CLOCK_TIME_IS_VALID (first_ts)) /* can happen with force = TRUE */
+ first_ts = 0;
+
+ demux->first_ts = first_ts;
+
+ /* update packets queued before we knew first timestamp */
+ for (i = 0; i < demux->num_streams; ++i) {
+ AsfStream *stream;
+ int j;
+ stream = &demux->stream[i];
+
+ for (j = 0; j < stream->payloads->len; ++j) {
+ AsfPayload *payload = &g_array_index (stream->payloads, AsfPayload, j);
+ if (GST_CLOCK_TIME_IS_VALID (payload->ts)) {
+ if (payload->ts > first_ts)
+ payload->ts -= first_ts;
+ else
+ payload->ts = 0;
+ }
+ }
+ }
+ }
+
+ gst_asf_demux_check_segment_ts (demux, 0);
+
+ return TRUE;
+}
+
+static gboolean
+gst_asf_demux_update_caps_from_payload (GstASFDemux * demux, AsfStream * stream)
+{
+ /* try to determine whether the stream is AC-3 or MPEG; In dvr-ms the codecTag is unreliable
+ and often set wrong, inspecting the data is the only way that seem to be working */
+ GstTypeFindProbability prob = GST_TYPE_FIND_NONE;
+ GstCaps *caps = NULL;
+ int i;
+ GstAdapter *adapter = gst_adapter_new ();
+
+ for (i = 0; i < stream->payloads->len && prob < GST_TYPE_FIND_LIKELY; ++i) {
+ const guint8 *data;
+ AsfPayload *payload;
+ int len;
+
+ payload = &g_array_index (stream->payloads, AsfPayload, i);
+ gst_adapter_push (adapter, gst_buffer_ref (payload->buf));
+ len = gst_adapter_available (adapter);
+ data = gst_adapter_map (adapter, len);
+
+ again:
+
+#define MIN_LENGTH 128
+
+ /* look for the sync points */
+ while (TRUE) {
+ if (len < MIN_LENGTH || /* give typefind something to work on */
+ (data[0] == 0x0b && data[1] == 0x77) || /* AC-3 sync point */
+ (data[0] == 0xFF && ((data[1] & 0xF0) >> 4) == 0xF)) /* MPEG sync point */
+ break;
+ ++data;
+ --len;
+ }
+
+ gst_caps_take (&caps, gst_type_find_helper_for_data (GST_OBJECT (demux),
+ data, len, &prob));
+
+ if (prob < GST_TYPE_FIND_LIKELY) {
+ ++data;
+ --len;
+ if (len > MIN_LENGTH)
+ /* this wasn't it, look for another sync point */
+ goto again;
+ }
+
+ gst_adapter_unmap (adapter);
+ }
+
+ gst_object_unref (adapter);
+
+ if (caps) {
+ gst_caps_take (&stream->caps, caps);
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
static gboolean
gst_asf_demux_check_activate_streams (GstASFDemux * demux, gboolean force)
{
@@ -1295,6 +1456,9 @@ gst_asf_demux_check_activate_streams (GstASFDemux * demux, gboolean force)
if (demux->activated_streams)
return TRUE;
+ if (G_UNLIKELY (!gst_asf_demux_check_first_ts (demux, force)))
+ return FALSE;
+
if (!all_streams_prerolled (demux) && !force) {
GST_DEBUG_OBJECT (demux, "not all streams with data beyond preroll yet");
return FALSE;
@@ -1304,6 +1468,14 @@ gst_asf_demux_check_activate_streams (GstASFDemux * demux, gboolean force)
AsfStream *stream = &demux->stream[i];
if (stream->payloads->len > 0) {
+
+ if (stream->inspect_payload && /* dvr-ms required payload inspection */
+ !stream->active && /* do not inspect active streams (caps were already set) */
+ !gst_asf_demux_update_caps_from_payload (demux, stream) && /* failed to determine caps */
+ stream->payloads->len < 20) { /* if we couldn't determine the caps from 20 packets then just give up and use whatever was in codecTag */
+ /* try to gather some more data */
+ return FALSE;
+ }
/* we don't check mutual exclusion stuff here; either we have data for
* a stream, then we active it, or we don't, then we'll ignore it */
GST_LOG_OBJECT (stream->pad, "is prerolled - activate!");
@@ -1334,6 +1506,7 @@ gst_asf_demux_find_stream_with_complete_payload (GstASFDemux * demux)
for (i = 0; i < demux->num_streams; ++i) {
AsfStream *stream;
+ int j;
stream = &demux->stream[i];
@@ -1342,11 +1515,20 @@ gst_asf_demux_find_stream_with_complete_payload (GstASFDemux * demux)
* don't need to be decoded after a seek, sending only data from the
* keyframe directly before our segment start */
if (stream->payloads->len > 0) {
- AsfPayload *payload;
- guint last_idx;
+ AsfPayload *payload = NULL;
+ gint last_idx;
+
+ /* find last payload with timestamp */
+ for (last_idx = stream->payloads->len - 1;
+ last_idx >= 0 && (payload == NULL
+ || !GST_CLOCK_TIME_IS_VALID (payload->ts)); --last_idx) {
+ payload = &g_array_index (stream->payloads, AsfPayload, last_idx);
+ }
+
+ /* if this is first payload after seek we might need to update the segment */
+ if (GST_CLOCK_TIME_IS_VALID (payload->ts))
+ gst_asf_demux_check_segment_ts (demux, payload->ts);
- last_idx = stream->payloads->len - 1;
- payload = &g_array_index (stream->payloads, AsfPayload, last_idx);
if (G_UNLIKELY (GST_CLOCK_TIME_IS_VALID (payload->ts) &&
(payload->ts < demux->segment.start))) {
if (G_UNLIKELY ((!demux->accurate) && payload->keyframe)) {
@@ -1366,7 +1548,14 @@ gst_asf_demux_find_stream_with_complete_payload (GstASFDemux * demux)
/* Now see if there's a complete payload queued for this stream */
- payload = &g_array_index (stream->payloads, AsfPayload, 0);
+ payload = NULL;
+ /* find first complete payload with timestamp */
+ for (j = 0;
+ j < stream->payloads->len && (payload == NULL
+ || !GST_CLOCK_TIME_IS_VALID (payload->ts)); ++j) {
+ payload = &g_array_index (stream->payloads, AsfPayload, j);
+ }
+
if (!gst_asf_payload_is_complete (payload))
continue;
@@ -1393,18 +1582,19 @@ gst_asf_demux_push_complete_payloads (GstASFDemux * demux, gboolean force)
/* streams are now activated */
}
- /* wait until we had a chance to "lock on" some payload's timestamp */
- if (G_UNLIKELY (demux->need_newsegment
- && !GST_CLOCK_TIME_IS_VALID (demux->segment_ts)))
- return GST_FLOW_OK;
-
while ((stream = gst_asf_demux_find_stream_with_complete_payload (demux))) {
AsfPayload *payload;
+ /* wait until we had a chance to "lock on" some payload's timestamp */
+ if (G_UNLIKELY (demux->need_newsegment
+ && !GST_CLOCK_TIME_IS_VALID (demux->segment_ts)))
+ return GST_FLOW_OK;
+
payload = &g_array_index (stream->payloads, AsfPayload, 0);
/* do we need to send a newsegment event */
if ((G_UNLIKELY (demux->need_newsegment))) {
+ GstEvent *segment_event;
/* safe default if insufficient upstream info */
if (!GST_CLOCK_TIME_IS_VALID (demux->in_gap))
@@ -1429,8 +1619,10 @@ gst_asf_demux_push_complete_payloads (GstASFDemux * demux, gboolean force)
&demux->segment);
/* note: we fix up all timestamps to start from 0, so this should be ok */
- gst_asf_demux_send_event_unlocked (demux,
- gst_event_new_segment (&demux->segment));
+ segment_event = gst_event_new_segment (&demux->segment);
+ if (demux->segment_seqnum)
+ gst_event_set_seqnum (segment_event, demux->segment_seqnum);
+ gst_asf_demux_send_event_unlocked (demux, segment_event);
/* now post any global tags we may have found */
if (demux->taglist == NULL) {
@@ -1447,6 +1639,7 @@ gst_asf_demux_push_complete_payloads (GstASFDemux * demux, gboolean force)
demux->taglist = NULL;
demux->need_newsegment = FALSE;
+ demux->segment_seqnum = 0;
demux->segment_running = TRUE;
}
@@ -1504,7 +1697,10 @@ gst_asf_demux_push_complete_payloads (GstASFDemux * demux, gboolean force)
* typically useful for live src, but might (unavoidably) mess with
* position reporting if a live src is playing not so live content
* (e.g. rtspsrc taking some time to fall back to tcp) */
- GST_BUFFER_TIMESTAMP (payload->buf) = payload->ts + demux->in_gap;
+ GST_BUFFER_PTS (payload->buf) = payload->ts;
+ if (GST_BUFFER_PTS_IS_VALID (payload->buf)) {
+ GST_BUFFER_PTS (payload->buf) += demux->in_gap;
+ }
if (payload->duration == GST_CLOCK_TIME_NONE
&& stream->ext_props.avg_time_per_frame != 0)
GST_BUFFER_DURATION (payload->buf) =
@@ -2172,7 +2368,8 @@ gst_asf_demux_get_stream (GstASFDemux * demux, guint16 id)
return &demux->stream[i];
}
- GST_WARNING ("Segment found for undefined stream: (%d)", id);
+ if (gst_asf_demux_is_unknown_stream (demux, id))
+ GST_WARNING ("Segment found for undefined stream: (%d)", id);
return NULL;
}
@@ -2368,6 +2565,7 @@ static void
gst_asf_demux_activate_stream (GstASFDemux * demux, AsfStream * stream)
{
if (!stream->active) {
+ GstEvent *event;
gchar *stream_id;
GST_INFO_OBJECT (demux, "Activating stream %2u, pad %s, caps %"
@@ -2376,8 +2574,26 @@ gst_asf_demux_activate_stream (GstASFDemux * demux, AsfStream * stream)
stream_id =
gst_pad_create_stream_id_printf (stream->pad, GST_ELEMENT_CAST (demux),
- "%u", stream->id);
- gst_pad_push_event (stream->pad, gst_event_new_stream_start (stream_id));
+ "%03u", stream->id);
+
+ event =
+ gst_pad_get_sticky_event (demux->sinkpad, GST_EVENT_STREAM_START, 0);
+ if (event) {
+ if (gst_event_parse_group_id (event, &demux->group_id))
+ demux->have_group_id = TRUE;
+ else
+ demux->have_group_id = FALSE;
+ gst_event_unref (event);
+ } else if (!demux->have_group_id) {
+ demux->have_group_id = TRUE;
+ demux->group_id = gst_util_group_id_next ();
+ }
+
+ event = gst_event_new_stream_start (stream_id);
+ if (demux->have_group_id)
+ gst_event_set_group_id (event, demux->group_id);
+
+ gst_pad_push_event (stream->pad, event);
g_free (stream_id);
gst_pad_set_caps (stream->pad, stream->caps);
@@ -2400,6 +2616,8 @@ gst_asf_demux_parse_stream_object (GstASFDemux * demux, guint8 * data,
guint stream_specific_size;
guint type_specific_size G_GNUC_UNUSED;
guint unknown G_GNUC_UNUSED;
+ gboolean inspect_payload = FALSE;
+ AsfStream *stream;
/* Get the rest of the header's header */
if (size < (16 + 16 + 8 + 4 + 4 + 2 + 4))
@@ -2424,6 +2642,25 @@ gst_asf_demux_parse_stream_object (GstASFDemux * demux, guint8 * data,
GST_DEBUG_OBJECT (demux, "Found stream %u, time_offset=%" GST_TIME_FORMAT,
stream_id, GST_TIME_ARGS (time_offset));
+ /* dvr-ms has audio stream declared in stream specific data */
+ if (stream_type == ASF_STREAM_EXT_EMBED_HEADER) {
+ AsfExtStreamType ext_stream_type;
+ gst_asf_demux_get_guid (&guid, &data, &size);
+ ext_stream_type = gst_asf_demux_identify_guid (asf_ext_stream_guids, &guid);
+
+ if (ext_stream_type == ASF_EXT_STREAM_AUDIO) {
+ inspect_payload = TRUE;
+
+ gst_asf_demux_get_guid (&guid, &data, &size);
+ gst_asf_demux_get_uint32 (&data, &size);
+ gst_asf_demux_get_uint32 (&data, &size);
+ gst_asf_demux_get_uint32 (&data, &size);
+ gst_asf_demux_get_guid (&guid, &data, &size);
+ gst_asf_demux_get_uint32 (&data, &size);
+ stream_type = ASF_STREAM_AUDIO;
+ }
+ }
+
switch (stream_type) {
case ASF_STREAM_AUDIO:{
asf_stream_audio audio_object;
@@ -2529,10 +2766,15 @@ gst_asf_demux_parse_stream_object (GstASFDemux * demux, guint8 * data,
default:
GST_WARNING_OBJECT (demux, "Unknown stream type for stream %u",
stream_id);
+ demux->other_streams =
+ g_slist_append (demux->other_streams, GINT_TO_POINTER (stream_id));
break;
}
- return gst_asf_demux_get_stream (demux, stream_id);
+ stream = gst_asf_demux_get_stream (demux, stream_id);
+ if (stream)
+ stream->inspect_payload = inspect_payload;
+ return stream;
not_enough_data:
{
@@ -3394,6 +3636,13 @@ not_enough_data:
}
}
+gboolean
+gst_asf_demux_is_unknown_stream (GstASFDemux * demux, guint stream_num)
+{
+ return g_slist_find (demux->other_streams,
+ GINT_TO_POINTER (stream_num)) == NULL;
+}
+
static GstFlowReturn
gst_asf_demux_process_ext_stream_props (GstASFDemux * demux, guint8 * data,
guint64 size)
@@ -3560,7 +3809,7 @@ done:
GST_TAG_LANGUAGE_CODE, demux->languages[stream->ext_props.lang_idx],
NULL);
}
- } else {
+ } else if (gst_asf_demux_is_unknown_stream (demux, stream_num)) {
GST_WARNING_OBJECT (demux, "Ext. stream properties for unknown stream");
}
@@ -4061,6 +4310,25 @@ gst_asf_demux_handle_src_query (GstPad * pad, GstObject * parent,
gst_query_set_latency (query, live, min, max);
break;
}
+ case GST_QUERY_SEGMENT:
+ {
+ GstFormat format;
+ gint64 start, stop;
+
+ format = demux->segment.format;
+
+ start =
+ gst_segment_to_stream_time (&demux->segment, format,
+ demux->segment.start);
+ if ((stop = demux->segment.stop) == -1)
+ stop = demux->segment.duration;
+ else
+ stop = gst_segment_to_stream_time (&demux->segment, format, stop);
+
+ gst_query_set_segment (query, demux->segment.rate, format, start, stop);
+ res = TRUE;
+ break;
+ }
default:
res = gst_pad_query_default (pad, parent, query);
break;