From a391bf52cc3c580c7a0a2316ca52eb66da3b85c1 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Mon, 31 May 2010 12:45:01 +0200 Subject: [PATCH] jpegdec: use libjpeg scatter-gather operation to avoid data copying Fixes #583047 (more). --- ext/jpeg/gstjpegdec.c | 46 +++++++++++++++++++++++++++------------------- ext/jpeg/gstjpegdec.h | 2 ++ 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/ext/jpeg/gstjpegdec.c b/ext/jpeg/gstjpegdec.c index 5782abb..55ca8f3 100644 --- a/ext/jpeg/gstjpegdec.c +++ b/ext/jpeg/gstjpegdec.c @@ -201,20 +201,23 @@ gst_jpeg_dec_class_init (GstJpegDecClass * klass) static boolean gst_jpeg_dec_fill_input_buffer (j_decompress_ptr cinfo) { -/* - struct GstJpegDecSourceMgr *src_mgr; GstJpegDec *dec; + guint av; - src_mgr = (struct GstJpegDecSourceMgr*) &cinfo->src; - dec = GST_JPEG_DEC (src_mgr->dec); -*/ - GST_DEBUG_OBJECT (CINFO_GET_JPEGDEC (cinfo), "fill_input_buffer"); -/* - g_return_val_if_fail (dec != NULL, TRUE); + dec = CINFO_GET_JPEGDEC (cinfo); + g_return_val_if_fail (dec != NULL, FALSE); + + av = gst_adapter_available_fast (dec->adapter); + GST_DEBUG_OBJECT (dec, "fill_input_buffer: fast av=%u, remaining=%u", av, + dec->rem_img_len); + + if (dec->rem_img_len < av) + av = dec->rem_img_len; + dec->rem_img_len -= av; + + cinfo->src->next_input_byte = gst_adapter_take (dec->adapter, av); + cinfo->src->bytes_in_buffer = av; - src_mgr->pub.next_input_byte = GST_BUFFER_DATA (dec->tempbuf); - src_mgr->pub.bytes_in_buffer = GST_BUFFER_SIZE (dec->tempbuf); -*/ return TRUE; } @@ -1113,7 +1116,10 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf) GstFlowReturn ret = GST_FLOW_OK; GstJpegDec *dec; GstBuffer *outbuf = NULL; - guchar *data, *outdata; +#ifndef GST_DISABLE_GST_DEBUG + guchar *data; +#endif + guchar *outdata; guchar *base[3], *last[3]; guint img_len, outsize; gint width, height; @@ -1175,11 +1181,16 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf) if (dec->packetized && !gst_jpeg_dec_do_qos (dec, timestamp)) goto skip_decoding; - data = (guint8 *) gst_adapter_peek (dec->adapter, img_len); GST_LOG_OBJECT (dec, "image size = %u", img_len); - dec->jsrc.pub.next_input_byte = data; - dec->jsrc.pub.bytes_in_buffer = img_len; +#ifndef GST_DISABLE_GST_DEBUG + data = (guint8 *) gst_adapter_peek (dec->adapter, 4); + GST_LOG_OBJECT (dec, "reading header %02x %02x %02x %02x", data[0], data[1], + data[2], data[3]); +#endif + + dec->rem_img_len = img_len; + gst_jpeg_dec_fill_input_buffer (&dec->cinfo); if (setjmp (dec->jerr.setjmp_buffer)) { code = dec->jerr.pub.msg_code; @@ -1191,9 +1202,6 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf) goto decode_error; } - GST_LOG_OBJECT (dec, "reading header %02x %02x %02x %02x", data[0], data[1], - data[2], data[3]); - /* read header */ hdr_ok = jpeg_read_header (&dec->cinfo, TRUE); if (G_UNLIKELY (hdr_ok != JPEG_HEADER_OK)) { @@ -1394,7 +1402,7 @@ gst_jpeg_dec_chain (GstPad * pad, GstBuffer * buf) skip_decoding: done: - gst_adapter_flush (dec->adapter, img_len); + gst_adapter_flush (dec->adapter, dec->rem_img_len); exit: diff --git a/ext/jpeg/gstjpegdec.h b/ext/jpeg/gstjpegdec.h index c5870b0..4864a21 100644 --- a/ext/jpeg/gstjpegdec.h +++ b/ext/jpeg/gstjpegdec.h @@ -119,6 +119,8 @@ struct _GstJpegDec { /* arrays for indirect decoding */ gboolean idr_width_allocated; guchar *idr_y[16],*idr_u[16],*idr_v[16]; + /* current (parsed) image size */ + guint rem_img_len; }; struct _GstJpegDecClass { -- 2.7.4