avidemux: Ensure that raw video have properly aligned buffers

That is, aligned to to 32 bytes for video. Fixes crashes if the raw
buffers are passed to SIMD processing functions.

https://bugzilla.gnome.org/show_bug.cgi?id=774428
This commit is contained in:
Sebastian Dröge 2016-11-20 13:14:08 +02:00
parent bb35f15d44
commit b8265e95a7
2 changed files with 45 additions and 0 deletions

View file

@ -1936,6 +1936,7 @@ gst_avi_demux_check_caps (GstAviDemux * avi, GstAviStream * stream,
s = gst_caps_get_structure (caps, 0); s = gst_caps_get_structure (caps, 0);
if (gst_structure_has_name (s, "video/x-raw")) { if (gst_structure_has_name (s, "video/x-raw")) {
stream->is_raw = TRUE; stream->is_raw = TRUE;
stream->alignment = 32;
if (!gst_structure_has_field (s, "pixel-aspect-ratio")) if (!gst_structure_has_field (s, "pixel-aspect-ratio"))
gst_structure_set (s, "pixel-aspect-ratio", GST_TYPE_FRACTION, gst_structure_set (s, "pixel-aspect-ratio", GST_TYPE_FRACTION,
1, 1, NULL); 1, 1, NULL);
@ -5137,6 +5138,44 @@ gst_avi_demux_find_next (GstAviDemux * avi, gfloat rate)
return stream_num; return stream_num;
} }
static GstBuffer *
gst_avi_demux_align_buffer (GstAviDemux * demux,
GstBuffer * buffer, gsize alignment)
{
GstMapInfo map;
gst_buffer_map (buffer, &map, GST_MAP_READ);
if (map.size < sizeof (guintptr)) {
gst_buffer_unmap (buffer, &map);
return buffer;
}
if (((guintptr) map.data) & (alignment - 1)) {
GstBuffer *new_buffer;
GstAllocationParams params = { 0, alignment - 1, 0, 0, };
new_buffer = gst_buffer_new_allocate (NULL,
gst_buffer_get_size (buffer), &params);
/* Copy data "by hand", so ensure alignment is kept: */
gst_buffer_fill (new_buffer, 0, map.data, map.size);
gst_buffer_copy_into (new_buffer, buffer, GST_BUFFER_COPY_METADATA, 0, -1);
GST_DEBUG_OBJECT (demux,
"We want output aligned on %" G_GSIZE_FORMAT ", reallocated",
alignment);
gst_buffer_unmap (buffer, &map);
gst_buffer_unref (buffer);
return new_buffer;
}
gst_buffer_unmap (buffer, &map);
return buffer;
}
static GstFlowReturn static GstFlowReturn
gst_avi_demux_loop_data (GstAviDemux * avi) gst_avi_demux_loop_data (GstAviDemux * avi)
{ {
@ -5256,6 +5295,8 @@ gst_avi_demux_loop_data (GstAviDemux * avi)
gst_buffer_get_size (buf), GST_TIME_ARGS (timestamp), gst_buffer_get_size (buf), GST_TIME_ARGS (timestamp),
GST_TIME_ARGS (duration), out_offset, out_offset_end); GST_TIME_ARGS (duration), out_offset, out_offset_end);
if (stream->alignment > 1)
buf = gst_avi_demux_align_buffer (avi, buf, stream->alignment);
ret = gst_pad_push (stream->pad, buf); ret = gst_pad_push (stream->pad, buf);
/* mark as processed, we increment the frame and byte counters then /* mark as processed, we increment the frame and byte counters then
@ -5545,6 +5586,9 @@ gst_avi_demux_stream_data (GstAviDemux * avi)
} else { } else {
GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT); GST_BUFFER_FLAG_UNSET (buf, GST_BUFFER_FLAG_DISCONT);
} }
if (stream->alignment > 1)
buf = gst_avi_demux_align_buffer (avi, buf, stream->alignment);
res = gst_pad_push (stream->pad, buf); res = gst_pad_push (stream->pad, buf);
buf = NULL; buf = NULL;

View file

@ -120,6 +120,7 @@ typedef struct {
gint index_id; gint index_id;
gboolean is_raw; gboolean is_raw;
gsize alignment;
} GstAviStream; } GstAviStream;
typedef enum { typedef enum {