Re: FTBFS with libav10
authoranton@khirnov.net <anton@khirnov.net>
Sat, 1 Mar 2014 09:28:51 +0000 (10:28 +0100)
committerAlessio Treglia <alessio@debian.org>
Thu, 14 Aug 2014 12:45:10 +0000 (13:45 +0100)
Gbp-Pq: Name libav10.patch

ffmpeg.c

index bd73f49e60635ac1b53f66335e8696d424bbebb5..97f7163190b0aec126aa4db14f0129568dc95174 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
 #endif
 
 #include <stdio.h>
-#ifdef HAVE_FFMPEG_AVCODEC_H
-#include <ffmpeg/avcodec.h>
-#include <ffmpeg/avformat.h>
-#include <ffmpeg/avio.h>
-#else
 #include <libavcodec/avcodec.h>
 #include <libavformat/avformat.h>
 #include <libavformat/avio.h>
-#ifndef AVUTIL_MATHEMATICS_H
+#include <libavresample/avresample.h>
+#include <libavutil/opt.h>
 #include <libavutil/mathematics.h>
-#endif
-#endif
 
 #if (LIBAVFORMAT_VERSION_INT < ((52<<16)+(31<<8)+0))
 # define NUM_FFMPEG_KEYS 8
@@ -77,6 +71,7 @@ struct ffmpeg_output {
        uint8_t *buffer_malloc;
        uint8_t *buffer_pos;    /* current buffer position */
        int buffer_used_len;
+       int buffer_size;
 };
 
 struct ffmpeg_private {
@@ -87,6 +82,13 @@ struct ffmpeg_private {
 
        struct ffmpeg_input *input;
        struct ffmpeg_output *output;
+
+       AVFrame *frame;
+
+       AVAudioResampleContext *avr;
+       uint64_t resample_channel_layout;
+       int      resample_sample_rate;
+       int      resample_sample_fmt;
 };
 
 static struct ffmpeg_input *ffmpeg_input_create(void)
@@ -112,7 +114,8 @@ static struct ffmpeg_output *ffmpeg_output_create(void)
 {
        struct ffmpeg_output *output = xnew(struct ffmpeg_output, 1);
 
-       output->buffer_malloc = xnew(uint8_t, AVCODEC_MAX_AUDIO_FRAME_SIZE + 15);
+       output->buffer_size = 192000 + 15;
+       output->buffer_malloc = xnew(uint8_t, output->buffer_size);
        output->buffer = output->buffer_malloc;
        /* align to 16 bytes so avcodec can SSE/Altivec/etc */
        while ((intptr_t) output->buffer % 16)
@@ -241,20 +244,12 @@ static int ffmpeg_open(struct input_plugin_data *ip_data)
                        break;
                }
 
-#if (LIBAVCODEC_VERSION_INT > ((51<<16)+(64<<8)+0))
-               if (cc->sample_fmt == AV_SAMPLE_FMT_FLT || cc->sample_fmt == AV_SAMPLE_FMT_DBL) {
-#else
-               if (cc->sample_fmt == AV_SAMPLE_FMT_FLT) {
-#endif
-                       err = -IP_ERROR_SAMPLE_FORMAT;
-                       break;
-               }
                /* We assume below that no more errors follow. */
        } while (0);
 
        if (err < 0) {
                /* Clean up.  cc is never opened at this point.  (See above assumption.) */
-               av_close_input_file(ic);
+               avformat_close_input(&ic);
                return err;
        }
 
@@ -262,11 +257,12 @@ static int ffmpeg_open(struct input_plugin_data *ip_data)
        priv->codec_context = cc;
        priv->input_context = ic;
        priv->codec = codec;
+       priv->frame = av_frame_alloc();
        priv->stream_index = stream_index;
        priv->input = ffmpeg_input_create();
        if (priv->input == NULL) {
                avcodec_close(cc);
-               av_close_input_file(ic);
+               avformat_close_input(&ic);
                free(priv);
                return -IP_ERROR_INTERNAL;
        }
@@ -300,8 +296,10 @@ static int ffmpeg_close(struct input_plugin_data *ip_data)
 {
        struct ffmpeg_private *priv = ip_data->private;
 
+       av_frame_free(&priv->frame);
+       avresample_free(&priv->avr);
        avcodec_close(priv->codec_context);
-       av_close_input_file(priv->input_context);
+       avformat_close_input(&priv->input_context);
        ffmpeg_input_free(priv->input);
        ffmpeg_output_free(priv->output);
        free(priv);
@@ -313,14 +311,18 @@ static int ffmpeg_close(struct input_plugin_data *ip_data)
  * This returns the number of bytes added to the buffer.
  * It returns < 0 on error.  0 on EOF.
  */
-static int ffmpeg_fill_buffer(AVFormatContext *ic, AVCodecContext *cc, struct ffmpeg_input *input,
+static int ffmpeg_fill_buffer(struct ffmpeg_private *priv, struct ffmpeg_input *input,
                              struct ffmpeg_output *output)
 {
+       AVFormatContext *ic = priv->input_context;
+       AVCodecContext  *cc = priv->codec_context;
+       AVFrame *frame      = priv->frame;
+
        while (1) {
                /* frame_size specifies the size of output->buffer for
                 * avcodec_decode_audio2. */
-               int frame_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
-               int len;
+               AVPacket avpkt;
+               int len, got_output, ret;
 
                if (input->curr_pkt_size <= 0) {
                        av_free_packet(&input->pkt);
@@ -335,26 +337,11 @@ static int ffmpeg_fill_buffer(AVFormatContext *ic, AVCodecContext *cc, struct ff
                        continue;
                }
 
-               /* The change to avcodec_decode_audio2 occurred between
-                * 51.28.0 and 51.29.0 */
-#if (LIBAVCODEC_VERSION_INT <= ((51<<16) + (28<<8) + 0))
-               len = avcodec_decode_audio(cc, (int16_t *)output->buffer, &frame_size,
-                               input->curr_pkt_buf, input->curr_pkt_size);
-               /* The change to avcodec_decode_audio3 occurred between
-                * 52.25.0 and 52.26.0 */
-#elif (LIBAVCODEC_VERSION_INT <= ((52<<16) + (25<<8) + 0))
-               len = avcodec_decode_audio2(cc, (int16_t *) output->buffer, &frame_size,
-                               input->curr_pkt_buf, input->curr_pkt_size);
-#else
-               {
-                       AVPacket avpkt;
-                       av_init_packet(&avpkt);
-                       avpkt.data = input->curr_pkt_buf;
-                       avpkt.size = input->curr_pkt_size;
-                       len = avcodec_decode_audio3(cc, (int16_t *) output->buffer, &frame_size, &avpkt);
-                       av_free_packet(&avpkt);
-               }
-#endif
+               av_init_packet(&avpkt);
+               avpkt.data = input->curr_pkt_buf;
+               avpkt.size = input->curr_pkt_size;
+               len = avcodec_decode_audio4(cc, frame, &got_output, &avpkt);
+
                if (len < 0) {
                        /* this is often reached when seeking, not sure why */
                        input->curr_pkt_size = 0;
@@ -362,10 +349,34 @@ static int ffmpeg_fill_buffer(AVFormatContext *ic, AVCodecContext *cc, struct ff
                }
                input->curr_pkt_size -= len;
                input->curr_pkt_buf += len;
-               if (frame_size > 0) {
+               if (got_output) {
+                       if (!priv->avr ||
+                           frame->format != priv->resample_sample_fmt ||
+                            frame->sample_rate != priv->resample_sample_rate ||
+                            frame->channel_layout != priv->resample_channel_layout) {
+
+                                avresample_free(&priv->avr);
+
+                                priv->avr = avresample_alloc_context();
+                                av_opt_set_int(priv->avr, "in_channel_layout", frame->channel_layout, 0);
+                                av_opt_set_int(priv->avr, "out_channel_layout", frame->channel_layout, 0);
+                                av_opt_set_int(priv->avr, "in_sample_rate", frame->sample_rate, 0);
+                                av_opt_set_int(priv->avr, "out_sample_rate", frame->sample_rate, 0);
+                                av_opt_set_int(priv->avr, "in_sample_fmt", frame->format, 0);
+                                av_opt_set_int(priv->avr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
+
+                                ret = avresample_open(priv->avr);
+                                if (ret < 0)
+                                        return -IP_ERROR_INTERNAL;
+                        }
+
+                        len = avresample_convert(priv->avr, (uint8_t**)&output->buffer, 
+                                       output->buffer_size, frame->nb_samples,
+                                       frame->extended_data, frame->linesize[0], frame->nb_samples);
+
                        output->buffer_pos = output->buffer;
-                       output->buffer_used_len = frame_size;
-                       return frame_size;
+                       output->buffer_used_len = len * 2 * cc->channels;
+                       return output->buffer_used_len;
                }
        }
        /* This should never get here. */
@@ -380,7 +391,7 @@ static int ffmpeg_read(struct input_plugin_data *ip_data, char *buffer, int coun
        int out_size;
 
        if (output->buffer_used_len == 0) {
-               rc = ffmpeg_fill_buffer(priv->input_context, priv->codec_context, priv->input, priv->output);
+               rc = ffmpeg_fill_buffer(priv, priv->input, priv->output);
                if (rc <= 0) {
                        return rc;
                }
@@ -494,7 +505,7 @@ static long ffmpeg_current_bitrate(struct input_plugin_data *ip_data)
        long bitrate = -1;
 #if (LIBAVFORMAT_VERSION_INT > ((51<<16)+(43<<8)+0))
        /* ape codec returns silly numbers */
-       if (priv->codec->id == CODEC_ID_APE)
+       if (priv->codec->id == AV_CODEC_ID_APE)
                return -1;
 #endif
        if (priv->input->curr_duration > 0) {