From 671b56f9da6ce3e337307eeba5d25b2e29645560 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Tue, 27 Sep 2011 15:59:24 +0100 Subject: [PATCH] matroskademux: ensure minimal alignment for audio/x-raw-* buffers Since matroskademux will attempt to push unaligned buffers, downstream might have trouble with those, especially if downstream uses ORC, such as audioconvert. Ensure we push buffers aligned to the basic type at least for those raw buffers. https://bugzilla.gnome.org/show_bug.cgi?id=659798 --- gst/matroska/matroska-demux.c | 21 +++++++++++++++++++++ gst/matroska/matroska-ids.h | 3 +++ gst/matroska/matroska-parse.c | 1 + 3 files changed, 25 insertions(+) diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c index fad741a26b..402f6a4996 100644 --- a/gst/matroska/matroska-demux.c +++ b/gst/matroska/matroska-demux.c @@ -552,6 +552,7 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux, GstEbmlRead * ebml) GST_MATROSKA_TRACK_LACING; context->last_flow = GST_FLOW_OK; context->to_offset = G_MAXINT64; + context->alignment = 1; demux->common.num_streams++; g_assert (demux->common.src->len == demux->common.num_streams); @@ -3507,6 +3508,24 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux, ret = stream->postprocess_frame (GST_ELEMENT (demux), stream, &sub); } + /* At this point, we have a sub-buffer pointing at data within a larger + buffer. This data might not be aligned with anything. If the data is + raw samples though, we want it aligned to the raw type (eg, 4 bytes + for 32 bit samples, etc), or bad things will happen downstream as + elements typically assume minimal alignment. + Therefore, create an aligned copy if necessary. */ + g_assert (stream->alignment <= G_MEM_ALIGN); + if (((guintptr) GST_BUFFER_DATA (sub)) & (stream->alignment - 1)) { + GstBuffer *buffer = gst_buffer_new_and_alloc (GST_BUFFER_SIZE (sub)); + memcpy (GST_BUFFER_DATA (buffer), GST_BUFFER_DATA (sub), + GST_BUFFER_SIZE (sub)); + gst_buffer_copy_metadata (buffer, sub, GST_BUFFER_COPY_ALL); + GST_DEBUG_OBJECT (demux, "We want output aligned on %d, reallocated", + stream->alignment); + gst_buffer_unref (sub); + sub = buffer; + } + ret = gst_pad_push (stream->pad, sub); if (demux->common.segment.rate < 0) { if (lace_time > demux->common.segment.stop @@ -5090,12 +5109,14 @@ gst_matroska_demux_audio_caps (GstMatroskaTrackAudioContext * *codec_name = g_strdup_printf ("Raw %d-bit PCM audio", audiocontext->bitdepth); + context->alignment = audiocontext->bitdepth / 8; } else if (!strcmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_PCM_FLOAT)) { caps = gst_caps_new_simple ("audio/x-raw-float", "endianness", G_TYPE_INT, G_LITTLE_ENDIAN, "width", G_TYPE_INT, audiocontext->bitdepth, NULL); *codec_name = g_strdup_printf ("Raw %d-bit floating-point audio", audiocontext->bitdepth); + context->alignment = audiocontext->bitdepth / 8; } else if (!strncmp (codec_id, GST_MATROSKA_CODEC_ID_AUDIO_AC3, strlen (GST_MATROSKA_CODEC_ID_AUDIO_AC3))) { caps = gst_caps_new_simple ("audio/x-ac3", diff --git a/gst/matroska/matroska-ids.h b/gst/matroska/matroska-ids.h index dcb8bf6dd2..ade72a00fe 100644 --- a/gst/matroska/matroska-ids.h +++ b/gst/matroska/matroska-ids.h @@ -537,6 +537,9 @@ struct _GstMatroskaTrackContext { /* Whether the stream is EOS */ gboolean eos; + + /* any alignment we need our output buffers to have */ + gint alignment; }; typedef struct _GstMatroskaTrackVideoContext { diff --git a/gst/matroska/matroska-parse.c b/gst/matroska/matroska-parse.c index a790a2f092..75222de707 100644 --- a/gst/matroska/matroska-parse.c +++ b/gst/matroska/matroska-parse.c @@ -413,6 +413,7 @@ gst_matroska_parse_add_stream (GstMatroskaParse * parse, GstEbmlRead * ebml) GST_MATROSKA_TRACK_LACING; context->last_flow = GST_FLOW_OK; context->to_offset = G_MAXINT64; + context->alignment = 1; parse->common.num_streams++; g_assert (parse->common.src->len == parse->common.num_streams);