From bfbfebadccfa68403fe769ffc6555a72f8319f75 Mon Sep 17 00:00:00 2001 From: Mr Dave Date: Tue, 21 Oct 2014 19:26:45 -0700 Subject: [PATCH] Allow netcams with modulo 8 dimensions --- CHANGELOG | 1 + netcam.c | 12 ++++++------ netcam_rtsp.c | 16 ++++++++-------- picture.c | 43 +++++++++++++++++++++++++++++-------------- 4 files changed, 44 insertions(+), 28 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index f6157780..1a3c1ca9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,5 @@ Summary of Changes + * Revised picture.c to allow for modulo 8 pictures and adjusted netcam modules accordingly as well. * Changes to ffmpeg.h/ffmpeg.c to allow for compiling without ffmpeg/libav or with older versions. * Merge mymalloc, free and casting changes from Alfred Klomp * Merge bug fix for sizeof from Alfred Klomp diff --git a/netcam.c b/netcam.c index 2eda9bcd..2dbc587a 100644 --- a/netcam.c +++ b/netcam.c @@ -2666,7 +2666,7 @@ int netcam_next(struct context *cnt, unsigned char *image) * * Returns: 0 on success * -1 on any failure - * -3 image dimensions are not modulo 16 + * -3 image dimensions are not modulo 8 */ int netcam_start(struct context *cnt) @@ -2865,17 +2865,17 @@ int netcam_start(struct context *cnt) } /* * Motion currently requires that image height and width is a - * multiple of 16. So we check for this. + * multiple of 8. So we check for this. */ - if (netcam->width % 16) { + if (netcam->width % 8) { MOTION_LOG(CRT, TYPE_NETCAM, NO_ERRNO, "%s: netcam image width (%d)" - " is not modulo 16", netcam->width); + " is not modulo 8", netcam->width); return -3; } - if (netcam->height % 16) { + if (netcam->height % 8) { MOTION_LOG(CRT, TYPE_NETCAM, NO_ERRNO, "%s: netcam image height (%d)" - " is not modulo 16", netcam->height); + " is not modulo 8", netcam->height); return -3; } diff --git a/netcam_rtsp.c b/netcam_rtsp.c index 3309fbbe..45e61b3d 100644 --- a/netcam_rtsp.c +++ b/netcam_rtsp.c @@ -853,15 +853,15 @@ int netcam_setup_rtsp(netcam_context_ptr netcam, struct url_t *url){ /* * Warn and fix dimensions as needed. */ - if (netcam->cnt->conf.width % 16) { - MOTION_LOG(CRT, TYPE_NETCAM, NO_ERRNO, "%s: Image width (%d) requested is not modulo 16.", netcam->cnt->conf.width); - netcam->cnt->conf.width = netcam->cnt->conf.width - (netcam->cnt->conf.width % 16) + 16; - MOTION_LOG(CRT, TYPE_NETCAM, NO_ERRNO, "%s: Adjusting width to next higher multiple of 16 (%d).", netcam->cnt->conf.width); + if (netcam->cnt->conf.width % 8) { + MOTION_LOG(CRT, TYPE_NETCAM, NO_ERRNO, "%s: Image width (%d) requested is not modulo 8.", netcam->cnt->conf.width); + netcam->cnt->conf.width = netcam->cnt->conf.width - (netcam->cnt->conf.width % 8) + 8; + MOTION_LOG(CRT, TYPE_NETCAM, NO_ERRNO, "%s: Adjusting width to next higher multiple of 8 (%d).", netcam->cnt->conf.width); } - if (netcam->cnt->conf.height % 16) { - MOTION_LOG(CRT, TYPE_NETCAM, NO_ERRNO, "%s: Image height (%d) requested is not modulo 16.", netcam->cnt->conf.height); - netcam->cnt->conf.height = netcam->cnt->conf.height - (netcam->cnt->conf.height % 16) + 16; - MOTION_LOG(CRT, TYPE_NETCAM, NO_ERRNO, "%s: Adjusting height to next higher multiple of 16 (%d).", netcam->cnt->conf.height); + if (netcam->cnt->conf.height % 8) { + MOTION_LOG(CRT, TYPE_NETCAM, NO_ERRNO, "%s: Image height (%d) requested is not modulo 8.", netcam->cnt->conf.height); + netcam->cnt->conf.height = netcam->cnt->conf.height - (netcam->cnt->conf.height % 8) + 8; + MOTION_LOG(CRT, TYPE_NETCAM, NO_ERRNO, "%s: Adjusting height to next higher multiple of 8 (%d).", netcam->cnt->conf.height); } av_register_all(); diff --git a/picture.c b/picture.c index f6585343..2e9550f6 100644 --- a/picture.c +++ b/picture.c @@ -452,21 +452,30 @@ static int put_jpeg_yuv420p_memory(unsigned char *dest_image, int image_size, jpeg_set_quality(&cinfo, quality, TRUE); cinfo.dct_method = JDCT_FASTEST; - + _jpeg_mem_dest(&cinfo, dest_image, image_size); // Data written to mem + jpeg_start_compress(&cinfo, TRUE); put_jpeg_exif(&cinfo, cnt, tm, box); - + + /* If the image is not a multiple of 16, this overruns the buffers + * we'll just pad those last bytes with zeros + */ for (j = 0; j < height; j += 16) { for (i = 0; i < 16; i++) { - y[i] = input_image + width * (i + j); - - if (i % 2 == 0) { - cb[i / 2] = input_image + width * height + width / 2 * ((i + j) /2); - cr[i / 2] = input_image + width * height + width * height / 4 + width / 2 * ((i + j) / 2); - } + if ((width * (i + j)) < (width * height)) { + y[i] = input_image + width * (i + j); + if (i % 2 == 0) { + cb[i / 2] = input_image + width * height + width / 2 * ((i + j) /2); + cr[i / 2] = input_image + width * height + width * height / 4 + width / 2 * ((i + j) / 2); + } + } else { + y[i] = 0x00; + cb[i] = 0x00; + cr[i] = 0x00; + } } jpeg_write_raw_data(&cinfo, data, 16); } @@ -594,12 +603,18 @@ static void put_jpeg_yuv420p_file(FILE *fp, for (j = 0; j < height; j += 16) { for (i = 0; i < 16; i++) { - y[i] = image + width * (i + j); - if (i % 2 == 0) { - cb[i / 2] = image + width * height + width / 2 * ((i + j) / 2); - cr[i / 2] = image + width * height + width * height / 4 + width / 2 * ((i + j) / 2); - } - } + if ((width * (i + j)) < (width * height)) { + y[i] = image + width * (i + j); + if (i % 2 == 0) { + cb[i / 2] = image + width * height + width / 2 * ((i + j) / 2); + cr[i / 2] = image + width * height + width * height / 4 + width / 2 * ((i + j) / 2); + } + } else { + y[i] = 0x00; + cb[i] = 0x00; + cr[i] = 0x00; + } + } jpeg_write_raw_data(&cinfo, data, 16); }