diff options
| author | Carl Hetherington <cth@carlh.net> | 2012-07-19 20:42:11 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2012-07-19 20:42:11 +0100 |
| commit | a81e35ba9a8807e1b13c2a6c4133bbf4ff36859a (patch) | |
| tree | dc42a853a19886090b003cce3c0b46693f5ca29e | |
| parent | c555b46db1eb31f90423b50af95dc8925875048e (diff) | |
#ifdef-y hacks to build with Ubuntu 12.04's ffmpeg.
| -rw-r--r-- | src/lib/decoder.cc | 62 | ||||
| -rw-r--r-- | src/lib/ffmpeg_compatibility.cc | 109 | ||||
| -rw-r--r-- | src/lib/ffmpeg_compatibility.h | 22 | ||||
| -rw-r--r-- | src/lib/image.cc | 3 | ||||
| -rw-r--r-- | src/lib/util.cc | 4 | ||||
| -rw-r--r-- | src/lib/wscript | 1 | ||||
| -rw-r--r-- | wscript | 5 |
7 files changed, 185 insertions, 21 deletions
diff --git a/src/lib/decoder.cc b/src/lib/decoder.cc index a904e085b..df3a4dda6 100644 --- a/src/lib/decoder.cc +++ b/src/lib/decoder.cc @@ -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 index 000000000..bdaf735a2 --- /dev/null +++ b/src/lib/ffmpeg_compatibility.cc @@ -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 index 000000000..7aaae92e2 --- /dev/null +++ b/src/lib/ffmpeg_compatibility.h @@ -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 (); + diff --git a/src/lib/image.cc b/src/lib/image.cc index 7a9ac7dd5..9ae0fe6f8 100644 --- a/src/lib/image.cc +++ b/src/lib/image.cc @@ -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> } diff --git a/src/lib/util.cc b/src/lib/util.cc index 1348d307e..92861739c 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -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()) << ", " diff --git a/src/lib/wscript b/src/lib/wscript index cee0a47e7..a263a13d1 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -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 @@ -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) |
