+2004-09-20 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
+
+ * ext/mad/gstmad.c: (gst_mad_check_caps_reset),
+ (gst_mad_change_state):
+ Allow for mp3 rate/channels changes. However, only very
+ conservatively. Reason that we *have* to enable this is smiply
+ because the mad find_sync() function is not good enough, it will
+ regularly sync on random data as valid frames and therefore make
+ us provide random caps as *final* caps of the stream. The best fix
+ I could think of is to simply require several of the same stream
+ changes in a row before we change caps.
+ The actual testcase that works now is #
+ * ext/ogg/Makefile.am:
+ * ext/ogg/gstogg.c: (plugin_init):
+ * ext/ogg/gstogmparse.c:
+ OGM support (video only for now; I need an audio sample file).
+ * gst/asfdemux/gstasfdemux.c: (gst_asf_demux_base_init),
+ (gst_asf_demux_process_stream), (gst_asf_demux_video_caps),
+ (gst_asf_demux_add_video_stream):
+ WMV extradata.
+ * gst/playback/gstplaybasebin.c: (unknown_type):
+ Don't error out on single unknown-types after all. It's wrong.
+ If we found type of video and audio but not of a subtitle stream,
+ it will still error out (which is unwanted). Will find a better fix
+ later on.
+ * gst/typefind/gsttypefindfunctions.c: (ogmvideo_type_find),
+ (ogmaudio_type_find), (plugin_init):
+ OGM support.
+
2004-09-20 Johan Dahlin <johan@gnome.org>
* ext/jpeg/gstjpegdec.c (gst_jpegdec_chain): Allocate the buffer
GstTagList *tags;
/* negotiated format */
- gint rate;
- gint channels;
+ gint rate, pending_rate;
+ gint channels, pending_channels;
+ gint times_pending;
gboolean caps_set; /* used to keep track of whether to change/update caps */
GstIndex *index;
GST_DEBUG
("Header changed from %d Hz/%d ch to %d Hz/%d ch, failed sync after seek ?",
mad->rate, mad->channels, rate, nchannels);
- return;
+ /* we're conservative on stream changes. However, our *initial* caps
+ * might have been wrong as well - mad ain't perfect in syncing. So,
+ * we count caps changes and change if we pass a limit treshold (3). */
+ if (nchannels != mad->pending_channels || rate != mad->pending_rate) {
+ mad->times_pending = 0;
+ mad->pending_channels = nchannels;
+ mad->pending_rate = rate;
+ }
+ if (++mad->times_pending < 3)
+ return;
}
}
gst_mad_update_info (mad);
mad->rate = 0;
mad->channels = 0;
mad->caps_set = FALSE;
+ mad->times_pending = mad->pending_rate = mad->pending_channels = 0;
mad->vbr_average = 0;
mad->segment_start = 0;
mad->new_header = TRUE;
static GstElementStateReturn gst_asf_demux_change_state (GstElement * element);
static GstCaps *gst_asf_demux_video_caps (guint32 codec_fcc,
- asf_stream_video_format * video, char **codec_name);
+ asf_stream_video_format * video, guint8 * extradata, char **codec_name);
static GstCaps *gst_asf_demux_audio_caps (guint16 codec_id,
asf_stream_audio * audio, guint8 * extradata, char **codec_name);
vidcaps = gst_caps_new_empty ();
for (i = 0; vid_list[i] != 0; i++) {
- temp = gst_asf_demux_video_caps (vid_list[i], NULL, NULL);
+ temp = gst_asf_demux_video_caps (vid_list[i], NULL, NULL, NULL);
gst_caps_append (vidcaps, temp);
}
asf_stream_video video_object;
asf_stream_video_format video_format_object;
guint16 size;
- GstBuffer *buf;
- guint32 got_bytes;
guint16 id;
/* Get the rest of the header's header */
if (!gst_asf_demux_add_video_stream (asf_demux, &video_format_object, id))
return FALSE;
-
- /* Read any additional information */
- if (size) {
- got_bytes = gst_bytestream_read (asf_demux->bs, &buf, size);
- /* There is additional data */
- while (got_bytes < size) {
- guint32 remaining;
- GstEvent *event;
-
- gst_bytestream_get_status (asf_demux->bs, &remaining, &event);
- gst_event_unref (event);
-
- got_bytes = gst_bytestream_read (asf_demux->bs, &buf, size);
- }
- }
break;
default:
GST_ELEMENT_ERROR (asf_demux, STREAM, WRONG_TYPE, (NULL),
static GstCaps *
gst_asf_demux_video_caps (guint32 codec_fcc,
- asf_stream_video_format * video, char **codec_name)
+ asf_stream_video_format * video, guint8 * extradata, char **codec_name)
{
GstCaps *caps = NULL;
gint width = 0, height = 0;
"width", G_TYPE_INT, video->width,
"height", G_TYPE_INT, video->height,
"framerate", G_TYPE_DOUBLE, (double) 25, NULL);
+
+ if (extradata) {
+ GstBuffer *buffer;
+
+ buffer = gst_buffer_new_and_alloc (video->size);
+ memcpy (GST_BUFFER_DATA (buffer), extradata, video->size);
+ /* gst_util_dump_mem (GST_BUFFER_DATA (buffer), video->size); */
+
+ gst_caps_set_simple (caps, "codec_data", GST_TYPE_BUFFER, buffer, NULL);
+ gst_data_unref (GST_DATA (buffer));
+ }
} else {
gst_caps_set_simple (caps,
"width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
gchar *name = NULL;
char *codec_name = NULL;
GstTagList *list = gst_tag_list_new ();
+ gint size_left = video->size - 40;
/* Create the audio pad */
name = g_strdup_printf ("video_%02d", asf_demux->num_video_streams);
g_free (name);
/* Now try some gstreamer formatted MIME types (from gst_avi_demux_strf_vids) */
- caps = gst_asf_demux_video_caps (video->tag, video, &codec_name);
+ if (size_left) {
+ guint8 *extradata;
+
+ GST_WARNING_OBJECT (asf_demux,
+ "asfdemux: Video header contains %d bytes of codec specific data",
+ size_left);
+ gst_bytestream_peek_bytes (asf_demux->bs, &extradata, size_left);
+ caps = gst_asf_demux_video_caps (video->tag, video, extradata, &codec_name);
+ gst_bytestream_flush (asf_demux->bs, size_left);
+ } else {
+ caps = gst_asf_demux_video_caps (video->tag, video, NULL, &codec_name);
+ }
gst_tag_list_add (list, GST_TAG_MERGE_APPEND, GST_TAG_VIDEO_CODEC,
codec_name, NULL);
gst_element_found_tags (GST_ELEMENT (asf_demux), list);