summaryrefslogtreecommitdiffstats
path: root/gst/matroska/matroska-mux.c
diff options
context:
space:
mode:
authorSebastian Dröge <slomo@circular-chaos.org>2008-08-09 13:48:22 +0000
committerSebastian Dröge <slomo@circular-chaos.org>2008-08-09 13:48:22 +0000
commitb6f5226f0415f1068f09d99ca4fc5cd4d819b175 (patch)
tree2204ea494ec57f6fa999a0dc55416dd86d647a99 /gst/matroska/matroska-mux.c
parent530c36d9e7177463a00d74cb840f415eaa0f1fab (diff)
gst/matroska/matroska-mux.c: Add support for muxing FLAC into Matroska containers.
Original commit message from CVS: * gst/matroska/matroska-mux.c: (flac_streamheader_to_codecdata), (gst_matroska_mux_audio_pad_setcaps): Add support for muxing FLAC into Matroska containers. Fixes bug #311586.
Diffstat (limited to 'gst/matroska/matroska-mux.c')
-rw-r--r--gst/matroska/matroska-mux.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/gst/matroska/matroska-mux.c b/gst/matroska/matroska-mux.c
index c2a73453..044504d6 100644
--- a/gst/matroska/matroska-mux.c
+++ b/gst/matroska/matroska-mux.c
@@ -118,6 +118,8 @@ static GstStaticPadTemplate audiosink_templ =
COMMON_AUDIO_CAPS "; "
"audio/x-vorbis, "
COMMON_AUDIO_CAPS "; "
+ "audio/x-flac, "
+ COMMON_AUDIO_CAPS "; "
"audio/x-raw-int, "
"width = (int) 8, "
"depth = (int) 8, "
@@ -198,6 +200,8 @@ static gboolean theora_streamheader_to_codecdata (const GValue * streamheader,
GstMatroskaTrackContext * context);
static gboolean vorbis_streamheader_to_codecdata (const GValue * streamheader,
GstMatroskaTrackContext * context);
+static gboolean flac_streamheader_to_codecdata (const GValue * streamheader,
+ GstMatroskaTrackContext * context);
static void
gst_matroska_mux_add_interfaces (GType type)
@@ -924,6 +928,74 @@ theora_streamheader_to_codecdata (const GValue * streamheader,
return TRUE;
}
+static gboolean
+flac_streamheader_to_codecdata (const GValue * streamheader,
+ GstMatroskaTrackContext * context)
+{
+ GArray *bufarr;
+ gint i;
+ GValue *bufval;
+ GstBuffer *buffer;
+
+ if (streamheader == NULL || G_VALUE_TYPE (streamheader) != GST_TYPE_ARRAY) {
+ GST_WARNING ("No or invalid streamheader field in the caps");
+ return FALSE;
+ }
+
+ bufarr = g_value_peek_pointer (streamheader);
+ if (bufarr->len < 2) {
+ GST_WARNING ("Too few headers in streamheader field");
+ return FALSE;
+ }
+
+ context->xiph_headers_to_skip = bufarr->len;
+
+ bufval = &g_array_index (bufarr, GValue, 0);
+ if (G_VALUE_TYPE (bufval) != GST_TYPE_BUFFER) {
+ GST_WARNING ("streamheaders array does not contain GstBuffers");
+ return FALSE;
+ }
+
+ buffer = g_value_peek_pointer (bufval);
+
+ /* Need at least OggFLAC mapping header, fLaC marker and STREAMINFO block */
+ if (GST_BUFFER_SIZE (buffer) < 9 + 4 + 4 + 34
+ || memcmp (GST_BUFFER_DATA (buffer) + 1, "FLAC", 4) != 0
+ || memcmp (GST_BUFFER_DATA (buffer) + 9, "fLaC", 4) != 0) {
+ GST_WARNING ("Invalid streamheader for FLAC");
+ return FALSE;
+ }
+
+ context->codec_priv = g_malloc (GST_BUFFER_SIZE (buffer) - 9);
+ context->codec_priv_size = GST_BUFFER_SIZE (buffer) - 9;
+ memcpy (context->codec_priv, GST_BUFFER_DATA (buffer) + 9,
+ GST_BUFFER_SIZE (buffer) - 9);
+
+ for (i = 1; i < bufarr->len; i++) {
+ bufval = &g_array_index (bufarr, GValue, i);
+
+ if (G_VALUE_TYPE (bufval) != GST_TYPE_BUFFER) {
+ g_free (context->codec_priv);
+ context->codec_priv = NULL;
+ context->codec_priv_size = 0;
+ GST_WARNING ("streamheaders array does not contain GstBuffers");
+ return FALSE;
+ }
+
+ buffer = g_value_peek_pointer (bufval);
+
+ context->codec_priv =
+ g_realloc (context->codec_priv,
+ context->codec_priv_size + GST_BUFFER_SIZE (buffer));
+ memcpy (context->codec_priv + context->codec_priv_size,
+ GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
+ context->codec_priv_size =
+ context->codec_priv_size + GST_BUFFER_SIZE (buffer);
+ }
+
+ return TRUE;
+}
+
/**
* gst_matroska_mux_audio_pad_setcaps:
* @pad: Pad which got the caps.
@@ -1094,6 +1166,23 @@ gst_matroska_mux_audio_pad_setcaps (GstPad * pad, GstCaps * caps)
return FALSE;
}
return TRUE;
+ } else if (!strcmp (mimetype, "audio/x-flac")) {
+ const GValue *streamheader;
+
+ context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_FLAC);
+ if (context->codec_priv != NULL) {
+ g_free (context->codec_priv);
+ context->codec_priv = NULL;
+ context->codec_priv_size = 0;
+ }
+
+ streamheader = gst_structure_get_value (structure, "streamheader");
+ if (!flac_streamheader_to_codecdata (streamheader, context)) {
+ GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL),
+ ("flac stream headers missing or malformed"));
+ return FALSE;
+ }
+ return TRUE;
} else if (!strcmp (mimetype, "audio/x-ac3")) {
context->codec_id = g_strdup (GST_MATROSKA_CODEC_ID_AUDIO_AC3);