summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Penquerc'h <vincent.penquerch@collabora.co.uk>2016-02-04 10:43:15 +0000
committerSebastian Dröge <sebastian@centricular.com>2016-02-23 10:47:43 +0200
commit565607107f7d19e360faa379a7c19a68d140b1d9 (patch)
tree782a95199c5379206b76e4bd4fa620c72354d6d0
parentafad769c786c02a0cf5c1c3c63a9f4374636e66b (diff)
downloadgstreamer-plugins-good-565607107f7d19e360faa379a7c19a68d140b1d9.tar.gz
matroska-mux: make up an OpusHead block if possible when missing
This block is needed in the Matroska file, but data coming from RTP may not have one. https://bugzilla.gnome.org/show_bug.cgi?id=761489
-rw-r--r--gst/matroska/matroska-mux.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/gst/matroska/matroska-mux.c b/gst/matroska/matroska-mux.c
index ea5586b4b..d4186f21d 100644
--- a/gst/matroska/matroska-mux.c
+++ b/gst/matroska/matroska-mux.c
@@ -53,6 +53,7 @@
#include <gst/audio/audio.h>
#include <gst/riff/riff-media.h>
#include <gst/tag/tag.h>
+#include <gst/pbutils/codec-utils.h>
#include "matroska-mux.h"
#include "matroska-ids.h"
@@ -1687,6 +1688,48 @@ wrong_content_type:
}
}
+static gboolean
+opus_make_codecdata (GstMatroskaTrackContext * context, GstCaps * caps)
+{
+ guint32 rate;
+ guint8 channels;
+ guint8 channel_mapping_family;
+ guint8 stream_count, coupled_count, channel_mapping[256];
+ GstBuffer *buffer;
+ GstMapInfo map;
+
+ /* Opus headers are not in-band */
+ context->xiph_headers_to_skip = 0;
+
+ context->codec_delay = 0;
+ context->seek_preroll = 80 * GST_MSECOND;
+
+ if (!gst_codec_utils_opus_parse_caps (caps, &rate, &channels,
+ &channel_mapping_family, &stream_count, &coupled_count,
+ channel_mapping)) {
+ GST_WARNING ("Failed to parse caps for Opus");
+ return FALSE;
+ }
+
+ buffer =
+ gst_codec_utils_opus_create_header (rate, channels,
+ channel_mapping_family, stream_count, coupled_count, channel_mapping, 0,
+ 0);
+ if (!buffer) {
+ GST_WARNING ("Failed to create Opus header from caps");
+ return FALSE;
+ }
+
+ gst_buffer_map (buffer, &map, GST_MAP_READ);
+ context->codec_priv_size = map.size;
+ context->codec_priv = g_malloc (context->codec_priv_size);
+ memcpy (context->codec_priv, map.data, map.size);
+ gst_buffer_unmap (buffer, &map);
+ gst_buffer_unref (buffer);
+
+ return TRUE;
+}
+
/**
* gst_matroska_mux_audio_pad_setcaps:
* @pad: Pad which got the caps.
@@ -1909,6 +1952,15 @@ gst_matroska_mux_audio_pad_setcaps (GstPad * pad, GstCaps * caps)
("opus stream headers missing or malformed"));
goto refuse_caps;
}
+ } else {
+ /* no streamheader, but we need to have one, so we make one up
+ based on caps */
+ gst_matroska_mux_free_codec_priv (context);
+ if (!opus_make_codecdata (context, caps)) {
+ GST_ELEMENT_ERROR (mux, STREAM, MUX, (NULL),
+ ("opus stream headers missing or malformed"));
+ goto refuse_caps;
+ }
}
} else if (!strcmp (mimetype, "audio/x-ac3")) {
gst_matroska_mux_set_codec_id (context, GST_MATROSKA_CODEC_ID_AUDIO_AC3);