diff --git a/conf.c b/conf.c index a06d2537..dca0bb33 100644 --- a/conf.c +++ b/conf.c @@ -531,7 +531,10 @@ config_param config_params[] = { { "ffmpeg_cap_new", "\n############################################################\n" - "# Film (mpeg) File Output - ffmpeg based\n" + "# FFMPEG related options\n" + "# Film (mpeg) file output, and deinterlacing of the video input\n" + "# The options movie_filename and timelapse_filename are also used\n" + "# by the ffmpeg feature\n" "############################################################\n\n" "# Use ffmpeg to encode mpeg movies in realtime (default: off)", CONF_OFFSET(ffmpeg_cap_new), @@ -593,6 +596,15 @@ config_param config_params[] = { copy_string, print_string }, + { + "ffmpeg_deinterlace", + "# Use ffmpeg to deinterlace video. Necessary if you use an analog camera\n" + "# and see horizontal combing on moving objects in video or pictures.\n" + "# (default: off)", + CONF_OFFSET(ffmpeg_deinterlace), + copy_bool, + print_bool + }, #endif /* HAVE_FFMPEG */ { @@ -723,12 +735,13 @@ config_param config_params[] = { }, #ifdef HAVE_FFMPEG { - "ffmpeg_filename", + "movie_filename", "# File path for motion triggered ffmpeg films (mpeg) relative to target_dir\n" "# Default: "DEF_MPEGPATH"\n" "# Default value is equivalent to legacy oldlayout option\n" "# For Motion 3.0 compatible mode choose: %Y/%m/%d/%H%M%S\n" - "# File extension .mpg or .avi is automatically added so do not include this", + "# File extension .mpg or .avi is automatically added so do not include this\n" + "# This option was previously called ffmpeg_filename", CONF_OFFSET(mpegpath), copy_string, print_string diff --git a/conf.h b/conf.h index c1a8d867..b60e6d24 100644 --- a/conf.h +++ b/conf.h @@ -59,6 +59,7 @@ struct config { int ffmpeg_cap_motion; int ffmpeg_bps; int ffmpeg_vbr; + int ffmpeg_deinterlace; const char *ffmpeg_video_codec; int webcam_port; int webcam_quality; diff --git a/ffmpeg.c b/ffmpeg.c index e6dd0cd5..32ce6a21 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -575,4 +575,43 @@ AVFrame *ffmpeg_prepare_frame(struct ffmpeg *ffmpeg, unsigned char *y, return picture; } + +/** ffmpeg_deinterlace + * Make the image suitable for deinterlacing using ffmpeg, then deinterlace the picture. + * + * Parameters + * img image in YUV420P format + * width image width in pixels + * height image height in pixels + * + * Returns + * Function returns nothing. + * img contains deinterlaced image + */ +void ffmpeg_deinterlace(unsigned char *img, int width, int height) +{ + AVFrame *picture; + int width2 = width / 2; + + picture = avcodec_alloc_frame(); + if (!picture) { + motion_log(LOG_ERR, 1, "Could not alloc frame"); + return; + } + + picture->data[0] = img; + picture->data[1] = img+width*height; + picture->data[2] = picture->data[1]+(width*height)/4; + picture->linesize[0] = width; + picture->linesize[1] = width2; + picture->linesize[2] = width2; + + /* We assume using 'PIX_FMT_YUV420P' always */ + avpicture_deinterlace((AVPicture *)picture, (AVPicture *)picture, PIX_FMT_YUV420P, width, height); + + av_free(picture); + + return; +} + #endif /* HAVE_FFMPEG */ diff --git a/ffmpeg.h b/ffmpeg.h index 0d93f0a4..4a9a7a1f 100644 --- a/ffmpeg.h +++ b/ffmpeg.h @@ -63,4 +63,7 @@ void ffmpeg_put_other_image( /* Closes the mpeg file. */ void ffmpeg_close(struct ffmpeg *); +/*Deinterlace the image. */ +void ffmpeg_deinterlace(unsigned char *, int, int); + #endif /* _INCLUDE_FFMPEG_H_ */ diff --git a/motion.c b/motion.c index 5801aeea..221d5eb8 100644 --- a/motion.c +++ b/motion.c @@ -819,6 +819,13 @@ static void *motion_loop(void *arg) } cnt->missing_frame_counter = 0; +#ifdef HAVE_FFMPEG + /* Deinterlace the image with ffmpeg, before the image is modified. */ + if(cnt->conf.ffmpeg_deinterlace) { + ffmpeg_deinterlace(newimg, cnt->imgs.width, cnt->imgs.height); + } +#endif + /* save the newly captured still virgin image to a buffer * which we will not alter with text and location graphics */