Package: motion
Version: 3.2.12+git20140228-7
Severity: important
Tags: patch
User: [email protected]
Usertags: ffmpeg2.9

Dear Maintainer,

your package fails to build with the upcoming ffmpeg 2.9.
This bug will become release-critical at some point when the
ffmpeg2.9 transition gets closer.

Attached is a patch replacing the deprecated functionality.
It also works with ffmpeg 2.8.
Please apply this patch and forward it upstream, if necessary.

These changes are non-trivial and should be runtime-tested.

Best regards,
Andreas

diff --git a/debian/control b/debian/control
index c898a07..6329f18 100644
--- a/debian/control
+++ b/debian/control
@@ -5,6 +5,7 @@ Maintainer: Ximin Luo <[email protected]>
 Homepage: http://motion.sf.net
 Build-Depends: debhelper (>= 9), dpkg-dev (>= 1.16), dh-autoreconf,
  libavcodec-dev,
+ libavfilter-dev,
  libavformat-dev,
  libjpeg-dev,
  libmysqlclient-dev (>= 5.5.17-4),
diff --git a/debian/patches/ffmpeg_2.9.patch b/debian/patches/ffmpeg_2.9.patch
new file mode 100644
index 0000000..50418b1
--- /dev/null
+++ b/debian/patches/ffmpeg_2.9.patch
@@ -0,0 +1,200 @@
+Description: Replace deprecated FFmpeg API
+Author: Andreas Cadhalpun <[email protected]>
+Last-Update: <2015-11-02>
+
+--- motion-3.2.12+git20140228.orig/configure.in
++++ motion-3.2.12+git20140228/configure.in
+@@ -518,7 +518,7 @@ if test "${FFMPEG_OK}" = "found"; then
+ #
+ 
+ 	if  test "${FFMPEG_OK}" = "found"; then	
+-        TEMP_LIBS="$TEMP_LIBS -L${FFMPEG_LIB} -lavformat -lavcodec -lavutil -lm -lz"
++        TEMP_LIBS="$TEMP_LIBS -L${FFMPEG_LIB} -lavfilter -lavformat -lavcodec -lavutil -lm -lz"
+         TEMP_LDFLAGS="${TEMP_LDFLAGS} -L${FFMPEG_LIB}"
+         TEMP_CFLAGS="${TEMP_CFLAGS} -DHAVE_FFMPEG ${FFMPEG_CFLAGS}"
+ 
+--- motion-3.2.12+git20140228.orig/ffmpeg.c
++++ motion-3.2.12+git20140228/ffmpeg.c
+@@ -655,7 +655,7 @@ struct ffmpeg *ffmpeg_open(char *ffmpeg_
+     }
+ 
+     /* Set the picture format - need in ffmpeg starting round April-May 2005 */
+-    c->pix_fmt = PIX_FMT_YUV420P;
++    c->pix_fmt = AV_PIX_FMT_YUV420P;
+ 
+     /* Get a mutex lock. */
+     pthread_mutex_lock(&global_lock);
+@@ -692,10 +692,10 @@ struct ffmpeg *ffmpeg_open(char *ffmpeg_
+     }
+ 
+     /* Allocate the encoded raw picture. */
+-    ffmpeg->picture = avcodec_alloc_frame();
++    ffmpeg->picture = av_frame_alloc();
+ 
+     if (!ffmpeg->picture) {
+-        MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "%s: avcodec_alloc_frame -"
++        MOTION_LOG(ERR, TYPE_ENCODER, NO_ERRNO, "%s: av_frame_alloc -"
+                    " could not alloc frame");
+         ffmpeg_cleanups(ffmpeg);
+         return NULL;
+@@ -801,7 +801,7 @@ void ffmpeg_cleanups(struct ffmpeg *ffmp
+ #endif
+             avcodec_close(AVSTREAM_CODEC_PTR(ffmpeg->video_st));
+         pthread_mutex_unlock(&global_lock);
+-        av_freep(&ffmpeg->picture);
++        av_frame_free(&ffmpeg->picture);
+         free(ffmpeg->video_outbuf);
+     }
+ 
+@@ -833,7 +833,7 @@ void ffmpeg_close(struct ffmpeg *ffmpeg)
+         pthread_mutex_lock(&global_lock);
+         avcodec_close(AVSTREAM_CODEC_PTR(ffmpeg->video_st));
+         pthread_mutex_unlock(&global_lock);
+-        av_freep(&ffmpeg->picture);
++        av_frame_free(&ffmpeg->picture);
+         free(ffmpeg->video_outbuf);
+     }
+ 
+@@ -897,7 +897,7 @@ int ffmpeg_put_other_image(struct ffmpeg
+     if (picture) {
+         ret = ffmpeg_put_frame(ffmpeg, picture);
+         if (!ret)
+-            av_free(picture);
++            av_frame_free(&picture);
+     }
+ 
+     return ret;
+@@ -1009,7 +1009,7 @@ AVFrame *ffmpeg_prepare_frame(struct ffm
+ {
+     AVFrame *picture;
+ 
+-    picture = avcodec_alloc_frame();
++    picture = av_frame_alloc();
+ 
+     if (!picture) {
+         MOTION_LOG(ERR, TYPE_ENCODER, SHOW_ERRNO, "%s: Could not alloc frame");
+@@ -1031,6 +1031,81 @@ AVFrame *ffmpeg_prepare_frame(struct ffm
+     return picture;
+ }
+ 
++AVFilterContext *buffersink_ctx;
++AVFilterContext *buffersrc_ctx;
++AVFilterGraph *filter_graph;
++AVFrame *filter_frame;
++int last_width = -1;
++int last_height = -1;
++enum AVPixelFormat last_pixfmt = AV_PIX_FMT_NONE;
++
++static void delete_filter_graph() {
++    if (filter_graph) {
++        av_frame_free(&filter_frame);
++        avfilter_graph_free(&filter_graph);
++    }
++}
++
++static int init_filter_graph(enum AVPixelFormat pixfmt, int width, int height) {
++    AVFilterInOut *inputs = NULL, *outputs = NULL;
++    char args[512];
++    int res;
++
++    delete_filter_graph();
++    filter_graph = avfilter_graph_alloc();
++    snprintf(args, sizeof(args),
++             "buffer=video_size=%dx%d:pix_fmt=%d:time_base=1/1:pixel_aspect=0/1[in];"
++             "[in]yadif[out];"
++             "[out]buffersink",
++             width, height, pixfmt);
++    res = avfilter_graph_parse2(filter_graph, args, &inputs, &outputs);
++    if (res < 0)
++        return res;
++    if(inputs || outputs)
++        return -1;
++    res = avfilter_graph_config(filter_graph, NULL);
++    if (res < 0)
++        return res;
++
++    buffersrc_ctx = avfilter_graph_get_filter(filter_graph, "Parsed_buffer_0");
++    buffersink_ctx = avfilter_graph_get_filter(filter_graph, "Parsed_buffersink_2");
++    if (!buffersrc_ctx || !buffersink_ctx)
++        return -1;
++    filter_frame = av_frame_alloc();
++    last_width = width;
++    last_height = height;
++    last_pixfmt = pixfmt;
++
++    return 0;
++}
++
++static int process_filter_graph(AVPicture *dst, const AVPicture *src,
++                                enum AVPixelFormat pixfmt, int width, int height) {
++    int res;
++
++    if (!filter_graph || width != last_width ||
++        height != last_height || pixfmt != last_pixfmt) {
++        res = init_filter_graph(pixfmt, width, height);
++        if (res < 0)
++            return res;
++    }
++
++    memcpy(filter_frame->data, src->data, sizeof(src->data));
++    memcpy(filter_frame->linesize, src->linesize, sizeof(src->linesize));
++    filter_frame->width = width;
++    filter_frame->height = height;
++    filter_frame->format = pixfmt;
++    res = av_buffersrc_add_frame(buffersrc_ctx, filter_frame);
++    if (res < 0)
++        return res;
++    res = av_buffersink_get_frame(buffersink_ctx, filter_frame);
++    if (res < 0)
++        return res;
++    av_picture_copy(dst, (const AVPicture *) filter_frame, pixfmt, width, height);
++    av_frame_unref(filter_frame);
++
++    return 0;
++}
+ 
+ /**
+  * ffmpeg_deinterlace
+@@ -1057,8 +1132,8 @@ void ffmpeg_deinterlace(unsigned char *i
+     picture.linesize[1] = width2;
+     picture.linesize[2] = width2;
+ 
+-    /* We assume using 'PIX_FMT_YUV420P' always */
+-    avpicture_deinterlace(&picture, &picture, PIX_FMT_YUV420P, width, height);
++    /* We assume using 'AV_PIX_FMT_YUV420P' always */
++    process_filter_graph(&picture, &picture, AV_PIX_FMT_YUV420P, width, height);
+ 
+ #ifdef __MMX__
+     __asm__ __volatile__ ( "emms");
+--- motion-3.2.12+git20140228.orig/ffmpeg.h
++++ motion-3.2.12+git20140228/ffmpeg.h
+@@ -6,6 +6,9 @@
+ 
+ #ifdef FFMPEG_NEW_INCLUDES
+ #include <libavformat/avformat.h>
++#include <libavfilter/avfilter.h>
++#include <libavfilter/buffersrc.h>
++#include <libavfilter/buffersink.h>
+ #else
+ #include <avformat.h>
+ #endif
+--- motion-3.2.12+git20140228.orig/netcam_rtsp.c
++++ motion-3.2.12+git20140228/netcam_rtsp.c
+@@ -233,7 +233,7 @@ int netcam_read_rtsp_image(netcam_contex
+   buffer = netcam->receiving;
+   buffer->used = 0;
+ 
+-  AVFrame *frame = avcodec_alloc_frame();
++  AVFrame *frame = av_frame_alloc();
+ 
+   AVPacket packet;
+   
+@@ -268,7 +268,7 @@ int netcam_read_rtsp_image(netcam_contex
+ 
+   // at this point, we are finished with the packet and frame, so free them.
+   av_free_packet(&packet);
+-  av_free(frame);
++  av_frame_free(&frame);
+   
+   struct timeval curtime;
+   
diff --git a/debian/patches/series b/debian/patches/series
index a6f2701..279f5bf 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -7,3 +7,4 @@ set-debian-file-paths.patch
 update-for-libav10.patch
 include-remote-images.patch
 fix-debian-kfreebsd.patch
+ffmpeg_2.9.patch

Reply via email to