diff options
author | hans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain> | 2009-03-11 13:08:51 +0100 |
---|---|---|
committer | hans@rhel5-devel.localdomain <hans@rhel5-devel.localdomain> | 2009-03-11 13:08:51 +0100 |
commit | e4def927f3ed43a4763652a0911f69180e803721 (patch) | |
tree | dbf5da435a1caa4afa33acc2f5a7e702a480427a | |
parent | 212f306971b622a70b8b3a20c61df11af814635a (diff) | |
download | mediapointer-dvb-s2-e4def927f3ed43a4763652a0911f69180e803721.tar.gz mediapointer-dvb-s2-e4def927f3ed43a4763652a0911f69180e803721.tar.bz2 |
libv4l: dont try to allocate large buffers on the stack
From: Hans de Goede <hdegoede@redhat.com>
When conversion requires multiple passes don't alloc the needed temporary
buffer on the stack, as some apps (ekiga) use so much stack themselves
this causes us to run out of stack space
Priority: normal
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
-rw-r--r-- | v4l2-apps/libv4l/ChangeLog | 6 | ||||
-rw-r--r-- | v4l2-apps/libv4l/Makefile | 2 | ||||
-rw-r--r-- | v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h | 6 | ||||
-rw-r--r-- | v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c | 57 |
4 files changed, 62 insertions, 9 deletions
diff --git a/v4l2-apps/libv4l/ChangeLog b/v4l2-apps/libv4l/ChangeLog index fa18321f4..f092cc418 100644 --- a/v4l2-apps/libv4l/ChangeLog +++ b/v4l2-apps/libv4l/ChangeLog @@ -1,3 +1,9 @@ +libv4l-0.5.3 +------------ +* When conversion requires multiple passes don't alloc the needed temporary + buffer on the stack, as some apps (ekiga) use so much stack themselves + this causes us to run out of stack space + libv4l-0.5.2 ------------ * Add Philips SPC210NC to list of cams with upside down sensor, reported by diff --git a/v4l2-apps/libv4l/Makefile b/v4l2-apps/libv4l/Makefile index bfc31a185..8de10a4cb 100644 --- a/v4l2-apps/libv4l/Makefile +++ b/v4l2-apps/libv4l/Makefile @@ -1,5 +1,5 @@ LIB_RELEASE=0 -V4L2_LIB_VERSION=$(LIB_RELEASE).5.2 +V4L2_LIB_VERSION=$(LIB_RELEASE).5.3 all clean install: $(MAKE) -C libv4lconvert V4L2_LIB_VERSION=$(V4L2_LIB_VERSION) $@ diff --git a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h index 99ffdec20..8473ba68f 100644 --- a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h +++ b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert-priv.h @@ -86,6 +86,12 @@ struct v4lconvert_data { struct jdec_private *jdec; struct v4l2_frmsizeenum framesizes[V4LCONVERT_MAX_FRAMESIZES]; unsigned int no_framesizes; + int convert_buf_size; + int rotate_buf_size; + int convert_pixfmt_buf_size; + unsigned char *convert_buf; + unsigned char *rotate_buf; + unsigned char *convert_pixfmt_buf; }; struct v4lconvert_flags_info { diff --git a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c index 4725e638f..ee6ef33a0 100644 --- a/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c +++ b/v4l2-apps/libv4l/libv4lconvert/libv4lconvert.c @@ -94,7 +94,6 @@ struct v4lconvert_data *v4lconvert_create(int fd) return NULL; data->fd = fd; - data->jdec = NULL; /* Check supported formats */ for (i = 0; ; i++) { @@ -135,6 +134,9 @@ void v4lconvert_destroy(struct v4lconvert_data *data) tinyjpeg_set_components(data->jdec, comps, 3); tinyjpeg_free(data->jdec); } + free(data->convert_buf); + free(data->rotate_buf); + free(data->convert_pixfmt_buf); free(data); } @@ -333,6 +335,23 @@ int v4lconvert_needs_conversion(struct v4lconvert_data *data, return 1; /* Needs flip and thus conversion */ } +static unsigned char *v4lconvert_alloc_buffer(struct v4lconvert_data *data, + int needed, unsigned char **buf, int *buf_size) +{ + if (*buf_size < needed) { + free(*buf); + *buf = malloc(needed); + if (*buf == NULL) { + *buf_size = 0; + V4LCONVERT_ERR("could not allocate memory\n"); + errno = ENOMEM; + return NULL; + } + *buf_size = needed; + } + return *buf; +} + static int v4lconvert_convert_pixfmt(struct v4lconvert_data *data, unsigned int src_pix_fmt, unsigned int dest_pix_fmt, unsigned int width, unsigned int height, @@ -444,8 +463,15 @@ static int v4lconvert_convert_pixfmt(struct v4lconvert_data *data, case V4L2_PIX_FMT_SPCA505: case V4L2_PIX_FMT_SPCA508: { - unsigned char tmpbuf[width * height * 3 / 2]; - unsigned char *d = (dest_pix_fmt != V4L2_PIX_FMT_YUV420) ? tmpbuf : dest; + unsigned char *d; + + if (dest_pix_fmt != V4L2_PIX_FMT_YUV420) { + d = v4lconvert_alloc_buffer(data, width * height * 3 / 2, + &data->convert_pixfmt_buf, &data->convert_pixfmt_buf_size); + if (!d) + return -1; + } else + d = dest; switch (src_pix_fmt) { case V4L2_PIX_FMT_SPCA501: @@ -461,10 +487,12 @@ static int v4lconvert_convert_pixfmt(struct v4lconvert_data *data, switch (dest_pix_fmt) { case V4L2_PIX_FMT_RGB24: - v4lconvert_yuv420_to_rgb24(tmpbuf, dest, width, height); + v4lconvert_yuv420_to_rgb24(data->convert_pixfmt_buf, dest, width, + height); break; case V4L2_PIX_FMT_BGR24: - v4lconvert_yuv420_to_bgr24(tmpbuf, dest, width, height); + v4lconvert_yuv420_to_bgr24(data->convert_pixfmt_buf, dest, width, + height); break; } break; @@ -475,9 +503,14 @@ static int v4lconvert_convert_pixfmt(struct v4lconvert_data *data, case V4L2_PIX_FMT_SN9C10X: case V4L2_PIX_FMT_PAC207: { - unsigned char tmpbuf[width * height]; + unsigned char *tmpbuf; unsigned int bayer_fmt = 0; + tmpbuf = v4lconvert_alloc_buffer(data, width * height, + &data->convert_pixfmt_buf, &data->convert_pixfmt_buf_size); + if (!tmpbuf) + return -1; + switch (src_pix_fmt) { case V4L2_PIX_FMT_SPCA561: v4lconvert_decode_spca561(src, tmpbuf, width, height); @@ -642,12 +675,20 @@ int v4lconvert_convert(struct v4lconvert_data *data, /* convert_pixfmt -> rotate -> crop, all steps are optional */ if (convert && (rotate || crop)) { - convert_dest = alloca(temp_needed); + convert_dest = v4lconvert_alloc_buffer(data, temp_needed, + &data->convert_buf, &data->convert_buf_size); + if (!convert_dest) + return -1; + rotate_src = crop_src = convert_dest; } if (rotate && crop) { - rotate_dest = alloca(temp_needed); + rotate_dest = v4lconvert_alloc_buffer(data, temp_needed, + &data->rotate_buf, &data->rotate_buf_size); + if (!rotate_dest) + return -1; + crop_src = rotate_dest; } |