summaryrefslogtreecommitdiffstats
path: root/gst/matroska
diff options
context:
space:
mode:
authorThiago Santos <thiagoss@embedded.ufcg.edu.br>2009-08-08 00:47:48 -0300
committerThiago Santos <thiagoss@embedded.ufcg.edu.br>2009-08-09 20:34:05 -0300
commit08862850a70674c3a2380a4f8232c0dee91dbd96 (patch)
tree3b731f40ab8b60b408b7e209e319c82bfa225119 /gst/matroska
parentdf442b47272295a2f5ec3e41023d5a0cf1b9c7a0 (diff)
matroska: Adds support to muxing/demuxing WMA
Adds support for muxing wma audio family and fixes demuxing of wma family in matroskademux. matroskademux was broken because it missed codec_data.
Diffstat (limited to 'gst/matroska')
-rw-r--r--gst/matroska/matroska-demux.c26
-rw-r--r--gst/matroska/matroska-mux.c84
-rw-r--r--gst/matroska/matroska-mux.h2
3 files changed, 92 insertions, 20 deletions
diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c
index 1384ee4f..1ffe8c49 100644
--- a/gst/matroska/matroska-demux.c
+++ b/gst/matroska/matroska-demux.c
@@ -5554,21 +5554,25 @@ gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext *
caps = gst_caps_new_simple ("audio/x-speex", NULL);
context->send_speex_headers = TRUE;
} else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_ACM)) {
- gst_riff_strf_auds *auds = NULL;
+ gst_riff_strf_auds auds;
if (data) {
- auds = (gst_riff_strf_auds *) data;
+ GstBuffer *codec_data = gst_buffer_new ();
/* little-endian -> byte-order */
- auds->format = GUINT16_FROM_LE (auds->format);
- auds->channels = GUINT16_FROM_LE (auds->channels);
- auds->rate = GUINT32_FROM_LE (auds->rate);
- auds->av_bps = GUINT32_FROM_LE (auds->av_bps);
- auds->blockalign = GUINT16_FROM_LE (auds->blockalign);
- auds->size = GUINT16_FROM_LE (auds->size);
-
- caps = gst_riff_create_audio_caps (auds->format, NULL, auds, NULL,
- NULL, codec_name);
+ auds.format = GST_READ_UINT16_LE (data);
+ auds.channels = GST_READ_UINT16_LE (data + 2);
+ auds.rate = GST_READ_UINT32_LE (data + 4);
+ auds.av_bps = GST_READ_UINT32_LE (data + 8);
+ auds.blockalign = GST_READ_UINT16_LE (data + 12);
+ auds.size = GST_READ_UINT16_LE (data + 16);
+
+ /* 18 is the waveformatex size */
+ gst_buffer_set_data (codec_data, data + 18, auds.size);
+
+ caps = gst_riff_create_audio_caps (auds.format, NULL, &auds, NULL,
+ codec_data, codec_name);
+ gst_buffer_unref (codec_data);
}
} else if (g_str_has_prefix (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AAC)) {
GstBuffer *priv = NULL;
diff --git a/gst/matroska/matroska-mux.c b/gst/matroska/matroska-mux.c
index a40cea32..7e21ad3a 100644
--- a/gst/matroska/matroska-mux.c
+++ b/gst/matroska/matroska-mux.c
@@ -48,6 +48,8 @@
#include <math.h>
#include <string.h>
+#include <gst/riff/riff-media.h>
+
#include "matroska-mux.h"
#include "matroska-ids.h"
@@ -176,7 +178,10 @@ static GstStaticPadTemplate audiosink_templ =
"width = (int) { 8, 16, 24 }, "
"channels = (int) { 1, 2 }, " "rate = (int) [ 8000, 96000 ]; "
"audio/x-pn-realaudio, "
- "raversion = (int) { 1, 2, 8 }, " COMMON_AUDIO_CAPS ";")
+ "raversion = (int) { 1, 2, 8 }, " COMMON_AUDIO_CAPS "; "
+ "audio/x-wma, " "wmaversion = (int) [ 1, 3 ], "
+ "block_align = (int) [ 0, 65535 ], bitrate = (int) [ 0, 524288 ], "
+ COMMON_AUDIO_CAPS)
);
static GstStaticPadTemplate subtitlesink_templ =
@@ -758,7 +763,6 @@ skip_details:
} else if (!strcmp (mimetype, "video/x-wmv")) {
gint wmvversion;
guint32 format;
- GST_WARNING_OBJECT (mux, "WMV");
if (gst_structure_get_fourcc (structure, "format", &format)) {
fourcc = format;
} else if (gst_structure_get_int (structure, "wmvversion", &wmvversion)) {
@@ -770,7 +774,6 @@ skip_details:
fourcc = GST_MAKE_FOURCC ('W', 'M', 'V', '3');
}
}
- GST_WARNING_OBJECT (mux, "fourcc=%u", fourcc);
}
if (!fourcc)
@@ -1406,6 +1409,8 @@ gst_matroska_mux_audio_pad_setcaps (GstPad * pad, GstCaps * caps)
const gchar *mimetype;
gint samplerate = 0, channels = 0;
GstStructure *structure;
+ const GValue *codec_data = NULL;
+ const GstBuffer *buf = NULL;
mux = GST_MATROSKA_MUX (GST_PAD_PARENT (pad));
@@ -1429,6 +1434,10 @@ gst_matroska_mux_audio_pad_setcaps (GstPad * pad, GstCaps * caps)
audiocontext->bitdepth = 0;
context->default_duration = 0;
+ codec_data = gst_structure_get_value (structure, "codec_data");
+ if (codec_data)
+ buf = gst_value_get_buffer (codec_data);
+
/* TODO: - check if we handle all codecs by the spec, i.e. codec private
* data and other settings
* - add new formats
@@ -1436,12 +1445,6 @@ gst_matroska_mux_audio_pad_setcaps (GstPad * pad, GstCaps * caps)
if (!strcmp (mimetype, "audio/mpeg")) {
gint mpegversion = 0;
- const GValue *codec_data;
- const GstBuffer *buf = NULL;
-
- codec_data = gst_structure_get_value (structure, "codec_data");
- if (codec_data)
- buf = gst_value_get_buffer (codec_data);
gst_structure_get_int (structure, "mpegversion", &mpegversion);
switch (mpegversion) {
@@ -1661,6 +1664,69 @@ gst_matroska_mux_audio_pad_setcaps (GstPad * pad, GstCaps * caps)
}
return TRUE;
+ } else if (!strcmp (mimetype, "audio/x-wma")) {
+ guint8 *codec_priv;
+ guint codec_priv_size;
+ guint16 format;
+ gint block_align;
+ gint bitrate;
+ gint wmaversion;
+ gint depth;
+
+ if (!gst_structure_get_int (structure, "wmaversion", &wmaversion)
+ || !gst_structure_get_int (structure, "block_align", &block_align)
+ || !gst_structure_get_int (structure, "bitrate", &bitrate)
+ || samplerate == 0 || channels == 0) {
+ GST_WARNING_OBJECT (mux, "Missing wmaversion/block_align/bitrate/"
+ "channels/rate on WMA caps");
+ return FALSE;
+ }
+
+ switch (wmaversion) {
+ case 1:
+ format = GST_RIFF_WAVE_FORMAT_WMAV1;
+ break;
+ case 2:
+ format = GST_RIFF_WAVE_FORMAT_WMAV2;
+ break;
+ case 3:
+ format = GST_RIFF_WAVE_FORMAT_WMAV3;
+ break;
+ default:
+ GST_WARNING_OBJECT (mux, "Unexpected WMA version: %d", wmaversion);
+ return FALSE;
+ }
+
+ if (gst_structure_get_int (structure, "depth", &depth))
+ audiocontext->bitdepth = depth;
+
+ codec_priv_size = WAVEFORMATEX_SIZE;
+ if (buf)
+ codec_priv_size += GST_BUFFER_SIZE (buf);
+
+ /* serialize waveformatex structure */
+ codec_priv = g_malloc0 (codec_priv_size);
+ GST_WRITE_UINT16_LE (codec_priv, format);
+ GST_WRITE_UINT16_LE (codec_priv + 2, channels);
+ GST_WRITE_UINT32_LE (codec_priv + 4, samplerate);
+ GST_WRITE_UINT32_LE (codec_priv + 8, bitrate / 8);
+ GST_WRITE_UINT16_LE (codec_priv + 12, block_align);
+ GST_WRITE_UINT16_LE (codec_priv + 14, 0);
+ if (buf)
+ GST_WRITE_UINT16_LE (codec_priv + 16, GST_BUFFER_SIZE (buf));
+ else
+ GST_WRITE_UINT16_LE (codec_priv + 16, 0);
+
+ /* process codec private/initialization data, if any */
+ if (buf) {
+ memcpy ((guint8 *) codec_priv + WAVEFORMATEX_SIZE,
+ GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+ }
+
+ context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_ACM);
+ context->codec_priv = (gpointer) codec_priv;
+ context->codec_priv_size = codec_priv_size;
+ return TRUE;
}
return FALSE;
diff --git a/gst/matroska/matroska-mux.h b/gst/matroska/matroska-mux.h
index 22ee9352..e969f85e 100644
--- a/gst/matroska/matroska-mux.h
+++ b/gst/matroska/matroska-mux.h
@@ -56,6 +56,8 @@ typedef struct _BITMAPINFOHEADER {
guint32 bi_clr_important;
} BITMAPINFOHEADER;
+#define WAVEFORMATEX_SIZE 18
+
typedef enum {
GST_MATROSKA_MUX_STATE_START,
GST_MATROSKA_MUX_STATE_HEADER,