summaryrefslogtreecommitdiffstats
path: root/ext/libpng
diff options
context:
space:
mode:
authorAlessandro Decina <alessandro@nnva.org>2008-01-29 18:43:32 +0000
committerWim Taymans <wim.taymans@gmail.com>2008-01-29 18:43:32 +0000
commit3ad8e778d7995fcb47f8edbc58b0db21331ec05e (patch)
tree48162ecce264d22cb005bbe662d2ff8a5391251b /ext/libpng
parentbc1734ac89690cc08e025195cfcc3586665b2ae2 (diff)
ext/libpng/gstpngenc.*: Preallocate the output buffer so that g_memdup() and gst_buffer_merge() aren't needed anymore...
Original commit message from CVS: Patch by: Alessandro Decina <alessandro at nnva dot org> * ext/libpng/gstpngenc.c: (user_write_data), (gst_pngenc_chain): * ext/libpng/gstpngenc.h: Preallocate the output buffer so that g_memdup() and gst_buffer_merge() aren't needed anymore. This greatly improves performances and fixes #512544.
Diffstat (limited to 'ext/libpng')
-rw-r--r--ext/libpng/gstpngenc.c44
-rw-r--r--ext/libpng/gstpngenc.h1
2 files changed, 26 insertions, 19 deletions
diff --git a/ext/libpng/gstpngenc.c b/ext/libpng/gstpngenc.c
index 0ca9bb3a..1d26ef79 100644
--- a/ext/libpng/gstpngenc.c
+++ b/ext/libpng/gstpngenc.c
@@ -222,25 +222,21 @@ user_flush_data (png_structp png_ptr)
static void
user_write_data (png_structp png_ptr, png_bytep data, png_uint_32 length)
{
- GstBuffer *buffer;
GstPngEnc *pngenc;
pngenc = (GstPngEnc *) png_get_io_ptr (png_ptr);
- buffer = gst_buffer_new ();
- GST_BUFFER_MALLOCDATA (buffer) = g_memdup (data, length);
- GST_BUFFER_DATA (buffer) = GST_BUFFER_MALLOCDATA (buffer);
- GST_BUFFER_SIZE (buffer) = length;
+ if (pngenc->written + length >= GST_BUFFER_SIZE (pngenc->buffer_out)) {
+ GST_ERROR_OBJECT (pngenc, "output buffer bigger than the input buffer!?");
+ /* yuck */
+ longjmp (pngenc->png_struct_ptr->jmpbuf, 1);
- if (pngenc->buffer_out) {
- GstBuffer *merge;
+ /* never reached */
+ return;
+ }
- merge = gst_buffer_merge (pngenc->buffer_out, buffer);
- gst_buffer_unref (buffer);
- gst_buffer_unref (pngenc->buffer_out);
- pngenc->buffer_out = merge;
- } else
- pngenc->buffer_out = buffer;
+ memcpy (GST_BUFFER_DATA (pngenc->buffer_out) + pngenc->written, data, length);
+ pngenc->written += length;
}
static GstFlowReturn
@@ -250,13 +246,12 @@ gst_pngenc_chain (GstPad * pad, GstBuffer * buf)
gint row_index;
png_byte *row_pointers[MAX_HEIGHT];
GstFlowReturn ret = GST_FLOW_OK;
+ GstBuffer *encoded_buf = NULL;
pngenc = GST_PNGENC (gst_pad_get_parent (pad));
GST_DEBUG_OBJECT (pngenc, "BEGINNING");
- pngenc->buffer_out = NULL;
-
/* initialize png struct stuff */
pngenc->png_struct_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING,
(png_voidp) NULL, user_error_fn, user_warning_fn);
@@ -309,20 +304,26 @@ gst_pngenc_chain (GstPad * pad, GstBuffer * buf)
(row_index * pngenc->stride);
}
+ /* allocate the output buffer */
+ pngenc->buffer_out =
+ gst_buffer_new_and_alloc (pngenc->height * pngenc->stride);
+ pngenc->written = 0;
+
png_write_info (pngenc->png_struct_ptr, pngenc->png_info_ptr);
png_write_image (pngenc->png_struct_ptr, row_pointers);
png_write_end (pngenc->png_struct_ptr, NULL);
user_flush_data (pngenc->png_struct_ptr);
+ encoded_buf = gst_buffer_create_sub (pngenc->buffer_out, 0, pngenc->written);
+
png_destroy_info_struct (pngenc->png_struct_ptr, &pngenc->png_info_ptr);
png_destroy_write_struct (&pngenc->png_struct_ptr, (png_infopp) NULL);
- gst_buffer_copy_metadata (pngenc->buffer_out, buf,
- GST_BUFFER_COPY_TIMESTAMPS);
+ gst_buffer_copy_metadata (encoded_buf, buf, GST_BUFFER_COPY_TIMESTAMPS);
gst_buffer_unref (buf);
- gst_buffer_set_caps (pngenc->buffer_out, GST_PAD_CAPS (pngenc->srcpad));
+ gst_buffer_set_caps (encoded_buf, GST_PAD_CAPS (pngenc->srcpad));
- if ((ret = gst_pad_push (pngenc->srcpad, pngenc->buffer_out)) != GST_FLOW_OK)
+ if ((ret = gst_pad_push (pngenc->srcpad, encoded_buf)) != GST_FLOW_OK)
goto done;
if (pngenc->snapshot) {
@@ -339,6 +340,11 @@ gst_pngenc_chain (GstPad * pad, GstBuffer * buf)
done:
GST_DEBUG_OBJECT (pngenc, "END, ret:%d", ret);
+ if (pngenc->buffer_out != NULL) {
+ gst_buffer_unref (pngenc->buffer_out);
+ pngenc->buffer_out = NULL;
+ }
+
gst_object_unref (pngenc);
return ret;
}
diff --git a/ext/libpng/gstpngenc.h b/ext/libpng/gstpngenc.h
index 571d16f6..848d15e8 100644
--- a/ext/libpng/gstpngenc.h
+++ b/ext/libpng/gstpngenc.h
@@ -44,6 +44,7 @@ struct _GstPngEnc
GstPad *sinkpad, *srcpad;
GstBuffer *buffer_out;
+ guint written;
png_structp png_struct_ptr;
png_infop png_info_ptr;