From b38e44828eabca21063f3cc570993d61ca419b7c Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 16 Apr 2004 01:20:44 +0000 Subject: gst/: Add MS RLE support. I added some functions to read out strf chunks into strf chunks and the data behind it. Thi... Original commit message from CVS: reviewed by: * gst-libs/gst/riff/riff-media.c: (gst_riff_create_video_caps_with_data), (gst_riff_create_video_caps), (gst_riff_create_audio_caps), (gst_riff_create_video_template_caps), (gst_riff_create_audio_template_caps): * gst-libs/gst/riff/riff-media.h: * gst-libs/gst/riff/riff-read.c: (gst_riff_read_strf_vids_with_data), (gst_riff_read_strf_vids): * gst-libs/gst/riff/riff-read.h: * gst/avi/gstavidemux.c: (gst_avi_demux_add_stream): Add MS RLE support. I added some functions to read out strf chunks into strf chunks and the data behind it. This is usually color palettes (as in RLE, but also in 8-bit RGB). Also use those during caps creation. Lastly, add ADPCM (similar to wavparse - which should eventually be rifflib based). * gst/matroska/matroska-demux.c: (gst_matroska_demux_class_init), (gst_matroska_demux_init), (gst_matroska_demux_reset): * gst/matroska/matroska-demux.h: Remove placeholders for some prehistoric tagging system. Didn't add support for any tag system really anyway. * gst/qtdemux/qtdemux.c: Add support for audio/x-m4a (MPEG-4) through spider. * gst/wavparse/gstwavparse.c: (gst_wavparse_parse_fmt), (gst_wavparse_loop): ADPCM support (#135862). Increase max. buffer size because we cannot split buffers for ADPCM (screws references) and I've seen files with 2048 byte chunks. 4096 seems safe for now. --- ChangeLog | 32 +++++++++++++++++ gst-libs/gst/riff/riff-media.c | 80 ++++++++++++++++++++++++++++++++++++++++-- gst-libs/gst/riff/riff-media.h | 12 +++++++ gst-libs/gst/riff/riff-read.c | 26 +++++++++++++- gst-libs/gst/riff/riff-read.h | 4 +++ gst/qtdemux/qtdemux.c | 4 +-- 6 files changed, 153 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index e098e2b7..4c4bd4c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +2004-04-15 Ronald Bultje + + reviewed by: + + * gst-libs/gst/riff/riff-media.c: + (gst_riff_create_video_caps_with_data), + (gst_riff_create_video_caps), (gst_riff_create_audio_caps), + (gst_riff_create_video_template_caps), + (gst_riff_create_audio_template_caps): + * gst-libs/gst/riff/riff-media.h: + * gst-libs/gst/riff/riff-read.c: + (gst_riff_read_strf_vids_with_data), (gst_riff_read_strf_vids): + * gst-libs/gst/riff/riff-read.h: + * gst/avi/gstavidemux.c: (gst_avi_demux_add_stream): + Add MS RLE support. I added some functions to read out strf chunks + into strf chunks and the data behind it. This is usually color + palettes (as in RLE, but also in 8-bit RGB). Also use those during + caps creation. Lastly, add ADPCM (similar to wavparse - which + should eventually be rifflib based). + * gst/matroska/matroska-demux.c: (gst_matroska_demux_class_init), + (gst_matroska_demux_init), (gst_matroska_demux_reset): + * gst/matroska/matroska-demux.h: + Remove placeholders for some prehistoric tagging system. Didn't add + support for any tag system really anyway. + * gst/qtdemux/qtdemux.c: + Add support for audio/x-m4a (MPEG-4) through spider. + * gst/wavparse/gstwavparse.c: (gst_wavparse_parse_fmt), + (gst_wavparse_loop): + ADPCM support (#135862). Increase max. buffer size because we + cannot split buffers for ADPCM (screws references) and I've seen + files with 2048 byte chunks. 4096 seems safe for now. + 2004-04-15 Thomas Vander Stichele * configure.ac: bump nano to 1 diff --git a/gst-libs/gst/riff/riff-media.c b/gst-libs/gst/riff/riff-media.c index 4da36976..621b05ee 100644 --- a/gst-libs/gst/riff/riff-media.c +++ b/gst-libs/gst/riff/riff-media.c @@ -26,9 +26,24 @@ #include "riff-ids.h" #include "riff-media.h" +/** + * gst_riff_create_video_caps_with_data: + * @codec_fcc: fourCC codec for this codec. + * @strh: pointer to the strh stream header structure. + * @strf: pointer to the strf stream header structure, including any + * data that is within the range of strf.size, but excluding any + * additional data withint this chunk but outside strf.size. + * @strf_data: a #GstBuffer containing the additional data in the strf + * chunk outside reach of strf.size. Ususally a palette. + * @strd_data: a #GstBuffer containing the data in the strd stream header + * chunk. Usually codec initialization data. + * @codec_name: if given, will be filled with a human-readable codec name. + */ + GstCaps * -gst_riff_create_video_caps (guint32 codec_fcc, - gst_riff_strh * strh, gst_riff_strf_vids * strf, char **codec_name) +gst_riff_create_video_caps_with_data (guint32 codec_fcc, + gst_riff_strh * strh, gst_riff_strf_vids * strf, + GstBuffer * strf_data, GstBuffer * strd_data, char **codec_name) { GstCaps *caps = NULL; @@ -39,6 +54,7 @@ gst_riff_create_video_caps (guint32 codec_fcc, if (codec_name) *codec_name = g_strdup ("Uncompressed planar YUV 4:2:0"); break; + case GST_MAKE_FOURCC ('Y', 'U', 'Y', '2'): caps = gst_caps_new_simple ("video/x-raw-yuv", "format", GST_TYPE_FOURCC, codec_fcc, NULL); @@ -51,6 +67,7 @@ gst_riff_create_video_caps (guint32 codec_fcc, if (codec_name) *codec_name = g_strdup ("Motion JPEG"); break; + case GST_MAKE_FOURCC ('J', 'P', 'E', 'G'): /* generic (mostly RGB) MJPEG */ caps = gst_caps_new_simple ("image/jpeg", NULL); if (codec_name) @@ -84,31 +101,37 @@ gst_riff_create_video_caps (guint32 codec_fcc, if (codec_name) *codec_name = g_strdup ("ITU H.26n"); break; + case GST_MAKE_FOURCC ('i', '2', '6', '3'): caps = gst_caps_new_simple ("video/x-h263", NULL); if (codec_name) *codec_name = g_strdup ("ITU H.263"); break; + case GST_MAKE_FOURCC ('L', '2', '6', '3'): caps = gst_caps_new_simple ("video/x-h263", NULL); if (codec_name) *codec_name = g_strdup ("Lead H.263"); break; + case GST_MAKE_FOURCC ('M', '2', '6', '3'): caps = gst_caps_new_simple ("video/x-h263", NULL); if (codec_name) *codec_name = g_strdup ("Microsoft H.263"); break; + case GST_MAKE_FOURCC ('V', 'D', 'O', 'W'): caps = gst_caps_new_simple ("video/x-h263", NULL); if (codec_name) *codec_name = g_strdup ("VDOLive"); break; + case GST_MAKE_FOURCC ('V', 'I', 'V', 'O'): caps = gst_caps_new_simple ("video/x-h263", NULL); if (codec_name) *codec_name = g_strdup ("Vivo H.263"); break; + case GST_MAKE_FOURCC ('x', '2', '6', '3'): caps = gst_caps_new_simple ("video/x-h263", NULL); if (codec_name) @@ -124,6 +147,7 @@ gst_riff_create_video_caps (guint32 codec_fcc, if (codec_name) *codec_name = g_strdup ("DivX MS-MPEG-4 Version 3"); break; + case GST_MAKE_FOURCC ('d', 'i', 'v', 'x'): case GST_MAKE_FOURCC ('D', 'I', 'V', 'X'): caps = gst_caps_new_simple ("video/x-divx", @@ -131,6 +155,7 @@ gst_riff_create_video_caps (guint32 codec_fcc, if (codec_name) *codec_name = g_strdup ("DivX MPEG-4 Version 4"); break; + case GST_MAKE_FOURCC ('D', 'X', '5', '0'): caps = gst_caps_new_simple ("video/x-divx", "divxversion", G_TYPE_INT, 5, NULL); @@ -220,6 +245,40 @@ gst_riff_create_video_caps (guint32 codec_fcc, *codec_name = g_strdup ("MS video v1"); break; + case GST_MAKE_FOURCC ('R', 'L', 'E', ' '): + case GST_MAKE_FOURCC ('m', 'r', 'l', 'e'): + 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); + } + if (strf) { + gst_caps_set_simple (caps, + "depth", G_TYPE_INT, (gint) strf->bit_cnt, NULL); + } else { + gst_caps_set_simple (caps, "depth", GST_TYPE_INT_RANGE, 1, 64, NULL); + } + if (codec_name) + *codec_name = g_strdup ("Mcrosoft RLE"); + break; + default: GST_WARNING ("Unkown video fourcc " GST_FOURCC_FORMAT, GST_FOURCC_ARGS (codec_fcc)); @@ -248,6 +307,14 @@ gst_riff_create_video_caps (guint32 codec_fcc, return caps; } +GstCaps * +gst_riff_create_video_caps (guint32 codec_fcc, + gst_riff_strh * strh, gst_riff_strf_vids * strf, char **codec_name) +{ + return gst_riff_create_video_caps_with_data (codec_fcc, + strh, strf, NULL, NULL, codec_name); +} + GstCaps * gst_riff_create_audio_caps (guint16 codec_id, gst_riff_strh * strh, gst_riff_strf_auds * strf, char **codec_name) @@ -289,6 +356,13 @@ gst_riff_create_audio_caps (guint16 codec_id, *codec_name = g_strdup ("Uncompressed PCM audio"); break; + case GST_RIFF_WAVE_FORMAT_ADPCM: + caps = gst_caps_new_simple ("audio/x-adpcm", + "layout", G_TYPE_STRING, "microsoft", NULL); + if (codec_name) + *codec_name = g_strdup ("ADPCM audio"); + break; + case GST_RIFF_WAVE_FORMAT_MULAW: if (strf != NULL && strf->size != 8) { GST_WARNING ("invalid depth (%d) of mulaw audio, overwriting.", @@ -394,6 +468,7 @@ gst_riff_create_video_template_caps (void) GST_MAKE_FOURCC ('3', 'I', 'V', '1'), GST_MAKE_FOURCC ('c', 'v', 'i', 'd'), GST_MAKE_FOURCC ('m', 's', 'v', 'c'), + GST_MAKE_FOURCC ('R', 'L', 'E', ' '), /* FILL ME */ 0 }; @@ -421,6 +496,7 @@ gst_riff_create_audio_template_caps (void) GST_RIFF_WAVE_FORMAT_A52, GST_RIFF_WAVE_FORMAT_ALAW, GST_RIFF_WAVE_FORMAT_MULAW, + GST_RIFF_WAVE_FORMAT_ADPCM, /* FILL ME */ 0 }; diff --git a/gst-libs/gst/riff/riff-media.h b/gst-libs/gst/riff/riff-media.h index 220671af..22c72fe6 100644 --- a/gst-libs/gst/riff/riff-media.h +++ b/gst-libs/gst/riff/riff-media.h @@ -45,6 +45,18 @@ GstCaps *gst_riff_create_iavs_caps (guint32 codec_fcc, gst_riff_strf_iavs *strf, char **codec_name); +/* + * Extended... + */ + +GstCaps * +gst_riff_create_video_caps_with_data (guint32 codec_fcc, + gst_riff_strh * strh, + gst_riff_strf_vids * strf, + GstBuffer * strf_data, + GstBuffer * strd_data, + char ** codec_name); + /* * Create template caps (includes all known types). */ diff --git a/gst-libs/gst/riff/riff-read.c b/gst-libs/gst/riff/riff-read.c index 0eed6242..a86ec866 100644 --- a/gst-libs/gst/riff/riff-read.c +++ b/gst-libs/gst/riff/riff-read.c @@ -458,7 +458,8 @@ gst_riff_read_strh (GstRiffRead * riff, gst_riff_strh ** header) } gboolean -gst_riff_read_strf_vids (GstRiffRead * riff, gst_riff_strf_vids ** header) +gst_riff_read_strf_vids_with_data (GstRiffRead * riff, + gst_riff_strf_vids ** header, GstBuffer ** extradata) { guint32 tag; GstBuffer *buf; @@ -496,10 +497,14 @@ gst_riff_read_strf_vids (GstRiffRead * riff, gst_riff_strf_vids ** header) #endif /* size checking */ + *extradata = NULL; if (strf->size > GST_BUFFER_SIZE (buf)) { g_warning ("strf_vids header gave %d bytes data, only %d available", strf->size, GST_BUFFER_SIZE (buf)); strf->size = GST_BUFFER_SIZE (buf); + } else if (strf->size < GST_BUFFER_SIZE (buf)) { + *extradata = gst_buffer_create_sub (buf, strf->size, + GST_BUFFER_SIZE (buf) - strf->size); } /* debug */ @@ -516,6 +521,8 @@ gst_riff_read_strf_vids (GstRiffRead * riff, gst_riff_strf_vids ** header) GST_INFO (" ypels_meter %d", strf->ypels_meter); GST_INFO (" num_colors %d", strf->num_colors); GST_INFO (" imp_colors %d", strf->imp_colors); + if (*extradata) + GST_INFO (" %d bytes extra_data", GST_BUFFER_SIZE (*extradata)); gst_buffer_unref (buf); @@ -524,6 +531,23 @@ gst_riff_read_strf_vids (GstRiffRead * riff, gst_riff_strf_vids ** header) return TRUE; } +/* + * Obsolete, use gst_riff_read_strf_vids_with_data (). + */ + +gboolean +gst_riff_read_strf_vids (GstRiffRead * riff, gst_riff_strf_vids ** header) +{ + GstBuffer *data = NULL; + gboolean ret; + + ret = gst_riff_read_strf_vids_with_data (riff, header, &data); + if (data) + gst_buffer_unref (data); + + return ret; +} + gboolean gst_riff_read_strf_auds (GstRiffRead * riff, gst_riff_strf_auds ** header) { diff --git a/gst-libs/gst/riff/riff-read.h b/gst-libs/gst/riff/riff-read.h index 9c663cca..d0c09b8c 100644 --- a/gst-libs/gst/riff/riff-read.h +++ b/gst-libs/gst/riff/riff-read.h @@ -86,6 +86,10 @@ gboolean gst_riff_read_strh (GstRiffRead *riff, gst_riff_strh **header); gboolean gst_riff_read_strf_vids (GstRiffRead *riff, gst_riff_strf_vids **header); +gboolean gst_riff_read_strf_vids_with_data + (GstRiffRead *riff, + gst_riff_strf_vids **header, + GstBuffer **extradata); gboolean gst_riff_read_strf_auds (GstRiffRead *riff, gst_riff_strf_auds **header); gboolean gst_riff_read_strf_iavs (GstRiffRead *riff, diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c index 224fcb66..3303c6c9 100644 --- a/gst/qtdemux/qtdemux.c +++ b/gst/qtdemux/qtdemux.c @@ -123,10 +123,10 @@ enum }; static GstStaticPadTemplate gst_qtdemux_sink_template = -GST_STATIC_PAD_TEMPLATE ("sink", + GST_STATIC_PAD_TEMPLATE ("sink", GST_PAD_SINK, GST_PAD_SOMETIMES, - GST_STATIC_CAPS ("video/quicktime") + GST_STATIC_CAPS ("video/quicktime; audio/x-m4a") ); static GstStaticPadTemplate gst_qtdemux_videosrc_template = -- cgit v1.2.1