Package: dff
Version: 1.3.0+dfsg.1-4.1
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 c329d81..759b8ed 100644
--- a/debian/control
+++ b/debian/control
@@ -15,6 +15,7 @@ Build-Depends: debhelper (>= 9.0),
     libmagic-dev,
     libicu-dev,
     libfuse-dev,
+    libavfilter-dev,
     libavformat-dev,
     libavdevice-dev,
     libavutil-dev,
diff --git a/debian/patches/ffmpeg_2.9.patch b/debian/patches/ffmpeg_2.9.patch
new file mode 100644
index 0000000..f405b14
--- /dev/null
+++ b/debian/patches/ffmpeg_2.9.patch
@@ -0,0 +1,242 @@
+Description: Replace deprecated FFmpeg API
+Author: Andreas Cadhalpun <[email protected]>
+Last-Update: <2015-11-02>
+
+--- dff-1.3.0+dfsg.1.orig/cmake_modules/FindFFmpeg.cmake
++++ dff-1.3.0+dfsg.1/cmake_modules/FindFFmpeg.cmake
+@@ -97,6 +97,7 @@ ENDMACRO(FFMPEG_FIND)
+ 
+ SET(FFMPEG_ROOT "$ENV{FFMPEG_DIR}" CACHE PATH "Location of FFMPEG")
+ 
++FFMPEG_FIND(LIBAVFILTER avfilter avfilter.h)
+ FFMPEG_FIND(LIBAVFORMAT avformat avformat.h)
+ FFMPEG_FIND(LIBAVDEVICE avdevice avdevice.h)
+ FFMPEG_FIND(LIBAVCODEC  avcodec  avcodec.h)
+@@ -105,7 +106,7 @@ FFMPEG_FIND(LIBSWSCALE  swscale  swscale
+ 
+ SET(FFMPEG_FOUND FALSE)
+ # Note we don't check FFMPEG_LIBSWSCALE_FOUND here, it's optional.
+-IF   (FFMPEG_LIBAVFORMAT_FOUND AND FFMPEG_LIBAVDEVICE_FOUND AND FFMPEG_LIBAVCODEC_FOUND AND FFMPEG_LIBAVUTIL_FOUND AND FFMPEG_LIBSWSCALE_FOUND)
++IF   (FFMPEG_LIBAVFORMAT_FOUND AND FFMPEG_LIBAVDEVICE_FOUND AND FFMPEG_LIBAVCODEC_FOUND AND FFMPEG_LIBAVUTIL_FOUND AND FFMPEG_LIBSWSCALE_FOUND AND FFMPEG_LIBAVFILTER_FOUND)
+ 
+     SET(FFMPEG_FOUND TRUE)
+ 
+@@ -115,6 +116,7 @@ IF   (FFMPEG_LIBAVFORMAT_FOUND AND FFMPE
+ 
+     # Note we don't add FFMPEG_LIBSWSCALE_LIBRARIES here, it will be added if found later.
+     SET(FFMPEG_LIBRARIES
++        ${FFMPEG_LIBAVFILTER_LIBRARIES}
+         ${FFMPEG_LIBAVFORMAT_LIBRARIES}
+         ${FFMPEG_LIBAVDEVICE_LIBRARIES}
+         ${FFMPEG_LIBAVCODEC_LIBRARIES}
+@@ -122,8 +124,8 @@ IF   (FFMPEG_LIBAVFORMAT_FOUND AND FFMPE
+         ${FFMPEG_LIBSWSCALE_LIBRARIES}
+ 	)
+ 
+-ELSE (FFMPEG_LIBAVFORMAT_FOUND AND FFMPEG_LIBAVDEVICE_FOUND AND FFMPEG_LIBAVCODEC_FOUND AND FFMPEG_LIBAVUTIL_FOUND AND FFMPEG_LIBSWSCALE_FOUND)
++ELSE (FFMPEG_LIBAVFORMAT_FOUND AND FFMPEG_LIBAVDEVICE_FOUND AND FFMPEG_LIBAVCODEC_FOUND AND FFMPEG_LIBAVUTIL_FOUND AND FFMPEG_LIBSWSCALE_FOUND AND FFMPEG_LIBAVFILTER_FOUND)
+ 
+ #    MESSAGE(STATUS "Could not find FFMPEG")
+ 
+-ENDIF(FFMPEG_LIBAVFORMAT_FOUND AND FFMPEG_LIBAVDEVICE_FOUND AND FFMPEG_LIBAVCODEC_FOUND AND FFMPEG_LIBAVUTIL_FOUND AND FFMPEG_LIBSWSCALE_FOUND)
++ENDIF(FFMPEG_LIBAVFORMAT_FOUND AND FFMPEG_LIBAVDEVICE_FOUND AND FFMPEG_LIBAVCODEC_FOUND AND FFMPEG_LIBAVUTIL_FOUND AND FFMPEG_LIBSWSCALE_FOUND AND FFMPEG_LIBAVFILTER_FOUND)
+--- dff-1.3.0+dfsg.1.orig/dff/api/gui/video/video.cpp
++++ dff-1.3.0+dfsg.1/dff/api/gui/video/video.cpp
+@@ -91,6 +91,9 @@ VideoDecoder::VideoDecoder(Node* node)
+   this->_packet = NULL;
+   this->_videoStream = -1;
+   this->_frameBuffer = NULL;
++  this->_last_width = -1;
++  this->_last_height = -1;
++  this->_last_pixfmt = AV_PIX_FMT_NONE;
+ 
+   try 
+   {
+@@ -131,7 +134,7 @@ VideoDecoder::VideoDecoder(Node* node)
+   }
+ 
+   this->_initializeVideo();
+-  this->_frame = avcodec_alloc_frame();
++  this->_frame = av_frame_alloc();
+ }
+ 
+ VideoDecoder::~VideoDecoder()
+@@ -168,7 +171,7 @@ void	VideoDecoder::_clear(void)
+   if (this->_stream)
+     this->_stream = NULL;
+   if (this->_frame)
+-    av_free(this->_frame);
++    av_frame_free(&this->_frame);
+   if (this->_frameBuffer)
+     av_free(this->_frameBuffer);
+   if (this->_packet)
+@@ -180,9 +183,10 @@ void	VideoDecoder::_clear(void)
+   if (this->_file)
+     this->_file->close();
+   delete this->_file;
++  _delete_filter_graph();
+ }
+ 
+-void VideoDecoder::_convertAndScaleFrame(PixelFormat format, int scaledSize, bool maintainAspectRatio, int& scaledWidth, int& scaledHeight)
++void VideoDecoder::_convertAndScaleFrame(AVPixelFormat format, int scaledSize, bool maintainAspectRatio, int& scaledWidth, int& scaledHeight)
+ {
+     this->_calculateDimensions(scaledSize, maintainAspectRatio, scaledWidth, scaledHeight);
+ 
+@@ -232,7 +236,7 @@ void VideoDecoder::_convertAndScaleFrame
+               convertedFrame->data, convertedFrame->linesize);
+     sws_freeContext(scaleContext);
+ 
+-    av_free(this->_frame);
++    av_frame_free(&this->_frame);
+     av_free(this->_frameBuffer);
+     
+     this->_frame        = convertedFrame;
+@@ -279,9 +283,9 @@ void VideoDecoder::_calculateDimensions(
+     }
+ }
+ 
+-void VideoDecoder::_createAVFrame(AVFrame** pAvFrame, uint8_t** pFrameBuffer, int width, int height, PixelFormat format)
++void VideoDecoder::_createAVFrame(AVFrame** pAvFrame, uint8_t** pFrameBuffer, int width, int height, AVPixelFormat format)
+ {
+-    *pAvFrame = avcodec_alloc_frame();
++    *pAvFrame = av_frame_alloc();
+ 
+     int numBytes = avpicture_get_size(format, width, height);
+     *pFrameBuffer = reinterpret_cast<uint8_t*>(av_malloc(numBytes));
+@@ -343,7 +347,7 @@ bool	VideoDecoder::_decodeVideoPacket()
+    if (this->_packet->stream_index != this->_videoStream)
+      return false;
+ 
+-   avcodec_get_frame_defaults(this->_frame);
++   av_frame_unref(this->_frame);
+ 
+    int frameFinished;
+    int bytesDecoded = avcodec_decode_video2(this->_codecContext, this->_frame, &frameFinished, this->_packet);
+@@ -426,16 +430,84 @@ void 	VideoDecoder::_initializeVideo()
+   }
+ }
+ 
++void VideoDecoder::_delete_filter_graph() {
++    if (this->_filter_graph) {
++        av_frame_free(&this->_filter_frame);
++        avfilter_graph_free(&this->_filter_graph);
++    }
++}
++
++int VideoDecoder::_init_filter_graph(enum AVPixelFormat pixfmt, int width, int height) {
++    AVFilterInOut *inputs = NULL, *outputs = NULL;
++    char args[512];
++    int res;
++
++    _delete_filter_graph();
++    this->_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(this->_filter_graph, args, &inputs, &outputs);
++    if (res < 0)
++        return res;
++    if (inputs || outputs)
++        return -1;
++    res = avfilter_graph_config(this->_filter_graph, NULL);
++    if (res < 0)
++        return res;
++
++    this->_buffersrc_ctx = avfilter_graph_get_filter(this->_filter_graph, "Parsed_buffer_0");
++    this->_buffersink_ctx = avfilter_graph_get_filter(this->_filter_graph, "Parsed_buffersink_2");
++    if (!this->_buffersrc_ctx || !this->_buffersink_ctx)
++        return -1;
++    this->_filter_frame = av_frame_alloc();
++    this->_last_width = width;
++    this->_last_height = height;
++    this->_last_pixfmt = pixfmt;
++
++    return 0;
++}
++
++int VideoDecoder::_process_filter_graph(AVPicture *dst, const AVPicture *src,
++                                enum AVPixelFormat pixfmt, int width, int height) {
++    int res;
++
++    if (!this->_filter_graph || width != this->_last_width ||
++        height != this->_last_height || pixfmt != this->_last_pixfmt) {
++        res = _init_filter_graph(pixfmt, width, height);
++        if (res < 0)
++            return res;
++    }
++
++    memcpy(this->_filter_frame->data, src->data, sizeof(src->data));
++    memcpy(this->_filter_frame->linesize, src->linesize, sizeof(src->linesize));
++    this->_filter_frame->width = width;
++    this->_filter_frame->height = height;
++    this->_filter_frame->format = pixfmt;
++    res = av_buffersrc_add_frame(this->_buffersrc_ctx, this->_filter_frame);
++    if (res < 0)
++        return res;
++    res = av_buffersink_get_frame(this->_buffersink_ctx, this->_filter_frame);
++    if (res < 0)
++        return res;
++    av_picture_copy(dst, (const AVPicture *) this->_filter_frame, pixfmt, width, height);
++    av_frame_unref(this->_filter_frame);
++
++    return 0;
++}
++
+ Image_p		VideoDecoder::_thumbnail(int32_t scaledSize)
+ {
+   int scaledHeight, scaledWidth;
+   bool maintainAspectRatio = 0;
+ 
+   if (this->_frame->interlaced_frame)
+-    avpicture_deinterlace((AVPicture*) this->_frame, (AVPicture*) this->_frame, this->_codecContext->pix_fmt, 
++    _process_filter_graph((AVPicture*) this->_frame, (AVPicture*) this->_frame, this->_codecContext->pix_fmt, 
+ 			  this->_codecContext->width, this->_codecContext->height);
+ 
+-  this->_convertAndScaleFrame(PIX_FMT_RGB32, scaledSize, maintainAspectRatio, scaledWidth, scaledHeight);
++  this->_convertAndScaleFrame(AV_PIX_FMT_RGB32, scaledSize, maintainAspectRatio, scaledWidth, scaledHeight);
+   Image_p	image(new Image(this->_frame->data[0], this->_frame->linesize[0] * scaledHeight, scaledWidth, scaledHeight));
+ 
+   return (image);
+--- dff-1.3.0+dfsg.1.orig/dff/api/gui/video/video.hpp
++++ dff-1.3.0+dfsg.1/dff/api/gui/video/video.hpp
+@@ -35,6 +35,9 @@ extern "C"
+   #define UINT64_C(c) (c ## ULL)
+ #endif
+ 
++#include <libavfilter/avfilter.h>
++#include <libavfilter/buffersrc.h>
++#include <libavfilter/buffersink.h>
+ #include <libavformat/avio.h>
+ #include <libavformat/avformat.h>
+ #include <libavutil/mem.h>
+@@ -82,6 +85,13 @@ private:
+   unsigned char*	_buffer;
+   uint8_t*		_frameBuffer;
+   int			_videoStream;
++  AVFilterContext *_buffersink_ctx;
++  AVFilterContext *_buffersrc_ctx;
++  AVFilterGraph *_filter_graph;
++  AVFrame *_filter_frame;
++  int _last_width;
++  int _last_height;
++  enum AVPixelFormat _last_pixfmt;
+ 
+   void 			_clear();
+   void			_initializeVideo(void); 
+@@ -89,9 +99,12 @@ private:
+   bool			_decodeVideoPacket(void);
+   bool			_getVideoPacket(void);
+   void			_seek(int64_t seconds);
+-  void			_convertAndScaleFrame(PixelFormat format, int scaledSize, bool maintainAspectRatio, int &scaledWidth, int &scaledHeight);
++  void			_convertAndScaleFrame(AVPixelFormat format, int scaledSize, bool maintainAspectRatio, int &scaledWidth, int &scaledHeight);
+   void 			_calculateDimensions(int squareSize, bool maintainAspectRatio, int& destWidth, int& destHeight);
+-  void 			_createAVFrame(AVFrame** pAvFrame, uint8_t** pFrameBuffer, int width, int height, PixelFormat format);
++  void 			_createAVFrame(AVFrame** pAvFrame, uint8_t** pFrameBuffer, int width, int height, AVPixelFormat format);
++  void			_delete_filter_graph();
++  int			_init_filter_graph(enum AVPixelFormat pixfmt, int width, int height);
++  int			_process_filter_graph(AVPicture *dst, const AVPicture *src, enum AVPixelFormat pixfmt, int width, int height);
+   Image_p		_thumbnail(int32_t scale = 64);
+ public:
+   EXPORT 			VideoDecoder(Node* node);
diff --git a/debian/patches/series b/debian/patches/series
index e0759ec..db5b8fa 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -2,3 +2,4 @@
 03-fix-ftbfs-libav9.patch
 04-fix-swig-detection.patch
 libav10.patch
+ffmpeg_2.9.patch

Reply via email to