mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 05:06:17 +00:00
ext/mpeg2dec/gstmpeg2dec.*: Align buffers to a 16 byte boundary so the altivec optimisations don't crash. Fixes #327350.
Original commit message from CVS: Patch by: Sebastian Dröge <slomo@circular-chaos.org> * ext/mpeg2dec/gstmpeg2dec.c: (gst_mpeg2dec_init), (gst_mpeg2dec_reset), (gst_mpeg2dec_alloc_sized_buf), (gst_mpeg2dec_alloc_buffer), (init_dummybuf), (handle_slice): * ext/mpeg2dec/gstmpeg2dec.h: Align buffers to a 16 byte boundary so the altivec optimisations don't crash. Fixes #327350.
This commit is contained in:
parent
ee9f77cd22
commit
1a8dbee3e7
3 changed files with 45 additions and 22 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
2006-11-21 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
|
Patch by: Sebastian Dröge <slomo@circular-chaos.org>
|
||||||
|
|
||||||
|
* ext/mpeg2dec/gstmpeg2dec.c: (gst_mpeg2dec_init),
|
||||||
|
(gst_mpeg2dec_reset), (gst_mpeg2dec_alloc_sized_buf),
|
||||||
|
(gst_mpeg2dec_alloc_buffer), (init_dummybuf), (handle_slice):
|
||||||
|
* ext/mpeg2dec/gstmpeg2dec.h:
|
||||||
|
Align buffers to a 16 byte boundary so the altivec optimisations
|
||||||
|
don't crash. Fixes #327350.
|
||||||
|
|
||||||
2006-11-20 Tim-Philipp Müller <tim at centricular dot net>
|
2006-11-20 Tim-Philipp Müller <tim at centricular dot net>
|
||||||
|
|
||||||
* gst/asfdemux/gstasfdemux.c: (gst_asf_demux_add_audio_stream):
|
* gst/asfdemux/gstasfdemux.c: (gst_asf_demux_add_audio_stream):
|
||||||
|
|
|
@ -26,8 +26,7 @@
|
||||||
|
|
||||||
#include "gstmpeg2dec.h"
|
#include "gstmpeg2dec.h"
|
||||||
|
|
||||||
/* libmpeg2 needs a 16-byte aligned buffer start address. This rounds the
|
/* 16byte-aligns a buffer for libmpeg2 */
|
||||||
* given pointer up to a multiply of 16 */
|
|
||||||
#define ALIGN_16(p) ((void *)(((uintptr_t)(p) + 15) & ~((uintptr_t)15)))
|
#define ALIGN_16(p) ((void *)(((uintptr_t)(p) + 15) & ~((uintptr_t)15)))
|
||||||
|
|
||||||
/* mpeg2dec changed a struct name after 0.3.1, here's a workaround */
|
/* mpeg2dec changed a struct name after 0.3.1, here's a workaround */
|
||||||
|
@ -233,6 +232,7 @@ gst_mpeg2dec_init (GstMpeg2dec * mpeg2dec)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mpeg2dec->error_count = 0;
|
mpeg2dec->error_count = 0;
|
||||||
|
mpeg2dec->can_allocate_aligned = TRUE;
|
||||||
|
|
||||||
/* initialize the mpeg2dec acceleration */
|
/* initialize the mpeg2dec acceleration */
|
||||||
}
|
}
|
||||||
|
@ -268,6 +268,7 @@ gst_mpeg2dec_reset (GstMpeg2dec * mpeg2dec)
|
||||||
mpeg2dec->next_time = -1;
|
mpeg2dec->next_time = -1;
|
||||||
mpeg2dec->offset = 0;
|
mpeg2dec->offset = 0;
|
||||||
mpeg2dec->error_count = 0;
|
mpeg2dec->error_count = 0;
|
||||||
|
mpeg2dec->can_allocate_aligned = TRUE;
|
||||||
mpeg2_reset (mpeg2dec->decoder, 1);
|
mpeg2_reset (mpeg2dec->decoder, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,22 +433,39 @@ static GstFlowReturn
|
||||||
gst_mpeg2dec_alloc_sized_buf (GstMpeg2dec * mpeg2dec, guint size,
|
gst_mpeg2dec_alloc_sized_buf (GstMpeg2dec * mpeg2dec, guint size,
|
||||||
GstBuffer ** obuf)
|
GstBuffer ** obuf)
|
||||||
{
|
{
|
||||||
GstFlowReturn ret;
|
if (mpeg2dec->can_allocate_aligned
|
||||||
|
&& mpeg2dec->decoded_width == mpeg2dec->width
|
||||||
|
&& mpeg2dec->decoded_height == mpeg2dec->height) {
|
||||||
|
GstFlowReturn ret;
|
||||||
|
|
||||||
if (mpeg2dec->decoded_width == mpeg2dec->width &&
|
|
||||||
mpeg2dec->decoded_height == mpeg2dec->height) {
|
|
||||||
ret = gst_pad_alloc_buffer_and_set_caps (mpeg2dec->srcpad,
|
ret = gst_pad_alloc_buffer_and_set_caps (mpeg2dec->srcpad,
|
||||||
GST_BUFFER_OFFSET_NONE, size, GST_PAD_CAPS (mpeg2dec->srcpad), obuf);
|
GST_BUFFER_OFFSET_NONE, size, GST_PAD_CAPS (mpeg2dec->srcpad), obuf);
|
||||||
} else {
|
if (ret != GST_FLOW_OK)
|
||||||
/* can't use gst_pad_alloc_buffer() here because the output buffer will
|
return ret;
|
||||||
* be cropped and basetransform-based elements will complain about
|
|
||||||
* the wrong unit size when not operating in passthrough mode */
|
/* libmpeg2 needs 16 byte aligned buffers... test for this here
|
||||||
*obuf = gst_buffer_new_and_alloc (size);
|
* and if it fails only a single time create our own buffers from
|
||||||
gst_buffer_set_caps (*obuf, GST_PAD_CAPS (mpeg2dec->srcpad));
|
* there on below that are correctly aligned */
|
||||||
ret = GST_FLOW_OK;
|
if (((uintptr_t) GST_BUFFER_DATA (*obuf)) % 16 == 0) {
|
||||||
|
GST_DEBUG_OBJECT (mpeg2dec, "return 16 byte aligned buffer");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (mpeg2dec,
|
||||||
|
"can get 16 byte aligned buffers, creating our own ones");
|
||||||
|
gst_buffer_unref (*obuf);
|
||||||
|
mpeg2dec->can_allocate_aligned = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
/* can't use gst_pad_alloc_buffer() here because the output buffer will
|
||||||
|
* be cropped and basetransform-based elements will complain about
|
||||||
|
* the wrong unit size when not operating in passthrough mode */
|
||||||
|
*obuf = gst_buffer_new_and_alloc (size + 15);
|
||||||
|
GST_BUFFER_DATA (*obuf) = ALIGN_16 (GST_BUFFER_DATA (*obuf));
|
||||||
|
GST_BUFFER_SIZE (*obuf) = size;
|
||||||
|
gst_buffer_set_caps (*obuf, GST_PAD_CAPS (mpeg2dec->srcpad));
|
||||||
|
|
||||||
|
return GST_FLOW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
|
@ -458,15 +476,10 @@ gst_mpeg2dec_alloc_buffer (GstMpeg2dec * mpeg2dec, gint64 offset,
|
||||||
guint8 *buf[3];
|
guint8 *buf[3];
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
|
||||||
ret = gst_mpeg2dec_alloc_sized_buf (mpeg2dec, mpeg2dec->size + 16, &outbuf);
|
ret = gst_mpeg2dec_alloc_sized_buf (mpeg2dec, mpeg2dec->size, &outbuf);
|
||||||
if (ret != GST_FLOW_OK)
|
if (ret != GST_FLOW_OK)
|
||||||
goto no_buffer;
|
goto no_buffer;
|
||||||
|
|
||||||
/* 16byte-align the buffer start address. As u_offs and v_offs are
|
|
||||||
* divideable by 16 without a rest it's only needed for the start */
|
|
||||||
GST_BUFFER_DATA (outbuf) = ALIGN_16 (GST_BUFFER_DATA (outbuf));
|
|
||||||
GST_BUFFER_SIZE (outbuf) = mpeg2dec->size;
|
|
||||||
|
|
||||||
buf[0] = GST_BUFFER_DATA (outbuf);
|
buf[0] = GST_BUFFER_DATA (outbuf);
|
||||||
buf[1] = buf[0] + mpeg2dec->u_offs;
|
buf[1] = buf[0] + mpeg2dec->u_offs;
|
||||||
buf[2] = buf[0] + mpeg2dec->v_offs;
|
buf[2] = buf[0] + mpeg2dec->v_offs;
|
||||||
|
@ -586,9 +599,7 @@ init_dummybuf (GstMpeg2dec * mpeg2dec)
|
||||||
{
|
{
|
||||||
g_free (mpeg2dec->dummybuf[3]);
|
g_free (mpeg2dec->dummybuf[3]);
|
||||||
|
|
||||||
/* 16byte-align the buffer start address. As u_offs and v_offs are
|
/* libmpeg2 needs 16 byte aligned buffers... care for this here */
|
||||||
* divideable by 16 without a rest it's only needed for the start.
|
|
||||||
* dummybuf[3] contains the malloc'ed address for free'ing later */
|
|
||||||
mpeg2dec->dummybuf[3] = g_malloc0 (mpeg2dec->size + 15);
|
mpeg2dec->dummybuf[3] = g_malloc0 (mpeg2dec->size + 15);
|
||||||
mpeg2dec->dummybuf[0] = ALIGN_16 (mpeg2dec->dummybuf[3]);
|
mpeg2dec->dummybuf[0] = ALIGN_16 (mpeg2dec->dummybuf[3]);
|
||||||
mpeg2dec->dummybuf[1] = mpeg2dec->dummybuf[0] + mpeg2dec->u_offs;
|
mpeg2dec->dummybuf[1] = mpeg2dec->dummybuf[0] + mpeg2dec->u_offs;
|
||||||
|
|
|
@ -111,6 +111,7 @@ struct _GstMpeg2dec {
|
||||||
gint index_id;
|
gint index_id;
|
||||||
|
|
||||||
gint error_count;
|
gint error_count;
|
||||||
|
gboolean can_allocate_aligned;
|
||||||
|
|
||||||
/* QoS stuff */ /* with LOCK*/
|
/* QoS stuff */ /* with LOCK*/
|
||||||
gdouble proportion;
|
gdouble proportion;
|
||||||
|
|
Loading…
Reference in a new issue