diff --git a/CHANGELOG b/CHANGELOG index 9661980..d014a46 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -16,7 +16,8 @@ Features Bugfixes * Fix Problem Encoding 1280x1024 resolution videos http://www.lavrsen.dk/twiki/bin/view/Motion/SupportQuestion2008x06x11x183727 (Angel Carpintero) - + * Add a new parameter netcam_broken, to be less strict with some buggy network cameras firmwares. + http://www.lavrsen.dk/twiki/bin/view/Motion/BugReport2008x06x19x123218 (Angel Carpintero) 3.2.10.1 Summary of Changes diff --git a/CREDITS b/CREDITS index 7b93b30..79cc82c 100644 --- a/CREDITS +++ b/CREDITS @@ -401,6 +401,8 @@ Angel Carpintero * Fix Problem Encoding 1280x1024 resolution videos http://www.lavrsen.dk/twiki/bin/view/Motion/SupportQuestion2008x06x11x183727 * Add write/read nonblock functions in webhttpd( timeout on read/write). + * Add a new parameter netcam_broken, to be less strict with some buggy network cameras firmwares. + http://www.lavrsen.dk/twiki/bin/view/Motion/BugReport2008x06x19x123218 Jared D * Change bayer2rgb24() to fix a problem with sn9c102 driver diff --git a/conf.c b/conf.c index b6e0457..3a077e9 100644 --- a/conf.c +++ b/conf.c @@ -136,6 +136,7 @@ struct config conf_template = { netcam_userpass: NULL, netcam_keepalive: "off", /* Choices: off, force or on */ netcam_proxy: NULL, + netcam_broken: 0, text_changes: 0, text_left: NULL, text_right: DEF_TIMESTAMP, @@ -357,6 +358,15 @@ config_param config_params[] = { print_string }, { + "netcam_broken", + "# Set less strict jpeg checks for network cameras with a poor/buggy firmware.\n" + "# Default: off", + 0, + CONF_OFFSET(netcam_broken), + copy_bool, + print_bool + }, + { "auto_brightness", "# Let motion regulate the brightness of a video device (default: off).\n" "# The auto_brightness feature uses the brightness option as its target value.\n" diff --git a/conf.h b/conf.h index 306ff9a..334e963 100644 --- a/conf.h +++ b/conf.h @@ -109,6 +109,7 @@ struct config { const char *netcam_userpass; const char *netcam_keepalive; const char *netcam_proxy; + unsigned int netcam_broken; int text_changes; const char *text_left; const char *text_right; diff --git a/configure b/configure index 14dfd31..c8e333e 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.61 for motion trunk-r366. +# Generated by GNU Autoconf 2.61 for motion trunk-r373. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. @@ -572,8 +572,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='motion' PACKAGE_TARNAME='motion' -PACKAGE_VERSION='trunk-r366' -PACKAGE_STRING='motion trunk-r366' +PACKAGE_VERSION='trunk-r373' +PACKAGE_STRING='motion trunk-r373' PACKAGE_BUGREPORT='' ac_unique_file="motion.c" @@ -1177,7 +1177,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures motion trunk-r366 to adapt to many kinds of systems. +\`configure' configures motion trunk-r373 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1238,7 +1238,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of motion trunk-r366:";; + short | recursive ) echo "Configuration of motion trunk-r373:";; esac cat <<\_ACEOF @@ -1374,7 +1374,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -motion configure trunk-r366 +motion configure trunk-r373 generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1388,7 +1388,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by motion $as_me trunk-r366, which was +It was created by motion $as_me trunk-r373, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ @@ -8666,7 +8666,7 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by motion $as_me trunk-r366, which was +This file was extended by motion $as_me trunk-r373, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -8715,7 +8715,7 @@ Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -motion config.status trunk-r366 +motion config.status trunk-r373 configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" diff --git a/motion-dist.conf.in b/motion-dist.conf.in index b4c4534..fb3aa04 100644 --- a/motion-dist.conf.in +++ b/motion-dist.conf.in @@ -102,6 +102,10 @@ netcam_keepalive off # Default: not defined ; netcam_proxy value +# Set less strict jpeg checks for network cameras with a poor/buggy firmware. +# Default: off +netcam_broken off + # Let motion regulate the brightness of a video device (default: off). # The auto_brightness feature uses the brightness option as its target value. # If brightness is zero auto_brightness will adjust to average brightness value 128. diff --git a/motion.1 b/motion.1 index a1236aa..f48e07e 100644 --- a/motion.1 +++ b/motion.1 @@ -225,6 +225,11 @@ Values: Max 4095 characters / Default: %v-%Y%m%d%H%M%S .br File path for motion triggered ffmpeg movies relative to target_dir. This was previously called ffmpeg_filename. .TP +.B netcam_broken boolean +Values: on, off / Default: off +.br +Set less strict jpeg checks for network cameras with a poor/buggy firmware. +.TP .B netcam_keepalive discrete string Values: off , force, on / Default: off .br diff --git a/netcam.c b/netcam.c index 1963aaa..7e92078 100644 --- a/netcam.c +++ b/netcam.c @@ -2793,6 +2793,9 @@ int netcam_start(struct context *cnt) "on first frame - giving up!"); return -1; } + + netcam->netcam_broken = cnt->conf.netcam_broken; + netcam->JFIF_marker = 0; netcam_get_dimensions(netcam); /* Motion currently requires that image height and width is a diff --git a/netcam.h b/netcam.h index 1a9148e..88ea7e5 100644 --- a/netcam.h +++ b/netcam.h @@ -241,6 +241,9 @@ typedef struct netcam_context { unsigned int width; /* info for decompression */ unsigned int height; + int JFIF_marker; /* Debug to know if JFIF was present or not */ + unsigned int netcam_broken; /* For network cameras with buggy firmwares */ + struct timeval last_image; /* time the most recent image was received */ diff --git a/netcam_jpeg.c b/netcam_jpeg.c index fee07f7..c727935 100644 --- a/netcam_jpeg.c +++ b/netcam_jpeg.c @@ -84,7 +84,7 @@ static boolean netcam_fill_input_buffer(j_decompress_ptr cinfo) } else { /* Insert a fake EOI marker - as per jpeglib recommendation */ if (debug_level > CAMERA_VERBOSE) - motion_log(LOG_INFO, 0, "**fake EOI inserted**"); + motion_log(LOG_INFO, 0, "%s: **fake EOI inserted**", __FUNCTION__); src->buffer[0] = (JOCTET) 0xFF; src->buffer[1] = (JOCTET) JPEG_EOI; /* 0xD9 */ nbytes = 2; @@ -177,6 +177,10 @@ static void netcam_error_exit(j_common_ptr cinfo) netcam->jpeg_error |= 1; /* need to "cleanup" the aborted decompression */ jpeg_destroy (cinfo); + + if (debug_level > CAMERA_VERBOSE) + motion_log(LOG_ERR, 0, "%s: netcam->jpeg_error %d", __FUNCTION__, netcam->jpeg_error); + /* jump back to wherever we started */ longjmp(netcam->setjmp_buffer, 1); } @@ -213,7 +217,8 @@ static void netcam_output_message(j_common_ptr cinfo) * some sort of table-lookup to decide which messages we really * care about. */ - if (cinfo->err->msg_code != JWRN_EXTRANEOUS_DATA) + if ( (cinfo->err->msg_code != JWRN_EXTRANEOUS_DATA) && + (cinfo->err->msg_code == JWRN_NOT_SEQUENTIAL) && (!netcam->netcam_broken) ) netcam->jpeg_error |= 2; /* Set flag to show problem */ /* * We only display and log errors when debug_level @@ -228,7 +233,7 @@ static void netcam_output_message(j_common_ptr cinfo) * Write it out to the motion log. */ (*cinfo->err->format_message)(cinfo, buffer); - motion_log(LOG_ERR, 0, buffer); + motion_log(LOG_ERR, 0, "%s: %s", __FUNCTION__, buffer); } } @@ -288,13 +293,13 @@ static int netcam_init_jpeg(netcam_context_ptr netcam, j_decompress_ptr cinfo) pthread_mutex_unlock(&netcam->mutex); if (debug_level > CAMERA_WARNINGS) - motion_log(-1, 0, "no new pic, no signal rcvd"); + motion_log(-1, 0, "%s: no new pic, no signal rcvd", __FUNCTION__); return NETCAM_GENERAL_ERROR | NETCAM_NOTHING_NEW_ERROR; } if (debug_level > CAMERA_VERBOSE) - motion_log(-1, 0, "***new pic delay successful***"); + motion_log(-1, 0, "%s: ***new pic delay successful***", __FUNCTION__); } netcam->imgcnt_last = netcam->imgcnt; @@ -330,6 +335,10 @@ static int netcam_init_jpeg(netcam_context_ptr netcam, j_decompress_ptr cinfo) /* Start the decompressor */ jpeg_start_decompress(cinfo); + + if (debug_level > CAMERA_VERBOSE) + motion_log(LOG_INFO, 0, "%s: jpeg_error %d", __FUNCTION__, netcam->jpeg_error); + return netcam->jpeg_error; } @@ -350,8 +359,8 @@ static int netcam_image_conv(netcam_context_ptr netcam, height = cinfo->output_height; if (width && ((width != netcam->width) || (height != netcam->height))) { motion_log(LOG_ERR, 0, - "JPEG image size %dx%d, JPEG was %dx%d", - netcam->width, netcam->height, width, height); + "%s: JPEG image size %dx%d, JPEG was %dx%d", + __FUNCTION__, netcam->width, netcam->height, width, height); jpeg_destroy_decompress (cinfo); netcam->jpeg_error |= 4; return netcam->jpeg_error; @@ -372,6 +381,7 @@ static int netcam_image_conv(netcam_context_ptr netcam, y = 0; while (cinfo->output_scanline < height) { jpeg_read_scanlines (cinfo, line, 1); + for (i = 0; i < linesize; i += 3) { pic[i / 3] = wline[i]; if (i & 1) { @@ -392,6 +402,10 @@ static int netcam_image_conv(netcam_context_ptr netcam, /* rotate as specified */ rotate_map(netcam->cnt, image); } + + if (debug_level > CAMERA_VERBOSE) + motion_log(LOG_INFO, 0, "%s: jpeg_error %d", __FUNCTION__, netcam->jpeg_error); + return netcam->jpeg_error; } @@ -425,14 +439,17 @@ int netcam_proc_jpeg(netcam_context_ptr netcam, unsigned char *image) * netcam->mutex to do this; */ if (debug_level > CAMERA_INFO) { - motion_log(LOG_INFO, 0, "processing jpeg image - content length " - "%d", netcam->latest->content_length); + motion_log(LOG_INFO, 0, "%s: processing jpeg image - content length " + "%d", __FUNCTION__, netcam->latest->content_length); } ret = netcam_init_jpeg(netcam, &cinfo); - if (ret != 0) + if (ret != 0) { + if (debug_level > CAMERA_INFO) + motion_log(LOG_ERR, 0, "%s: ret %d", __FUNCTION__, ret); return ret; + } /* Do a sanity check on dimensions * If dimensions have changed we throw an @@ -442,12 +459,12 @@ int netcam_proc_jpeg(netcam_context_ptr netcam, unsigned char *image) if (netcam->width) { /* 0 means not yet init'ed */ if ((cinfo.output_width != netcam->width) || (cinfo.output_height != netcam->height)) { + retval = NETCAM_RESTART_ERROR; motion_log(LOG_ERR, 0, - "Camera width/height mismatch " + "%s: Camera width/height mismatch " "with JPEG image - expected %dx%d, JPEG %dx%d", - netcam->width, netcam->height, - cinfo.output_width, cinfo.output_height); - retval = NETCAM_RESTART_ERROR; + " retval %d", __FUNCTION__, netcam->width, netcam->height, + cinfo.output_width, cinfo.output_height, retval); return retval; } } @@ -455,8 +472,12 @@ int netcam_proc_jpeg(netcam_context_ptr netcam, unsigned char *image) /* do the conversion */ ret = netcam_image_conv(netcam, &cinfo, image); - if (ret != 0) + if (ret != 0) { retval |= NETCAM_JPEG_CONV_ERROR; + if (debug_level > CAMERA_INFO) + motion_log(LOG_ERR, 0, "%s: ret %d retval %d", __FUNCTION__, + ret, retval); + } return retval; } @@ -477,10 +498,17 @@ int netcam_proc_jpeg(netcam_context_ptr netcam, unsigned char *image) void netcam_get_dimensions(netcam_context_ptr netcam) { struct jpeg_decompress_struct cinfo; /* decompression control struct */ + int ret; + + ret = netcam_init_jpeg(netcam, &cinfo); - netcam_init_jpeg(netcam, &cinfo); netcam->width = cinfo.output_width; netcam->height = cinfo.output_height; + netcam->JFIF_marker = cinfo.saw_JFIF_marker; jpeg_destroy_decompress(&cinfo); + + if (debug_level > CAMERA_INFO) + motion_log(LOG_ERR, 0, "%s: JFIF_marker %s PRESENT ret %d", + __FUNCTION__, netcam->JFIF_marker ? "IS" : "NOT", ret); }