#ifdef-y hacks to build with Ubuntu 12.04's ffmpeg.
authorCarl Hetherington <cth@carlh.net>
Thu, 19 Jul 2012 19:42:11 +0000 (20:42 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 19 Jul 2012 19:42:11 +0000 (20:42 +0100)
src/lib/decoder.cc
src/lib/ffmpeg_compatibility.cc [new file with mode: 0644]
src/lib/ffmpeg_compatibility.h [new file with mode: 0644]
src/lib/image.cc
src/lib/util.cc
src/lib/wscript
wscript

index a904e085b173131b87090c031879416010a6ab2e..df3a4dda6bf504f753b3f319fe751bfbff3b42ce 100644 (file)
@@ -25,8 +25,8 @@
 #include <stdint.h>
 extern "C" {
 #include <libavfilter/avfiltergraph.h>
-#include <libavfilter/buffersink.h>
-#include <libavfilter/avcodec.h>
+#include <libavfilter/vsrc_buffer.h>
+#include <libavformat/avio.h>
 }
 #include "film.h"
 #include "format.h"
@@ -40,6 +40,7 @@ extern "C" {
 #include "decoder.h"
 #include "filter.h"
 #include "delay_line.h"
+#include "ffmpeg_compatibility.h"
 
 using namespace std;
 using namespace boost;
@@ -192,20 +193,51 @@ Decoder::process_video (AVFrame* frame)
        if (_opt->decode_video_frequency != 0) {
                gap = _fs->length / _opt->decode_video_frequency;
        }
-       
+
        if (_opt->decode_video_frequency != 0 && gap != 0 && (_video_frame % gap) != 0) {
                ++_video_frame;
                return;
        }
 
+#ifdef DVDOMATIC_FFMPEG_0_8_3
+       
+       AVRational par;
+       par.num = sample_aspect_ratio_numerator ();
+       par.den = sample_aspect_ratio_denominator ();
+
+       if (av_vsrc_buffer_add_frame (_buffer_src_context, frame, 0, par) < 0) {
+               throw DecodeError ("could not push buffer into filter chain.");
+       }
+
+#else
+
        if (av_vsrc_buffer_add_frame (_buffer_src_context, frame, 0) < 0) {
                throw DecodeError ("could not push buffer into filter chain.");
        }
+
+#endif 
        
        while (avfilter_poll_frame (_buffer_sink_context->inputs[0])) {
+
+#ifdef DVDOMATIC_FFMPEG_0_8_3
+
+               int r = avfilter_request_frame (_buffer_sink_context->inputs[0]);
+               if (r < 0) {
+                       throw DecodeError ("could not request filtered frame");
+               }
+               
+               AVFilterBufferRef* filter_buffer = _buffer_sink_context->inputs[0]->cur_buf;
+               
+#else
+
                AVFilterBufferRef* filter_buffer;
-               if (av_buffersink_get_buffer_ref (_buffer_sink_context, &filter_buffer, 0) >= 0) {
-                       
+               if (avbuffersink_get_buffer_ref (_buffer_sink_context, &filter_buffer, 0) < 0) {
+                       filter_buffer = 0;
+               }
+
+#endif         
+               
+               if (filter_buffer) {
                        /* This takes ownership of filter_buffer */
                        shared_ptr<Image> image (new FilterBufferImage ((PixelFormat) frame->format, filter_buffer));
 
@@ -246,17 +278,14 @@ Decoder::setup_video_filters ()
        if (graph == 0) {
                throw DecodeError ("Could not create filter graph.");
        }
-       
+
        AVFilter* buffer_src = avfilter_get_by_name("buffer");
        if (buffer_src == 0) {
-               throw DecodeError ("Could not create buffer src filter");
+               throw DecodeError ("Could not find buffer src filter");
        }
-       
-       AVFilter* buffer_sink = avfilter_get_by_name("buffersink");
-       if (buffer_sink == 0) {
-               throw DecodeError ("Could not create buffer sink filter");
-       }
-       
+
+       AVFilter* buffer_sink = get_sink ();
+
        stringstream a;
        a << native_size().width << ":"
          << native_size().height << ":"
@@ -289,12 +318,19 @@ Decoder::setup_video_filters ()
        inputs->next = 0;
 
        _log->log ("Using filter chain `" + filters + "'");
+#ifdef DVDOMATIC_FFMPEG_0_8_3  
+       if (avfilter_graph_parse (graph, filters.c_str(), inputs, outputs, 0) < 0) {
+#else
        if (avfilter_graph_parse (graph, filters.c_str(), &inputs, &outputs, 0) < 0) {
+#endif         
+               
                throw DecodeError ("could not set up filter graph.");
        }
 
        if (avfilter_graph_config (graph, 0) < 0) {
                throw DecodeError ("could not configure filter graph.");
        }
+
+       /* XXX: leaking `inputs' / `outputs' ? */
 }
 
diff --git a/src/lib/ffmpeg_compatibility.cc b/src/lib/ffmpeg_compatibility.cc
new file mode 100644 (file)
index 0000000..bdaf735
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+    Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+extern "C" {
+#include <libavfilter/avfiltergraph.h>
+}
+#include "exceptions.h"
+
+#ifdef DVDOMATIC_FFMPEG_0_8_3  
+
+typedef struct {
+       enum PixelFormat pix_fmt;
+} AVSinkContext;
+
+static int
+avsink_init (AVFilterContext* ctx, const char* args, void* opaque)
+{
+       AVSinkContext* priv = (AVSinkContext *) ctx->priv;
+       if (!opaque) {
+               return AVERROR (EINVAL);
+       }
+
+       *priv = *(AVSinkContext *) opaque;
+       return 0;
+}
+
+static void
+null_end_frame (AVFilterLink *)
+{
+
+}
+
+static int
+avsink_query_formats (AVFilterContext* ctx)
+{
+       AVSinkContext* priv = (AVSinkContext *) ctx->priv;
+       enum PixelFormat pix_fmts[] = {
+               priv->pix_fmt,
+               PIX_FMT_NONE
+       };
+
+       avfilter_set_common_formats (ctx, avfilter_make_format_list ((int *) pix_fmts));
+       return 0;
+}
+
+#endif
+
+AVFilter*
+get_sink ()
+{
+#ifdef DVDOMATIC_FFMPEG_0_8_3  
+       /* XXX does this leak stuff? */
+       AVFilter* buffer_sink = new AVFilter;
+       buffer_sink->name = av_strdup ("avsink");
+       buffer_sink->priv_size = sizeof (AVSinkContext);
+       buffer_sink->init = avsink_init;
+       buffer_sink->query_formats = avsink_query_formats;
+       buffer_sink->inputs = new AVFilterPad[2];
+       AVFilterPad* i0 = const_cast<AVFilterPad*> (&buffer_sink->inputs[0]);
+       i0->name = "default";
+       i0->type = AVMEDIA_TYPE_VIDEO;
+       i0->min_perms = AV_PERM_READ;
+       i0->rej_perms = 0;
+       i0->start_frame = 0;
+       i0->get_video_buffer = 0;
+       i0->get_audio_buffer = 0;
+       i0->end_frame = null_end_frame;
+       i0->draw_slice = 0;
+       i0->filter_samples = 0;
+       i0->poll_frame = 0;
+       i0->request_frame = 0;
+       i0->config_props = 0;
+       const_cast<AVFilterPad*> (&buffer_sink->inputs[1])->name = 0;
+       buffer_sink->outputs = new AVFilterPad[1];
+       const_cast<AVFilterPad*> (&buffer_sink->outputs[0])->name = 0;
+       return buffer_sink;
+#else
+       AVFilter* buffer_sink = avfilter_get_by_name("buffersink");
+       if (buffer_sink == 0) {
+               throw DecodeError ("Could not create buffer sink filter");
+       }
+
+       return buffer_sink;
+#endif
+}
+
+#ifdef DVDOMATIC_FFMPEG_0_8_3
+AVFilterInOut *
+avfilter_inout_alloc ()
+{
+       return (AVFilterInOut *) av_malloc (sizeof (AVFilterInOut));
+}
+#endif
diff --git a/src/lib/ffmpeg_compatibility.h b/src/lib/ffmpeg_compatibility.h
new file mode 100644 (file)
index 0000000..7aaae92
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+    Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+extern AVFilter* get_sink ();
+extern AVFilterInOut* avfilter_inout_alloc ();
+
index 7a9ac7dd5d1f6d235a5c6be0557304530bd92723..9ae0fe6f8f888579aaa69dde0392e3a1f30191f3 100644 (file)
@@ -33,10 +33,7 @@ extern "C" {
 #include <libavcodec/avcodec.h>
 #include <libavformat/avformat.h>
 #include <libswscale/swscale.h>
-#include <libswresample/swresample.h>
 #include <libavfilter/avfiltergraph.h>
-#include <libavfilter/avcodec.h>
-#include <libavfilter/buffersink.h>
 #include <libpostproc/postprocess.h>
 #include <libavutil/pixfmt.h>
 }
index 1348d307e9c3d50296d8e0b2cbabf2122c101d20..92861739c85004312371456f46bf68486a82ee88 100644 (file)
@@ -39,10 +39,7 @@ extern "C" {
 #include <libavcodec/avcodec.h>
 #include <libavformat/avformat.h>
 #include <libswscale/swscale.h>
-#include <libswresample/swresample.h>
 #include <libavfilter/avfiltergraph.h>
-#include <libavfilter/avcodec.h>
-#include <libavfilter/buffersink.h>
 #include <libpostproc/postprocess.h>
 #include <libavutil/pixfmt.h>
 }
@@ -265,7 +262,6 @@ dependency_version_summary ()
        stringstream s;
        s << "libopenjpeg " << opj_version () << ", "
          << "vobcopy " << vobcopy_version() << ", "
-         << "libswresample " << ffmpeg_version_to_string (swresample_version()) << ", "
          << "libavcodec " << ffmpeg_version_to_string (avcodec_version()) << ", "
          << "libavfilter " << ffmpeg_version_to_string (avfilter_version()) << ", "
          << "libavformat " << ffmpeg_version_to_string (avformat_version()) << ", "
index cee0a47e79929570625803760810e3502c1ac407..a263a13d1597f22f44cce74477cda44d214a5ab7 100644 (file)
@@ -24,6 +24,7 @@ def build(bld):
                 encoder.cc
                  encoder_factory.cc
                 examine_content_job.cc
+                 ffmpeg_compatibility.cc
                  ffmpeg_decoder.cc
                 film.cc
                 film_state.cc
diff --git a/wscript b/wscript
index 9e550eb2ec37dd486d61b90c15b2bd03a749dbbd..ceacc0093851c87dbbaf891f1ea50f73996de671 100644 (file)
--- a/wscript
+++ b/wscript
@@ -6,6 +6,7 @@ def options(opt):
     opt.add_option('--debug-hash', action='store_true', default = False, help = 'print hashes of data at various points')
     opt.add_option('--enable-debug', action='store_true', default = False, help = 'build with debugging information and without optimisation')
     opt.add_option('--disable-gui', action='store_true', default = False, help = 'disable building of GUI tools')
+    opt.add_option('--ffmpeg-083', action='store_true', default = False, help = 'Use FFmpeg version in Ubuntu 12.04')
 
 def configure(conf):
     conf.load('compiler_cxx')
@@ -20,6 +21,9 @@ def configure(conf):
     else:
         conf.env.append_value('CXXFLAGS', '-O3')
 
+    if conf.options.ffmpeg_083:
+        conf.env.append_value('CXXFLAGS', '-DDVDOMATIC_FFMPEG_0_8_3')
+
     conf.env.DISABLE_GUI = conf.options.disable_gui
 
     conf.check_cfg(package = 'sigc++-2.0', args = '--cflags --libs', uselib_store = 'SIGC++', mandatory = True)
@@ -28,7 +32,6 @@ def configure(conf):
     conf.check_cfg(package = 'libavcodec', args = '--cflags --libs', uselib_store = 'AVCODEC', mandatory = True)
     conf.check_cfg(package = 'libavutil', args = '--cflags --libs', uselib_store = 'AVUTIL', mandatory = True)
     conf.check_cfg(package = 'libswscale', args = '--cflags --libs', uselib_store = 'SWSCALE', mandatory = True)
-    conf.check_cfg(package = 'libswresample', args = '--cflags --libs', uselib_store = 'SWRESAMPLE', mandatory = True)
     conf.check_cfg(package = 'libpostproc', args = '--cflags --libs', uselib_store = 'POSTPROC', mandatory = True)
     conf.check_cfg(package = 'sndfile', args = '--cflags --libs', uselib_store = 'SNDFILE', mandatory = True)
     conf.check_cfg(package = 'libdcp', args = '--cflags --libs', uselib_store = 'DCP', mandatory = True)