From: <tp...@ke...> - 2006-06-28 11:20:17
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Wed Jun 28 2006 11:20:15 UTC Log message: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_setup_pad), (gst_asf_demux_add_audio_stream), (gst_asf_demux_add_video_stream), (gst_asf_demux_push_buffer): * gst/asfdemux/gstasfdemux.h: Handle unknown codec IDs/fourccs properly (#345879); send tag events after newsegment event; fix use of GST_FOURCC_FORMAT macro. Modified files: . : ChangeLog gst/asfdemux : gstasfdemux.c gstasfdemux.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2055&r2=1.2056 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.100&r2=1.101 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h.diff?r1=1.20&r2=1.21 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2055 retrieving revision 1.2056 diff -u -d -r1.2055 -r1.2056 --- ChangeLog 23 Jun 2006 16:29:41 -0000 1.2055 +++ ChangeLog 28 Jun 2006 11:20:03 -0000 1.2056 @@ -1,3 +1,13 @@ +2006-06-28 Tim-Philipp Müller <tim at centricular dot net> + + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_setup_pad), + (gst_asf_demux_add_audio_stream), (gst_asf_demux_add_video_stream), + (gst_asf_demux_push_buffer): + * gst/asfdemux/gstasfdemux.h: + Handle unknown codec IDs/fourccs properly (#345879); send tag + events after newsegment event; fix use of GST_FOURCC_FORMAT + macro. 2006-06-23 Jan Schmidt <th...@ma...> * ext/a52dec/gsta52dec.c: (plugin_init): Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.100 retrieving revision 1.101 diff -u -d -r1.100 -r1.101 --- gstasfdemux.c 10 May 2006 14:40:03 -0000 1.100 +++ gstasfdemux.c 28 Jun 2006 11:20:03 -0000 1.101 @@ -809,7 +809,7 @@ static void gst_asf_demux_setup_pad (GstASFDemux * demux, GstPad * src_pad, - GstCaps * caps, guint16 id, gboolean is_video) + GstCaps * caps, guint16 id, gboolean is_video, GstTagList * tags) { asf_stream_context *stream; @@ -835,6 +835,7 @@ stream->fps_known = !is_video; /* bit hacky for audio */ stream->is_video = is_video; stream->need_newsegment = TRUE; + stream->pending_tags = tags; gst_pad_set_element_private (src_pad, stream); @@ -844,20 +845,13 @@ ++demux->num_streams; gst_element_add_pad (GST_ELEMENT (demux), src_pad); - - /* FIXME */ -#if 0 - if (demux->taglist) { - /* ... push tag event downstream ... */ - } -#endif } gst_asf_demux_add_audio_stream (GstASFDemux * demux, asf_stream_audio * audio, guint16 id, guint8 ** p_data, guint64 * p_size) - GstTagList *list = gst_tag_list_new (); + GstTagList *tags = NULL; GstBuffer *extradata = NULL; GstPad *src_pad; GstCaps *caps; @@ -887,10 +881,18 @@ caps = gst_riff_create_audio_caps (audio->codec_tag, NULL, (gst_riff_strf_auds *) audio, extradata, NULL, &codec_name); + if (caps == NULL) { + caps = gst_caps_new_simple ("audio/x-asf-unknown", "codec_id", + G_TYPE_INT, (gint) audio->codec_tag, NULL); + } /* Informing about that audio format we just added */ - gst_tag_list_add (list, GST_TAG_MERGE_APPEND, GST_TAG_AUDIO_CODEC, - codec_name, NULL); - g_free (codec_name); + if (codec_name) { + tags = gst_tag_list_new (); + gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_AUDIO_CODEC, + codec_name, NULL); + g_free (codec_name); if (extradata) gst_buffer_unref (extradata); @@ -900,17 +902,15 @@ ++demux->num_audio_streams; - gst_asf_demux_setup_pad (demux, src_pad, caps, id, FALSE); - gst_element_found_tags_for_pad (GST_ELEMENT (demux), src_pad, list); + gst_asf_demux_setup_pad (demux, src_pad, caps, id, FALSE, tags); -static void +static gboolean gst_asf_demux_add_video_stream (GstASFDemux * demux, asf_stream_video_format * video, guint16 id, guint8 ** p_data, guint64 * p_size) @@ -929,27 +929,35 @@ gst_asf_demux_get_buffer (&extradata, size_left, p_data, p_size); } + GST_DEBUG ("video codec %" GST_FOURCC_FORMAT, GST_FOURCC_ARGS (video->tag)); /* yes, asf_stream_video_format and gst_riff_strf_vids are the same */ caps = gst_riff_create_video_caps (video->tag, NULL, (gst_riff_strf_vids *) video, extradata, NULL, &codec_name); - gst_tag_list_add (list, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC, + caps = gst_caps_new_simple ("video/x-asf-unknown", "fourcc", + GST_TYPE_FOURCC, video->tag, NULL); + gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC, - GST_INFO ("Adding video stream %u codec " GST_FOURCC_FORMAT " (0x%08x)", + GST_INFO ("Adding video stream %u codec %" GST_FOURCC_FORMAT " (0x%08x)", demux->num_video_streams, GST_FOURCC_ARGS (video->tag), video->tag); gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION, 25, 1, NULL); ++demux->num_video_streams; - gst_asf_demux_setup_pad (demux, src_pad, caps, id, TRUE); + gst_asf_demux_setup_pad (demux, src_pad, caps, id, TRUE, tags); static GstFlowReturn @@ -1767,6 +1775,14 @@ stream->need_newsegment = FALSE; + /* need to send tags? */ + if (stream->pending_tags) { + GST_LOG_OBJECT (demux, "tags %" GST_PTR_FORMAT, stream->pending_tags); + gst_element_found_tags_for_pad (GST_ELEMENT (demux), stream->pad, + stream->pending_tags); + stream->pending_tags = NULL; /* don't set the same time stamp on multiple consecutive outgoing * video buffers, set it on the first one and set NONE on the others, * it's the decoder's job to fill the missing bits properly */ Index: gstasfdemux.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h,v retrieving revision 1.20 retrieving revision 1.21 diff -u -d -r1.20 -r1.21 --- gstasfdemux.h 1 Jun 2006 21:11:40 -0000 1.20 +++ gstasfdemux.h 28 Jun 2006 11:20:03 -0000 1.21 @@ -60,6 +60,8 @@ GstBuffer *cache; GstCaps *caps; + GstTagList *pending_tags; } asf_stream_context; typedef enum { |
From: <tp...@ke...> - 2006-07-07 19:26:53
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Fri Jul 07 2006 19:26:52 UTC Log message: * gst/asfdemux/asfheaders.c: * gst/asfdemux/asfheaders.h: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_identify_guid), (gst_asf_demux_process_header), (gst_asf_demux_push_obj), (gst_asf_demux_pop_obj), (gst_asf_demux_process_object), (gst_asf_demux_change_state): * gst/asfdemux/gstasfdemux.h: Add some more GUIDs and make debug log more readable and easier to follow when parsing the headers. Modified files: . : ChangeLog gst/asfdemux : asfheaders.c asfheaders.h gstasfdemux.c gstasfdemux.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2059&r2=1.2060 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.c.diff?r1=1.3&r2=1.4 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.h.diff?r1=1.10&r2=1.11 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.101&r2=1.102 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h.diff?r1=1.21&r2=1.22 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2059 retrieving revision 1.2060 diff -u -d -r1.2059 -r1.2060 --- ChangeLog 30 Jun 2006 11:26:22 -0000 1.2059 +++ ChangeLog 7 Jul 2006 19:26:40 -0000 1.2060 @@ -1,3 +1,15 @@ +2006-07-07 Tim-Philipp Müller <tim at centricular dot net> + + * gst/asfdemux/asfheaders.c: + * gst/asfdemux/asfheaders.h: + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_identify_guid), + (gst_asf_demux_process_header), (gst_asf_demux_push_obj), + (gst_asf_demux_pop_obj), (gst_asf_demux_process_object), + (gst_asf_demux_change_state): + * gst/asfdemux/gstasfdemux.h: + Add some more GUIDs and make debug log more readable + and easier to follow when parsing the headers. 2006-06-30 Tim-Philipp Müller <tim at centricular dot net> * ext/dvdread/dvdreadsrc.c: (gst_dvd_read_src_init), Index: asfheaders.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- asfheaders.c 15 Feb 2006 15:48:07 -0000 1.3 +++ asfheaders.c 7 Jul 2006 19:26:40 -0000 1.4 @@ -25,11 +25,10 @@ {ASF_CORRECTION_ON, "ASF_CORRECTION_ON", {0xBFC3CD50, 0x11CF618F, 0xAA00B28B, 0x20E2B400} }, -/* - { ASF_CORRECTION_OFF, "ASF_CORRECTION_OFF", - {0x20FB5700, 0x11CF5B55, 0x8000FDA8, 0x2B445C5F} - }, -*/ + {ASF_CORRECTION_OFF, "ASF_CORRECTION_OFF", + {0x20FB5700, 0x11CF5B55, 0x8000FDA8, 0x2B445C5F} + }, + /* CHECKME: where does this 49F1A440... GUID come from? (tpm) */ {ASF_CORRECTION_OFF, "ASF_CORRECTION_OFF", {0x49F1A440, 0x11D04ECE, 0xA000ACA3, 0xF64803C9} @@ -50,15 +49,6 @@ } }; - -2 unknown GUIDs found in an extended header object : -(0x26f18b5d/0x47ec4584/0x650e5f9f/0xc952041f) with size=26 -(0xd9aade20/0x4f9c7c17/0x558528bc/0xa2e298dd) with size=34 const ASFGuidHash asf_object_guids[] = { {ASF_OBJ_STREAM, "ASF_OBJ_STREAM", {0xB7DC0791, 0x11CFA9B7, 0xC000E68E, 0x6553200C} @@ -114,6 +104,21 @@ {ASF_OBJ_EXTENDED_STREAM_PROPS, "ASF_OBJ_EXTENDED_STREAM_PROPS", {0x14e6a5cb, 0x4332c672, 0x69a99983, 0x5a5b0652} + {ASF_OBJ_COMPATIBILITY, "ASF_OBJ_COMPATIBILITY", + {0x26f18b5d, 0x47ec4584, 0x650e5f9f, 0xc952041f} + {ASF_OBJ_INDEX_PLACEHOLDER, "ASF_OBJ_INDEX_PLACEHOLDER", + {0xd9aade20, 0x4f9c7c17, 0x558528bc, 0xa2e298dd} + {ASF_OBJ_INDEX_PARAMETERS, "ASF_OBJ_INDEX_PARAMETERS", + {0xd6e229df, 0x11d135da, 0xa0003490, 0xbe4903c9} + {ASF_OBJ_ADVANCED_MUTUAL_EXCLUSION, "ASF_OBJ_ADVANCED_MUTUAL_EXCLUSION", + {0xa08649cf, 0x46704775, 0x356e168a, 0xcd667535} + {ASF_OBJ_STREAM_PRIORITIZATION, "ASF_OBJ_STREAM_PRIORITIZATION", + {0xd4fed15b, 0x454f88d3, 0x5cedf081, 0x249e9945} {ASF_OBJ_UNDEFINED, "ASF_OBJ_UNDEFINED", {0, 0, 0, 0} Index: asfheaders.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.h,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- asfheaders.h 15 Feb 2006 15:48:07 -0000 1.10 +++ asfheaders.h 7 Jul 2006 19:26:40 -0000 1.11 @@ -54,7 +54,12 @@ ASF_OBJ_BITRATE_MUTEX, ASF_OBJ_LANGUAGE_LIST, ASF_OBJ_METADATA_OBJECT, - ASF_OBJ_EXTENDED_STREAM_PROPS + ASF_OBJ_EXTENDED_STREAM_PROPS, + ASF_OBJ_COMPATIBILITY, + ASF_OBJ_INDEX_PLACEHOLDER, + ASF_OBJ_INDEX_PARAMETERS, + ASF_OBJ_ADVANCED_MUTUAL_EXCLUSION, + ASF_OBJ_STREAM_PRIORITIZATION enum { Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.101 retrieving revision 1.102 diff -u -d -r1.101 -r1.102 --- gstasfdemux.c 28 Jun 2006 11:20:03 -0000 1.101 +++ gstasfdemux.c 7 Jul 2006 19:26:40 -0000 1.102 @@ -419,12 +419,11 @@ { guint32 ret; - GST_LOG ("identifying 0x%08x-0x%08x-0x%08x-0x%08x", - guid->v1, guid->v2, guid->v3, guid->v4); ret = gst_asf_identify_guid (guids, guid); - GST_LOG ("identified as %s", gst_asf_get_guid_nick (guids, ret)); + GST_LOG ("%s 0x%08x-0x%08x-0x%08x-0x%08x", + gst_asf_get_guid_nick (guids, ret), + guid->v1, guid->v2, guid->v3, guid->v4); return ret; } @@ -1388,7 +1387,8 @@ /* Loop through the header's objects, processing those */ for (i = 0; i < object.num_objects; ++i) { - GST_DEBUG ("reading header part %u: data=%p", i, *p_data); + GST_DEBUG ("reading header part %u: offset=0x%" G_GINT64_MODIFIER "x", + i, gst_asf_demux_get_current_offset (demux, *p_data)); ret = gst_asf_demux_process_object (demux, p_data, p_size); if (ret != GST_FLOW_OK) { GST_WARNING ("process_object returned %s", gst_asf_get_flow_name (ret)); @@ -1585,6 +1585,41 @@ +static const gchar * +gst_asf_demux_push_obj (GstASFDemux * demux, guint32 obj_id) +{ + const gchar *nick; + nick = gst_asf_get_guid_nick (asf_object_guids, obj_id); + if (g_str_has_prefix (nick, "ASF_OBJ_")) + nick += strlen ("ASF_OBJ_"); + if (demux->objpath == NULL) { + demux->objpath = g_strdup (nick); + } else { + gchar *newpath; + newpath = g_strdup_printf ("%s/%s", demux->objpath, nick); + g_free (demux->objpath); + demux->objpath = newpath; + } + return (const gchar *) demux->objpath; +} +static void +gst_asf_demux_pop_obj (GstASFDemux * demux) + gchar *s; + if ((s = g_strrstr (demux->objpath, "/"))) { + *s = '\0'; + demux->objpath = NULL; static GstFlowReturn gst_asf_demux_process_object (GstASFDemux * demux, guint8 ** p_data, guint64 * p_size) @@ -1606,8 +1641,9 @@ return ASF_FLOW_NEED_MORE_DATA; } - GST_INFO ("processing object %s with size %" G_GUINT64_FORMAT, - gst_asf_get_guid_nick (asf_object_guids, obj_id), + gst_asf_demux_push_obj (demux, obj_id); + GST_INFO ("%s, size %" G_GUINT64_FORMAT, demux->objpath, obj_size + ASF_DEMUX_OBJECT_HEADER_SIZE); switch (obj_id) { @@ -1645,6 +1681,11 @@ case ASF_OBJ_LANGUAGE_LIST: case ASF_OBJ_METADATA_OBJECT: case ASF_OBJ_EXTENDED_STREAM_PROPS: + case ASF_OBJ_COMPATIBILITY: + case ASF_OBJ_INDEX_PLACEHOLDER: + case ASF_OBJ_INDEX_PARAMETERS: + case ASF_OBJ_ADVANCED_MUTUAL_EXCLUSION: + case ASF_OBJ_STREAM_PRIORITIZATION: default: /* Unknown/unhandled object read. Just ignore * it, people don't like fatal errors much */ @@ -1657,7 +1698,9 @@ break; - GST_DEBUG ("ret = %s", gst_asf_get_flow_name (ret)); + GST_LOG ("ret = %s (%s)", gst_asf_get_flow_name (ret), demux->objpath); + gst_asf_demux_pop_obj (demux); @@ -2543,6 +2586,8 @@ demux->taglist = NULL; demux->state = GST_ASF_DEMUX_STATE_HEADER; + g_free (demux->objpath); + demux->objpath = NULL; } Index: gstasfdemux.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h,v retrieving revision 1.21 retrieving revision 1.22 diff -u -d -r1.21 -r1.22 --- gstasfdemux.h 28 Jun 2006 11:20:03 -0000 1.21 +++ gstasfdemux.h 7 Jul 2006 19:26:40 -0000 1.22 @@ -125,6 +125,8 @@ guint16 ds_chunk_size; guint16 ds_data_size; + /* for debugging only */ + gchar *objpath; struct _GstASFDemuxClass { |
From: <tp...@ke...> - 2006-07-08 20:30:09
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Sat Jul 08 2006 20:30:08 UTC Log message: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_process_chunk): Skip chunks for unknown streams properly. Fixes broken sound and/or video for files that have additional streams that we don't recognise yet (e.g. if they are embedded in extended stream properties). Partly fixes #343763. Modified files: . : ChangeLog gst/asfdemux : gstasfdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2060&r2=1.2061 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.102&r2=1.103 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2060 retrieving revision 1.2061 diff -u -d -r1.2060 -r1.2061 --- ChangeLog 7 Jul 2006 19:26:40 -0000 1.2060 +++ ChangeLog 8 Jul 2006 20:29:56 -0000 1.2061 @@ -1,3 +1,11 @@ +2006-07-08 Tim-Philipp Müller <tim at centricular dot net> + + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_process_chunk): + Skip chunks for unknown streams properly. Fixes broken sound + and/or video for files that have additional streams that + we don't recognise yet (e.g. if they are embedded in extended + stream properties). Partly fixes #343763. 2006-07-07 Tim-Philipp Müller <tim at centricular dot net> * gst/asfdemux/asfheaders.c: Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.102 retrieving revision 1.103 diff -u -d -r1.102 -r1.103 --- gstasfdemux.c 7 Jul 2006 19:26:40 -0000 1.102 +++ gstasfdemux.c 8 Jul 2006 20:29:56 -0000 1.103 @@ -1869,6 +1869,8 @@ stream = gst_asf_demux_get_stream (demux, segment_info->stream_number); if (stream == NULL) { GST_WARNING ("invalid stream number %d", segment_info->stream_number); + if (!gst_asf_demux_skip_bytes (segment_info->chunk_size, p_data, p_size)) + ret = ASF_FLOW_NEED_MORE_DATA; goto done; } |
From: <tp...@ke...> - 2006-07-28 15:58:40
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Fri Jul 28 2006 15:15:27 UTC Log message: * gst/asfdemux/Makefile.am: * gst/asfdemux/asfheaders.c: * gst/asfdemux/asfheaders.h: * gst/asfdemux/gstasf.c: (plugin_init): * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_process_object): Error out when the stream is encrypted (rather than feeding garbage to the decoders). Fixes #349025. Modified files: . : ChangeLog gst/asfdemux : Makefile.am asfheaders.c asfheaders.h gstasf.c gstasfdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2071&r2=1.2072 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/Makefile.am.diff?r1=1.11&r2=1.12 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.c.diff?r1=1.4&r2=1.5 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.h.diff?r1=1.12&r2=1.13 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasf.c.diff?r1=1.6&r2=1.7 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.106&r2=1.107 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2071 retrieving revision 1.2072 diff -u -d -r1.2071 -r1.2072 --- ChangeLog 28 Jul 2006 15:11:42 -0000 1.2071 +++ ChangeLog 28 Jul 2006 15:15:15 -0000 1.2072 @@ -1,5 +1,15 @@ 2006-07-28 Tim-Philipp Müller <tim at centricular dot net> + * gst/asfdemux/Makefile.am: + * gst/asfdemux/asfheaders.c: + * gst/asfdemux/asfheaders.h: + * gst/asfdemux/gstasf.c: (plugin_init): + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_process_object): + Error out when the stream is encrypted (rather than feeding + garbage to the decoders). Fixes #349025. + +2006-07-28 Tim-Philipp Müller <tim at centricular dot net> * Makefile.am: * autogen.sh: * configure.ac: Index: Makefile.am RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/Makefile.am,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- Makefile.am 16 Feb 2006 17:57:59 -0000 1.11 +++ Makefile.am 28 Jul 2006 15:15:15 -0000 1.12 @@ -1,7 +1,7 @@ plugin_LTLIBRARIES = libgstasf.la libgstasf_la_SOURCES = gstasfdemux.c gstasf.c asfheaders.c -libgstasf_la_CFLAGS = $(GST_BASE_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) +libgstasf_la_CFLAGS = $(GST_BASE_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) libgstasf_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(GST_LIBS)\ -lgstriff-@GST_MAJORMINOR@ libgstasf_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) Index: asfheaders.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- asfheaders.c 7 Jul 2006 19:26:40 -0000 1.4 +++ asfheaders.c 28 Jul 2006 15:15:15 -0000 1.5 @@ -119,6 +119,18 @@ {ASF_OBJ_STREAM_PRIORITIZATION, "ASF_OBJ_STREAM_PRIORITIZATION", {0xd4fed15b, 0x454f88d3, 0x5cedf081, 0x249e9945} }, + {ASF_OBJ_CONTENT_ENCRYPTION, "ASF_OBJ_CONTENT_ENCRYPTION", + {0x2211b3fb, 0x11d2bd23, 0xa000b7b4, 0x6efc55c9} + }, + {ASF_OBJ_EXT_CONTENT_ENCRYPTION, "ASF_OBJ_EXT_CONTENT_ENCRYPTION", + {0x298ae614, 0x4c172622, 0xe0da35b9, 0x9c28e97e} + {ASF_OBJ_DIGITAL_SIGNATURE_OBJECT, "ASF_OBJ_DIGITAL_SIGNATURE_OBJECT", + {0x2211b3fc, 0x11d2bd23, 0xa000b7b4, 0x6efc55c9} + {ASF_OBJ_SCRIPT_COMMAND, "ASF_OBJ_SCRIPT_COMMAND", + {0x1efb1a30, 0x11d00b62, 0xa0009ba3, 0xf64803c9} {ASF_OBJ_UNDEFINED, "ASF_OBJ_UNDEFINED", {0, 0, 0, 0} } Index: asfheaders.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.h,v retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- asfheaders.h 14 Jul 2006 13:02:53 -0000 1.12 +++ asfheaders.h 28 Jul 2006 15:15:15 -0000 1.13 @@ -59,7 +59,11 @@ ASF_OBJ_INDEX_PLACEHOLDER, ASF_OBJ_INDEX_PARAMETERS, ASF_OBJ_ADVANCED_MUTUAL_EXCLUSION, - ASF_OBJ_STREAM_PRIORITIZATION + ASF_OBJ_STREAM_PRIORITIZATION, + ASF_OBJ_CONTENT_ENCRYPTION, + ASF_OBJ_EXT_CONTENT_ENCRYPTION, + ASF_OBJ_DIGITAL_SIGNATURE_OBJECT, + ASF_OBJ_SCRIPT_COMMAND }; enum { Index: gstasf.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasf.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- gstasf.c 22 May 2006 08:24:09 -0000 1.6 +++ gstasf.c 28 Jul 2006 15:15:15 -0000 1.7 @@ -22,7 +22,8 @@ #endif #include <gst/gst.h> -#include <gst/riff/riff-media.h> +#include <gst/riff/riff-read.h> +#include "gst/gst-i18n-plugin.h" #include "gstasfdemux.h" /* #include "gstasfmux.h" */ @@ -30,6 +31,11 @@ static gboolean plugin_init (GstPlugin * plugin) { +#ifdef ENABLE_NLS + setlocale (LC_ALL, ""); + bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); +#endif /* ENABLE_NLS */ gst_riff_init (); if (!gst_element_register (plugin, "asfdemux", GST_RANK_SECONDARY, Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.106 retrieving revision 1.107 diff -u -d -r1.106 -r1.107 --- gstasfdemux.c 15 Jul 2006 13:33:38 -0000 1.106 +++ gstasfdemux.c 28 Jul 2006 15:15:15 -0000 1.107 @@ -25,6 +25,7 @@ #include <gst/gstutils.h> #include <gst/riff/riff-media.h> #include <string.h> @@ -935,7 +936,7 @@ gst_asf_demux_setup_pad (demux, src_pad, caps, id, FALSE, tags); } -static gboolean +static void gst_asf_demux_add_video_stream (GstASFDemux * demux, asf_stream_video_format * video, guint16 id, guint8 ** p_data, guint64 * p_size) @@ -1832,7 +1833,6 @@ GstFlowReturn ret; guint32 obj_id; guint64 obj_size, obj_data_size; - gint64 processed; if (!gst_asf_demux_get_object_header (demux, &obj_id, &obj_size, p_data, p_size)) { @@ -1887,6 +1887,10 @@ case ASF_OBJ_LANGUAGE_LIST: ret = gst_asf_demux_process_language_list (demux, p_data, p_size); break; + case ASF_OBJ_CONTENT_ENCRYPTION: + case ASF_OBJ_EXT_CONTENT_ENCRYPTION: + case ASF_OBJ_DIGITAL_SIGNATURE_OBJECT: + goto error_encrypted; case ASF_OBJ_CONCEAL_NONE: case ASF_OBJ_HEAD2: case ASF_OBJ_UNDEFINED: @@ -1900,6 +1904,7 @@ case ASF_OBJ_INDEX_PARAMETERS: case ASF_OBJ_ADVANCED_MUTUAL_EXCLUSION: case ASF_OBJ_STREAM_PRIORITIZATION: + case ASF_OBJ_SCRIPT_COMMAND: default: /* Unknown/unhandled object read. Just ignore * it, people don't like fatal errors much */ @@ -1918,6 +1923,14 @@ gst_asf_demux_pop_obj (demux); return ret; +/* ERRORS */ +error_encrypted: + { + GST_ELEMENT_ERROR (demux, STREAM, DECODE, + (_("This file is encrypted and cannot be played.")), (NULL)); + return GST_FLOW_ERROR; + } static void |
From: <tp...@ke...> - 2006-08-22 15:52:32
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Tue Aug 22 2006 15:52:28 UTC Log message: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_base_init), (gst_asf_demux_add_audio_stream), (gst_asf_demux_add_video_stream): Use static pad templates with ANY caps for the source pads for simplicity and to avoid warnings when creating pads for unhandled codec IDs (#351795). Modified files: . : ChangeLog gst/asfdemux : gstasfdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2086&r2=1.2087 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.108&r2=1.109 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2086 retrieving revision 1.2087 diff -u -d -r1.2086 -r1.2087 --- ChangeLog 16 Aug 2006 10:34:57 -0000 1.2086 +++ ChangeLog 22 Aug 2006 15:52:16 -0000 1.2087 @@ -1,3 +1,11 @@ +2006-08-22 Tim-Philipp Müller <tim at centricular dot net> + + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_base_init), + (gst_asf_demux_add_audio_stream), (gst_asf_demux_add_video_stream): + Use static pad templates with ANY caps for the source pads for + simplicity and to avoid warnings when creating pads for unhandled + codec IDs (#351795). 2006-08-16 Wim Taymans <wi...@fl...> Patch by: Michal Benes <michal dot benes at itonis dot tv> Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.108 retrieving revision 1.109 diff -u -d -r1.108 -r1.109 --- gstasfdemux.c 31 Jul 2006 09:53:05 -0000 1.108 +++ gstasfdemux.c 22 Aug 2006 15:52:16 -0000 1.109 @@ -38,6 +38,18 @@ GST_STATIC_CAPS ("video/x-ms-asf") ); +static GstStaticPadTemplate audio_src_template = +GST_STATIC_PAD_TEMPLATE ("audio_%02d", + GST_PAD_SRC, + GST_PAD_SOMETIMES, + GST_STATIC_CAPS_ANY); +static GstStaticPadTemplate video_src_template = +GST_STATIC_PAD_TEMPLATE ("video_%02d", /* abuse this GstFlowReturn enum for internal usage */ #define ASF_FLOW_NEED_MORE_DATA 99 @@ -65,9 +77,6 @@ GST_BOILERPLATE (GstASFDemux, gst_asf_demux, GstElement, GST_TYPE_ELEMENT); -static GstPadTemplate *videosrctempl; -static GstPadTemplate *audiosrctempl; - static void gst_asf_demux_base_init (gpointer g_class) { @@ -78,16 +87,11 @@ "Demultiplexes ASF Streams", "Owen Fraser-Green <ow...@di...>" }; - GstCaps *audcaps = gst_riff_create_audio_template_caps (), - *vidcaps = gst_riff_create_video_template_caps (); - audiosrctempl = gst_pad_template_new ("audio_%02d", - GST_PAD_SRC, GST_PAD_SOMETIMES, audcaps); - videosrctempl = gst_pad_template_new ("video_%02d", - GST_PAD_SRC, GST_PAD_SOMETIMES, vidcaps); - gst_element_class_add_pad_template (element_class, audiosrctempl); - gst_element_class_add_pad_template (element_class, videosrctempl); + gst_element_class_add_pad_template (element_class, + gst_static_pad_template_get (&audio_src_template)); + gst_static_pad_template_get (&video_src_template)); gst_element_class_add_pad_template (element_class, gst_static_pad_template_get (&gst_asf_demux_sink_template)); @@ -886,7 +890,7 @@ /* Create the audio pad */ name = g_strdup_printf ("audio_%02d", demux->num_audio_streams); - src_pad = gst_pad_new_from_template (audiosrctempl, name); + src_pad = gst_pad_new_from_static_template (&audio_src_template, name); g_free (name); /* Swallow up any left over data and set up the @@ -951,7 +955,7 @@ /* Create the video pad */ name = g_strdup_printf ("video_%02d", demux->num_video_streams); - src_pad = gst_pad_new_from_template (videosrctempl, name); + src_pad = gst_pad_new_from_static_template (&video_src_template, name); /* Now try some gstreamer formatted MIME types (from gst_avi_demux_strf_vids) */ |
From: <tp...@ke...> - 2006-11-20 15:52:59
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Mon Nov 20 2006 15:52:54 UTC Log message: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_add_audio_stream): The availability of extra codec data isn't something that warrants debug messages at WARNING level (see #376958). Modified files: . : ChangeLog gst/asfdemux : gstasfdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2124&r2=1.2125 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.113&r2=1.114 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2124 retrieving revision 1.2125 diff -u -d -r1.2124 -r1.2125 --- ChangeLog 19 Nov 2006 13:08:30 -0000 1.2124 +++ ChangeLog 20 Nov 2006 15:52:42 -0000 1.2125 @@ -1,3 +1,9 @@ +2006-11-20 Tim-Philipp Müller <tim at centricular dot net> + + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_add_audio_stream): + The availability of extra codec data isn't something that + warrants debug messages at WARNING level (see #376958). 2006-11-19 Tim-Philipp Müller <tim at centricular dot net> * gst/mpegstream/gstdvddemux.c: (gst_dvd_demux_base_init), Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.113 retrieving revision 1.114 diff -u -d -r1.113 -r1.114 --- gstasfdemux.c 9 Oct 2006 12:09:14 -0000 1.113 +++ gstasfdemux.c 20 Nov 2006 15:52:42 -0000 1.114 @@ -902,7 +902,7 @@ /* Swallow up any left over data and set up the * standard properties from the header info */ if (size_left) { - GST_WARNING ("Audio header contains %d bytes of " + GST_INFO_OBJECT (demux, "Audio header contains %d bytes of " "codec specific data", size_left); gst_asf_demux_get_buffer (&extradata, size_left, p_data, p_size); |
From: <tp...@ke...> - 2006-12-15 17:55:06
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Fri Dec 15 2006 17:55:01 UTC Log message: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_handle_seek_event), (gst_asf_demux_process_data), (gst_asf_demux_process_file), (gst_asf_demux_handle_src_query), (gst_asf_demux_change_state): * gst/asfdemux/gstasfdemux.h: Don't crash in the seek event handling code when playtime is 0, as may be the case with live streams (#386218). Implement SEEKING query so applications can query seekability without second-guessing based on whether we have a duration or not. Modified files: . : ChangeLog gst/asfdemux : gstasfdemux.c gstasfdemux.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2138&r2=1.2139 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.114&r2=1.115 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h.diff?r1=1.23&r2=1.24 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2138 retrieving revision 1.2139 diff -u -d -r1.2138 -r1.2139 --- ChangeLog 15 Dec 2006 11:12:21 -0000 1.2138 +++ ChangeLog 15 Dec 2006 17:54:48 -0000 1.2139 @@ -1,3 +1,14 @@ +2006-12-15 Tim-Philipp Müller <tim at centricular dot net> + + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_handle_seek_event), + (gst_asf_demux_process_data), (gst_asf_demux_process_file), + (gst_asf_demux_handle_src_query), (gst_asf_demux_change_state): + * gst/asfdemux/gstasfdemux.h: + Don't crash in the seek event handling code when playtime is 0, + as may be the case with live streams (#386218). Implement SEEKING + query so applications can query seekability without second-guessing + based on whether we have a duration or not. 2006-12-15 Thomas Vander Stichele <thomas at apestaart dot org> * Makefile.am: Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.114 retrieving revision 1.115 diff -u -d -r1.114 -r1.115 --- gstasfdemux.c 20 Nov 2006 15:52:42 -0000 1.114 +++ gstasfdemux.c 15 Dec 2006 17:54:48 -0000 1.115 @@ -227,18 +227,25 @@ gdouble rate; gint64 cur, stop; gint64 seek_offset; + gint64 seek_time; guint64 seek_packet; + if (demux->seekable == FALSE || demux->packet_size == 0 || + demux->num_packets == 0 || demux->play_time == 0) { + GST_LOG_OBJECT (demux, "stream is not seekable"); + return FALSE; + } gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur, &stop_type, &stop); if (format != GST_FORMAT_TIME) { - GST_LOG ("seeking is only supported in TIME format"); + GST_LOG_OBJECT (demux, "seeking is only supported in TIME format"); return FALSE; } if (rate <= 0.0) { - GST_LOG ("backward playback is not supported yet"); + GST_LOG_OBJECT (demux, "backward playback is not supported yet"); @@ -260,30 +267,23 @@ GST_DEBUG ("trying to seek to time %" GST_TIME_FORMAT, GST_TIME_ARGS (segment.start)); - if (demux->packet_size > 0) { - gint64 seek_time = segment.start; + seek_time = segment.start; - /* Hackety hack, this sucks. We just seek to an earlier position - * and let the sinks throw away the stuff before the segment start */ - if (flush && (accurate || keyunit_sync)) { - seek_time -= 5 * GST_SECOND; - if (seek_time < 0) - seek_time = 0; - } + /* Hackety hack, this sucks. We just seek to an earlier position + * and let the sinks throw away the stuff before the segment start */ + if (flush && (accurate || keyunit_sync)) { + seek_time -= 5 * GST_SECOND; + if (seek_time < 0) + seek_time = 0; - seek_packet = demux->num_packets * seek_time / demux->play_time; + seek_packet = demux->num_packets * seek_time / demux->play_time; - if (seek_packet > demux->num_packets) - seek_packet = demux->num_packets; + if (seek_packet > demux->num_packets) + seek_packet = demux->num_packets; - seek_offset = seek_packet * demux->packet_size + demux->data_offset; - /* demux->next_byte_offset will be set via newsegment event */ - } else { - /* FIXME */ - g_message ("IMPLEMENT ME: seeking for packet_size == 0 (asfdemux)"); - ret = FALSE; - goto done; - } + seek_offset = seek_packet * demux->packet_size + demux->data_offset; + /* demux->next_byte_offset will be set via newsegment event */ GST_LOG ("seeking to byte offset %" G_GINT64_FORMAT, seek_offset); @@ -1407,6 +1407,9 @@ demux->packet = 0; demux->num_packets = data_object.packets; + if (demux->num_packets == 0) + demux->seekable = FALSE; /* minus object header and data object header */ demux->data_size = object_size - ASF_DEMUX_OBJECT_HEADER_SIZE - (16 + 8 + 1 + 1); @@ -1451,22 +1454,40 @@ guint64 * p_size) { asf_obj_file object; + gboolean broadcast; /* Get the rest of the header's header */ if (!gst_asf_demux_get_obj_file (&object, p_data, p_size)) return ASF_FLOW_NEED_MORE_DATA; + broadcast = !!(object.flags & 0x01); + demux->seekable = !!(object.flags & 0x02); + GST_DEBUG_OBJECT (demux, "flags::broadcast = %d", broadcast); + GST_DEBUG_OBJECT (demux, "flags::seekable = %d", demux->seekable); + if (broadcast) { + /* these fields are invalid if the broadcast flag is set */ + object.play_time = 0; + object.file_size = 0; if (object.min_pktsize == object.max_pktsize) { demux->packet_size = object.max_pktsize; } else { demux->packet_size = (guint32) - 1; GST_WARNING ("Non-const packet size, seeking disabled"); /* FIXME: do we need object.send_time as well? what is it? */ demux->play_time = (guint64) object.play_time * (GST_SECOND / 10000000); demux->preroll = object.preroll; + if (demux->play_time == 0) GST_DEBUG_OBJECT (demux, "play_time %" GST_TIME_FORMAT " preroll %" GST_TIME_FORMAT, GST_TIME_ARGS (demux->play_time), GST_TIME_ARGS (demux->preroll)); @@ -2788,6 +2809,24 @@ break; } + case GST_QUERY_SEEKING:{ + GstFormat format; + gst_query_parse_seeking (query, &format, NULL, NULL, NULL); + if (format == GST_FORMAT_TIME) { + gint64 duration; + GST_OBJECT_LOCK (demux); + duration = demux->segment.duration; + GST_OBJECT_UNLOCK (demux); + gst_query_set_seeking (query, GST_FORMAT_TIME, demux->seekable, + 0, duration); + res = TRUE; + } + break; + } default: res = gst_pad_query_default (pad, query); @@ -2838,6 +2877,7 @@ g_slist_free (demux->ext_stream_props); demux->ext_stream_props = NULL; memset (demux->stream, 0, sizeof (demux->stream)); + demux->seekable = FALSE; Index: gstasfdemux.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -r1.23 -r1.24 --- gstasfdemux.h 14 Jul 2006 13:02:53 -0000 1.23 +++ gstasfdemux.h 15 Dec 2006 17:54:48 -0000 1.24 @@ -116,6 +116,8 @@ guint64 preroll; guint64 pts; + gboolean seekable; /* expected byte offset of next buffer to be received by chain * function. Used to calculate the current byte offset into the * file from the adapter state and the data parser state */ |
From: <tp...@ke...> - 2006-12-15 23:56:33
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Fri Dec 15 2006 18:26:53 UTC Log message: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_get_src_query_types): Update query_types function too. Modified files: . : ChangeLog gst/asfdemux : gstasfdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2141&r2=1.2142 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.115&r2=1.116 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2141 retrieving revision 1.2142 diff -u -d -r1.2141 -r1.2142 --- ChangeLog 15 Dec 2006 18:25:17 -0000 1.2141 +++ ChangeLog 15 Dec 2006 18:26:41 -0000 1.2142 @@ -1,5 +1,10 @@ 2006-12-15 Tim-Philipp Müller <tim at centricular dot net> + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_get_src_query_types): + Update query_types function too. + +2006-12-15 Tim-Philipp Müller <tim at centricular dot net> * gst/realmedia/rmdemux.c: (gst_rmdemux_src_query), (gst_rmdemux_src_query_types): Implement SEEKING query, make query function thread-safe. Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.115 retrieving revision 1.116 diff -u -d -r1.115 -r1.116 --- gstasfdemux.c 15 Dec 2006 17:54:48 -0000 1.115 +++ gstasfdemux.c 15 Dec 2006 18:26:41 -0000 1.116 @@ -2734,6 +2734,7 @@ static const GstQueryType types[] = { GST_QUERY_POSITION, GST_QUERY_DURATION, + GST_QUERY_SEEKING, 0 }; |
From: <tp...@ke...> - 2007-01-24 17:36:58
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Wed Jan 24 2007 17:36:48 UTC Log message: Patch by: Xavier B. <xavierb gmail com> * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_get_guid), (gst_asf_demux_add_audio_stream), (gst_asf_demux_add_video_stream), (gst_asf_demux_process_ext_content_desc), (gst_asf_demux_process_data), (gst_asf_demux_process_language_list), (gst_asf_demux_process_ext_stream_props), (gst_asf_demux_process_segment), (gst_asf_demux_handle_data): Guard places where we assume that a certain amount of data is available better against less data being available (should fix infamous assertion crasher bug #336370). Also fixes a small memory leak. Modified files: . : ChangeLog gst/asfdemux : gstasfdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2150&r2=1.2151 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.117&r2=1.118 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2150 retrieving revision 1.2151 diff -u -d -r1.2150 -r1.2151 --- ChangeLog 11 Jan 2007 12:49:23 -0000 1.2150 +++ ChangeLog 24 Jan 2007 17:36:35 -0000 1.2151 @@ -1,3 +1,19 @@ +2007-01-24 Tim-Philipp Müller <tim at centricular dot net> + + Patch by: Xavier B. <xavierb gmail com> + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_get_guid), + (gst_asf_demux_add_audio_stream), (gst_asf_demux_add_video_stream), + (gst_asf_demux_process_ext_content_desc), + (gst_asf_demux_process_data), + (gst_asf_demux_process_language_list), + (gst_asf_demux_process_ext_stream_props), + (gst_asf_demux_process_segment), (gst_asf_demux_handle_data): + Guard places where we assume that a certain amount of data is + available better against less data being available (should fix + infamous assertion crasher bug #336370). Also fixes a small + memory leak. 2007-01-11 Tim-Philipp Müller <tim at centricular dot net> * gst/realmedia/Makefile.am: Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.117 retrieving revision 1.118 diff -u -d -r1.117 -r1.118 --- gstasfdemux.c 21 Dec 2006 08:16:41 -0000 1.117 +++ gstasfdemux.c 24 Jan 2007 17:36:36 -0000 1.118 @@ -584,17 +584,15 @@ } -static gboolean +static void gst_asf_demux_get_guid (ASFGuid * guid, guint8 ** p_data, guint64 * p_size) { - if (*p_size < 4 * sizeof (guint32)) - return FALSE; + g_assert (*p_size >= 4 * sizeof (guint32)); guid->v1 = gst_asf_demux_get_uint32 (p_data, p_size); guid->v2 = gst_asf_demux_get_uint32 (p_data, p_size); guid->v3 = gst_asf_demux_get_uint32 (p_data, p_size); guid->v4 = gst_asf_demux_get_uint32 (p_data, p_size); - return TRUE; static gboolean @@ -905,6 +903,7 @@ GST_INFO_OBJECT (demux, "Audio header contains %d bytes of " "codec specific data", size_left); + g_assert (size_left <= *p_size); gst_asf_demux_get_buffer (&extradata, size_left, p_data, p_size); } @@ -967,6 +966,7 @@ /* Now try some gstreamer formatted MIME types (from gst_avi_demux_strf_vids) */ if (size_left) { GST_LOG ("Video header has %d bytes of codec specific data", size_left); @@ -1273,15 +1273,18 @@ if (!gst_asf_demux_get_string (&name, &name_len, p_data, p_size)) goto not_enough_data; - if (*p_size < 2) + if (*p_size < 2) { + g_free (name); - + } /* Descriptor Value Data Type */ datatype = gst_asf_demux_get_uint16 (p_data, p_size); /* Descriptor Value (not really a string, but same thing reading-wise) */ - if (!gst_asf_demux_get_string (&value, &value_len, p_data, p_size)) + if (!gst_asf_demux_get_string (&value, &value_len, p_data, p_size)) { gst_tag_name = gst_asf_demux_get_gst_tag_from_tag_name (name, name_len); if (gst_tag_name != NULL) { @@ -1396,6 +1399,9 @@ guint8 ** p_data, guint64 * p_size) asf_obj_data data_object; + guint64 size_at_start; + size_at_start = *p_size; /* Get the rest of the header */ if (!gst_asf_demux_get_obj_data (&data_object, p_data, p_size)) @@ -1414,6 +1420,7 @@ demux->seekable = FALSE; /* minus object header and data object header */ + g_assert (size_at_start - *p_size == (16 + 8 + 1 + 1)); demux->data_size = object_size - ASF_DEMUX_OBJECT_HEADER_SIZE - (16 + 8 + 1 + 1); demux->data_offset = gst_asf_demux_get_current_offset (demux, *p_data); @@ -1679,6 +1686,8 @@ for (i = 0; i < demux->num_languages; ++i) { guint8 len, *data = NULL; + if (*p_size < 1) + goto not_enough_data; len = gst_asf_demux_get_uint8 (p_data, p_size); if (gst_asf_demux_get_bytes (&data, len, p_data, p_size)) { gchar *utf8; @@ -1693,10 +1702,19 @@ GST_DEBUG ("[%u] %s", i, GST_STR_NULL (utf8)); demux->languages[i] = utf8; g_free (data); + } else { } return GST_FLOW_OK; +not_enough_data: + { + g_free (demux->languages); + demux->languages = NULL; + return ASF_FLOW_NEED_MORE_DATA; + } static GstFlowReturn @@ -1712,7 +1730,7 @@ guint8 *data_start = *p_data; guint i; - if (*p_size < 88) + if (*p_size < 8 + 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 2 + 2 + 8 + 2 + 2) /*64 */ return ASF_FLOW_NEED_MORE_DATA; esp.start_time = gst_asf_demux_get_uint64 (p_data, p_size); @@ -1749,9 +1767,11 @@ guint16 stream_lang_idx; gchar *stream_name = NULL; + if (*p_size < 2) + return ASF_FLOW_NEED_MORE_DATA; stream_lang_idx = gst_asf_demux_get_uint16 (p_data, p_size); if (!gst_asf_demux_get_string (&stream_name, NULL, p_data, p_size)) - return GST_FLOW_ERROR; GST_INFO ("stream name %d: %s", i, GST_STR_NULL (stream_name)); g_free (stream_name); /* TODO: store names in struct */ @@ -1762,12 +1782,14 @@ guint32 sys_info_len; if (!gst_asf_demux_skip_bytes (16 + 2, p_data, p_size) || *p_size < 4) + if (*p_size < 4) sys_info_len = gst_asf_demux_get_uint32 (p_data, p_size); GST_LOG ("payload systems info len = %u", sys_info_len); if (!gst_asf_demux_skip_bytes (sys_info_len, p_data, p_size)) GST_LOG ("bytes read: %u/%u", (guint) (*p_data - data_start), obj_size); @@ -1777,17 +1799,17 @@ goto done; /* get size of the stream object */ - if (!gst_asf_demux_get_object_header (demux, &obj_id, &len, p_data, p_size) || - obj_id != ASF_OBJ_STREAM || len > (10 * 1024 * 1024)) { + if (!gst_asf_demux_get_object_header (demux, &obj_id, &len, p_data, p_size)) + if (obj_id != ASF_OBJ_STREAM || len > (10 * 1024 * 1024)) return GST_FLOW_ERROR; - } len -= ASF_DEMUX_OBJECT_HEADER_SIZE; /* process this stream object later after all the other 'normal' ones * have been processed (since the others are more important/non-hidden) */ if (!gst_asf_demux_get_bytes (&data, (guint) len, p_data, p_size)) - return GST_FLOW_ERROR; esp.stream_obj_data = data; esp.stream_obj_len = len; @@ -2371,6 +2393,18 @@ #endif + const guint lengths[4] = { 0, 1, 2, 4 }; + guint needed; + needed = lengths[packet_info->seqtype] + + lengths[packet_info->fragoffsettype] + + lengths[packet_info->replicsizetype]; + if (*p_size < needed) segment_info.sequence = gst_asf_demux_get_var_length (packet_info->seqtype, p_data, p_size); segment_info.frag_offset = @@ -2409,6 +2443,8 @@ if (replic_size == 1) { /* It's compressed */ segment_info.compressed = TRUE; + if (*p_size < 1) + return ASF_FLOW_NEED_MORE_DATA; time_delta = gst_asf_demux_get_uint8 (p_data, p_size); GST_DEBUG ("time_delta = %u", time_delta); } else { @@ -2424,6 +2460,11 @@ packet_info->multiple, segment_info.compressed); if (packet_info->multiple) { + if (*p_size < lengths[packet_info->segsizetype]) frag_size = gst_asf_demux_get_var_length (packet_info->segsizetype, p_data, p_size); } else { @@ -2439,6 +2480,8 @@ if (segment_info.compressed) { while (frag_size > 0) { byte = gst_asf_demux_get_uint8 (p_data, p_size); packet_info->size_left--; segment_info.chunk_size = byte; @@ -2468,7 +2511,6 @@ ret = GST_FLOW_ERROR; */ return ASF_FLOW_NEED_MORE_DATA; - break; } @@ -2514,7 +2556,7 @@ if (*p_size < 1) { - GST_WARNING ("unexpected end of data"); + GST_WARNING ("unexpected end of data"); /* unexpected, why? */ @@ -2541,6 +2583,18 @@ packet_info.multiple = ((flags & 0x01) == 0x01); + needed = lengths[(flags >> 5) & 0x03] + + lengths[(flags >> 3) & 0x03] + + lengths[(flags >> 1) & 0x03]; packet_length = gst_asf_demux_get_var_length ((flags >> 5) & 0x03, p_data, p_size); @@ -2575,8 +2629,12 @@ /* Are there multiple payloads? */ if (packet_info.multiple) { - guint8 multi_flags = gst_asf_demux_get_uint8 (p_data, p_size); + guint8 multi_flags; + multi_flags = gst_asf_demux_get_uint8 (p_data, p_size); packet_info.segsizetype = (multi_flags >> 6) & 0x03; num_segments = multi_flags & 0x3f; |
From: <tp...@ke...> - 2007-02-01 11:12:42
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Thu Feb 01 2007 11:12:37 UTC Log message: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_sink_event): Post an error if we receive an EOS event while still waiting for the ASF header object to come through. Modified files: . : ChangeLog gst/asfdemux : gstasfdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2151&r2=1.2152 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.118&r2=1.119 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2151 retrieving revision 1.2152 diff -u -d -r1.2151 -r1.2152 --- ChangeLog 24 Jan 2007 17:36:35 -0000 1.2151 +++ ChangeLog 1 Feb 2007 11:12:25 -0000 1.2152 @@ -1,3 +1,9 @@ +2007-02-01 Tim-Philipp Müller <tim at centricular dot net> + + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_sink_event): + Post an error if we receive an EOS event while still waiting for the + ASF header object to come through. 2007-01-24 Tim-Philipp Müller <tim at centricular dot net> Patch by: Xavier B. <xavierb gmail com> Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.118 retrieving revision 1.119 diff -u -d -r1.118 -r1.119 --- gstasfdemux.c 24 Jan 2007 17:36:36 -0000 1.118 +++ gstasfdemux.c 1 Feb 2007 11:12:25 -0000 1.119 @@ -195,6 +195,12 @@ } case GST_EVENT_EOS:{ + if (demux->state == GST_ASF_DEMUX_STATE_HEADER) { + GST_ELEMENT_ERROR (demux, STREAM, DEMUX, + (_("This stream contains no data.")), + ("got eos and didn't receive a complete header object")); + break; + } GST_OBJECT_LOCK (demux); gst_adapter_clear (demux->adapter); demux->bytes_needed = 0; |
From: <tp...@ke...> - 2007-02-08 21:07:50
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Thu Feb 08 2007 21:07:39 UTC Log message: * gst/asfdemux/asfheaders.c: * gst/asfdemux/asfheaders.h: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_init), (gst_asf_demux_sink_event), (gst_asf_demux_handle_seek_event), (gst_asf_demux_identify_guid), (asf_demux_peek_object), (gst_asf_demux_chain_headers), (gst_asf_demux_chain), (gst_asf_demux_setup_pad), (gst_asf_demux_process_stream), (gst_asf_demux_process_ext_content_desc), (gst_asf_demux_get_object_header), (gst_asf_demux_process_header), (gst_asf_demux_process_file), (gst_asf_demux_process_comment), (gst_asf_demux_process_bitrate_props_object), (gst_asf_demux_process_header_ext), (gst_asf_demux_process_language_list), (gst_asf_demux_process_ext_stream_props), (gst_asf_demux_process_queued_extended_stream_objects), (gst_asf_demux_process_object), (gst_asf_demux_change_state): * gst/asfdemux/gstasfdemux.h: Refactor and clean up header parsing and chain function a bit; get rid of some cruft; make header parsing a tad more robust, fixing #403188. Modified files: . : ChangeLog gst/asfdemux : asfheaders.c asfheaders.h gstasfdemux.c gstasfdemux.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2152&r2=1.2153 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.c.diff?r1=1.5&r2=1.6 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.h.diff?r1=1.13&r2=1.14 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.119&r2=1.120 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h.diff?r1=1.24&r2=1.25 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2152 retrieving revision 1.2153 diff -u -d -r1.2152 -r1.2153 --- ChangeLog 1 Feb 2007 11:12:25 -0000 1.2152 +++ ChangeLog 8 Feb 2007 21:07:27 -0000 1.2153 @@ -1,3 +1,26 @@ +2007-02-08 Tim-Philipp Müller <tim at centricular dot net> + + * gst/asfdemux/asfheaders.c: + * gst/asfdemux/asfheaders.h: + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_init), + (gst_asf_demux_sink_event), (gst_asf_demux_handle_seek_event), + (gst_asf_demux_identify_guid), (asf_demux_peek_object), + (gst_asf_demux_chain_headers), (gst_asf_demux_chain), + (gst_asf_demux_setup_pad), (gst_asf_demux_process_stream), + (gst_asf_demux_process_ext_content_desc), + (gst_asf_demux_get_object_header), (gst_asf_demux_process_header), + (gst_asf_demux_process_file), (gst_asf_demux_process_comment), + (gst_asf_demux_process_bitrate_props_object), + (gst_asf_demux_process_header_ext), + (gst_asf_demux_process_language_list), + (gst_asf_demux_process_ext_stream_props), + (gst_asf_demux_process_queued_extended_stream_objects), + (gst_asf_demux_process_object), (gst_asf_demux_change_state): + * gst/asfdemux/gstasfdemux.h: + Refactor and clean up header parsing and chain function a bit; get + rid of some cruft; make header parsing a tad more robust, fixing + #403188. 2007-02-01 Tim-Philipp Müller <tim at centricular dot net> * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_sink_event): Index: asfheaders.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- asfheaders.c 28 Jul 2006 15:15:15 -0000 1.5 +++ asfheaders.c 8 Feb 2007 21:07:27 -0000 1.6 @@ -131,6 +131,9 @@ {ASF_OBJ_SCRIPT_COMMAND, "ASF_OBJ_SCRIPT_COMMAND", {0x1efb1a30, 0x11d00b62, 0xa0009ba3, 0xf64803c9} }, + {ASF_OBJ_MARKER, "ASF_OBJ_MARKER", + {0xf487cd01, 0x11cfa951, 0xc000e68e, 0x6553200c} + }, {ASF_OBJ_UNDEFINED, "ASF_OBJ_UNDEFINED", {0, 0, 0, 0} } Index: asfheaders.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.h,v retrieving revision 1.13 retrieving revision 1.14 diff -u -d -r1.13 -r1.14 --- asfheaders.h 28 Jul 2006 15:15:15 -0000 1.13 +++ asfheaders.h 8 Feb 2007 21:07:27 -0000 1.14 @@ -35,7 +35,7 @@ ASFGuid guid; } ASFGuidHash; -enum { +typedef enum { ASF_OBJ_UNDEFINED = 0, ASF_OBJ_STREAM, ASF_OBJ_DATA, @@ -63,8 +63,9 @@ ASF_OBJ_CONTENT_ENCRYPTION, ASF_OBJ_EXT_CONTENT_ENCRYPTION, ASF_OBJ_DIGITAL_SIGNATURE_OBJECT, - ASF_OBJ_SCRIPT_COMMAND -}; + ASF_OBJ_SCRIPT_COMMAND, + ASF_OBJ_MARKER +} AsfObjectID; enum { ASF_STREAM_UNDEFINED = 0, @@ -91,49 +92,6 @@ const gchar *gst_asf_get_guid_nick (const ASFGuidHash * guids, guint32 obj_id); - -struct _asf_obj_header { - guint32 num_objects; - guint8 unknown1; - guint8 unknown2; -typedef struct _asf_obj_header asf_obj_header; -struct _asf_obj_header_ext { - ASFGuid reserved1; - guint16 reserved2; - guint32 data_size; -typedef struct _asf_obj_header_ext asf_obj_header_ext; -struct _asf_obj_comment { - guint16 title_length; - guint16 author_length; - guint16 copyright_length; - guint16 description_length; - guint16 rating_length; -typedef struct _asf_obj_comment asf_obj_comment; -struct _asf_obj_file { - ASFGuid file_id; - guint64 file_size; - guint64 creation_time; - guint64 packets_count; - guint64 play_time; - guint64 send_time; - guint64 preroll; - guint32 flags; - guint32 min_pktsize; - guint32 max_pktsize; - guint32 min_bitrate; -typedef struct _asf_obj_file asf_obj_file; struct _asf_obj_ext_stream_properties { guint64 start_time; guint64 end_time; @@ -183,16 +141,6 @@ typedef struct _asf_stream_audio asf_stream_audio; -struct _asf_stream_correction { - guint8 span; - guint16 packet_size; - guint16 chunk_size; - guint16 data_size; - guint8 silence_data; -typedef struct _asf_stream_correction asf_stream_correction; struct _asf_stream_video { guint32 width; guint32 height; @@ -218,16 +166,6 @@ typedef struct _asf_stream_video_format asf_stream_video_format; -struct _asf_obj_data { - guint64 packets; - /* guint8 unknown2; FIXME: this object is supposed to be 26 bytes?! */ - guint8 correction; -typedef struct _asf_obj_data asf_obj_data; struct _asf_obj_data_correction { guint8 type; guint8 cycle; @@ -273,11 +211,4 @@ typedef struct _asf_replicated_data asf_replicated_data; -struct _asf_bitrate_record { - guint16 stream_id; - guint32 bitrate; -typedef struct _asf_bitrate_record asf_bitrate_record; #endif /* __ASFHEADERS_H__ */ Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.119 retrieving revision 1.120 diff -u -d -r1.119 -r1.120 --- gstasfdemux.c 1 Feb 2007 11:12:25 -0000 1.119 +++ gstasfdemux.c 8 Feb 2007 21:07:27 -0000 1.120 @@ -50,7 +50,10 @@ GST_PAD_SOMETIMES, GST_STATIC_CAPS_ANY); +/* size of an ASF object header, ie. GUID (16 bytes) + object size (8 bytes) */ +#define ASF_OBJECT_HEADER_SIZE (16+8) +/* FIXME: get rid of this */ /* abuse this GstFlowReturn enum for internal usage */ #define ASF_FLOW_NEED_MORE_DATA 99 @@ -69,11 +72,14 @@ [...1552 lines suppressed...] - break; - } - default: - g_return_val_if_reached (GST_FLOW_UNEXPECTED); - } - return ret; -} static const GstQueryType * gst_asf_demux_get_src_query_types (GstPad * pad) { @@ -2914,7 +2825,6 @@ case GST_STATE_CHANGE_READY_TO_PAUSED:{ gst_segment_init (&demux->segment, GST_FORMAT_TIME); demux->adapter = gst_adapter_new (); - demux->next_byte_offset = GST_BUFFER_OFFSET_NONE; break; } default: Index: gstasfdemux.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h,v retrieving revision 1.24 retrieving revision 1.25 diff -u -d -r1.24 -r1.25 --- gstasfdemux.h 15 Dec 2006 17:54:48 -0000 1.24 +++ gstasfdemux.h 8 Feb 2007 21:07:27 -0000 1.25 @@ -66,8 +66,7 @@ typedef enum { GST_ASF_DEMUX_STATE_HEADER, - GST_ASF_DEMUX_STATE_DATA, - GST_ASF_DEMUX_STATE_EOS + GST_ASF_DEMUX_STATE_DATA } GstAsfDemuxState; #define GST_ASF_DEMUX_NUM_VIDEO_PADS 16 @@ -84,13 +83,6 @@ GstTagList *taglist; GstAsfDemuxState state; - /* The number of bytes needed for the next parsing unit. Set by - * parsing functions when they return ASF_FLOW_NEED_MORE_DATA. - * if not set after an ASF_FLOW_NEED_MORE_DATA, this indicates - * that we are parsing broken data and want to parse beyond an - * object or packet boundary. */ - guint bytes_needed; guint64 data_offset; /* byte offset where packets start */ guint64 data_size; /* total size of packet data in bytes */ guint64 num_packets; /* total number of data packets */ @@ -118,12 +110,6 @@ gboolean seekable; - /* expected byte offset of next buffer to be received by chain - * function. Used to calculate the current byte offset into the - * file from the adapter state and the data parser state */ - gint64 next_byte_offset; - GstSegment segment; /* configured play segment */ /* Descrambler settings */ |
From: <tp...@ke...> - 2007-02-15 19:56:17
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Thu Feb 15 2007 19:56:07 UTC Log message: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_process_file), (gst_asf_demux_process_advanced_mutual_exclusion), (gst_asf_demux_process_queued_extended_stream_objects), (gst_asf_demux_process_object), (gst_asf_demux_change_state): * gst/asfdemux/gstasfdemux.h: Parse advanced mutual exclusion object and only add pads for 'hidden' streams (those in an extended stream header) that are mutually exclusive with an already existing 'main stream' if the broadcasting flag is not set. If the broadcasting flag is set, assume that data for this stream isn't sent. (This should ideally be solved better by making playbin more robust against this and/or by making mmssrc send some information downstream about which streams will be streamed). Fixes #353116. Modified files: . : ChangeLog gst/asfdemux : gstasfdemux.c gstasfdemux.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2161&r2=1.2162 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.120&r2=1.121 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h.diff?r1=1.25&r2=1.26 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2161 retrieving revision 1.2162 diff -u -d -r1.2161 -r1.2162 --- ChangeLog 13 Feb 2007 12:00:58 -0000 1.2161 +++ ChangeLog 15 Feb 2007 19:55:54 -0000 1.2162 @@ -1,3 +1,19 @@ +2007-02-15 Tim-Philipp Müller <tim at centricular dot net> + + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_process_file), + (gst_asf_demux_process_advanced_mutual_exclusion), + (gst_asf_demux_process_queued_extended_stream_objects), + (gst_asf_demux_process_object), (gst_asf_demux_change_state): + * gst/asfdemux/gstasfdemux.h: + Parse advanced mutual exclusion object and only add pads for + 'hidden' streams (those in an extended stream header) that are + mutually exclusive with an already existing 'main stream' if + the broadcasting flag is not set. If the broadcasting flag is set, + assume that data for this stream isn't sent. (This should ideally be + solved better by making playbin more robust against this and/or by + making mmssrc send some information downstream about which streams + will be streamed). Fixes #353116. 2007-02-13 Jan Schmidt <th...@ma...> * gst/synaesthesia/gstsynaesthesia.c: Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.120 retrieving revision 1.121 diff -u -d -r1.120 -r1.121 --- gstasfdemux.c 8 Feb 2007 21:07:27 -0000 1.120 +++ gstasfdemux.c 15 Feb 2007 19:55:55 -0000 1.121 @@ -1438,7 +1438,6 @@ guint64 file_size, creation_time, packets_count; guint64 play_time, send_time, preroll; guint32 flags, min_pktsize, max_pktsize, min_bitrate; - gboolean broadcast; if (size < (16 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + 4 + 4)) goto not_enough_data; @@ -1455,13 +1454,13 @@ max_pktsize = gst_asf_demux_get_uint32 (&data, &size); min_bitrate = gst_asf_demux_get_uint32 (&data, &size); - broadcast = !!(flags & 0x01); + demux->broadcast = !!(flags & 0x01); demux->seekable = !!(flags & 0x02); - GST_DEBUG_OBJECT (demux, "flags::broadcast = %d", broadcast); + GST_DEBUG_OBJECT (demux, "flags::broadcast = %d", demux->broadcast); GST_DEBUG_OBJECT (demux, "flags::seekable = %d", demux->seekable); - if (broadcast) { + if (demux->broadcast) { /* these fields are invalid if the broadcast flag is set */ play_time = 0; file_size = 0; @@ -1725,6 +1724,50 @@ } static GstFlowReturn +gst_asf_demux_process_advanced_mutual_exclusion (GstASFDemux * demux, + guint8 * data, guint64 size) +{ + ASFGuid guid; + guint16 num, i; + guint8 *mes; + if (size < 16 + 2 + (2 * 2)) + goto not_enough_data; + gst_asf_demux_get_guid (&guid, &data, &size); + num = gst_asf_demux_get_uint16 (&data, &size); + if (num < 2) { + GST_WARNING_OBJECT (demux, "nonsensical mutually exclusive streams count"); + return GST_FLOW_OK; + } + if (size < (num * sizeof (guint16))) + /* read mutually exclusive stream numbers */ + mes = g_new (guint8, num + 1); + for (i = 0; i < num; ++i) { + mes[i] = gst_asf_demux_get_uint16 (&data, &size) & 0x7f; + GST_LOG_OBJECT (demux, "mutually exclusive: stream #%d", mes[i]); + /* add terminator so we can easily get the count or know when to stop */ + mes[i] = (guint8) - 1; + demux->mut_ex_streams = g_slist_append (demux->mut_ex_streams, mes); + return GST_FLOW_OK; + /* Errors */ +not_enough_data: + { + GST_WARNING_OBJECT (demux, "short read parsing advanced mutual exclusion"); + return GST_FLOW_OK; /* not absolutely fatal */ +} +static GstFlowReturn gst_asf_demux_process_ext_stream_props (GstASFDemux * demux, guint8 * data, guint64 size) { @@ -1883,27 +1926,59 @@ static void gst_asf_demux_process_queued_extended_stream_objects (GstASFDemux * demux) - GSList *l; + GSList *l, *x; GST_DEBUG_OBJECT (demux, "parsing %d stream objects embedded in extended " "stream properties", g_slist_length (demux->ext_stream_props)); for (l = demux->ext_stream_props; l != NULL; l = l->next) { asf_obj_ext_stream_properties *esp; - guint64 len; - guint8 *data; + gboolean is_hidden = FALSE; + guint8 *mes, i; esp = (asf_obj_ext_stream_properties *) l->data; - data = esp->stream_obj_data; - len = esp->stream_obj_len; - GST_DEBUG ("Parsing stream data allocated at %p", data); + GST_DEBUG ("Parsing queued extended stream with ID %d", esp->stream_num); - if (data && gst_asf_demux_process_stream (demux, data, len) != GST_FLOW_OK) { - GST_WARNING_OBJECT (demux, - "failed to parse stream object in extended " - "stream properties object for stream %u", esp->stream_num); + for (x = demux->mut_ex_streams; x != NULL; x = x->next) { + /* check for each mutual exclusion whether it affects this stream */ + for (mes = (guint8 *) x->data; mes != NULL && *mes != 0xff; ++mes) { + if (*mes == esp->stream_num) { + /* if yes, check if we've already added streams that are mutually + * exclusive with the stream we're about to add */ + for (mes = (guint8 *) x->data; mes != NULL && *mes != 0xff; ++mes) { + for (i = 0; i < demux->num_streams; ++i) { + /* if the broadcast flag is set, assume the hidden streams aren't + * actually streamed and hide them (or playbin won't work right), + * otherwise assume their data is available */ + if (demux->stream[i].id == *mes && demux->broadcast) { + is_hidden = TRUE; + GST_LOG_OBJECT (demux, "broadcast stream ID %d to be added is " + "mutually exclusive with already existing stream ID %d, " + "hiding stream", esp->stream_num, demux->stream[i].id); + break; + } + } + } + break; + } + } } + if (!is_hidden && esp->stream_obj_data != NULL) { + guint64 len; + guint8 *data; + data = esp->stream_obj_data; + len = esp->stream_obj_len; + if (gst_asf_demux_process_stream (demux, data, len) != GST_FLOW_OK) { + GST_WARNING_OBJECT (demux, + "failed to parse stream object in extended " + "stream properties object for stream %u", esp->stream_num); + } g_free (esp->stream_obj_data); esp->stream_obj_data = NULL; esp->stream_obj_data = 0; @@ -1966,6 +2041,10 @@ case ASF_OBJ_LANGUAGE_LIST: ret = gst_asf_demux_process_language_list (demux, *p_data, obj_data_size); break; + case ASF_OBJ_ADVANCED_MUTUAL_EXCLUSION: + ret = gst_asf_demux_process_advanced_mutual_exclusion (demux, *p_data, + obj_data_size); + break; case ASF_OBJ_CONTENT_ENCRYPTION: case ASF_OBJ_EXT_CONTENT_ENCRYPTION: case ASF_OBJ_DIGITAL_SIGNATURE_OBJECT: @@ -1981,7 +2060,6 @@ case ASF_OBJ_COMPATIBILITY: case ASF_OBJ_INDEX_PLACEHOLDER: case ASF_OBJ_INDEX_PARAMETERS: - case ASF_OBJ_ADVANCED_MUTUAL_EXCLUSION: case ASF_OBJ_STREAM_PRIORITIZATION: case ASF_OBJ_SCRIPT_COMMAND: default: @@ -2853,6 +2931,8 @@ demux->num_languages = 0; g_slist_foreach (demux->ext_stream_props, (GFunc) g_free, NULL); g_slist_free (demux->ext_stream_props); + g_slist_foreach (demux->mut_ex_streams, (GFunc) g_free, NULL); + g_slist_free (demux->mut_ex_streams); demux->ext_stream_props = NULL; memset (demux->stream, 0, sizeof (demux->stream)); demux->seekable = FALSE; Index: gstasfdemux.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h,v retrieving revision 1.25 retrieving revision 1.26 diff -u -d -r1.25 -r1.26 --- gstasfdemux.h 8 Feb 2007 21:07:27 -0000 1.25 +++ gstasfdemux.h 15 Feb 2007 19:55:55 -0000 1.26 @@ -95,6 +95,7 @@ guint num_languages; GSList *ext_stream_props; + GSList *mut_ex_streams; /* mutually exclusive streams */ guint32 num_audio_streams; guint32 num_video_streams; @@ -109,6 +110,7 @@ guint64 pts; gboolean seekable; + gboolean broadcast; GstSegment segment; /* configured play segment */ |
From: <tp...@ke...> - 2007-03-10 15:56:42
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Sat Mar 10 2007 15:56:38 UTC Log message: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_process_header_ext): Printf format fix. Modified files: . : ChangeLog gst/asfdemux : gstasfdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2169&r2=1.2170 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.121&r2=1.122 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2169 retrieving revision 1.2170 diff -u -d -r1.2169 -r1.2170 --- ChangeLog 2 Mar 2007 13:01:48 -0000 1.2169 +++ ChangeLog 10 Mar 2007 15:56:26 -0000 1.2170 @@ -1,3 +1,8 @@ +2007-03-10 Tim-Philipp Müller <tim at centricular dot net> + + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_process_header_ext): + Printf format fix. 2007-03-02 Tim-Philipp Müller <tim at centricular dot net> Patch by: Zaheer Abbas Merali <zaheermerali at gmail com> Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.121 retrieving revision 1.122 diff -u -d -r1.121 -r1.122 --- gstasfdemux.c 15 Feb 2007 19:55:55 -0000 1.121 +++ gstasfdemux.c 10 Mar 2007 15:56:26 -0000 1.122 @@ -1646,7 +1646,7 @@ gst_asf_demux_skip_bytes (16 + 2, &data, &size); hdr_size = gst_asf_demux_get_uint32 (&data, &size); - GST_INFO ("object is an extended header with a size of %u bytes", size); + GST_INFO ("extended header object with a size of %u bytes", (guint) size); /* FIXME: does data_size include the rest of the header that we have read? */ if (hdr_size > size) |
From: <tp...@ke...> - 2007-04-12 13:38:21
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Thu Apr 12 2007 13:38:16 UTC Log message: * gst/asfdemux/asfheaders.c: * gst/asfdemux/asfheaders.h: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_free_stream), (gst_asf_demux_reset), (gst_asf_demux_init), (gst_asf_demux_activate), (gst_asf_demux_activate_push), (gst_asf_demux_activate_pull), (gst_asf_demux_sink_event), (gst_asf_demux_seek_index_lookup), (gst_asf_demux_reset_stream_state_after_discont), (gst_asf_demux_handle_seek_event), (gst_asf_demux_handle_src_event), (gst_asf_demux_chain_headers), (gst_asf_demux_chain), (gst_asf_demux_pull_data), (gst_asf_demux_pull_indices), (gst_asf_demux_parse_data_object_start), (gst_asf_demux_pull_headers), (gst_asf_demux_loop), (gst_asf_demux_setup_pad), (gst_asf_demux_process_file), (gst_asf_demux_process_simple_index), (gst_asf_demux_process_object), (gst_asf_demux_send_event_unlocked), (gst_asf_demux_push_buffer), (gst_asf_demux_handle_data), (gst_asf_demux_change_state): * gst/asfdemux/gstasfdemux.h: Make asfdemux work in pull mode where possible. If there's an index at the end of the file, read it and use it for seeking purposes. Modified files: . : ChangeLog gst/asfdemux : asfheaders.c asfheaders.h gstasfdemux.c gstasfdemux.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2180&r2=1.2181 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.c.diff?r1=1.6&r2=1.7 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.h.diff?r1=1.14&r2=1.15 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.122&r2=1.123 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h.diff?r1=1.26&r2=1.27 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2180 retrieving revision 1.2181 diff -u -d -r1.2180 -r1.2181 --- ChangeLog 12 Apr 2007 10:19:18 -0000 1.2180 +++ ChangeLog 12 Apr 2007 13:38:03 -0000 1.2181 @@ -1,3 +1,28 @@ +2007-04-12 Tim-Philipp Müller <tim at centricular dot net> + + * gst/asfdemux/asfheaders.c: + * gst/asfdemux/asfheaders.h: + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_free_stream), + (gst_asf_demux_reset), (gst_asf_demux_init), + (gst_asf_demux_activate), (gst_asf_demux_activate_push), + (gst_asf_demux_activate_pull), (gst_asf_demux_sink_event), + (gst_asf_demux_seek_index_lookup), + (gst_asf_demux_reset_stream_state_after_discont), + (gst_asf_demux_handle_seek_event), + (gst_asf_demux_handle_src_event), (gst_asf_demux_chain_headers), + (gst_asf_demux_chain), (gst_asf_demux_pull_data), + (gst_asf_demux_pull_indices), + (gst_asf_demux_parse_data_object_start), + (gst_asf_demux_pull_headers), (gst_asf_demux_loop), + (gst_asf_demux_setup_pad), (gst_asf_demux_process_file), + (gst_asf_demux_process_simple_index), + (gst_asf_demux_process_object), + (gst_asf_demux_send_event_unlocked), (gst_asf_demux_push_buffer), + (gst_asf_demux_handle_data), (gst_asf_demux_change_state): + * gst/asfdemux/gstasfdemux.h: + Make asfdemux work in pull mode where possible. If there's an index + at the end of the file, read it and use it for seeking purposes. 2007-04-12 Wim Taymans <wi...@fl...> * gst/synaesthesia/gstsynaesthesia.c: (gst_synaesthesia_init), Index: asfheaders.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- asfheaders.c 8 Feb 2007 21:07:27 -0000 1.6 +++ asfheaders.c 12 Apr 2007 13:38:03 -0000 1.7 @@ -74,9 +74,12 @@ {ASF_OBJ_CODEC_COMMENT1, "ASF_OBJ_CODEC_COMMENT1", {0x86d15241, 0x11d0311d, 0xA000A4a3, 0xF64803c9} }, - {ASF_OBJ_INDEX, "ASF_OBJ_INDEX", + {ASF_OBJ_SIMPLE_INDEX, "ASF_OBJ_SIMPLE_INDEX", {0x33000890, 0x11cfe5b1, 0xA000F489, 0xCB4903c9} + {ASF_OBJ_INDEX, "ASF_OBJ_INDEX", + {0xd6e229d3, 0x11d135da, 0xa0003490, 0xbe4903c9} + }, {ASF_OBJ_HEAD1, "ASF_OBJ_HEAD1", {0x5fbf03b5, 0x11cfa92e, 0xC000E38e, 0x6553200c} Index: asfheaders.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.h,v retrieving revision 1.14 retrieving revision 1.15 diff -u -d -r1.14 -r1.15 --- asfheaders.h 8 Feb 2007 21:07:27 -0000 1.14 +++ asfheaders.h 12 Apr 2007 13:38:03 -0000 1.15 @@ -45,6 +45,7 @@ ASF_OBJ_COMMENT, ASF_OBJ_CODEC_COMMENT, ASF_OBJ_CODEC_COMMENT1, + ASF_OBJ_SIMPLE_INDEX, ASF_OBJ_INDEX, ASF_OBJ_HEAD1, ASF_OBJ_HEAD2, Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.122 retrieving revision 1.123 diff -u -d -r1.122 -r1.123 --- gstasfdemux.c 10 Mar 2007 15:56:26 -0000 1.122 +++ gstasfdemux.c 12 Apr 2007 13:38:03 -0000 1.123 @@ -1,6 +1,6 @@ /* GStreamer ASF/WMV/WMA demuxer - * Copyright (C) <1999> Erik Walthinsen <om...@cs...> - * Copyright (C) <2006> Tim-Philipp Müller <tim centricular net> + * Copyright (C) 1999 Erik Walthinsen <om...@cs...> + * Copyright (C) 2006-2007 Tim-Philipp Müller <tim centricular net> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -18,6 +18,21 @@ * Boston, MA 02111-1307, USA. */ [...1098 lines suppressed...] - demux->state = GST_ASF_DEMUX_STATE_HEADER; - g_free (demux->objpath); - demux->objpath = NULL; - g_strfreev (demux->languages); - demux->languages = NULL; - demux->num_languages = 0; - g_slist_foreach (demux->ext_stream_props, (GFunc) g_free, NULL); - g_slist_free (demux->ext_stream_props); - g_slist_foreach (demux->mut_ex_streams, (GFunc) g_free, NULL); - g_slist_free (demux->mut_ex_streams); - demux->ext_stream_props = NULL; - memset (demux->stream, 0, sizeof (demux->stream)); - demux->seekable = FALSE; + case GST_STATE_CHANGE_PAUSED_TO_READY: + gst_asf_demux_reset (demux); break; - } default: } Index: gstasfdemux.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h,v retrieving revision 1.26 retrieving revision 1.27 diff -u -d -r1.26 -r1.27 --- gstasfdemux.h 15 Feb 2007 19:55:55 -0000 1.26 +++ gstasfdemux.h 12 Apr 2007 13:38:03 -0000 1.27 @@ -51,8 +51,6 @@ guint64 last_pts; GstBuffer *payload; - gboolean need_newsegment; /* do we need to send a new-segment event? */ - /* video-only */ guint64 last_buffer_timestamp; /* timestamp of last buffer sent out */ gboolean is_video; @@ -62,6 +60,8 @@ GstCaps *caps; GstTagList *pending_tags; + gboolean discont; } asf_stream_context; typedef enum { @@ -83,10 +83,11 @@ GstTagList *taglist; GstAsfDemuxState state; - guint64 data_offset; /* byte offset where packets start */ - guint64 data_size; /* total size of packet data in bytes */ - guint64 num_packets; /* total number of data packets */ - guint64 packet; /* current packet */ + guint64 index_offset; /* byte offset where index might be, or 0 */ + guint64 data_offset; /* byte offset where packets start */ + guint64 data_size; /* total size of packet data in bytes, or 0 */ + guint64 num_packets; /* total number of data packets, or 0 */ + guint64 packet; /* current packet */ /* bitrates are unused at the moment */ guint32 bitrate[GST_ASF_DEMUX_NUM_STREAM_IDS]; @@ -102,8 +103,8 @@ guint32 num_streams; asf_stream_context stream[GST_ASF_DEMUX_NUM_STREAMS]; - guint32 packet_size; /* -1 if not fixed or not known */ - guint32 timestamp; /* in milliseconds */ + guint32 packet_size; + guint32 timestamp; /* in milliseconds */ guint64 play_time; guint64 preroll; @@ -112,7 +113,11 @@ gboolean seekable; gboolean broadcast; - GstSegment segment; /* configured play segment */ + GstSegment segment; /* configured play segment */ + gboolean need_newsegment; /* do we need to send a new-segment event? */ + gboolean segment_running; /* if we've started the current segment */ + gboolean streaming; /* TRUE if we are operating chain-based */ /* Descrambler settings */ guint8 span; @@ -122,6 +127,11 @@ /* for debugging only */ gchar *objpath; + /* simple index, if available */ + GstClockTime sidx_interval; /* interval between entries in ns */ + guint sidx_num_entries; /* number of index entries */ + guint32 *sidx_entries; /* packet number for each entry */ }; struct _GstASFDemuxClass { |
From: <tp...@ke...> - 2007-04-17 10:22:09
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Tue Apr 17 2007 10:22:02 UTC Log message: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_handle_seek_event), (gst_asf_demux_pull_indices): Printf format fixes. Modified files: . : ChangeLog gst/asfdemux : gstasfdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2183&r2=1.2184 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.123&r2=1.124 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2183 retrieving revision 1.2184 diff -u -d -r1.2183 -r1.2184 --- ChangeLog 16 Apr 2007 16:30:50 -0000 1.2183 +++ ChangeLog 17 Apr 2007 10:21:50 -0000 1.2184 @@ -1,3 +1,9 @@ +2007-04-17 Tim-Philipp Müller <tim at centricular dot net> + + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_handle_seek_event), + (gst_asf_demux_pull_indices): + Printf format fixes. 2007-04-16 Tim-Philipp Müller <tim at centricular dot net> * gst/mpegstream/gstmpegparse.c: (gst_mpeg_parse_process_event), Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.123 retrieving revision 1.124 diff -u -d -r1.123 -r1.124 --- gstasfdemux.c 12 Apr 2007 13:38:03 -0000 1.123 +++ gstasfdemux.c 17 Apr 2007 10:21:50 -0000 1.124 @@ -456,7 +456,7 @@ packet = demux->num_packets; } - GST_DEBUG_OBJECT (demux, "seeking to packet %" G_GINT64_FORMAT, packet); + GST_DEBUG_OBJECT (demux, "seeking to packet %u", packet); GST_OBJECT_LOCK (demux); demux->segment = segment; @@ -773,7 +773,7 @@ break; GST_LOG_OBJECT (demux, "index object at offset 0x%" G_GINT64_MODIFIER "X" - ", size %u", offset, obj.size); + ", size %u", offset, (guint) obj.size); offset += obj.size; /* increase before _process_object changes it */ |
From: <tp...@ke...> - 2007-04-20 17:32:18
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Fri Apr 20 2007 17:32:12 UTC Log message: * gst/asfdemux/asfheaders.h: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_free_stream), (gst_asf_demux_seek_index_lookup), (gst_asf_demux_handle_seek_event), (gst_asf_demux_get_stream), (gst_asf_demux_setup_pad), (gst_asf_demux_add_video_stream), (gst_asf_demux_process_ext_content_desc), (gst_asf_demux_process_file), (gst_asf_demux_descramble_segment), (gst_asf_demux_push_buffer), (gst_asf_demux_process_chunk), (gst_asf_demux_process_segment), (gst_asf_demux_handle_data): * gst/asfdemux/gstasfdemux.h: Some clean-ups and small fixes: rename asf_stream_context structure to AsfStream; inline some three-line utility functions that are only used once anyway and get rid of their associated helper structs; make debug category global so that it is used by the debug statements in the other file as well; simplify gst_asf_demux_get_stream(); fix accidental implicit initialisation of stream->last_buffer_timestamp to 0, which would lead to missing timestamps on the first buffer; put fourcc format into video caps to make certain proprietary wmv decoders happy (for the case of WMVA in particular); play_time is offset by preroll as well, so fix overreporting of duration for some files. Modified files: . : ChangeLog gst/asfdemux : asfheaders.h gstasfdemux.c gstasfdemux.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2184&r2=1.2185 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.h.diff?r1=1.15&r2=1.16 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.124&r2=1.125 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h.diff?r1=1.27&r2=1.28 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2184 retrieving revision 1.2185 diff -u -d -r1.2184 -r1.2185 --- ChangeLog 17 Apr 2007 10:21:50 -0000 1.2184 +++ ChangeLog 20 Apr 2007 17:31:59 -0000 1.2185 @@ -1,3 +1,26 @@ +2007-04-20 Tim-Philipp Müller <tim at centricular dot net> + + * gst/asfdemux/asfheaders.h: + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_free_stream), + (gst_asf_demux_seek_index_lookup), + (gst_asf_demux_handle_seek_event), (gst_asf_demux_get_stream), + (gst_asf_demux_setup_pad), (gst_asf_demux_add_video_stream), + (gst_asf_demux_process_ext_content_desc), + (gst_asf_demux_process_file), (gst_asf_demux_descramble_segment), + (gst_asf_demux_push_buffer), (gst_asf_demux_process_chunk), + (gst_asf_demux_process_segment), (gst_asf_demux_handle_data): + * gst/asfdemux/gstasfdemux.h: + Some clean-ups and small fixes: rename asf_stream_context structure to + AsfStream; inline some three-line utility functions that are only used + once anyway and get rid of their associated helper structs; make debug + category global so that it is used by the debug statements in the other + file as well; simplify gst_asf_demux_get_stream(); fix accidental + implicit initialisation of stream->last_buffer_timestamp to 0, which + would lead to missing timestamps on the first buffer; put fourcc format + into video caps to make certain proprietary wmv decoders happy (for the + case of WMVA in particular); play_time is offset by preroll as well, so + fix overreporting of duration for some files. 2007-04-17 Tim-Philipp Müller <tim at centricular dot net> * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_handle_seek_event), Index: asfheaders.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.h,v retrieving revision 1.15 retrieving revision 1.16 diff -u -d -r1.15 -r1.16 --- asfheaders.h 12 Apr 2007 13:38:03 -0000 1.15 +++ asfheaders.h 20 Apr 2007 17:32:00 -0000 1.16 @@ -174,13 +174,6 @@ typedef struct _asf_obj_data_correction asf_obj_data_correction; -struct _asf_obj_data_packet { - guint8 flags; - guint8 property; -}; - -typedef struct _asf_obj_data_packet asf_obj_data_packet; struct _asf_packet_info { guint32 padsize; guint8 replicsizetype; @@ -205,11 +198,4 @@ typedef struct _asf_segment_info asf_segment_info; -struct _asf_replicated_data { - guint32 object_size; - guint32 frag_timestamp; -typedef struct _asf_replicated_data asf_replicated_data; #endif /* __ASFHEADERS_H__ */ Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.124 retrieving revision 1.125 diff -u -d -r1.124 -r1.125 --- gstasfdemux.c 17 Apr 2007 10:21:50 -0000 1.124 +++ gstasfdemux.c 20 Apr 2007 17:32:00 -0000 1.125 @@ -76,8 +76,7 @@ (flow == ASF_FLOW_NEED_MORE_DATA) ? \ "need-more-data" : gst_flow_get_name (flow) -GST_DEBUG_CATEGORY_STATIC (asf_debug); -#define GST_CAT_DEFAULT asf_debug +GST_DEBUG_CATEGORY (asf_debug); static GstStateChangeReturn gst_asf_demux_change_state (GstElement * element, GstStateChange transition); @@ -144,7 +143,7 @@ } static void -gst_asf_demux_free_stream (GstASFDemux * demux, asf_stream_context * stream) +gst_asf_demux_free_stream (GstASFDemux * demux, AsfStream * stream) { gst_buffer_replace (&stream->cache, NULL); gst_buffer_replace (&stream->payload, NULL); @@ -336,8 +335,9 @@ *packet = demux->sidx_entries[idx]; - GST_DEBUG_OBJECT (demux, "%" GST_TIME_FORMAT " => packet %u", - GST_TIME_ARGS (seek_time), *packet); + GST_DEBUG_OBJECT (demux, "%" GST_TIME_FORMAT " => packet %u at %" + GST_TIME_FORMAT, GST_TIME_ARGS (seek_time), *packet, + GST_TIME_ARGS (demux->sidx_interval * idx)); return TRUE; @@ -440,6 +440,8 @@ seek_time = segment.start; + /* FIXME: should check the KEY_UNIT flag; need to adjust last_stop to + * real start of data and segment_start to indexed time for key unit seek*/ if (!gst_asf_demux_seek_index_lookup (demux, &packet, seek_time)) { /* Hackety hack, this sucks. We just seek to an earlier position * and let the sinks throw away the stuff before the segment start */ @@ -1184,18 +1186,6 @@ static gboolean -gst_asf_demux_get_replicated_data (asf_replicated_data * rep, guint8 ** p_data, - guint64 * p_size) -{ - if (*p_size < (4 + 4)) - return FALSE; - rep->object_size = gst_asf_demux_get_uint32 (p_data, p_size); - rep->frag_timestamp = gst_asf_demux_get_uint32 (p_data, p_size); - return TRUE; -} -static gboolean gst_asf_demux_get_obj_data_correction (asf_obj_data_correction * object, guint8 ** p_data, guint64 * p_size) @@ -1261,23 +1251,17 @@ -static asf_stream_context * +AsfStream * gst_asf_demux_get_stream (GstASFDemux * demux, guint16 id) - guint8 i; - asf_stream_context *stream; + guint i; for (i = 0; i < demux->num_streams; i++) { - stream = &demux->stream[i]; - if (stream->id == id) { - /* We've found the one with the matching id */ + if (demux->stream[i].id == id) return &demux->stream[i]; - } } - /* Base case if we haven't found one at all */ GST_WARNING ("Segment found for undefined stream: (%d)", id); return NULL; @@ -1301,7 +1285,7 @@ gst_asf_demux_setup_pad (GstASFDemux * demux, GstPad * src_pad, GstCaps * caps, guint16 id, gboolean is_video, GstTagList * tags) + AsfStream *stream; gst_pad_use_fixed_caps (src_pad); gst_pad_set_caps (src_pad, caps); @@ -1322,6 +1306,7 @@ stream->delay = 0; stream->first_pts = GST_CLOCK_TIME_NONE; stream->last_pts = GST_CLOCK_TIME_NONE; + stream->last_buffer_timestamp = GST_CLOCK_TIME_NONE; stream->fps_known = !is_video; /* bit hacky for audio */ stream->is_video = is_video; stream->pending_tags = tags; @@ -1442,6 +1427,9 @@ GST_TYPE_FOURCC, video->tag, NULL); + /* add fourcc format to caps, some proprietary decoders seem to need it */ + gst_caps_set_simple (caps, "format", GST_TYPE_FOURCC, video->tag, NULL); if (codec_name) { tags = gst_tag_list_new (); gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC, @@ -1766,6 +1754,7 @@ } else { g_value_init (&tag_value, G_TYPE_STRING); g_value_set_string (&tag_value, value_utf8); + /* FIXME: convert to target value type if required */ } } else if (value_utf8 == NULL) { GST_WARNING ("Failed to convert string value to UTF8, skipping"); @@ -1893,7 +1882,10 @@ demux->packet_size = max_pktsize; /* FIXME: do we need send_time as well? what is it? */ - demux->play_time = (guint64) play_time *(GST_SECOND / 10000000); + if ((play_time * 100) >= (preroll * GST_MSECOND)) + demux->play_time = (play_time * 100) - (preroll * GST_MSECOND); + else + demux->play_time = 0; demux->preroll = preroll; @@ -1902,7 +1894,8 @@ GST_DEBUG_OBJECT (demux, "play_time %" GST_TIME_FORMAT " preroll %" GST_TIME_FORMAT, - GST_TIME_ARGS (demux->play_time), GST_TIME_ARGS (demux->preroll)); + GST_TIME_ARGS (demux->play_time), + GST_TIME_ARGS (demux->preroll * GST_MSECOND)); if (demux->play_time > 0) { gst_segment_set_duration (&demux->segment, GST_FORMAT_TIME, @@ -2556,7 +2549,7 @@ gst_asf_demux_descramble_segment (GstASFDemux * demux, - asf_segment_info * segment_info, asf_stream_context * stream) + asf_segment_info * segment_info, AsfStream * stream) GstBuffer *scrambled_buffer; GstBuffer *descrambled_buffer; @@ -2644,7 +2637,7 @@ static GstFlowReturn -gst_asf_demux_push_buffer (GstASFDemux * demux, asf_stream_context * stream, +gst_asf_demux_push_buffer (GstASFDemux * demux, AsfStream * stream, GstBuffer * buf) GstFlowReturn ret; @@ -2703,7 +2696,7 @@ GstFlowReturn ret = GST_FLOW_OK; GstBuffer *buffer; stream = gst_asf_demux_get_stream (demux, segment_info->stream_number); @@ -2931,7 +2924,7 @@ /* FIXME: check (doesn't work) */ #if 0 { - asf_stream_context *stream; + AsfStream *stream; stream = gst_asf_demux_get_stream (demux, segment_info.stream_number); if (stream && stream->last_pts == GST_CLOCK_TIME_NONE && @@ -2971,38 +2964,35 @@ segment_info.sequence, segment_info.frag_offset, replic_size); if (replic_size > 1) { - asf_replicated_data replicated_data_header; segment_info.compressed = FALSE; /* It's uncompressed with replic data */ - if (!gst_asf_demux_get_replicated_data (&replicated_data_header, p_data, - p_size)) - return ASF_FLOW_NEED_MORE_DATA; -/* { - GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), - ("The payload has replicated data but the size is less than 8")); - return GST_FLOW_ERROR; -*/ - segment_info.frag_timestamp = replicated_data_header.frag_timestamp; - segment_info.segment_size = replicated_data_header.object_size; + if (*p_size < (4 + 4)) + goto short_repdata; + segment_info.segment_size = gst_asf_demux_get_uint32 (p_data, p_size); + segment_info.frag_timestamp = gst_asf_demux_get_uint32 (p_data, p_size); + GST_LOG ("frag_timestamp: %" GST_TIME_FORMAT, + GST_TIME_ARGS (segment_info.frag_timestamp * GST_MSECOND)); if (replic_size > 8) { if (!gst_asf_demux_skip_bytes ((replic_size - 8), p_data, p_size)) return ASF_FLOW_NEED_MORE_DATA; } + } else if (replic_size == 1) { + /* It's compressed */ + segment_info.compressed = TRUE; + if (*p_size < 1) + return ASF_FLOW_NEED_MORE_DATA; + time_delta = gst_asf_demux_get_uint8 (p_data, p_size); + GST_DEBUG ("time_delta = %u", time_delta); + time_start = segment_info.frag_offset; + segment_info.frag_offset = 0; + segment_info.frag_timestamp = time_start; /* was: demux->timestamp */ } else { - if (replic_size == 1) { - /* It's compressed */ - segment_info.compressed = TRUE; - if (*p_size < 1) - return ASF_FLOW_NEED_MORE_DATA; - time_delta = gst_asf_demux_get_uint8 (p_data, p_size); - GST_DEBUG ("time_delta = %u", time_delta); - } else { - segment_info.compressed = FALSE; + segment_info.compressed = FALSE; time_start = segment_info.frag_offset; segment_info.frag_offset = 0; @@ -3073,6 +3063,20 @@ return ret; +/* ERRORS */ +short_repdata: + { + if (replic_size < 8) { + GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), + ("payload has replicated data, but size is less than 8")); + } else { + ("payload has %u bytes of replicated data, but size is only %u", + replic_size, (guint) * p_size)); + } + return GST_FLOW_ERROR; + } @@ -3168,6 +3172,7 @@ return ASF_FLOW_NEED_MORE_DATA; + /* FIXME: isn't this the send time, ie. not the presentation time? (tpm) */ demux->timestamp = gst_asf_demux_get_uint32 (p_data, p_size); duration = gst_asf_demux_get_uint16 (p_data, p_size); Index: gstasfdemux.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h,v retrieving revision 1.27 retrieving revision 1.28 diff -u -d -r1.27 -r1.28 --- gstasfdemux.h 12 Apr 2007 13:38:03 -0000 1.27 +++ gstasfdemux.h 20 Apr 2007 17:32:00 -0000 1.28 @@ -37,6 +37,9 @@ #define GST_IS_ASF_DEMUX_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ASF_DEMUX)) +GST_DEBUG_CATEGORY_EXTERN (asf_debug); +#define GST_CAT_DEFAULT asf_debug typedef struct _GstASFDemux GstASFDemux; typedef struct _GstASFDemuxClass GstASFDemuxClass; @@ -62,7 +65,7 @@ GstTagList *pending_tags; gboolean discont; -} asf_stream_context; +} AsfStream; typedef enum { GST_ASF_DEMUX_STATE_HEADER, @@ -101,7 +104,7 @@ guint32 num_audio_streams; guint32 num_video_streams; guint32 num_streams; - asf_stream_context stream[GST_ASF_DEMUX_NUM_STREAMS]; + AsfStream stream[GST_ASF_DEMUX_NUM_STREAMS]; guint32 packet_size; guint32 timestamp; /* in milliseconds */ |
From: <tp...@ke...> - 2007-04-20 20:58:16
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Fri Apr 20 2007 20:58:08 UTC Log message: * gst/asfdemux/Makefile.am: * gst/asfdemux/asfpacket.c: (asf_packet_read_varlen_int), (asf_packet_create_payload_buffer), (asf_payload_find_previous_fragment), (gst_asf_payload_queue_for_stream), (gst_asf_demux_parse_payload), (gst_asf_demux_parse_packet): * gst/asfdemux/asfpacket.h: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_reset_stream_state_after_discont), (gst_asf_demux_push_complete_payloads), (gst_asf_demux_loop), (gst_asf_demux_setup_pad), (gst_asf_demux_descramble_buffer), (gst_asf_demux_process_chunk): * gst/asfdemux/gstasfdemux.h: New packet parsing code: should put halfway decent timestamps on buffers, and might even set the appropriate keyframe/discont buffer flags from time to time (and even if it doesn't, I'm at least able to debug this code); only used in pull-mode so far. Still needs some more work, like payload extensions parsing and proper flow aggregation, and stream activation based on preroll. Stay tuned. Modified files: . : ChangeLog gst/asfdemux : Makefile.am gstasfdemux.c gstasfdemux.h Added files: gst/asfdemux : asfpacket.c asfpacket.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2185&r2=1.2186 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/Makefile.am.diff?r1=1.12&r2=1.13 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/asfpacket.c?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/asfpacket.h?rev=1.1&content-type=text/vnd.viewcvs-markup http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.125&r2=1.126 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h.diff?r1=1.28&r2=1.29 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2185 retrieving revision 1.2186 diff -u -d -r1.2185 -r1.2186 --- ChangeLog 20 Apr 2007 17:31:59 -0000 1.2185 +++ ChangeLog 20 Apr 2007 20:57:55 -0000 1.2186 @@ -1,5 +1,27 @@ 2007-04-20 Tim-Philipp Müller <tim at centricular dot net> + * gst/asfdemux/Makefile.am: + * gst/asfdemux/asfpacket.c: (asf_packet_read_varlen_int), + (asf_packet_create_payload_buffer), + (asf_payload_find_previous_fragment), + (gst_asf_payload_queue_for_stream), (gst_asf_demux_parse_payload), + (gst_asf_demux_parse_packet): + * gst/asfdemux/asfpacket.h: + * gst/asfdemux/gstasfdemux.c: + (gst_asf_demux_reset_stream_state_after_discont), + (gst_asf_demux_push_complete_payloads), (gst_asf_demux_loop), + (gst_asf_demux_setup_pad), (gst_asf_demux_descramble_buffer), + (gst_asf_demux_process_chunk): + * gst/asfdemux/gstasfdemux.h: + New packet parsing code: should put halfway decent timestamps on + buffers, and might even set the appropriate keyframe/discont buffer + flags from time to time (and even if it doesn't, I'm at least able + to debug this code); only used in pull-mode so far. Still needs + some more work, like payload extensions parsing and proper flow + aggregation, and stream activation based on preroll. Stay tuned. + +2007-04-20 Tim-Philipp Müller <tim at centricular dot net> + * gst/asfdemux/asfheaders.h: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_free_stream), (gst_asf_demux_seek_index_lookup), Index: Makefile.am RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/Makefile.am,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- Makefile.am 28 Jul 2006 15:15:15 -0000 1.12 +++ Makefile.am 20 Apr 2007 20:57:56 -0000 1.13 @@ -1,9 +1,9 @@ plugin_LTLIBRARIES = libgstasf.la -libgstasf_la_SOURCES = gstasfdemux.c gstasf.c asfheaders.c +libgstasf_la_SOURCES = gstasfdemux.c gstasf.c asfheaders.c asfpacket.c libgstasf_la_CFLAGS = $(GST_BASE_CFLAGS) $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) libgstasf_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) $(GST_BASE_LIBS) $(GST_LIBS)\ -lgstriff-@GST_MAJORMINOR@ libgstasf_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -noinst_HEADERS = gstasfdemux.h asfheaders.h gstasfmux.h +noinst_HEADERS = gstasfdemux.h asfheaders.h asfpacket.h gstasfmux.h --- NEW FILE: asfpacket.c --- /* GStreamer ASF/WMV/WMA demuxer * Copyright (C) 2007 Tim-Philipp Müller <tim centricular net> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * 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. */ /* FIXME: * file:///home/tpm/samples/video/asf//336370-regis-velo862.wmv * file:///home/tpm/samples/video/asf//336370-eichhoer.wmv * throw errors (not always necessarily) in this code path * (looks like they carry broken payloads/packets though) */ #include "asfpacket.h" #include <gst/gstutils.h> #include <gst/gstinfo.h> #include <string.h> /* we are unlikely to deal with lengths > 2GB here any time soon, so just * return a signed int and use that for error reporting */ static gint asf_packet_read_varlen_int (guint lentype_flags, guint lentype_bit_offset, const guint8 ** p_data, guint * p_size) { const guint lens[4] = { 0, 1, 2, 4 }; guint len, val; len = lens[(lentype_flags >> lentype_bit_offset) & 0x03]; /* will make caller bail out with a short read if there's not enough data */ if (*p_size < len) { GST_WARNING ("need %u bytes, but only %u bytes available", len, *p_size); return -1; } switch (len) { case 0: val = 0; break; case 1: val = GST_READ_UINT8 (*p_data); case 2: val = GST_READ_UINT16_LE (*p_data); case 4: val = GST_READ_UINT32_LE (*p_data); default: g_assert_not_reached (); *p_data += len; *p_size -= len; return (gint) val; } static GstBuffer * asf_packet_create_payload_buffer (AsfPacket * packet, const guint8 ** p_data, guint * p_size, guint payload_len) guint off; g_assert (payload_len <= *p_size); off = (guint) (*p_data - GST_BUFFER_DATA (packet->buf)); g_assert (off < GST_BUFFER_SIZE (packet->buf)); *p_data += payload_len; *p_size -= payload_len; return gst_buffer_create_sub (packet->buf, off, payload_len); static AsfPayload * asf_payload_find_previous_fragment (AsfPayload * payload, AsfStream * stream) AsfPayload *ret; if (stream->payloads->len == 0) { GST_DEBUG ("No previous fragments to merge with for stream %u", stream->id); return NULL; ret = &g_array_index (stream->payloads, AsfPayload, stream->payloads->len - 1); if (ret->mo_size != payload->mo_size || ret->mo_number != payload->mo_number || ret->mo_offset != 0) { GST_WARNING ("Previous fragment does not match continued fragment"); #if 0 if (this_fragment->mo_offset + this_payload_len > first_fragment->mo_size) { GST_WARNING ("Merged fragments would be bigger than the media object"); return FALSE; #endif return ret; static void gst_asf_payload_queue_for_stream (GstASFDemux * demux, AsfPayload * payload, AsfStream * stream) /* remove any incomplete payloads that will never be completed */ while (stream->payloads->len > 0) { AsfPayload *prev; guint idx_last; idx_last = stream->payloads->len - 1; prev = &g_array_index (stream->payloads, AsfPayload, idx_last); if (gst_asf_payload_is_complete (prev)) GST_DEBUG_OBJECT (demux, "Dropping incomplete fragmented media object " "queued for stream %u", stream->id); gst_buffer_replace (&prev->buf, NULL); g_array_remove_index (stream->payloads, idx_last); /* there's data missing, so there's a discontinuity now */ GST_BUFFER_FLAG_SET (payload->buf, GST_BUFFER_FLAG_DISCONT); g_array_append_vals (stream->payloads, payload, 1); static gboolean gst_asf_demux_parse_payload (GstASFDemux * demux, AsfPacket * packet, gint lentype, const guint8 ** p_data, guint * p_size) AsfPayload payload = { 0, }; AsfStream *stream; gboolean is_compressed; guint payload_len; guint stream_num; if (*p_size < 1) { GST_WARNING_OBJECT (demux, "Short packet!"); stream_num = GST_READ_UINT8 (*p_data) & 0x7f; payload.keyframe = ((GST_READ_UINT8 (*p_data) & 0x80) != 0); *p_data += 1; *p_size -= 1; payload.mo_number = asf_packet_read_varlen_int (packet->prop_flags, 4, p_data, p_size); payload.mo_offset = asf_packet_read_varlen_int (packet->prop_flags, 2, p_data, p_size); payload.rep_data_len = asf_packet_read_varlen_int (packet->prop_flags, 0, p_data, p_size); is_compressed = (payload.rep_data_len == 1); GST_LOG_OBJECT (demux, "payload for stream %u", stream_num); GST_LOG_OBJECT (demux, "keyframe : %s", (payload.keyframe) ? "yes" : "no"); GST_LOG_OBJECT (demux, "compressed : %s", (is_compressed) ? "yes" : "no"); if (*p_size < payload.rep_data_len) { GST_WARNING_OBJECT (demux, "Short packet! rep_data_len=%u, size=%u", payload.rep_data_len, *p_size); memcpy (payload.rep_data, *p_data, MIN (sizeof (payload.rep_data), payload.rep_data_len)); *p_data += payload.rep_data_len; *p_size -= payload.rep_data_len; if (*p_size == 0) { GST_WARNING_OBJECT (demux, "payload without data!?"); /* we use -1 as lentype for a single payload that's the size of the packet */ if (lentype >= 0 && lentype <= 3) { payload_len = asf_packet_read_varlen_int (lentype, 0, p_data, p_size); if (*p_size < payload_len) { GST_WARNING_OBJECT (demux, "Short packet! payload_len=%u, size=%u", payload_len, *p_size); return FALSE; } } else { payload_len = *p_size; GST_LOG_OBJECT (demux, "payload length: %u", payload_len); stream = gst_asf_demux_get_stream (demux, stream_num); if (stream == NULL) { GST_WARNING_OBJECT (demux, "Payload for unknown stream %u, skipping", stream_num); *p_data += payload_len; *p_size -= payload_len; return TRUE; if (!is_compressed) { GstClockTime ts = GST_CLOCK_TIME_NONE; GST_LOG_OBJECT (demux, "replicated data length: %u", payload.rep_data_len); if (payload.rep_data_len >= 8) { payload.mo_size = GST_READ_UINT32_LE (payload.rep_data); ts = GST_READ_UINT32_LE (payload.rep_data + 4) * GST_MSECOND; ts -= demux->preroll * GST_MSECOND; GST_LOG_OBJECT (demux, "media object size : %u", payload.mo_size); GST_LOG_OBJECT (demux, "media object ts : %" GST_TIME_FORMAT, GST_TIME_ARGS (ts)); /* TODO: parse payload extensions, if there are any */ } else if (payload.rep_data_len != 0) { GST_WARNING_OBJECT (demux, "invalid replicated data length, very bad"); GST_LOG_OBJECT (demux, "media object offset : %u", payload.mo_offset); GST_LOG_OBJECT (demux, "payload length: %u", payload_len); if ((stream = gst_asf_demux_get_stream (demux, stream_num))) { payload.buf = asf_packet_create_payload_buffer (packet, p_data, p_size, payload_len); /* n-th fragment of a fragmented media object? */ if (payload.mo_offset != 0) { AsfPayload *prev; if ((prev = asf_payload_find_previous_fragment (&payload, stream))) { if (payload.mo_offset != GST_BUFFER_SIZE (prev->buf)) { GST_WARNING_OBJECT (demux, "Offset doesn't match previous data?!"); } /* note: buffer join/merge might not preserve buffer flags */ prev->buf = gst_buffer_join (prev->buf, payload.buf); GST_LOG_OBJECT (demux, "Merged fragments, merged size: %u", GST_BUFFER_SIZE (prev->buf)); } else { gst_buffer_unref (payload.buf); } payload.buf = NULL; } else { GST_BUFFER_TIMESTAMP (payload.buf) = ts; gst_asf_payload_queue_for_stream (demux, &payload, stream); } const guint8 *payload_data; GstClockTime ts, ts_delta; guint num; GST_LOG_OBJECT (demux, "Compressed payload, length=%u", payload_len); payload_data = *p_data; ts = (payload.mo_offset - demux->preroll) * GST_MSECOND; ts_delta = payload.rep_data[0] * GST_MSECOND; for (num = 0; payload_len > 0; ++num) { guint sub_payload_len; sub_payload_len = GST_READ_UINT8 (payload_data); GST_LOG_OBJECT (demux, "subpayload #%u: len=%u, ts=%" GST_TIME_FORMAT, num, sub_payload_len, GST_TIME_ARGS (ts)); ++payload_data; --payload_len; if (payload_len < sub_payload_len) { GST_WARNING_OBJECT (demux, "Short payload! %u bytes left", payload_len); return FALSE; payload.buf = asf_packet_create_payload_buffer (packet, &payload_data, &payload_len, sub_payload_len); GST_BUFFER_TIMESTAMP (payload.buf) = ts; GST_BUFFER_DURATION (payload.buf) = ts_delta; gst_asf_payload_queue_for_stream (demux, &payload, stream); ts += ts_delta; return TRUE; gboolean gst_asf_demux_parse_packet (GstASFDemux * demux, GstBuffer * buf) AsfPacket packet = { 0, }; const guint8 *data; gboolean has_multiple_payloads; gboolean ret = TRUE; guint8 ec_flags, flags1; guint size; data = GST_BUFFER_DATA (buf); size = GST_BUFFER_SIZE (buf); /* need at least two payload flag bytes, send time, and duration */ if (size < 2 + 4 + 2) goto short_packet; packet.buf = buf; ec_flags = GST_READ_UINT8 (data); /* skip optional error correction stuff */ if ((ec_flags & 0x80) != 0) { guint ec_len_type, ec_len; ec_len_type = (ec_flags & 0x60) >> 5; if (ec_len_type == 0) { ec_len = ec_flags & 0x0f; } else { GST_WARNING_OBJECT (demux, "unexpected error correction length type %u", ec_len_type); ec_len = 2; GST_LOG ("packet has error correction (%u bytes)", ec_len); /* still need at least two payload flag bytes, send time, and duration */ if (size <= (1 + ec_len) + 2 + 4 + 2) goto short_packet; data += 1 + ec_len; size -= 1 + ec_len; /* parse payload info */ flags1 = GST_READ_UINT8 (data); packet.prop_flags = GST_READ_UINT8 (data + 1); data += 2; size -= 2; has_multiple_payloads = (flags1 & 0x01) != 0; packet.length = asf_packet_read_varlen_int (flags1, 5, &data, &size); packet.sequence = asf_packet_read_varlen_int (flags1, 1, &data, &size); packet.padding = asf_packet_read_varlen_int (flags1, 3, &data, &size); if (size < 6) packet.send_time = GST_READ_UINT32_LE (data) * GST_MSECOND; packet.duration = GST_READ_UINT16_LE (data + 4) * GST_MSECOND; data += 4 + 2; size -= 4 + 2; GST_LOG_OBJECT (demux, "multiple payloads: %u", has_multiple_payloads); GST_LOG_OBJECT (demux, "packet length : %u", packet.length); GST_LOG_OBJECT (demux, "sequence : %u", packet.sequence); GST_LOG_OBJECT (demux, "padding : %u", packet.padding); GST_LOG_OBJECT (demux, "send time : %" GST_TIME_FORMAT, GST_TIME_ARGS (packet.send_time)); GST_LOG_OBJECT (demux, "duration : %" GST_TIME_FORMAT, GST_TIME_ARGS (packet.duration)); if (packet.padding == (guint) - 1 || size < packet.padding) size -= packet.padding; if (has_multiple_payloads) { guint i, num, lentype; if (size < 1) num = (GST_READ_UINT8 (data) & 0x3F) >> 0; lentype = (GST_READ_UINT8 (data) & 0xC0) >> 6; ++data; --size; GST_LOG_OBJECT (demux, "num payloads : %u", num); for (i = 0; i < num; ++i) { GST_LOG_OBJECT (demux, "Parsing payload %u/%u", i + 1, num); ret = gst_asf_demux_parse_payload (demux, &packet, lentype, &data, &size); if (!ret) { GST_WARNING_OBJECT (demux, "Failed to parse payload %u/%u", i + 1, num); break; GST_LOG_OBJECT (demux, "Parsing single payload"); ret = gst_asf_demux_parse_payload (demux, &packet, -1, &data, &size); /* ERRORS */ short_packet: { --- NEW FILE: asfpacket.h --- #ifndef __ASF_PACKET_H__ #define __ASF_PACKET_H__ #include <gst/gstbuffer.h> #include <gst/gstclock.h> #include "gstasfdemux.h" G_BEGIN_DECLS typedef struct { gboolean keyframe; /* buffer flags might not survive merge.. */ guint mo_number; /* media object number (unused) */ guint mo_offset; /* offset (timestamp for compressed data) */ guint mo_size; /* size of media-object-to-be, or 0 */ guint rep_data_len; /* should never be more than 256, since */ guint8 rep_data[256]; /* the length should be stored in a byte */ /* GstClockTime duration; */ /* TODO:get from payload extension system */ GstBuffer *buf; } AsfPayload; guint length; /* packet length (unused) */ guint padding; /* length of padding at end of packet */ guint sequence; /* sequence (unused) */ GstClockTime send_time; GstClockTime duration; guint8 prop_flags; /* payload length types */ } AsfPacket; gboolean gst_asf_demux_parse_packet (GstASFDemux * demux, GstBuffer * buf); #define gst_asf_payload_is_complete(payload) \ (GST_BUFFER_SIZE ((payload)->buf) >= (payload)->mo_size) G_END_DECLS #endif /* __ASF_PACKET_H__ */ Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.125 retrieving revision 1.126 diff -u -d -r1.125 -r1.126 --- gstasfdemux.c 20 Apr 2007 17:32:00 -0000 1.125 +++ gstasfdemux.c 20 Apr 2007 20:57:56 -0000 1.126 @@ -45,6 +45,7 @@ #include "gstasfdemux.h" #include "asfheaders.h" +#include "asfpacket.h" static GstStaticPadTemplate gst_asf_demux_sink_template = GST_STATIC_PAD_TEMPLATE ("sink", @@ -103,6 +104,8 @@ static void gst_asf_demux_reset_stream_state_after_discont (GstASFDemux * asf); static gboolean gst_asf_demux_parse_data_object_start (GstASFDemux * demux, guint8 * data); +static void gst_asf_demux_descramble_buffer (GstASFDemux * demux, + AsfStream * stream, GstBuffer ** p_buffer); GST_BOILERPLATE (GstASFDemux, gst_asf_demux, GstElement, GST_TYPE_ELEMENT); @@ -358,6 +361,17 @@ demux->stream[n].last_buffer_timestamp = GST_CLOCK_TIME_NONE; demux->stream[n].sequence = 0; demux->stream[n].discont = TRUE; + demux->stream[n].last_flow = GST_FLOW_OK; + while (demux->stream[n].payloads->len > 0) { + AsfPayload *payload; + guint last; + last = demux->stream[n].payloads->len - 1; + payload = &g_array_index (demux->stream[n].payloads, AsfPayload, last); + gst_buffer_replace (&payload->buf, NULL); + g_array_remove_index (demux->stream[n].payloads, last); + } } } @@ -911,6 +925,61 @@ static void +gst_asf_demux_push_complete_payloads (GstASFDemux * demux) +{ + guint i; + for (i = 0; i < demux->num_streams; ++i) { + AsfStream *stream; + stream = &demux->stream[i]; + while (stream->payloads->len > 0) { + payload = &g_array_index (stream->payloads, AsfPayload, 0); + if (!gst_asf_payload_is_complete (payload)) + break; + /* We have the whole packet now so we should push the packet to + * the src pad now. First though we should check if we need to do + * descrambling */ + if (demux->span > 1) { + gst_asf_demux_descramble_buffer (demux, stream, &payload->buf); + } + payload->buf = gst_buffer_make_metadata_writable (payload->buf); + if (!payload->keyframe) { + GST_BUFFER_FLAG_SET (payload->buf, GST_BUFFER_FLAG_DELTA_UNIT); + if (stream->discont) { + GST_BUFFER_FLAG_SET (payload->buf, GST_BUFFER_FLAG_DISCONT); + stream->discont = FALSE; + gst_buffer_set_caps (payload->buf, stream->caps); + /* FIXME: we should really set durations on buffers if we can */ + /* (this is a hack, obviously) + if (strncmp (GST_PAD_NAME (stream->pad), "video", 5) == 0 && + !GST_BUFFER_DURATION_IS_VALID (payload->buf)) { + GST_BUFFER_DURATION (payload->buf) = GST_SECOND / 30; + } + */ + GST_LOG_OBJECT (stream->pad, "pushing buffer, ts=%" GST_TIME_FORMAT + ", size=%u", GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (payload->buf)), + GST_BUFFER_SIZE (payload->buf)); + stream->last_flow = gst_pad_push (stream->pad, payload->buf); + payload->buf = NULL; + g_array_remove_index (stream->payloads, 0); + } +} +static void gst_asf_demux_loop (GstASFDemux * demux) { GstFlowReturn flow; @@ -944,12 +1013,44 @@ goto read_failed; - /* - flow = gst_asf_demux_parse_packet (demux, buf); - gst_buffer_unref (buf); - */ + if (demux->need_newsegment) { + if (demux->segment.stop == GST_CLOCK_TIME_NONE) + demux->segment.stop = demux->segment.duration; + GST_DEBUG_OBJECT (demux, "sending new-segment event %" GST_SEGMENT_FORMAT, + &demux->segment); + /* FIXME: check last parameter, streams may have non-zero start */ + gst_asf_demux_send_event_unlocked (demux, + gst_event_new_new_segment (FALSE, demux->segment.rate, + GST_FORMAT_TIME, demux->segment.start, demux->segment.stop, + demux->segment.start)); + demux->need_newsegment = FALSE; + demux->segment_running = TRUE; + /* FIXME: maybe we should just skip broken packets and error out only + * after a few broken packets in a row? */ + if (!gst_asf_demux_parse_packet (demux, buf)) { + GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), + ("Error parsing ASF packet %u", (guint) demux->packet)); + flow = GST_FLOW_ERROR; + gst_buffer_unref (buf); + gst_asf_demux_push_complete_payloads (demux); + ++demux->packet; + if (demux->num_packets > 0 && demux->packet >= demux->num_packets) { + GST_LOG_OBJECT (demux, "reached EOS"); + goto eos; + /* FIXME: aggregate flow returns from the various streams */ - flow = gst_asf_demux_chain (demux->sinkpad, buf); if (flow != GST_FLOW_OK) goto pause; @@ -1312,6 +1413,9 @@ stream->pending_tags = tags; stream->discont = TRUE; + stream->payloads = g_array_new (FALSE, FALSE, sizeof (AsfPayload)); gst_pad_set_element_private (src_pad, stream); GST_INFO ("Adding pad %s for stream %u with caps %" GST_PTR_FORMAT, @@ -2548,11 +2652,11 @@ -gst_asf_demux_descramble_segment (GstASFDemux * demux, - asf_segment_info * segment_info, AsfStream * stream) +gst_asf_demux_descramble_buffer (GstASFDemux * demux, AsfStream * stream, + GstBuffer ** p_buffer) - GstBuffer *scrambled_buffer; GstBuffer *descrambled_buffer; + GstBuffer *scrambled_buffer; GstBuffer *sub_buffer; guint offset; guint off; @@ -2562,12 +2666,12 @@ /* descrambled_buffer is initialised in the first iteration */ descrambled_buffer = NULL; - scrambled_buffer = stream->payload; + scrambled_buffer = *p_buffer; - if (segment_info->segment_size < demux->ds_packet_size * demux->span) + if (GST_BUFFER_SIZE (scrambled_buffer) < demux->ds_packet_size * demux->span) return; - for (offset = 0; offset < segment_info->segment_size; + for (offset = 0; offset < GST_BUFFER_SIZE (scrambled_buffer); offset += demux->ds_chunk_size) { off = offset / demux->ds_chunk_size; row = off / demux->span; @@ -2575,8 +2679,8 @@ idx = row + col * demux->ds_packet_size / demux->ds_chunk_size; GST_DEBUG ("idx=%u, row=%u, col=%u, off=%u, ds_chunk_size=%u", idx, row, col, off, demux->ds_chunk_size); - GST_DEBUG ("segment_info->segment_size=%u, span=%u, packet_size=%u", - segment_info->segment_size, demux->span, demux->ds_packet_size); + GST_DEBUG ("scrambled buffer size=%u, span=%u, packet_size=%u", + GST_BUFFER_SIZE (scrambled_buffer), demux->span, demux->ds_packet_size); GST_DEBUG ("GST_BUFFER_SIZE (scrambled_buffer) = %u", GST_BUFFER_SIZE (scrambled_buffer)); sub_buffer = @@ -2585,17 +2689,15 @@ if (!offset) { descrambled_buffer = sub_buffer; } else { - GstBuffer *newbuf; - - newbuf = gst_buffer_merge (descrambled_buffer, sub_buffer); - gst_buffer_unref (sub_buffer); - gst_buffer_unref (descrambled_buffer); - descrambled_buffer = newbuf; + descrambled_buffer = gst_buffer_join (descrambled_buffer, sub_buffer); } - stream->payload = descrambled_buffer; + gst_buffer_stamp (descrambled_buffer, scrambled_buffer); + /* FIXME/CHECK: do we need to transfer buffer flags here too? */ gst_buffer_unref (scrambled_buffer); + *p_buffer = descrambled_buffer; @@ -2811,15 +2913,15 @@ the src pad now. First though we should check if we need to do descrambling */ if (demux->span > 1) { - gst_asf_demux_descramble_segment (demux, segment_info, stream); + gst_asf_demux_descramble_buffer (demux, stream, &stream->payload); if (stream->is_video) { GST_DEBUG ("%s: demux->pts=%lld=%" GST_TIME_FORMAT ", stream->last_pts=%lld=%" GST_TIME_FORMAT, GST_PAD_NAME (stream->pad), demux->pts, - GST_TIME_ARGS ((GST_SECOND / 1000) * demux->pts), stream->last_pts, - GST_TIME_ARGS ((GST_SECOND / 1000) * stream->last_pts)); + GST_TIME_ARGS (GST_MSECOND * demux->pts), stream->last_pts, + GST_TIME_ARGS (GST_MSECOND * stream->last_pts)); /* FIXME: last_pts is not a GstClockTime and not in nanoseconds, so @@ -2829,11 +2931,11 @@ stream->last_pts = demux->pts; - GST_BUFFER_TIMESTAMP (stream->payload) = - (GST_SECOND / 1000) * stream->last_pts; + GST_BUFFER_TIMESTAMP (stream->payload) = GST_MSECOND * stream->last_pts; - GST_DEBUG ("sending stream %d of size %d", stream->id, - segment_info->chunk_size); + GST_DEBUG ("sending stream %d of size %d, ts=%" GST_TIME_FORMAT, + stream->id, segment_info->chunk_size, + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (stream->payload))); if (!stream->fps_known) { if (!stream->cache) { Index: gstasfdemux.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h,v retrieving revision 1.28 retrieving revision 1.29 diff -u -d -r1.28 -r1.29 --- gstasfdemux.h 20 Apr 2007 17:32:00 -0000 1.28 +++ gstasfdemux.h 20 Apr 2007 20:57:56 -0000 1.29 @@ -65,6 +65,11 @@ GstTagList *pending_tags; gboolean discont; + /* for new parsing code */ + GstFlowReturn last_flow; /* last flow return */ + GArray *payloads; /* pending payloads */ } AsfStream; typedef enum { @@ -141,7 +146,9 @@ GstElementClass parent_class; }; -GType gst_asf_demux_get_type (void); +GType gst_asf_demux_get_type (void); +AsfStream * gst_asf_demux_get_stream (GstASFDemux * demux, guint16 id); G_END_DECLS |
From: <tp...@ke...> - 2007-04-27 18:39:47
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Fri Apr 27 2007 18:39:33 UTC Log message: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_pull_data), (gst_asf_demux_push_complete_payloads), (gst_asf_demux_loop): Fix silly bug when we can't pull as much data as we want; don't forget to announce pending tags in the new packet parsing code. Modified files: . : ChangeLog gst/asfdemux : gstasfdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2188&r2=1.2189 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.126&r2=1.127 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2188 retrieving revision 1.2189 diff -u -d -r1.2188 -r1.2189 --- ChangeLog 25 Apr 2007 17:23:33 -0000 1.2188 +++ ChangeLog 27 Apr 2007 18:39:21 -0000 1.2189 @@ -1,3 +1,10 @@ +2007-04-27 Tim-Philipp Müller <tim at centricular dot net> + + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_pull_data), + (gst_asf_demux_push_complete_payloads), (gst_asf_demux_loop): + Fix silly bug when we can't pull as much data as we want; don't + forget to announce pending tags in the new packet parsing code. 2007-04-25 Tim-Philipp Müller <tim at centricular dot net> * configure.ac: Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.126 retrieving revision 1.127 diff -u -d -r1.126 -r1.127 --- gstasfdemux.c 20 Apr 2007 20:57:56 -0000 1.126 +++ gstasfdemux.c 27 Apr 2007 18:39:21 -0000 1.127 @@ -749,7 +749,7 @@ GST_DEBUG_OBJECT (demux, "short read pulling buffer at %" G_GUINT64_FORMAT "+%u (got only %u bytes)", offset, size, GST_BUFFER_SIZE (*p_buf)); gst_buffer_unref (*p_buf); - if (*p_flow) + if (p_flow) *p_flow = GST_FLOW_UNEXPECTED; *p_buf = NULL; return FALSE; @@ -940,6 +940,14 @@ if (!gst_asf_payload_is_complete (payload)) break; + /* Do we have tags pending for this stream? */ + if (stream->pending_tags) { + GST_LOG_OBJECT (stream->pad, "%" GST_PTR_FORMAT, stream->pending_tags); + gst_element_found_tags_for_pad (GST_ELEMENT (demux), stream->pad, + stream->pending_tags); + stream->pending_tags = NULL; + } /* We have the whole packet now so we should push the packet to * the src pad now. First though we should check if we need to do * descrambling */ @@ -1093,6 +1101,7 @@ { /* upstream should already have posted an error */ GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("pull_range failed")); + gst_asf_demux_send_event_unlocked (demux, gst_event_new_eos ()); goto pause; } } |
From: <tp...@ke...> - 2007-04-28 10:49:36
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Sat Apr 28 2007 10:49:29 UTC Log message: * gst/asfdemux/gstasf.c: (plugin_init): * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_base_init): * gst/asfdemux/gstasfdemux.h: Init debug category before using it. Modified files: . : ChangeLog gst/asfdemux : gstasf.c gstasfdemux.c gstasfdemux.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2189&r2=1.2190 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasf.c.diff?r1=1.8&r2=1.9 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.127&r2=1.128 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h.diff?r1=1.29&r2=1.30 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2189 retrieving revision 1.2190 diff -u -d -r1.2189 -r1.2190 --- ChangeLog 27 Apr 2007 18:39:21 -0000 1.2189 +++ ChangeLog 28 Apr 2007 10:49:16 -0000 1.2190 @@ -1,3 +1,10 @@ +2007-04-28 Tim-Philipp Müller <tim at centricular dot net> + + * gst/asfdemux/gstasf.c: (plugin_init): + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_base_init): + * gst/asfdemux/gstasfdemux.h: + Init debug category before using it. 2007-04-27 Tim-Philipp Müller <tim at centricular dot net> * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_pull_data), Index: gstasf.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasf.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- gstasf.c 29 Jul 2006 11:20:30 -0000 1.8 +++ gstasf.c 28 Apr 2007 10:49:17 -0000 1.9 @@ -31,6 +31,8 @@ static gboolean plugin_init (GstPlugin * plugin) { + GST_DEBUG_CATEGORY_INIT (asfdemux_dbg, "asfdemux", 0, "asf demuxer element"); #ifdef ENABLE_NLS GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE, LOCALEDIR); Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.127 retrieving revision 1.128 diff -u -d -r1.127 -r1.128 --- gstasfdemux.c 27 Apr 2007 18:39:21 -0000 1.127 +++ gstasfdemux.c 28 Apr 2007 10:49:17 -0000 1.128 @@ -77,7 +77,7 @@ (flow == ASF_FLOW_NEED_MORE_DATA) ? \ "need-more-data" : gst_flow_get_name (flow) -GST_DEBUG_CATEGORY (asf_debug); +GST_DEBUG_CATEGORY (asfdemux_dbg); static GstStateChangeReturn gst_asf_demux_change_state (GstElement * element, GstStateChange transition); @@ -128,8 +128,6 @@ gst_static_pad_template_get (&gst_asf_demux_sink_template)); gst_element_class_set_details (element_class, &gst_asf_demux_details); - - GST_DEBUG_CATEGORY_INIT (asf_debug, "asfdemux", 0, "asf demuxer element"); } static void Index: gstasfdemux.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h,v retrieving revision 1.29 retrieving revision 1.30 diff -u -d -r1.29 -r1.30 --- gstasfdemux.h 20 Apr 2007 20:57:56 -0000 1.29 +++ gstasfdemux.h 28 Apr 2007 10:49:17 -0000 1.30 @@ -37,8 +37,8 @@ #define GST_IS_ASF_DEMUX_CLASS(klass) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ASF_DEMUX)) -GST_DEBUG_CATEGORY_EXTERN (asf_debug); -#define GST_CAT_DEFAULT asf_debug +GST_DEBUG_CATEGORY_EXTERN (asfdemux_dbg); +#define GST_CAT_DEFAULT asfdemux_dbg typedef struct _GstASFDemux GstASFDemux; typedef struct _GstASFDemuxClass GstASFDemuxClass; |
From: <tp...@ke...> - 2007-04-30 11:41:44
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Mon Apr 30 2007 11:41:34 UTC Log message: * gst/asfdemux/asfheaders.h: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_free_stream), (gst_asf_demux_reset), (gst_asf_demux_parse_data_object_start), (gst_asf_demux_loop), (gst_asf_demux_setup_pad), (gst_asf_demux_add_audio_stream), (gst_asf_demux_activate_stream), (gst_asf_demux_parse_stream_object), (gst_asf_demux_process_ext_stream_props), (gst_asf_demux_process_queued_extended_stream_objects), (gst_asf_demux_activate_ext_props_streams), (gst_asf_demux_process_object): * gst/asfdemux/gstasfdemux.h: Refactor stream parse/activation a bit (stream activation heuristics are still the same though); some more clean-ups. Modified files: . : ChangeLog gst/asfdemux : asfheaders.h gstasfdemux.c gstasfdemux.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2191&r2=1.2192 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.h.diff?r1=1.16&r2=1.17 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.128&r2=1.129 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h.diff?r1=1.30&r2=1.31 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2191 retrieving revision 1.2192 diff -u -d -r1.2191 -r1.2192 --- ChangeLog 28 Apr 2007 12:23:16 -0000 1.2191 +++ ChangeLog 30 Apr 2007 11:41:22 -0000 1.2192 @@ -1,3 +1,19 @@ +2007-04-30 Tim-Philipp Müller <tim at centricular dot net> + + * gst/asfdemux/asfheaders.h: + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_free_stream), + (gst_asf_demux_reset), (gst_asf_demux_parse_data_object_start), + (gst_asf_demux_loop), (gst_asf_demux_setup_pad), + (gst_asf_demux_add_audio_stream), (gst_asf_demux_activate_stream), + (gst_asf_demux_parse_stream_object), + (gst_asf_demux_process_ext_stream_props), + (gst_asf_demux_process_queued_extended_stream_objects), + (gst_asf_demux_activate_ext_props_streams), + (gst_asf_demux_process_object): + * gst/asfdemux/gstasfdemux.h: + Refactor stream parse/activation a bit (stream activation heuristics + are still the same though); some more clean-ups. 2007-04-28 Tim-Philipp Müller <tim at centricular dot net> * win32/common/.cvsignore: Index: asfheaders.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.h,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- asfheaders.h 20 Apr 2007 17:32:00 -0000 1.16 +++ asfheaders.h 30 Apr 2007 11:41:22 -0000 1.17 @@ -20,6 +20,8 @@ #ifndef __ASFHEADERS_H__ #define __ASFHEADERS_H__ +G_BEGIN_DECLS typedef struct { guint32 v1; guint32 v2; @@ -68,17 +70,17 @@ ASF_OBJ_MARKER } AsfObjectID; -enum { +typedef enum { ASF_STREAM_UNDEFINED = 0, ASF_STREAM_VIDEO, ASF_STREAM_AUDIO -}; +} AsfStreamType; ASF_CORRECTION_UNDEFINED = 0, ASF_CORRECTION_ON, ASF_CORRECTION_OFF +} AsfCorrectionType; extern const ASFGuidHash asf_correction_guids[]; @@ -93,43 +95,6 @@ const gchar *gst_asf_get_guid_nick (const ASFGuidHash * guids, guint32 obj_id); -struct _asf_obj_ext_stream_properties { - guint64 start_time; - guint64 end_time; - guint64 avg_time_per_frame; - guint32 data_bitrate; - guint32 buffer_size; - guint32 intial_buf_fullness; - guint32 data_bitrate2; - guint32 buffer_size2; - guint32 intial_buf_fullness2; - guint32 max_obj_size; - guint32 flags; - guint16 stream_num; - guint16 lang_idx; - /* missing: stream names */ - /* missing: payload extension system stuff */ - - /* for delayed processing of these stream objects */ - guint8 *stream_obj_data; - guint64 stream_obj_len; -typedef struct _asf_obj_ext_stream_properties asf_obj_ext_stream_properties; -struct _asf_obj_stream { - ASFGuid type; - ASFGuid correction; - guint64 time_offset; - guint32 type_specific_size; - guint32 stream_specific_size; - guint8 id; - guint8 encrypted; - guint32 unknown2; -typedef struct _asf_obj_stream asf_obj_stream; struct _asf_stream_audio { guint16 codec_tag; guint16 channels; @@ -198,4 +163,6 @@ typedef struct _asf_segment_info asf_segment_info; +G_END_DECLS #endif /* __ASFHEADERS_H__ */ Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.128 retrieving revision 1.129 diff -u -d -r1.128 -r1.129 --- gstasfdemux.c 28 Apr 2007 10:49:17 -0000 1.128 +++ gstasfdemux.c 30 Apr 2007 11:41:22 -0000 1.129 @@ -97,6 +97,7 @@ static void gst_asf_demux_loop (GstASFDemux * demux); static void gst_asf_demux_process_queued_extended_stream_objects (GstASFDemux * demux); +static void gst_asf_demux_activate_ext_props_streams (GstASFDemux * demux); static gboolean gst_asf_demux_pull_headers (GstASFDemux * demux); static void gst_asf_demux_pull_indices (GstASFDemux * demux); static GstFlowReturn gst_asf_demux_handle_data (GstASFDemux * demux, @@ -154,7 +155,10 @@ stream->pending_tags = NULL; } if (stream->pad) { - gst_element_remove_pad (GST_ELEMENT_CAST (demux), stream->pad); + if (stream->active) + gst_element_remove_pad (GST_ELEMENT_CAST (demux), stream->pad); + else + gst_object_unref (stream->pad); stream->pad = NULL; } @@ -181,7 +185,8 @@ g_strfreev (demux->languages); demux->languages = NULL; demux->num_languages = 0; - g_slist_foreach (demux->ext_stream_props, (GFunc) g_free, NULL); + g_slist_foreach (demux->ext_stream_props, (GFunc) gst_mini_object_unref, + NULL); g_slist_free (demux->ext_stream_props); demux->ext_stream_props = NULL; while (demux->num_streams > 0) { @@ -844,6 +849,7 @@ /* process pending stream objects and create pads for those */ gst_asf_demux_process_queued_extended_stream_objects (demux); + gst_asf_demux_activate_ext_props_streams (demux); gst_element_no_more_pads (GST_ELEMENT (demux)); GST_INFO_OBJECT (demux, "Stream has %" G_GUINT64_FORMAT " packets, " @@ -1038,11 +1044,8 @@ /* FIXME: maybe we should just skip broken packets and error out only * after a few broken packets in a row? */ - if (!gst_asf_demux_parse_packet (demux, buf)) { - GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), - ("Error parsing ASF packet %u", (guint) demux->packet)); - flow = GST_FLOW_ERROR; - } + if (!gst_asf_demux_parse_packet (demux, buf)) + goto parse_error; gst_buffer_unref (buf); @@ -1102,6 +1105,14 @@ gst_asf_demux_send_event_unlocked (demux, gst_event_new_eos ()); goto pause; +parse_error: + { + gst_buffer_unref (buf); + GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), + ("Error parsing ASF packet %u", (guint) demux->packet)); + gst_asf_demux_send_event_unlocked (demux, gst_event_new_eos ()); + goto pause; + } static inline gboolean @@ -1272,28 +1283,6 @@ static gboolean -gst_asf_demux_get_obj_stream (asf_obj_stream * stream, guint8 ** p_data, - guint64 * p_size) -{ - guint16 flags; - if (*p_size < (16 + 16 + 8 + 4 + 4 + 2 + 4)) - return FALSE; - gst_asf_demux_get_guid (&stream->type, p_data, p_size); - gst_asf_demux_get_guid (&stream->correction, p_data, p_size); - stream->time_offset = gst_asf_demux_get_uint64 (p_data, p_size) * 100; - stream->type_specific_size = gst_asf_demux_get_uint32 (p_data, p_size); - stream->stream_specific_size = gst_asf_demux_get_uint32 (p_data, p_size); - flags = gst_asf_demux_get_uint16 (p_data, p_size); - stream->id = flags & 0x7f; - stream->encrypted = (flags & 0x8000) << 15; - stream->unknown2 = gst_asf_demux_get_uint32 (p_data, p_size); - return TRUE; -} -static gboolean gst_asf_demux_get_obj_data_correction (asf_obj_data_correction * object, guint8 ** p_data, guint64 * p_size) { @@ -1373,22 +1362,6 @@ return NULL; -static asf_obj_ext_stream_properties * -gst_asf_demux_get_ext_stream_props_for_stream (GstASFDemux * demux, gint id) - GSList *l; - for (l = demux->ext_stream_props; l != NULL; l = l->next) { - asf_obj_ext_stream_properties *esp; - esp = (asf_obj_ext_stream_properties *) l->data; - if (esp->stream_num == id) - return esp; - return NULL; gst_asf_demux_setup_pad (GstASFDemux * demux, GstPad * src_pad, GstCaps * caps, guint16 id, gboolean is_video, GstTagList * tags) @@ -1422,22 +1395,18 @@ stream->payloads = g_array_new (FALSE, FALSE, sizeof (AsfPayload)); - gst_pad_set_element_private (src_pad, stream); - GST_INFO ("Adding pad %s for stream %u with caps %" GST_PTR_FORMAT, + GST_INFO ("Created pad %s for stream %u with caps %" GST_PTR_FORMAT, GST_PAD_NAME (src_pad), demux->num_streams, caps); ++demux->num_streams; - gst_pad_set_active (src_pad, TRUE); - gst_element_add_pad (GST_ELEMENT (demux), src_pad); + stream->active = FALSE; gst_asf_demux_add_audio_stream (GstASFDemux * demux, asf_stream_audio * audio, guint16 id, guint8 ** p_data, guint64 * p_size) - asf_obj_ext_stream_properties *ext_props; GstTagList *tags = NULL; GstBuffer *extradata = NULL; GstPad *src_pad; @@ -1482,20 +1451,12 @@ g_free (codec_name); - /* add language info if we have it */ - ext_props = gst_asf_demux_get_ext_stream_props_for_stream (demux, id); - if (ext_props && ext_props->lang_idx < demux->num_languages) { - if (tags == NULL) - tags = gst_tag_list_new (); - gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_LANGUAGE_CODE, - demux->languages[ext_props->lang_idx], NULL); if (extradata) gst_buffer_unref (extradata); - GST_INFO ("Adding audio stream %u codec %u (0x%04x), tags=%" GST_PTR_FORMAT, - demux->num_video_streams, audio->codec_tag, audio->codec_tag, tags); + GST_INFO ("Adding audio stream #%u, id %u codec %u (0x%04x), tags=%" + GST_PTR_FORMAT, demux->num_audio_streams, id, audio->codec_tag, + audio->codec_tag, tags); ++demux->num_audio_streams; @@ -1561,25 +1522,57 @@ gst_asf_demux_setup_pad (demux, src_pad, caps, id, TRUE, tags); -static GstFlowReturn -gst_asf_demux_process_stream (GstASFDemux * demux, guint8 * data, guint64 size) +static void +gst_asf_demux_activate_stream (GstASFDemux * demux, AsfStream * stream) - asf_obj_stream object; - guint32 stream_id; - guint32 correction; + if (!stream->active) { + GST_INFO_OBJECT (demux, "Activating stream %2u, pad %s, caps %" + GST_PTR_FORMAT, stream->id, GST_PAD_NAME (stream->pad), stream->caps); + gst_pad_set_active (stream->pad, TRUE); + gst_element_add_pad (GST_ELEMENT_CAST (demux), stream->pad); + stream->active = TRUE; +} +static AsfStream * +gst_asf_demux_parse_stream_object (GstASFDemux * demux, guint8 * data, + guint64 size) +{ + AsfCorrectionType correction_type; + AsfStreamType stream_type; + GstClockTime time_offset; + gboolean is_encrypted; + guint16 stream_id; + guint16 flags; + ASFGuid guid; + guint stream_specific_size; + guint type_specific_size; + guint unknown; /* Get the rest of the header's header */ - if (!gst_asf_demux_get_obj_stream (&object, &data, &size)) + if (size < (16 + 16 + 8 + 4 + 4 + 2 + 4)) goto not_enough_data; - GST_DEBUG ("Found stream #%u", object.id); + gst_asf_demux_get_guid (&guid, &data, &size); + stream_type = gst_asf_demux_identify_guid (asf_stream_guids, &guid); - /* Identify the stream type */ - stream_id = gst_asf_demux_identify_guid (asf_stream_guids, &object.type); - correction = - gst_asf_demux_identify_guid (asf_correction_guids, &object.correction); + correction_type = gst_asf_demux_identify_guid (asf_correction_guids, &guid); - switch (stream_id) { + time_offset = gst_asf_demux_get_uint64 (&data, &size) * 100; + type_specific_size = gst_asf_demux_get_uint32 (&data, &size); + stream_specific_size = gst_asf_demux_get_uint32 (&data, &size); + flags = gst_asf_demux_get_uint16 (&data, &size); + stream_id = flags & 0x7f; + is_encrypted = !!((flags & 0x8000) << 15); + unknown = gst_asf_demux_get_uint32 (&data, &size); + GST_DEBUG_OBJECT (demux, "Found stream %u, time_offset=%" GST_TIME_FORMAT, + stream_id, GST_TIME_ARGS (time_offset)); + switch (stream_type) { case ASF_STREAM_AUDIO:{ asf_stream_audio audio_object; @@ -1589,10 +1582,10 @@ GST_INFO ("Object is an audio stream with %u bytes of additional data", audio_object.size); - gst_asf_demux_add_audio_stream (demux, &audio_object, object.id, + gst_asf_demux_add_audio_stream (demux, &audio_object, stream_id, &data, &size); - switch (correction) { + switch (correction_type) { case ASF_CORRECTION_ON:{ guint span, packet_size, chunk_size, data_size, silence_data; @@ -1642,22 +1635,16 @@ #endif break; } - case ASF_CORRECTION_OFF: + case ASF_CORRECTION_OFF:{ GST_INFO ("Error correction off"); -#if 0 - /* gst_bytestream_flush (demux->bs, object.stream_specific_size); */ -#else - /* FIXME: CHECKME */ - if (!gst_asf_demux_skip_bytes (object.stream_specific_size, - &data, &size)) { + if (!gst_asf_demux_skip_bytes (stream_specific_size, &data, &size)) goto not_enough_data; - } -#endif + } default: GST_ELEMENT_ERROR (demux, STREAM, DEMUX, (NULL), ("Audio stream using unknown error correction")); - return GST_FLOW_ERROR; + return NULL; } break; @@ -1681,25 +1668,25 @@ goto not_enough_data; - gst_asf_demux_add_video_stream (demux, &video_format_object, object.id, + gst_asf_demux_add_video_stream (demux, &video_format_object, stream_id, } default: - GST_WARNING_OBJECT (demux, "Unknown asf stream (id %08x)", - (guint) stream_id); + GST_WARNING_OBJECT (demux, "Unknown stream type for stream %u", + stream_id); - return GST_FLOW_OK; + return gst_asf_demux_get_stream (demux, stream_id); not_enough_data: { GST_WARNING_OBJECT (demux, "Unexpected end of data parsing stream object"); - /* pretend it's ok, we'll error out later if we found no streams */ - return GST_FLOW_OK; + /* we'll error out later if we found no streams */ + return NULL; @@ -2338,20 +2325,23 @@ gst_asf_demux_process_ext_stream_props (GstASFDemux * demux, guint8 * data, guint64 size) + AsfStreamExtProps esp; + AsfStream *stream = NULL; AsfObject stream_obj; - asf_obj_ext_stream_properties esp = { 0, }; guint16 stream_name_count; guint16 payload_ext_sys_count; guint64 len; + guint8 *stream_obj_data = NULL; guint8 *data_start = data; guint obj_size = (guint) size; - guint i; + guint i, stream_num; - if (size < 8 + 8 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 4 + 2 + 2 + 8 + 2 + 2) /* 64 */ + if (size < 64) - esp.start_time = gst_asf_demux_get_uint64 (&data, &size); - esp.end_time = gst_asf_demux_get_uint64 (&data, &size); + esp.valid = TRUE; + esp.start_time = gst_asf_demux_get_uint64 (&data, &size) * GST_MSECOND; + esp.end_time = gst_asf_demux_get_uint64 (&data, &size) * GST_MSECOND; esp.data_bitrate = gst_asf_demux_get_uint32 (&data, &size); esp.buffer_size = gst_asf_demux_get_uint32 (&data, &size); esp.intial_buf_fullness = gst_asf_demux_get_uint32 (&data, &size); @@ -2360,20 +2350,20 @@ esp.intial_buf_fullness2 = gst_asf_demux_get_uint32 (&data, &size); esp.max_obj_size = gst_asf_demux_get_uint32 (&data, &size); esp.flags = gst_asf_demux_get_uint32 (&data, &size); - esp.stream_num = gst_asf_demux_get_uint16 (&data, &size); + stream_num = gst_asf_demux_get_uint16 (&data, &size); esp.lang_idx = gst_asf_demux_get_uint16 (&data, &size); - esp.avg_time_per_frame = gst_asf_demux_get_uint64 (&data, &size); + esp.avg_time_per_frame = gst_asf_demux_get_uint64 (&data, &size) * 100; stream_name_count = gst_asf_demux_get_uint16 (&data, &size); payload_ext_sys_count = gst_asf_demux_get_uint16 (&data, &size); GST_INFO ("start_time = %" GST_TIME_FORMAT, - GST_TIME_ARGS (esp.start_time * GST_MSECOND)); + GST_TIME_ARGS (esp.start_time)); GST_INFO ("end_time = %" GST_TIME_FORMAT, - GST_TIME_ARGS (esp.end_time * GST_MSECOND)); + GST_TIME_ARGS (esp.end_time)); GST_INFO ("flags = %08x", esp.flags); GST_INFO ("average time per frame = %" GST_TIME_FORMAT, - GST_TIME_ARGS (esp.avg_time_per_frame * 100)); - GST_INFO ("stream number = %u", esp.stream_num); + GST_TIME_ARGS (esp.avg_time_per_frame)); + GST_INFO ("stream number = %u", stream_num); GST_INFO ("stream language ID idx = %u (%s)", esp.lang_idx, (esp.lang_idx < demux->num_languages) ? GST_STR_NULL (demux->languages[esp.lang_idx]) : "??"); @@ -2408,9 +2398,13 @@ GST_LOG ("bytes read: %u/%u", (guint) (data - data_start), obj_size); - /* there might be an optional STREAM_INFO object here now */ - if (size == 0) + /* there might be an optional STREAM_INFO object here now; if not, we + * should have parsed the corresponding stream info object already (since + * we are parsing the extended stream properties objects delayed) */ + if (size == 0) { + stream = gst_asf_demux_get_stream (demux, stream_num); goto done; /* get size of the stream object */ if (!asf_demux_peek_object (demux, data, size, &stream_obj)) @@ -2428,15 +2422,31 @@ /* process this stream object later after all the other 'normal' ones * have been processed (since the others are more important/non-hidden) */ len = stream_obj.size - ASF_OBJECT_HEADER_SIZE; - if (!gst_asf_demux_get_bytes (&esp.stream_obj_data, len, &data, &size)) + if (!gst_asf_demux_get_bytes (&stream_obj_data, len, &data, &size)) - esp.stream_obj_len = len; + /* parse stream object */ + stream = gst_asf_demux_parse_stream_object (demux, stream_obj_data, len); + g_free (stream_obj_data); done: - demux->ext_stream_props = g_slist_append (demux->ext_stream_props, - g_memdup (&esp, sizeof (esp))); + if (stream) { + stream->ext_props = esp; + /* add language info now if we have it */ + if (stream->ext_props.lang_idx < demux->num_languages) { + if (stream->pending_tags == NULL) + stream->pending_tags = gst_tag_list_new (); + GST_LOG_OBJECT (demux, "stream %u has language '%s'", stream->id, + demux->languages[stream->ext_props.lang_idx]); + gst_tag_list_add (stream->pending_tags, GST_TAG_MERGE_APPEND, + GST_TAG_LANGUAGE_CODE, demux->languages[stream->ext_props.lang_idx], + NULL); + } + } else { + GST_WARNING_OBJECT (demux, "Ext. stream properties for unknown stream"); return GST_FLOW_OK; @@ -2493,37 +2503,66 @@ gst_asf_demux_process_queued_extended_stream_objects (GstASFDemux * demux) - GSList *l, *x; + GSList *l; + guint i; - GST_DEBUG_OBJECT (demux, "parsing %d stream objects embedded in extended " - "stream properties", g_slist_length (demux->ext_stream_props)); + /* Parse the queued extended stream property objects and add the info + * to the existing streams or add the new embedded streams, but without + * activating them yet */ + GST_LOG_OBJECT (demux, "%u queued extended stream properties objects", + g_slist_length (demux->ext_stream_props)); - gboolean is_hidden = FALSE; - guint8 *mes, i; + for (l = demux->ext_stream_props, i = 0; l != NULL; l = l->next, ++i) { + GstBuffer *buf = GST_BUFFER (l->data); + GST_LOG_OBJECT (demux, "parsing ext. stream properties object #%u", i); + gst_asf_demux_process_ext_stream_props (demux, GST_BUFFER_DATA (buf), + GST_BUFFER_SIZE (buf)); + g_slist_free (demux->ext_stream_props); + demux->ext_stream_props = NULL; - GST_DEBUG ("Parsing queued extended stream with ID %d", esp->stream_num); +gst_asf_demux_activate_ext_props_streams (GstASFDemux * demux) + guint i, j; + for (i = 0; i < demux->num_streams; ++i) { + AsfStream *stream; + gboolean is_hidden; + GSList *x; + stream = &demux->stream[i]; + GST_LOG_OBJECT (demux, "checking stream %2u", stream->id); + if (stream->active) { + GST_LOG_OBJECT (demux, "stream %2u is already activated", stream->id); + continue; + is_hidden = FALSE; for (x = demux->mut_ex_streams; x != NULL; x = x->next) { + guint8 *mes; /* check for each mutual exclusion whether it affects this stream */ for (mes = (guint8 *) x->data; mes != NULL && *mes != 0xff; ++mes) { - if (*mes == esp->stream_num) { + if (*mes == stream->id) { /* if yes, check if we've already added streams that are mutually * exclusive with the stream we're about to add */ for (mes = (guint8 *) x->data; mes != NULL && *mes != 0xff; ++mes) { - for (i = 0; i < demux->num_streams; ++i) { + for (j = 0; j < demux->num_streams; ++j) { /* if the broadcast flag is set, assume the hidden streams aren't * actually streamed and hide them (or playbin won't work right), * otherwise assume their data is available */ - if (demux->stream[i].id == *mes && demux->broadcast) { + if (demux->stream[j].id == *mes && demux->broadcast) { is_hidden = TRUE; GST_LOG_OBJECT (demux, "broadcast stream ID %d to be added is " "mutually exclusive with already existing stream ID %d, " - "hiding stream", esp->stream_num, demux->stream[i].id); - break; + "hiding stream", stream->id, demux->stream[j].id); + goto next; } } } @@ -2532,23 +2571,11 @@ - if (!is_hidden && esp->stream_obj_data != NULL) { - guint64 len; - guint8 *data; - data = esp->stream_obj_data; - len = esp->stream_obj_len; - if (gst_asf_demux_process_stream (demux, data, len) != GST_FLOW_OK) { - GST_WARNING_OBJECT (demux, - "failed to parse stream object in extended " - "stream properties object for stream %u", esp->stream_num); - } - } + next: - g_free (esp->stream_obj_data); - esp->stream_obj_data = NULL; - esp->stream_obj_data = 0; + /* FIXME: we should do stream activation based on preroll data */ + if (!is_hidden) + gst_asf_demux_activate_stream (demux, stream); @@ -2576,9 +2603,16 @@ GST_INFO ("%s: size %" G_GUINT64_FORMAT, demux->objpath, obj.size); switch (obj.id) { - case ASF_OBJ_STREAM: - ret = gst_asf_demux_process_stream (demux, *p_data, obj_data_size); + case ASF_OBJ_STREAM:{ + AsfStream *stream; + stream = + gst_asf_demux_parse_stream_object (demux, *p_data, obj_data_size); + if (stream) + gst_asf_demux_activate_stream (demux, stream); + ret = GST_FLOW_OK; case ASF_OBJ_FILE: ret = gst_asf_demux_process_file (demux, *p_data, obj_data_size); @@ -2601,11 +2635,18 @@ gst_asf_demux_process_ext_content_desc (demux, *p_data, obj_data_size); - case ASF_OBJ_EXTENDED_STREAM_PROPS: - ret = - gst_asf_demux_process_ext_stream_props (demux, *p_data, - obj_data_size); + case ASF_OBJ_EXTENDED_STREAM_PROPS:{ + GstBuffer *buf; + /* process these later, we might not have parsed the corresponding + * stream object yet */ + GST_LOG ("%s: queued for later parsing", demux->objpath); + buf = gst_buffer_new_and_alloc (obj_data_size); + memcpy (GST_BUFFER_DATA (buf), *p_data, obj_data_size); + demux->ext_stream_props = g_slist_append (demux->ext_stream_props, buf); case ASF_OBJ_LANGUAGE_LIST: ret = gst_asf_demux_process_language_list (demux, *p_data, obj_data_size); Index: gstasfdemux.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h,v retrieving revision 1.30 retrieving revision 1.31 diff -u -d -r1.30 -r1.31 --- gstasfdemux.h 28 Apr 2007 10:49:17 -0000 1.30 +++ gstasfdemux.h 30 Apr 2007 11:41:22 -0000 1.31 @@ -24,6 +24,8 @@ #include <gst/gst.h> #include <gst/base/gstadapter.h> +#include "asfheaders.h" G_BEGIN_DECLS #define GST_TYPE_ASF_DEMUX \ @@ -45,6 +47,31 @@ typedef struct + gboolean valid; /* TRUE if structure is valid/filled */ + GstClockTime start_time; + GstClockTime end_time; + GstClockTime avg_time_per_frame; + guint32 data_bitrate; + guint32 buffer_size; + guint32 intial_buf_fullness; + guint32 data_bitrate2; + guint32 buffer_size2; + guint32 intial_buf_fullness2; + guint32 max_obj_size; + guint32 flags; + guint16 lang_idx; + /* missing: stream names */ + /* missing: payload extension system stuff */ +} AsfStreamExtProps; +typedef struct + AsfStreamType type; + gboolean active; /* if the stream has been activated (pad added) */ GstPad *pad; guint16 id; guint32 frag_offset; @@ -70,6 +97,9 @@ GstFlowReturn last_flow; /* last flow return */ GArray *payloads; /* pending payloads */ + /* extended stream properties (optional) */ + AsfStreamExtProps ext_props; } AsfStream; typedef enum { @@ -103,8 +133,8 @@ gchar **languages; guint num_languages; - GSList *ext_stream_props; - GSList *mut_ex_streams; /* mutually exclusive streams */ + GSList *ext_stream_props; /* for delayed processing (buffers) */ + GSList *mut_ex_streams; /* mutually exclusive streams */ guint32 num_audio_streams; guint32 num_video_streams; |
From: <tp...@ke...> - 2007-04-30 15:36:20
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Mon Apr 30 2007 15:36:12 UTC Log message: * gst/asfdemux/asfheaders.c: * gst/asfdemux/asfheaders.h: * gst/asfdemux/asfpacket.c: (asf_payload_parse_replicated_data_extensions), (gst_asf_demux_parse_payload): * gst/asfdemux/asfpacket.h: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_free_stream), (gst_asf_demux_push_complete_payloads), (gst_asf_demux_process_ext_stream_props): * gst/asfdemux/gstasfdemux.h: Implement payload extension system/extended replicated data parsing, so we can extract payload durations if they're specified. Modified files: . : ChangeLog gst/asfdemux : asfheaders.c asfheaders.h asfpacket.c asfpacket.h gstasfdemux.c gstasfdemux.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2192&r2=1.2193 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.c.diff?r1=1.7&r2=1.8 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.h.diff?r1=1.17&r2=1.18 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/asfpacket.c.diff?r1=1.1&r2=1.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/asfpacket.h.diff?r1=1.1&r2=1.2 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.129&r2=1.130 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h.diff?r1=1.31&r2=1.32 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2192 retrieving revision 1.2193 diff -u -d -r1.2192 -r1.2193 --- ChangeLog 30 Apr 2007 11:41:22 -0000 1.2192 +++ ChangeLog 30 Apr 2007 15:36:00 -0000 1.2193 @@ -1,5 +1,20 @@ 2007-04-30 Tim-Philipp Müller <tim at centricular dot net> + * gst/asfdemux/asfheaders.c: + * gst/asfdemux/asfheaders.h: + * gst/asfdemux/asfpacket.c: + (asf_payload_parse_replicated_data_extensions), + (gst_asf_demux_parse_payload): + * gst/asfdemux/asfpacket.h: + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_free_stream), + (gst_asf_demux_push_complete_payloads), + (gst_asf_demux_process_ext_stream_props): + * gst/asfdemux/gstasfdemux.h: + Implement payload extension system/extended replicated data parsing, + so we can extract payload durations if they're specified. + +2007-04-30 Tim-Philipp Müller <tim at centricular dot net> * gst/asfdemux/asfheaders.h: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_free_stream), (gst_asf_demux_reset), (gst_asf_demux_parse_data_object_start), Index: asfheaders.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- asfheaders.c 12 Apr 2007 13:38:03 -0000 1.7 +++ asfheaders.c 30 Apr 2007 15:36:00 -0000 1.8 @@ -21,6 +21,15 @@ #include "asfheaders.h" +const ASFGuidHash asf_payload_ext_guids[] = { + {ASF_PAYLOAD_EXTENSION_DURATION, "ASF_PAYLOAD_EXTENSION_DURATION", + {0xC6BD9450, 0x4907867F, 0x79C7A383, 0xAD33B721} + }, + {ASF_PAYLOAD_EXTENSION_UNDEFINED, "ASF_PAYLOAD_EXTENSION_UNDEFINED", + {0, 0, 0, 0} + } +}; const ASFGuidHash asf_correction_guids[] = { {ASF_CORRECTION_ON, "ASF_CORRECTION_ON", {0xBFC3CD50, 0x11CF618F, 0xAA00B28B, 0x20E2B400} Index: asfheaders.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/asfheaders.h,v retrieving revision 1.17 retrieving revision 1.18 diff -u -d -r1.17 -r1.18 --- asfheaders.h 30 Apr 2007 11:41:22 -0000 1.17 +++ asfheaders.h 30 Apr 2007 15:36:00 -0000 1.18 @@ -82,6 +82,13 @@ ASF_CORRECTION_OFF } AsfCorrectionType; +typedef enum { + ASF_PAYLOAD_EXTENSION_UNDEFINED = 0, + ASF_PAYLOAD_EXTENSION_DURATION +} AsfPayloadExtensionID; +extern const ASFGuidHash asf_payload_ext_guids[]; extern const ASFGuidHash asf_correction_guids[]; extern const ASFGuidHash asf_stream_guids[]; Index: asfpacket.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/asfpacket.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- asfpacket.c 20 Apr 2007 20:57:56 -0000 1.1 +++ asfpacket.c 30 Apr 2007 15:36:00 -0000 1.2 @@ -114,6 +114,9 @@ return ret; } +/* TODO: if we have another payload already queued for this stream and that + * payload doesn't have a duration, maybe we can calculate a duration for it + * (if the previous timestamp is smaller etc. etc.) */ static void gst_asf_payload_queue_for_stream (GstASFDemux * demux, AsfPayload * payload, AsfStream * stream) @@ -142,6 +145,38 @@ g_array_append_vals (stream->payloads, payload, 1); +static void +asf_payload_parse_replicated_data_extensions (AsfStream * stream, + AsfPayload * payload) +{ + AsfPayloadExtension *ext; + guint off; + if (!stream->ext_props.valid || stream->ext_props.payload_extensions == NULL) + return; + off = 8; + for (ext = stream->ext_props.payload_extensions; ext->len > 0; ++ext) { + if (off + ext->len > payload->rep_data_len) { + GST_WARNING ("not enough replicated data for defined extensions"); + return; + } + switch (ext->id) { + case ASF_PAYLOAD_EXTENSION_DURATION: + if (ext->len == 2) { + payload->duration = + GST_READ_UINT16_LE (payload->rep_data + off) * GST_MSECOND; + } else { + GST_WARNING ("unexpected DURATION extensions len %u", ext->len); + } + break; + default: + off += ext->len; + } +} static gboolean gst_asf_demux_parse_payload (GstASFDemux * demux, AsfPacket * packet, gint lentype, const guint8 ** p_data, guint * p_size) @@ -163,6 +198,9 @@ *p_data += 1; *p_size -= 1; + payload.ts = GST_CLOCK_TIME_NONE; + payload.duration = GST_CLOCK_TIME_NONE; payload.mo_number = asf_packet_read_varlen_int (packet->prop_flags, 4, p_data, p_size); payload.mo_offset = @@ -218,19 +256,19 @@ } if (!is_compressed) { - GstClockTime ts = GST_CLOCK_TIME_NONE; - GST_LOG_OBJECT (demux, "replicated data length: %u", payload.rep_data_len); if (payload.rep_data_len >= 8) { payload.mo_size = GST_READ_UINT32_LE (payload.rep_data); - ts = GST_READ_UINT32_LE (payload.rep_data + 4) * GST_MSECOND; - ts -= demux->preroll * GST_MSECOND; + payload.ts = GST_READ_UINT32_LE (payload.rep_data + 4) * GST_MSECOND; + payload.ts -= demux->preroll * GST_MSECOND; + asf_payload_parse_replicated_data_extensions (stream, &payload); GST_LOG_OBJECT (demux, "media object size : %u", payload.mo_size); GST_LOG_OBJECT (demux, "media object ts : %" GST_TIME_FORMAT, - GST_TIME_ARGS (ts)); - /* TODO: parse payload extensions, if there are any */ + GST_TIME_ARGS (payload.ts)); + GST_LOG_OBJECT (demux, "media object dur : %" GST_TIME_FORMAT, + GST_TIME_ARGS (payload.duration)); } else if (payload.rep_data_len != 0) { GST_WARNING_OBJECT (demux, "invalid replicated data length, very bad"); } @@ -260,7 +298,6 @@ } payload.buf = NULL; } else { - GST_BUFFER_TIMESTAMP (payload.buf) = ts; gst_asf_payload_queue_for_stream (demux, &payload, stream); } @@ -298,8 +335,9 @@ payload.buf = asf_packet_create_payload_buffer (packet, &payload_data, &payload_len, sub_payload_len); - GST_BUFFER_TIMESTAMP (payload.buf) = ts; - GST_BUFFER_DURATION (payload.buf) = ts_delta; + payload.ts = ts; + payload.duration = ts_delta; gst_asf_payload_queue_for_stream (demux, &payload, stream); ts += ts_delta; Index: asfpacket.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/asfpacket.h,v --- asfpacket.h 20 Apr 2007 20:57:56 -0000 1.1 +++ asfpacket.h 30 Apr 2007 15:36:00 -0000 1.2 @@ -34,7 +34,8 @@ guint mo_size; /* size of media-object-to-be, or 0 */ guint rep_data_len; /* should never be more than 256, since */ guint8 rep_data[256]; /* the length should be stored in a byte */ - /* GstClockTime duration; */ /* TODO:get from payload extension system */ + GstClockTime ts; + GstClockTime duration; /* is not always available */ GstBuffer *buf; } AsfPayload; Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.129 retrieving revision 1.130 diff -u -d -r1.129 -r1.130 --- gstasfdemux.c 30 Apr 2007 11:41:22 -0000 1.129 +++ gstasfdemux.c 30 Apr 2007 15:36:00 -0000 1.130 @@ -161,6 +161,14 @@ gst_object_unref (stream->pad); stream->pad = NULL; + if (stream->payloads) { + g_array_free (stream->payloads, TRUE); + stream->payloads = NULL; + if (stream->ext_props.valid) { + g_free (stream->ext_props.payload_extensions); + stream->ext_props.payload_extensions = NULL; @@ -972,6 +980,9 @@ gst_buffer_set_caps (payload->buf, stream->caps); + GST_BUFFER_TIMESTAMP (payload->buf) = payload->ts; + GST_BUFFER_DURATION (payload->buf) = payload->duration; /* FIXME: we should really set durations on buffers if we can */ /* (this is a hack, obviously) if (strncmp (GST_PAD_NAME (stream->pad), "video", 5) == 0 && @@ -981,7 +992,9 @@ */ GST_LOG_OBJECT (stream->pad, "pushing buffer, ts=%" GST_TIME_FORMAT - ", size=%u", GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (payload->buf)), + ", dur=%" GST_TIME_FORMAT " size=%u", + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (payload->buf)), + GST_TIME_ARGS (GST_BUFFER_DURATION (payload->buf)), GST_BUFFER_SIZE (payload->buf)); stream->last_flow = gst_pad_push (stream->pad, payload->buf); @@ -2329,7 +2342,7 @@ AsfStream *stream = NULL; AsfObject stream_obj; guint16 stream_name_count; - guint16 payload_ext_sys_count; + guint16 num_payload_ext; guint64 len; guint8 *stream_obj_data = NULL; guint8 *data_start = data; @@ -2354,7 +2367,7 @@ esp.lang_idx = gst_asf_demux_get_uint16 (&data, &size); esp.avg_time_per_frame = gst_asf_demux_get_uint64 (&data, &size) * 100; stream_name_count = gst_asf_demux_get_uint16 (&data, &size); - payload_ext_sys_count = gst_asf_demux_get_uint16 (&data, &size); + num_payload_ext = gst_asf_demux_get_uint16 (&data, &size); GST_INFO ("start_time = %" GST_TIME_FORMAT, GST_TIME_ARGS (esp.start_time)); @@ -2384,16 +2397,31 @@ /* read payload extension systems stuff */ - GST_LOG ("payload ext sys count = %u", payload_ext_sys_count); - for (i = 0; i < payload_ext_sys_count; ++i) { + GST_LOG ("payload extension systems count = %u", num_payload_ext); + if (num_payload_ext > 0) + esp.payload_extensions = g_new0 (AsfPayloadExtension, num_payload_ext + 1); + else + esp.payload_extensions = NULL; + for (i = 0; i < num_payload_ext; ++i) { + AsfPayloadExtension ext; + ASFGuid ext_guid; guint32 sys_info_len; - if (!gst_asf_demux_skip_bytes (16 + 2, &data, &size) || size < 4) + if (size < 16 + 2 + 4) goto not_enough_data; + gst_asf_demux_get_guid (&ext_guid, &data, &size); + ext.id = gst_asf_demux_identify_guid (asf_payload_ext_guids, &ext_guid); + ext.len = gst_asf_demux_get_uint16 (&data, &size); sys_info_len = gst_asf_demux_get_uint32 (&data, &size); GST_LOG ("payload systems info len = %u", sys_info_len); if (!gst_asf_demux_skip_bytes (sys_info_len, &data, &size)) + esp.payload_extensions[i] = ext; GST_LOG ("bytes read: %u/%u", (guint) (data - data_start), obj_size); Index: gstasfdemux.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h,v retrieving revision 1.31 retrieving revision 1.32 diff -u -d -r1.31 -r1.32 --- gstasfdemux.h 30 Apr 2007 11:41:22 -0000 1.31 +++ gstasfdemux.h 30 Apr 2007 15:36:00 -0000 1.32 @@ -45,6 +45,12 @@ typedef struct _GstASFDemux GstASFDemux; typedef struct _GstASFDemuxClass GstASFDemuxClass; +typedef struct { + AsfPayloadExtensionID id : 16; /* extension ID; the :16 makes sure the + * struct gets packed into 4 bytes */ + guint16 len; /* save this so we can skip unknown IDs */ +} AsfPayloadExtension; typedef struct { gboolean valid; /* TRUE if structure is valid/filled */ @@ -62,8 +68,11 @@ guint32 flags; guint16 lang_idx; + /* may be NULL if there are no extensions; otherwise, terminated by + * an AsfPayloadExtension record with len 0 */ + AsfPayloadExtension *payload_extensions; /* missing: stream names */ - /* missing: payload extension system stuff */ } AsfStreamExtProps; |
From: <tp...@ke...> - 2007-05-01 09:19:37
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Tue May 01 2007 09:19:25 UTC Log message: * gst/asfdemux/asfpacket.c: (gst_asf_payload_queue_for_stream): * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_seek_index_lookup), (gst_asf_demux_handle_seek_event), (gst_asf_demux_push_complete_payloads): Seeking improvements: honour the KEY_UNIT seek flag; after a seek, only send data from the keyframe right before the new segment start to make sure the decoder doesn't have to decode more than absolutely necessary. Modified files: . : ChangeLog gst/asfdemux : asfpacket.c gstasfdemux.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2193&r2=1.2194 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/asfpacket.c.diff?r1=1.2&r2=1.3 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.130&r2=1.131 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2193 retrieving revision 1.2194 diff -u -d -r1.2193 -r1.2194 --- ChangeLog 30 Apr 2007 15:36:00 -0000 1.2193 +++ ChangeLog 1 May 2007 09:19:12 -0000 1.2194 @@ -1,3 +1,14 @@ +2007-05-01 Tim-Philipp Müller <tim at centricular dot net> + + * gst/asfdemux/asfpacket.c: (gst_asf_payload_queue_for_stream): + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_seek_index_lookup), + (gst_asf_demux_handle_seek_event), + (gst_asf_demux_push_complete_payloads): + Seeking improvements: honour the KEY_UNIT seek flag; after a seek, only + send data from the keyframe right before the new segment start to + make sure the decoder doesn't have to decode more than absolutely + necessary. 2007-04-30 Tim-Philipp Müller <tim at centricular dot net> * gst/asfdemux/asfheaders.c: Index: asfpacket.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/asfpacket.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- asfpacket.c 30 Apr 2007 15:36:00 -0000 1.2 +++ asfpacket.c 1 May 2007 09:19:13 -0000 1.3 @@ -142,6 +142,31 @@ GST_BUFFER_FLAG_SET (payload->buf, GST_BUFFER_FLAG_DISCONT); } + /* If we're about to queue a key frame that is before the segment start, we + * can ditch any previously queued payloads (which would also be before the + * segment start). This makes sure the decoder doesn't decode more than + * absolutely necessary after a seek (we don't push out payloads that are + * before the segment start until we have at least one that falls within the + * segment) */ + if (GST_CLOCK_TIME_IS_VALID (payload->ts) && + payload->ts < demux->segment.start && payload->keyframe) { + GST_DEBUG_OBJECT (demux, "Queueing keyframe before segment start, removing" + " %u previously-queued payloads, which would be out of segment too and" + " hence don't have to be decoded", stream->payloads->len); + while (stream->payloads->len > 0) { + AsfPayload *last; + guint idx_last; + idx_last = stream->payloads->len - 1; + last = &g_array_index (stream->payloads, AsfPayload, idx_last); + gst_buffer_replace (&last->buf, NULL); + g_array_remove_index (stream->payloads, idx_last); + } + /* Mark discontinuity (should be done via stream->discont anyway though) */ + GST_BUFFER_FLAG_SET (payload->buf, GST_BUFFER_FLAG_DISCONT); + } g_array_append_vals (stream->payloads, payload, 1); } Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.130 retrieving revision 1.131 diff -u -d -r1.130 -r1.131 --- gstasfdemux.c 30 Apr 2007 15:36:00 -0000 1.130 +++ gstasfdemux.c 1 May 2007 09:19:13 -0000 1.131 @@ -336,22 +336,40 @@ static gboolean gst_asf_demux_seek_index_lookup (GstASFDemux * demux, guint * packet, - GstClockTime seek_time) + GstClockTime seek_time, GstClockTime * p_idx_time) { + GstClockTime idx_time; guint idx; if (demux->sidx_num_entries == 0 || demux->sidx_interval == 0) return FALSE; idx = (guint) (seek_time / demux->sidx_interval); + /* FIXME: seek beyond end of file should result in immediate EOS from + * streaming thread instead of a failed seek */ if (idx >= demux->sidx_num_entries) *packet = demux->sidx_entries[idx]; + /* so we get closer to the actual time of the packet ... actually, let's not + * do this, since we throw away superfluous payloads before the seek position + * anyway; this way, our key unit seek 'snap resolution' is a bit better + * (ie. same as index resolution) */ + /* + while (idx > 0 && demux->sidx_entries[idx-1] == demux->sidx_entries[idx]) + --idx; + */ + idx_time = demux->sidx_interval * idx; GST_DEBUG_OBJECT (demux, "%" GST_TIME_FORMAT " => packet %u at %" GST_TIME_FORMAT, GST_TIME_ARGS (seek_time), *packet, - GST_TIME_ARGS (demux->sidx_interval * idx)); + GST_TIME_ARGS (idx_time)); + if (p_idx_time) + *p_idx_time = idx_time; return TRUE; @@ -389,6 +407,7 @@ gst_asf_demux_handle_seek_event (GstASFDemux * demux, GstEvent * event) GstSegment segment; GstSeekFlags flags; GstSeekType cur_type, stop_type; @@ -467,7 +486,7 @@ /* FIXME: should check the KEY_UNIT flag; need to adjust last_stop to * real start of data and segment_start to indexed time for key unit seek*/ - if (!gst_asf_demux_seek_index_lookup (demux, &packet, seek_time)) { + if (!gst_asf_demux_seek_index_lookup (demux, &packet, seek_time, &idx_time)) { /* Hackety hack, this sucks. We just seek to an earlier position * and let the sinks throw away the stuff before the segment start */ if (flush && (accurate || keyunit_sync)) { @@ -481,6 +500,15 @@ if (packet > demux->num_packets) packet = demux->num_packets; + } else { + if (keyunit_sync) { + GST_DEBUG_OBJECT (demux, "key unit seek, adjust seek_time = %" + GST_TIME_FORMAT " to index_time = %" GST_TIME_FORMAT, + GST_TIME_ARGS (seek_time), GST_TIME_ARGS (idx_time)); + segment.start = idx_time; + segment.last_stop = idx_time; + segment.time = idx_time; GST_DEBUG_OBJECT (demux, "seeking to packet %u", packet); @@ -945,6 +973,27 @@ AsfStream *stream; stream = &demux->stream[i]; + /* Don't push any data until we have at least one payload that falls within + * the current segment. This way we can remove out-of-segment payloads that + * 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; + last_idx = stream->payloads->len - 1; + payload = &g_array_index (stream->payloads, AsfPayload, last_idx); + if (GST_CLOCK_TIME_IS_VALID (payload->ts) && + payload->ts < demux->segment.start) { + GST_DEBUG_OBJECT (stream->pad, "Last queued payload has timestamp %" + GST_TIME_FORMAT " which is before our segment start %" + GST_TIME_FORMAT ", not pushing yet", GST_TIME_ARGS (payload->ts), + GST_TIME_ARGS (demux->segment.start)); + continue; + } while (stream->payloads->len > 0) { AsfPayload *payload; |
From: <tp...@ke...> - 2007-05-01 11:11:04
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Tue May 01 2007 11:10:43 UTC Log message: * gst/asfdemux/asfpacket.c: (gst_asf_demux_parse_payload), (gst_asf_demux_parse_packet): If packet size is specified within the packet and smaller than the actual packet size, don't parse beyond the size specified in the packet (this makes us parse some cases of packets with single compressed payloads cleanly, see e.g stream from #431318). Also add a sanity check when parsing compressed single payloads. Modified files: . : ChangeLog gst/asfdemux : asfpacket.c Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2194&r2=1.2195 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/asfpacket.c.diff?r1=1.3&r2=1.4 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2194 retrieving revision 1.2195 diff -u -d -r1.2194 -r1.2195 --- ChangeLog 1 May 2007 09:19:12 -0000 1.2194 +++ ChangeLog 1 May 2007 11:10:31 -0000 1.2195 @@ -1,5 +1,15 @@ 2007-05-01 Tim-Philipp Müller <tim at centricular dot net> + * gst/asfdemux/asfpacket.c: (gst_asf_demux_parse_payload), + (gst_asf_demux_parse_packet): + If packet size is specified within the packet and smaller than + the actual packet size, don't parse beyond the size specified in + the packet (this makes us parse some cases of packets with single + compressed payloads cleanly, see e.g stream from #431318). Also + add a sanity check when parsing compressed single payloads. + +2007-05-01 Tim-Philipp Müller <tim at centricular dot net> * gst/asfdemux/asfpacket.c: (gst_asf_payload_queue_for_stream): * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_seek_index_lookup), (gst_asf_demux_handle_seek_event), Index: asfpacket.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/asfpacket.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- asfpacket.c 1 May 2007 09:19:13 -0000 1.3 +++ asfpacket.c 1 May 2007 11:10:31 -0000 1.4 @@ -357,13 +357,15 @@ return FALSE; } - payload.buf = asf_packet_create_payload_buffer (packet, - &payload_data, &payload_len, sub_payload_len); + if (sub_payload_len > 0) { + payload.buf = asf_packet_create_payload_buffer (packet, + &payload_data, &payload_len, sub_payload_len); - payload.ts = ts; - payload.duration = ts_delta; + payload.ts = ts; + payload.duration = ts_delta; - gst_asf_payload_queue_for_stream (demux, &payload, stream); + gst_asf_payload_queue_for_stream (demux, &payload, stream); + } ts += ts_delta; } @@ -453,6 +455,13 @@ size -= packet.padding; + /* adjust available size for parsing if there's less actual packet data for + * parsing than there is data in bytes (for sample see bug 431318) */ + if (packet.length != 0 && packet.length < demux->packet_size) { + GST_LOG_OBJECT (demux, "shortened packet, adjusting available data size"); + size -= (demux->packet_size - packet.length); + } if (has_multiple_payloads) { guint i, num, lentype; |
From: <tp...@ke...> - 2007-05-04 11:04:36
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Fri May 04 2007 11:04:28 UTC Log message: * gst/asfdemux/asfpacket.c: (gst_asf_payload_queue_for_stream): * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_reset), (gst_asf_demux_init), (gst_asf_demux_push_complete_payloads), (gst_asf_demux_process_file): * gst/asfdemux/gstasfdemux.h: Make all timestamps start from zero in pull-mode too; some small clean-ups and FIXMEs here and there. Modified files: . : ChangeLog gst/asfdemux : asfpacket.c gstasfdemux.c gstasfdemux.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2195&r2=1.2196 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/asfpacket.c.diff?r1=1.4&r2=1.5 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.131&r2=1.132 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h.diff?r1=1.32&r2=1.33 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2195 retrieving revision 1.2196 diff -u -d -r1.2195 -r1.2196 --- ChangeLog 1 May 2007 11:10:31 -0000 1.2195 +++ ChangeLog 4 May 2007 11:04:15 -0000 1.2196 @@ -1,3 +1,13 @@ +2007-05-04 Tim-Philipp Müller <tim at centricular dot net> + + * gst/asfdemux/asfpacket.c: (gst_asf_payload_queue_for_stream): + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_reset), + (gst_asf_demux_init), (gst_asf_demux_push_complete_payloads), + (gst_asf_demux_process_file): + * gst/asfdemux/gstasfdemux.h: + Make all timestamps start from zero in pull-mode too; some small + clean-ups and FIXMEs here and there. 2007-05-01 Tim-Philipp Müller <tim at centricular dot net> * gst/asfdemux/asfpacket.c: (gst_asf_demux_parse_payload), Index: asfpacket.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/asfpacket.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- asfpacket.c 1 May 2007 11:10:31 -0000 1.4 +++ asfpacket.c 4 May 2007 11:04:16 -0000 1.5 @@ -121,6 +121,27 @@ gst_asf_payload_queue_for_stream (GstASFDemux * demux, AsfPayload * payload, AsfStream * stream) { + /* remember the first timestamp in the stream */ + if (!GST_CLOCK_TIME_IS_VALID (demux->first_ts) && + GST_CLOCK_TIME_IS_VALID (payload->ts)) { + GST_DEBUG_OBJECT (demux, "first ts: %" GST_TIME_FORMAT, + GST_TIME_ARGS (payload->ts)); + demux->first_ts = payload->ts; + } + /* better drop a few frames at the beginning than send bogus timestamps */ + if (G_UNLIKELY (payload->ts < demux->first_ts)) { + GST_LOG_OBJECT (stream->pad, "Dropping payload with timestamp %" + GST_TIME_FORMAT " which is before the first timestamp %" + GST_TIME_FORMAT, GST_TIME_ARGS (payload->ts), + GST_TIME_ARGS (demux->first_ts)); + gst_buffer_replace (&payload->buf, NULL); + return; + /* make timestamps start from 0 */ + payload->ts -= demux->first_ts; /* remove any incomplete payloads that will never be completed */ while (stream->payloads->len > 0) { AsfPayload *prev; Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.131 retrieving revision 1.132 diff -u -d -r1.131 -r1.132 --- gstasfdemux.c 1 May 2007 09:19:13 -0000 1.131 +++ gstasfdemux.c 4 May 2007 11:04:16 -0000 1.132 @@ -205,6 +205,7 @@ demux->num_audio_streams = 0; demux->num_video_streams = 0; demux->num_streams = 0; + demux->first_ts = GST_CLOCK_TIME_NONE; demux->state = GST_ASF_DEMUX_STATE_HEADER; demux->seekable = FALSE; demux->broadcast = FALSE; @@ -237,6 +238,7 @@ demux->taglist = NULL; } @@ -1033,12 +1035,6 @@ GST_BUFFER_DURATION (payload->buf) = payload->duration; /* FIXME: we should really set durations on buffers if we can */ - /* (this is a hack, obviously) - if (strncmp (GST_PAD_NAME (stream->pad), "video", 5) == 0 && - !GST_BUFFER_DURATION_IS_VALID (payload->buf)) { - GST_BUFFER_DURATION (payload->buf) = GST_SECOND / 30; - } - */ GST_LOG_OBJECT (stream->pad, "pushing buffer, ts=%" GST_TIME_FORMAT ", dur=%" GST_TIME_FORMAT " size=%u", @@ -2047,14 +2043,14 @@ else demux->play_time = 0; - demux->preroll = preroll; + demux->preroll = preroll; /* FIXME: make GstClockTime */ if (demux->play_time == 0) demux->seekable = FALSE; - GST_DEBUG_OBJECT (demux, - "play_time %" GST_TIME_FORMAT " preroll %" GST_TIME_FORMAT, - GST_TIME_ARGS (demux->play_time), + GST_DEBUG_OBJECT (demux, "play_time %" GST_TIME_FORMAT, + GST_TIME_ARGS (demux->play_time)); + GST_DEBUG_OBJECT (demux, "preroll %" GST_TIME_FORMAT, GST_TIME_ARGS (demux->preroll * GST_MSECOND)); if (demux->play_time > 0) { Index: gstasfdemux.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h,v retrieving revision 1.32 retrieving revision 1.33 diff -u -d -r1.32 -r1.33 --- gstasfdemux.h 30 Apr 2007 15:36:00 -0000 1.32 +++ gstasfdemux.h 4 May 2007 11:04:16 -0000 1.33 @@ -87,7 +87,7 @@ guint32 sequence; guint64 delay; guint64 first_pts; - guint64 last_pts; + guint64 last_pts; /* FIXME: remove, not actually evaluated */ GstBuffer *payload; /* video-only */ @@ -150,11 +150,13 @@ guint32 num_streams; AsfStream stream[GST_ASF_DEMUX_NUM_STREAMS]; + GstClockTime first_ts; /* first timestamp found */ guint32 packet_size; guint32 timestamp; /* in milliseconds */ guint64 play_time; - guint64 preroll; + guint64 preroll; /* FIXME: make into GstClockTime */ guint64 pts; gboolean seekable; |
From: <tp...@ke...> - 2007-05-07 13:52:06
|
CVS Root: /cvs/gstreamer Module: gst-plugins-ugly Changes by: tpm Date: Mon May 07 2007 13:51:55 UTC Log message: * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_reset), (gst_asf_demux_chain_headers), (gst_asf_demux_parse_data_object_start), (all_streams_prerolled), (gst_asf_demux_have_mutually_exclusive_active_stream), (gst_asf_demux_check_activate_streams), (gst_asf_demux_find_stream_with_complete_payload), (gst_asf_demux_push_complete_payloads), (gst_asf_demux_loop), (gst_asf_demux_activate_ext_props_streams), (gst_asf_demux_process_object): * gst/asfdemux/gstasfdemux.h: Activate streams (ie. add the pads to the element) depending on whether we actually get data for those streams within the ASF preroll value specified. Currently only done in pull-mode though (this will fix problems with playbin hanging on mms streams once we use this in push-mode as well). Modified files: . : ChangeLog gst/asfdemux : gstasfdemux.c gstasfdemux.h Links: http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/ChangeLog.diff?r1=1.2196&r2=1.2197 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c.diff?r1=1.132&r2=1.133 http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h.diff?r1=1.33&r2=1.34 ====Begin Diffs==== Index: ChangeLog =================================================================== RCS file: /cvs/gstreamer/gst-plugins-ugly/ChangeLog,v retrieving revision 1.2196 retrieving revision 1.2197 diff -u -d -r1.2196 -r1.2197 --- ChangeLog 4 May 2007 11:04:15 -0000 1.2196 +++ ChangeLog 7 May 2007 13:51:41 -0000 1.2197 @@ -1,3 +1,21 @@ +2007-05-07 Tim-Philipp Müller <tim at centricular dot net> + + * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_reset), + (gst_asf_demux_chain_headers), + (gst_asf_demux_parse_data_object_start), (all_streams_prerolled), + (gst_asf_demux_have_mutually_exclusive_active_stream), + (gst_asf_demux_check_activate_streams), + (gst_asf_demux_find_stream_with_complete_payload), + (gst_asf_demux_push_complete_payloads), (gst_asf_demux_loop), + (gst_asf_demux_activate_ext_props_streams), + (gst_asf_demux_process_object): + * gst/asfdemux/gstasfdemux.h: + Activate streams (ie. add the pads to the element) depending on + whether we actually get data for those streams within the ASF + preroll value specified. Currently only done in pull-mode though + (this will fix problems with playbin hanging on mms streams once + we use this in push-mode as well). 2007-05-04 Tim-Philipp Müller <tim at centricular dot net> * gst/asfdemux/asfpacket.c: (gst_asf_payload_queue_for_stream): Index: gstasfdemux.c RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.c,v retrieving revision 1.132 retrieving revision 1.133 diff -u -d -r1.132 -r1.133 --- gstasfdemux.c 4 May 2007 11:04:16 -0000 1.132 +++ gstasfdemux.c 7 May 2007 13:51:43 -0000 1.133 @@ -107,6 +107,8 @@ gst_asf_demux_parse_data_object_start (GstASFDemux * demux, guint8 * data); static void gst_asf_demux_descramble_buffer (GstASFDemux * demux, AsfStream * stream, GstBuffer ** p_buffer); +static void gst_asf_demux_activate_stream (GstASFDemux * demux, + AsfStream * stream); GST_BOILERPLATE (GstASFDemux, gst_asf_demux, GstElement, GST_TYPE_ELEMENT); @@ -205,6 +207,7 @@ demux->num_audio_streams = 0; demux->num_video_streams = 0; demux->num_streams = 0; + demux->activated_streams = FALSE; demux->first_ts = GST_CLOCK_TIME_NONE; demux->state = GST_ASF_DEMUX_STATE_HEADER; demux->seekable = FALSE; @@ -648,6 +651,11 @@ if (demux->num_streams == 0) goto no_streams; + /* FIXME: remove when we activate streams after internal preroll in + * streaming mode as well */ + GST_LOG_OBJECT (demux, "signalling no more pads"); + gst_element_no_more_pads (GST_ELEMENT_CAST (demux)); g_free (data); return GST_FLOW_OK; @@ -888,7 +896,6 @@ /* process pending stream objects and create pads for those */ gst_asf_demux_process_queued_extended_stream_objects (demux); gst_asf_demux_activate_ext_props_streams (demux); - gst_element_no_more_pads (GST_ELEMENT (demux)); GST_INFO_OBJECT (demux, "Stream has %" G_GUINT64_FORMAT " packets, " "data_offset=%" G_GINT64_FORMAT ", data_size=%" G_GINT64_FORMAT @@ -966,9 +973,127 @@ } } -static void -gst_asf_demux_push_complete_payloads (GstASFDemux * demux) +static gboolean +all_streams_prerolled (GstASFDemux * demux) { + GstClockTime preroll_time; + guint i, num_no_data = 0; + preroll_time = demux->preroll * GST_MSECOND; + /* returns TRUE as long as there isn't a stream which (a) has data queued + * 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; + AsfStream *stream; + guint last_idx; + stream = &demux->stream[i]; + if (stream->payloads->len == 0) { + ++num_no_data; + GST_LOG_OBJECT (stream->pad, "no data queued"); + continue; + } + last_idx = stream->payloads->len - 1; + 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 (last_payload->ts <= preroll_time) { + GST_LOG_OBJECT (stream->pad, "not beyond preroll point yet"); + return FALSE; + } + if (num_no_data == demux->num_streams) + return FALSE; + return TRUE; +} +#if 0 +gst_asf_demux_have_mutually_exclusive_active_stream (GstASFDemux * demux, + AsfStream * stream) +{ + GSList *l; + for (l = demux->mut_ex_streams; l != NULL; l = l->next) { + guint8 *mes; + /* check for each mutual exclusion group whether it affects this stream */ + for (mes = (guint8 *) l->data; mes != NULL && *mes != 0xff; ++mes) { + if (*mes == stream->id) { + /* we are in this group; let's check if we've already activated streams + * that are in the same group (and hence mutually exclusive to this + * one) */ + for (mes = (guint8 *) l->data; mes != NULL && *mes != 0xff; ++mes) { + guint i; + for (i = 0; i < demux->num_streams; ++i) { + if (demux->stream[i].id == *mes && demux->stream[i].active) { + GST_LOG_OBJECT (demux, "stream with ID %d is mutually exclusive " + "to already active stream with ID %d", stream->id, + demux->stream[i].id); + return TRUE; + } + } + } + /* we can only be in this group once, let's break out and move on to + * the next mutual exclusion group */ + break; + } + return FALSE; +#endif +gst_asf_demux_check_activate_streams (GstASFDemux * demux, gboolean force) + guint i; + if (demux->activated_streams) + return TRUE; + if (!all_streams_prerolled (demux) && !force) { + GST_DEBUG_OBJECT (demux, "not all streams with data beyond preroll yet"); + AsfStream *stream = &demux->stream[i]; + if (stream->payloads->len > 0) { + /* 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!"); + gst_asf_demux_activate_stream (demux, stream); + } else { + GST_LOG_OBJECT (stream->pad, "no data, ignoring stream"); + demux->activated_streams = TRUE; + gst_element_no_more_pads (GST_ELEMENT (demux)); +/* returns the stream that has a complete payload with the lowest timestamp + * queued, or NULL (we push things by timestamp because during the internal + * prerolling we might accumulate more data then the external queues can take, + * so we'd lock up if we pushed all accumulated data for stream N in one go) */ +static AsfStream * +gst_asf_demux_find_stream_with_complete_payload (GstASFDemux * demux) + AsfPayload *best_payload = NULL; + AsfStream *best_stream = NULL; guint i; for (i = 0; i < demux->num_streams; ++i) { @@ -996,56 +1121,103 @@ } } - while (stream->payloads->len > 0) { + /* Now see if there's a complete payload queued for this stream */ AsfPayload *payload; payload = &g_array_index (stream->payloads, AsfPayload, 0); if (!gst_asf_payload_is_complete (payload)) - break; + continue; - /* Do we have tags pending for this stream? */ - if (stream->pending_tags) { - GST_LOG_OBJECT (stream->pad, "%" GST_PTR_FORMAT, stream->pending_tags); - gst_element_found_tags_for_pad (GST_ELEMENT (demux), stream->pad, - stream->pending_tags); - stream->pending_tags = NULL; + /* ... and whether its timestamp is lower than the current best */ + if (best_stream == NULL || best_payload->ts > payload->ts) { + best_stream = stream; + best_payload = payload; - /* We have the whole packet now so we should push the packet to - * the src pad now. First though we should check if we need to do - * descrambling */ - if (demux->span > 1) { - gst_asf_demux_descramble_buffer (demux, stream, &payload->buf); - } + return best_stream; - payload->buf = gst_buffer_make_metadata_writable (payload->buf); +static void +gst_asf_demux_push_complete_payloads (GstASFDemux * demux, gboolean force) + AsfStream *stream; - if (!payload->keyframe) { - GST_BUFFER_FLAG_SET (payload->buf, GST_BUFFER_FLAG_DELTA_UNIT); + if (G_UNLIKELY (!demux->activated_streams)) { + if (!gst_asf_demux_check_activate_streams (demux, force)) + return; + /* streams are now activated */ - if (stream->discont) { - GST_BUFFER_FLAG_SET (payload->buf, GST_BUFFER_FLAG_DISCONT); - stream->discont = FALSE; + /* do we need to send a newsegment event */ + if (demux->need_newsegment) { + if (demux->segment.stop == GST_CLOCK_TIME_NONE && + demux->segment.duration > 0) { + demux->segment.stop = demux->segment.duration; - gst_buffer_set_caps (payload->buf, stream->caps); + GST_DEBUG_OBJECT (demux, "sending new-segment event %" GST_SEGMENT_FORMAT, + &demux->segment); - GST_BUFFER_TIMESTAMP (payload->buf) = payload->ts; - GST_BUFFER_DURATION (payload->buf) = payload->duration; + /* 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_new_segment (FALSE, demux->segment.rate, + GST_FORMAT_TIME, demux->segment.start, demux->segment.stop, + demux->segment.start)); - /* FIXME: we should really set durations on buffers if we can */ + demux->need_newsegment = FALSE; + demux->segment_running = TRUE; - GST_LOG_OBJECT (stream->pad, "pushing buffer, ts=%" GST_TIME_FORMAT - ", dur=%" GST_TIME_FORMAT " size=%u", - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (payload->buf)), - GST_TIME_ARGS (GST_BUFFER_DURATION (payload->buf)), - GST_BUFFER_SIZE (payload->buf)); + while ((stream = gst_asf_demux_find_stream_with_complete_payload (demux))) { + AsfPayload *payload; - stream->last_flow = gst_pad_push (stream->pad, payload->buf); - payload->buf = NULL; - g_array_remove_index (stream->payloads, 0); + payload = &g_array_index (stream->payloads, AsfPayload, 0); + /* Do we have tags pending for this stream? */ + if (stream->pending_tags) { + GST_LOG_OBJECT (stream->pad, "%" GST_PTR_FORMAT, stream->pending_tags); + gst_element_found_tags_for_pad (GST_ELEMENT (demux), stream->pad, + stream->pending_tags); + stream->pending_tags = NULL; + /* We have the whole packet now so we should push the packet to + * the src pad now. First though we should check if we need to do + * descrambling */ + if (demux->span > 1) { + gst_asf_demux_descramble_buffer (demux, stream, &payload->buf); + payload->buf = gst_buffer_make_metadata_writable (payload->buf); + if (!payload->keyframe) { + GST_BUFFER_FLAG_SET (payload->buf, GST_BUFFER_FLAG_DELTA_UNIT); + if (stream->discont) { + GST_BUFFER_FLAG_SET (payload->buf, GST_BUFFER_FLAG_DISCONT); + stream->discont = FALSE; + gst_buffer_set_caps (payload->buf, stream->caps); + GST_BUFFER_TIMESTAMP (payload->buf) = payload->ts; + GST_BUFFER_DURATION (payload->buf) = payload->duration; + /* FIXME: we should really set durations on buffers if we can */ + GST_LOG_OBJECT (stream->pad, "pushing buffer, ts=%" GST_TIME_FORMAT + ", dur=%" GST_TIME_FORMAT " size=%u", + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (payload->buf)), + GST_TIME_ARGS (GST_BUFFER_DURATION (payload->buf)), + GST_BUFFER_SIZE (payload->buf)); + stream->last_flow = gst_pad_push (stream->pad, payload->buf); + payload->buf = NULL; + g_array_remove_index (stream->payloads, 0); @@ -1083,23 +1255,6 @@ goto read_failed; - if (demux->need_newsegment) { - if (demux->segment.stop == GST_CLOCK_TIME_NONE) - demux->segment.stop = demux->segment.duration; - - GST_DEBUG_OBJECT (demux, "sending new-segment event %" GST_SEGMENT_FORMAT, - &demux->segment); - /* FIXME: check last parameter, streams may have non-zero start */ - gst_asf_demux_send_event_unlocked (demux, - gst_event_new_new_segment (FALSE, demux->segment.rate, - GST_FORMAT_TIME, demux->segment.start, demux->segment.stop, - demux->segment.start)); - demux->need_newsegment = FALSE; - demux->segment_running = TRUE; - } /* FIXME: maybe we should just skip broken packets and error out only * after a few broken packets in a row? */ if (!gst_asf_demux_parse_packet (demux, buf)) @@ -1107,7 +1262,7 @@ gst_buffer_unref (buf); - gst_asf_demux_push_complete_payloads (demux); + gst_asf_demux_push_complete_payloads (demux, FALSE); ++demux->packet; @@ -1128,6 +1283,12 @@ eos: { + /* if we haven't actived our streams yet, this might be because we have + * less data queued than required for preroll; force stream activation and + * send any pending payloads before sending EOS */ + if (!demux->activated_streams) + gst_asf_demux_push_complete_payloads (demux, TRUE); if (demux->segment.flags & GST_SEEK_FLAG_SEGMENT) { gint64 stop; @@ -2646,8 +2807,9 @@ next: - /* FIXME: we should do stream activation based on preroll data */ - if (!is_hidden) + /* FIXME: we should do stream activation based on preroll data in + * streaming mode too */ + if (demux->streaming && !is_hidden) gst_asf_demux_activate_stream (demux, stream); @@ -2681,8 +2843,12 @@ stream = gst_asf_demux_parse_stream_object (demux, *p_data, obj_data_size); - if (stream) + /* FIXME: we should do stream activation based on preroll data in + * streaming mode too */ + if (demux->streaming && stream != NULL) gst_asf_demux_activate_stream (demux, stream); ret = GST_FLOW_OK; break; Index: gstasfdemux.h RCS file: /cvs/gstreamer/gst-plugins-ugly/gst/asfdemux/gstasfdemux.h,v retrieving revision 1.33 retrieving revision 1.34 diff -u -d -r1.33 -r1.34 --- gstasfdemux.h 4 May 2007 11:04:16 -0000 1.33 +++ gstasfdemux.h 7 May 2007 13:51:43 -0000 1.34 @@ -149,6 +149,7 @@ guint32 num_video_streams; guint32 num_streams; AsfStream stream[GST_ASF_DEMUX_NUM_STREAMS]; + gboolean activated_streams; GstClockTime first_ts; /* first timestamp found */ |