From e3e910e971141c6ee88c0dbb802469bf81855e12 Mon Sep 17 00:00:00 2001 From: Stefan Kost Date: Tue, 3 Nov 2009 17:35:15 +0200 Subject: [PATCH] jpegdec: don't allocate big arrays on the stack Add the arrays to the instance data and allocate on first use. --- ext/jpeg/gstjpegdec.c | 41 +++++++++++++++++++++++++++-------------- ext/jpeg/gstjpegdec.h | 4 ++++ 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/ext/jpeg/gstjpegdec.c b/ext/jpeg/gstjpegdec.c index f481e0e..07128d4 100644 --- a/ext/jpeg/gstjpegdec.c +++ b/ext/jpeg/gstjpegdec.c @@ -148,12 +148,19 @@ static void gst_jpeg_dec_finalize (GObject * object) { GstJpegDec *dec = GST_JPEG_DEC (object); + gint i; jpeg_destroy_decompress (&dec->cinfo); if (dec->tempbuf) gst_buffer_unref (dec->tempbuf); + for (i = 0; i < 16; i++) { + g_free (dec->idr_y[i]); + g_free (dec->idr_u[i]); + g_free (dec->idr_v[i]); + } + G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -679,20 +686,7 @@ static void gst_jpeg_dec_decode_indirect (GstJpegDec * dec, guchar * base[3], guchar * last[3], guint width, guint height, gint r_v, gint r_h) { - /* FIXME: these are too large now that MAX_WIDTH is 64k! Allocating 3MB on - * the stack is not very nice... */ - guchar y[16][MAX_WIDTH]; - guchar u[16][MAX_WIDTH]; - guchar v[16][MAX_WIDTH]; - guchar *y_rows[16] = { y[0], y[1], y[2], y[3], y[4], y[5], y[6], y[7], - y[8], y[9], y[10], y[11], y[12], y[13], y[14], y[15] - }; - guchar *u_rows[16] = { u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7], - u[8], u[9], u[10], u[11], u[12], u[13], u[14], u[15] - }; - guchar *v_rows[16] = { v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], - v[8], v[9], v[10], v[11], v[12], v[13], v[14], v[15] - }; + guchar *y_rows[16], *u_rows[16], *v_rows[16]; guchar **scanarray[3] = { y_rows, u_rows, v_rows }; gint i, j, k; gint lines; @@ -700,6 +694,25 @@ gst_jpeg_dec_decode_indirect (GstJpegDec * dec, guchar * base[3], GST_DEBUG_OBJECT (dec, "unadvantageous width or r_h, taking slow route involving memcpy"); + if (G_UNLIKELY (!dec->idr_allocated)) { + gboolean res = TRUE; + + for (i = 0; ((i < 16) && res); i++) { + res &= ((dec->idr_y[i] = g_try_malloc (MAX_WIDTH)) != NULL); + res &= ((dec->idr_u[i] = g_try_malloc (MAX_WIDTH)) != NULL); + res &= ((dec->idr_v[i] = g_try_malloc (MAX_WIDTH)) != NULL); + } + if (!res) { + GST_WARNING_OBJECT (dec, "out of memory"); + return; + } + dec->idr_allocated = TRUE; + } + + memcpy (y_rows, dec->idr_y, 16 * sizeof (gpointer)); + memcpy (u_rows, dec->idr_u, 16 * sizeof (gpointer)); + memcpy (v_rows, dec->idr_v, 16 * sizeof (gpointer)); + for (i = 0; i < height; i += r_v * DCTSIZE) { lines = jpeg_read_raw_data (&dec->cinfo, scanarray, r_v * DCTSIZE); if (G_LIKELY (lines > 0)) { diff --git a/ext/jpeg/gstjpegdec.h b/ext/jpeg/gstjpegdec.h index aa23c61..0be9951 100644 --- a/ext/jpeg/gstjpegdec.h +++ b/ext/jpeg/gstjpegdec.h @@ -106,6 +106,10 @@ struct _GstJpegDec { struct jpeg_decompress_struct cinfo; struct GstJpegDecErrorMgr jerr; struct GstJpegDecSourceMgr jsrc; + + /* arrays for indirect decoding */ + gboolean idr_allocated; + guchar *idr_y[16],*idr_u[16],*idr_v[16]; }; struct _GstJpegDecClass { -- 2.7.4