diff --git a/ChangeLog b/ChangeLog index 754fc27614..828166a264 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2004-10-02 Ronald S. Bultje + + * gst-libs/gst/riff/riff-media.c: + (gst_riff_create_video_caps_with_data), + (gst_riff_create_video_template_caps): + Add DIB fourcc (raw, palettized 8-bit RGB). + * gst-libs/gst/riff/riff-read.c: + (gst_riff_read_strf_vids_with_data): + Oops, fix strf_data reading bug. + * gst/avi/gstavidemux.c: (gst_avi_demux_add_stream): + Use a non-NULL tag. + * gst/qtdemux/qtdemux.c: (qtdemux_parse_trak): + Time for hacks. Sorry Dave. At least one quicktime movie (a + trailer) that I've encountered contains multiple video tracks. + One of those is the actual video track, the other are one-frame + tracks (images). Unfortunately, the number of frames according + to the trak header is 1 for each, so that doesn't help. So + instead, I look at the duration and discard tracks with a + duration shorter than 20% of the length of the stream. Better + than nothing. + 2004-10-01 Christian Schaller * Patch fra Phil Blundell diff --git a/gst-libs/gst/riff/riff-media.c b/gst-libs/gst/riff/riff-media.c index 040f203dc8..7e6c4dbc4c 100644 --- a/gst-libs/gst/riff/riff-media.c +++ b/gst-libs/gst/riff/riff-media.c @@ -46,8 +46,19 @@ gst_riff_create_video_caps_with_data (guint32 codec_fcc, GstBuffer * strf_data, GstBuffer * strd_data, char **codec_name) { GstCaps *caps = NULL; + GstBuffer *palette = NULL; switch (codec_fcc) { + case GST_MAKE_FOURCC ('D', 'I', 'B', ' '): + caps = gst_caps_new_simple ("video/x-raw-rgb", + "bpp", G_TYPE_INT, 8, + "depth", G_TYPE_INT, 8, "endianness", G_TYPE_INT, G_BYTE_ORDER, NULL); + palette = strf_data; + strf_data = NULL; + if (codec_name) + *codec_name = g_strdup ("Palettized 8-bit RGB"); + break; + case GST_MAKE_FOURCC ('I', '4', '2', '0'): caps = gst_caps_new_simple ("video/x-raw-yuv", "format", GST_TYPE_FOURCC, codec_fcc, NULL); @@ -267,26 +278,8 @@ gst_riff_create_video_caps_with_data (guint32 codec_fcc, case GST_MAKE_FOURCC (0x1, 0x0, 0x0, 0x0): /* why, why, why? */ caps = gst_caps_new_simple ("video/x-rle", "layout", G_TYPE_STRING, "microsoft", NULL); - if (strf_data && GST_BUFFER_SIZE (strf_data) >= 256 * 4) { - GstBuffer *copy = gst_buffer_copy (strf_data); - GValue value = { 0 }; - -#if (G_BYTE_ORDER == G_BIG_ENDIAN) - gint n; - guint32 *data = (guint32 *) GST_BUFFER_DATA (copy); - - /* own endianness */ - for (n = 0; n < 256; n++) - data[n] = GUINT32_FROM_LE (data[n]); -#endif - g_value_init (&value, GST_TYPE_BUFFER); - g_value_set_boxed (&value, copy); - gst_structure_set_value (gst_caps_get_structure (caps, 0), - "palette_data", &value); - g_value_unset (&value); - gst_buffer_unref (copy); - strf_data = NULL; /* used */ - } + palette = strf_data; + strf_data = NULL; if (strf) { gst_caps_set_simple (caps, "depth", G_TYPE_INT, (gint) strf->bit_cnt, NULL); @@ -328,6 +321,22 @@ gst_riff_create_video_caps_with_data (guint32 codec_fcc, strf_data ? strf_data : strd_data, NULL); } + /* palette */ + if (palette && GST_BUFFER_SIZE (palette) >= 256 * 4) { + GstBuffer *copy = gst_buffer_copy (palette); + +#if (G_BYTE_ORDER == G_BIG_ENDIAN) + gint n; + guint32 *data = (guint32 *) GST_BUFFER_DATA (copy); + + /* own endianness */ + for (n = 0; n < 256; n++) + data[n] = GUINT32_FROM_LE (data[n]); +#endif + gst_caps_set_simple (caps, "palette_data", GST_TYPE_BUFFER, copy, NULL); + gst_buffer_unref (copy); + } + return caps; } @@ -557,6 +566,7 @@ gst_riff_create_video_template_caps (void) GST_MAKE_FOURCC ('c', 'v', 'i', 'd'), GST_MAKE_FOURCC ('m', 's', 'v', 'c'), GST_MAKE_FOURCC ('R', 'L', 'E', ' '), + GST_MAKE_FOURCC ('D', 'I', 'B', ' '), /* FILL ME */ 0 }; diff --git a/gst-libs/gst/riff/riff-read.c b/gst-libs/gst/riff/riff-read.c index 54e79ff073..97c51f0d43 100644 --- a/gst-libs/gst/riff/riff-read.c +++ b/gst-libs/gst/riff/riff-read.c @@ -582,9 +582,9 @@ gst_riff_read_strf_vids_with_data (GstRiffRead * riff, } else if (strf->size < GST_BUFFER_SIZE (buf)) { gint len; - len = GST_BUFFER_SIZE (buf) - strf->size - 2; + len = GST_BUFFER_SIZE (buf) - strf->size; if (len > 0) { - *extradata = gst_buffer_create_sub (buf, strf->size + 2, len); + *extradata = gst_buffer_create_sub (buf, strf->size, len); } } diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c index b6ee29be1a..e62fba0cb1 100644 --- a/gst/qtdemux/qtdemux.c +++ b/gst/qtdemux/qtdemux.c @@ -1876,6 +1876,9 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak) tkhd = qtdemux_tree_get_child_by_type (trak, FOURCC_tkhd); g_assert (tkhd); + GST_LOG ("track[tkhd] version/flags: 0x%08x", + QTDEMUX_GUINT32_GET (tkhd->data + 8)); + /* track duration? */ mdia = qtdemux_tree_get_child_by_type (trak, FOURCC_mdia); @@ -1885,7 +1888,21 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak) g_assert (mdhd); stream->timescale = QTDEMUX_GUINT32_GET (mdhd->data + 20); - GST_INFO ("track timescale: %d", stream->timescale); + GST_LOG ("track timescale: %d", stream->timescale); + GST_LOG ("track duration: %d", QTDEMUX_GUINT32_GET (mdhd->data + 24)); + + /* HACK: + * some of those trailers, nowadays, have prologue images that are + * themselves vide tracks as well. I haven't really found a way to + * identify those yet, except for just looking at their duration. */ + if ((guint64) QTDEMUX_GUINT32_GET (mdhd->data + 24) * + qtdemux->timescale * 10 / (stream->timescale * qtdemux->duration) < 2) { + GST_WARNING ("Track shorter than 20%% (%d/%d vs. %d/%d) of the stream " + "found, assuming preview image or something; skipping track", + QTDEMUX_GUINT32_GET (mdhd->data + 24), stream->timescale, + qtdemux->duration, qtdemux->timescale); + return; + } hdlr = qtdemux_tree_get_child_by_type (mdia, FOURCC_hdlr); g_assert (hdlr);