--- Begin Message ---
Package: ffmpeg2theora
Version: 0.29.0~git+20140316-3
Severity: important
Tags: patch
User: pkg-multimedia-maintainers@lists.alioth.debian.org
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/patches/ffmpeg_2.9.patch b/debian/patches/ffmpeg_2.9.patch
new file mode 100644
index 0000000..9c0dfb0
--- /dev/null
+++ b/debian/patches/ffmpeg_2.9.patch
@@ -0,0 +1,205 @@
+Description: Replace deprecated FFmpeg API
+Author: Andreas Cadhalpun <andreas.cadhal...@googlemail.com>
+Last-Update: <2015-11-02>
+
+--- ffmpeg2theora-0.29.0~git+20140316.orig/src/avinfo.c
++++ ffmpeg2theora-0.29.0~git+20140316/src/avinfo.c
+@@ -178,8 +178,6 @@ void json_codec_info(FILE *output, AVCod
+ /* fake mpeg2 transport stream codec (currently not
+ registered) */
+ codec_name = "mpeg2ts";
+- } else if (enc->codec_name[0] != '\0') {
+- codec_name = enc->codec_name;
+ } else {
+ /* output avi tags */
+ if( isprint(enc->codec_tag&0xFF) && isprint((enc->codec_tag>>8)&0xFF)
+@@ -200,7 +198,7 @@ void json_codec_info(FILE *output, AVCod
+ case AVMEDIA_TYPE_VIDEO:
+ codec_name = fix_codec_name(codec_name);
+ json_add_key_value(output, "codec", (void *)codec_name, JSON_STRING, 0, indent);
+- if (enc->pix_fmt != PIX_FMT_NONE) {
++ if (enc->pix_fmt != AV_PIX_FMT_NONE) {
+ json_add_key_value(output, "pixel_format", (void *)av_get_pix_fmt_name(enc->pix_fmt), JSON_STRING, 0, indent);
+ }
+ if (enc->width) {
+--- ffmpeg2theora-0.29.0~git+20140316.orig/src/ffmpeg2theora.c
++++ ffmpeg2theora-0.29.0~git+20140316/src/ffmpeg2theora.c
+@@ -148,13 +148,13 @@ static AVFrame *frame_alloc(int pix_fmt,
+ uint8_t *picture_buf;
+ int size;
+
+- picture = avcodec_alloc_frame();
++ picture = av_frame_alloc();
+ if (!picture)
+ return NULL;
+ size = avpicture_get_size (pix_fmt, width, height);
+ picture_buf = av_malloc (size);
+ if (!picture_buf) {
+- av_free (picture);
++ av_frame_free (&picture);
+ return NULL;
+ }
+ avpicture_fill((AVPicture *) picture, picture_buf, pix_fmt, width, height);
+@@ -167,7 +167,7 @@ static AVFrame *frame_alloc(int pix_fmt,
+ static void frame_dealloc(AVFrame *frame) {
+ if (frame) {
+ avpicture_free((AVPicture*)frame);
+- av_free(frame);
++ av_frame_free(&frame);
+ }
+ }
+
+@@ -231,7 +231,7 @@ static ff2theora ff2theora_init() {
+ this->kate_streams=NULL;
+ this->ignore_non_utf8 = 0;
+
+- this->pix_fmt = PIX_FMT_YUV420P;
++ this->pix_fmt = AV_PIX_FMT_YUV420P;
+
+ // ffmpeg2theora --nosound -f dv -H 32000 -S 0 -v 8 -x 384 -y 288 -G 1.5 input.dv
+ this->video_gamma = 0.0;
+@@ -521,6 +521,74 @@ static const char *find_language_for_sub
+ return lang;
+ }
+
++static void delete_filter_graph(ff2theora this) {
++ if (this->filter_graph) {
++ av_frame_free(&this->filter_frame);
++ avfilter_graph_free(&this->filter_graph);
++ }
++}
++
++static int init_filter_graph(ff2theora this, enum AVPixelFormat pixfmt, int width, int height) {
++ AVFilterInOut *inputs = NULL, *outputs = NULL;
++ char args[512];
++ int res;
++
++ delete_filter_graph(this);
++ 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;
++}
++
++static int process_filter_graph(ff2theora this, 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(this, 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;
++}
++
+ void ff2theora_output(ff2theora this) {
+ unsigned int i;
+ AVCodecContext *aenc = NULL;
+@@ -1468,7 +1536,7 @@ void ff2theora_output(ff2theora this) {
+ }
+ if ((this->deinterlace==0 && frame->interlaced_frame) ||
+ this->deinterlace==1) {
+- if (avpicture_deinterlace((AVPicture *)output,(AVPicture *)output_tmp,this->pix_fmt,display_width,display_height)<0) {
++ if (process_filter_graph(this, (AVPicture *)output,(AVPicture *)output_tmp,this->pix_fmt,display_width,display_height)<0) {
+ fprintf(stderr, "Deinterlace failed.\n");
+ exit(1);
+ }
+@@ -1565,7 +1633,7 @@ void ff2theora_output(ff2theora this) {
+ int bytes_per_sample = av_get_bytes_per_sample(aenc->sample_fmt);
+
+ if (avpkt.size > 0) {
+- if (!audio_frame && !(audio_frame = avcodec_alloc_frame())) {
++ if (!audio_frame && !(audio_frame = av_frame_alloc())) {
+ fprintf(stderr, "Failed to allocate memory\n");
+ exit(1);
+ }
+@@ -1615,7 +1683,7 @@ void ff2theora_output(ff2theora this) {
+ }
+ }
+ oggmux_add_audio(&info, audio_p, dst_nb_samples, audio_eos);
+- avcodec_free_frame(&audio_frame);
++ av_frame_free(&audio_frame);
+ this->sample_count += dst_nb_samples;
+ }
+ if(audio_eos) {
+@@ -1816,7 +1884,7 @@ void ff2theora_output(ff2theora this) {
+ if (ppContext)
+ pp_free_context(ppContext);
+ if (!info.audio_only) {
+- av_free(frame_p);
++ av_frame_free(&frame_p);
+ frame_dealloc(output_p);
+ frame_dealloc(output_tmp_p);
+ frame_dealloc(output_resized_p);
+@@ -1837,6 +1905,7 @@ void ff2theora_output(ff2theora this) {
+ }
+
+ void ff2theora_close(ff2theora this) {
++ delete_filter_graph(this);
+ sws_freeContext(this->sws_colorspace_ctx);
+ sws_freeContext(this->sws_scale_ctx);
+ this->sws_colorspace_ctx = NULL;
+--- ffmpeg2theora-0.29.0~git+20140316.orig/src/ffmpeg2theora.h
++++ ffmpeg2theora-0.29.0~git+20140316/src/ffmpeg2theora.h
+@@ -2,6 +2,9 @@
+ #define _F2T_FFMPEG2THEORA_H_
+
+ #include "subtitles.h"
++#include <libavfilter/avfilter.h>
++#include <libavfilter/buffersrc.h>
++#include <libavfilter/buffersink.h>
+
+ typedef struct ff2theora_subtitle{
+ char *text;
+@@ -117,6 +120,13 @@ typedef struct ff2theora{
+ unsigned char y_lut[256];
+ unsigned char uv_lut[256];
+
++ AVFilterContext *buffersink_ctx;
++ AVFilterContext *buffersrc_ctx;
++ AVFilterGraph *filter_graph;
++ AVFrame *filter_frame;
++ int last_width;
++ int last_height;
++ enum AVPixelFormat last_pixfmt;
+ }
+ *ff2theora;
+
diff --git a/debian/patches/series b/debian/patches/series
index 433f5a7..270d545 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -3,3 +3,4 @@
#003-libswresample.patch
libavresample.patch
link-libm.patch
+ffmpeg_2.9.patch
--- End Message ---