[cmus] patch for newer ffmpeg

Leigh Scott leigh123linux at rpmfusion.org
Wed Jul 27 10:23:33 CEST 2016


commit bd5046d0fc9a7180998a74c07bf91a0cfe8e8ca9
Author: leigh123linux <leigh123linux at googlemail.com>
Date:   Wed Jul 27 09:23:25 2016 +0100

    patch for newer ffmpeg

 cmus.spec        |   8 +-
 new_ffmpeg.patch | 728 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 735 insertions(+), 1 deletion(-)
---
diff --git a/cmus.spec b/cmus.spec
index a63edf0..a8b4cb0 100644
--- a/cmus.spec
+++ b/cmus.spec
@@ -1,11 +1,13 @@
 Name:           cmus
 Version:        2.7.1
-Release:        1%{?dist}
+Release:        2%{?dist}
 Summary:        Ncurses-Based Music Player
 Group:          Applications/Multimedia
 License:        GPLv2+
 URL:            https://cmus.github.io/
 Source0:        https://github.com/cmus/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz
+# patch from https://github.com/mahkoh/cmus/commits/ffmpeg_legacy
+Patch0:         new_ffmpeg.patch
 
 BuildRequires:  alsa-lib-devel
 BuildRequires:  faad2-devel
@@ -32,6 +34,7 @@ operating systems
 
 %prep
 %setup -q
+%patch0 -p1
 
 
 %build
@@ -85,6 +88,9 @@ chmod -x examples/*
 
 
 %changelog
+* Wed Jul 27 2016 Leigh Scott <leigh123linux at googlemail.com> - 2.7.1-2
+- patch for newer ffmpeg
+
 * Fri Dec 04 2015 Sérgio Basto <sergio at serjux.com> - 2.7.1-1
 - Update to 2.7.1
 
diff --git a/new_ffmpeg.patch b/new_ffmpeg.patch
new file mode 100644
index 0000000..4c461f6
--- /dev/null
+++ b/new_ffmpeg.patch
@@ -0,0 +1,728 @@
+--- a/ffmpeg.c
++++ b/ffmpeg.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright 2008-2013 Various Authors
++ * Copyright 2008-2016 Various Authors
+  * Copyright 2007 Kevin Ko <kevin.s.ko at gmail.com>
+  *
+  * This program is free software; you can redistribute it and/or
+@@ -26,57 +26,67 @@
+ #endif
+ 
+ #include <stdio.h>
+-#ifdef HAVE_FFMPEG_AVCODEC_H
+-#include <ffmpeg/avcodec.h>
+-#include <ffmpeg/avformat.h>
+-#include <ffmpeg/avio.h>
+-#include <ffmpeg/swresample.h>
+-#include <ffmpeg/opt.h>
+-#include <ffmpeg/audioconvert.h>
+-#else
++#include <stdbool.h>
++
++/* Minimum API versions:
++ * avcodec:    54
++ * avformat:   54
++ * avutil:     51
++ * swresample: 0
++ */
++
+ #include <libavcodec/avcodec.h>
+ #include <libavformat/avformat.h>
+ #include <libavformat/avio.h>
+ #include <libswresample/swresample.h>
+ #include <libavutil/opt.h>
+-#include <libavutil/audioconvert.h>
++#if LIBAVUTIL_VERSION_MAJOR >= 53
++#	include <libavutil/channel_layout.h>
++#else
++#	include <libavutil/audioconvert.h>
++#endif
+ #ifndef AVUTIL_MATHEMATICS_H
+ #include <libavutil/mathematics.h>
+ #endif
+-#endif
+-
+-#if (LIBAVFORMAT_VERSION_INT < ((52<<16)+(31<<8)+0))
+-# define NUM_FFMPEG_KEYS 8
+-#endif
+-
+-#if (LIBAVCODEC_VERSION_INT < ((52<<16)+(64<<8)+0))
+-# define AVMEDIA_TYPE_AUDIO CODEC_TYPE_AUDIO
+-#endif
+-
+-#if (LIBAVCODEC_VERSION_INT < ((52<<16)+(94<<8)+1))
+-#define AV_SAMPLE_FMT_U8   SAMPLE_FMT_U8
+-#define AV_SAMPLE_FMT_S16  SAMPLE_FMT_S16
+-#define AV_SAMPLE_FMT_S32  SAMPLE_FMT_S32
+-#define AV_SAMPLE_FMT_FLT  SAMPLE_FMT_FLT
+-#if (LIBAVCODEC_VERSION_INT > ((51<<16)+(64<<8)+0))
+-#define AV_SAMPLE_FMT_DBL  SAMPLE_FMT_DBL
+-#endif
+-#endif
+-
+-#if (LIBAVUTIL_VERSION_INT < ((51<<16)+(5<<8)+0))
+-#define AV_DICT_IGNORE_SUFFIX AV_METADATA_IGNORE_SUFFIX
+-#define av_dict_get av_metadata_get
+-#define AVDictionaryEntry AVMetadataTag
+-#endif
+ 
+ #ifndef AVCODEC_MAX_AUDIO_FRAME_SIZE
+-#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000
++#	define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000
++#endif
++
++#if LIBAVCODEC_VERSION_MAJOR >= 56
++#	define ffmpeg_packet_unref(pkt) av_packet_unref(pkt)
++#	define ffmpeg_frame_alloc()     av_frame_alloc()
++#	define ffmpeg_frame_free(frame) av_frame_free(frame)
++#	define ffmpeg_free_context(cc)  avcodec_free_context(cc)
++#else
++#	define ffmpeg_packet_unref(pkt) av_free_packet(pkt)
++#	define ffmpeg_frame_alloc()     avcodec_alloc_frame()
++#	define ffmpeg_frame_free(frame) avcodec_free_frame(frame)
++#	define ffmpeg_free_context(cc)  do { avcodec_close(*cc); av_freep(cc); } while (0)
++#endif
++
++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 40, 100)
++#	define ffmpeg_initialize_context(cc, stream) \
++		avcodec_copy_context(cc, stream->codec)
++#else
++#	define ffmpeg_initialize_context(cc, stream) \
++		avcodec_parameters_to_context(cc, stream->codecpar)
++#	define ffmpeg_receive_frame(...) avcodec_receive_frame(__VA_ARGS__)
++#	define ffmpeg_send_packet(...) avcodec_send_packet(__VA_ARGS__)
++#endif
++
++#if LIBAVCODEC_VERSION_MAJOR >= 55
++#	define FFMPEG_CODEC_ID_APE AV_CODEC_ID_APE
++#else
++#	define FFMPEG_CODEC_ID_APE CODEC_ID_APE
+ #endif
+ 
+ struct ffmpeg_input {
+ 	AVPacket pkt;
+ 	int curr_pkt_size;
+ 	uint8_t *curr_pkt_buf;
++	int stream_index;
++	bool eof;
+ 
+ 	unsigned long curr_size;
+ 	unsigned long curr_duration;
+@@ -94,12 +104,55 @@
+ 	AVFormatContext *input_context;
+ 	AVCodec *codec;
+ 	SwrContext *swr;
+-	int stream_index;
+ 
+ 	struct ffmpeg_input *input;
+ 	struct ffmpeg_output *output;
+ };
+ 
++#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 40, 100)
++static int ffmpeg_receive_frame(AVCodecContext *cc, AVFrame *frame)
++{
++	struct ffmpeg_private *private = cc->opaque;
++	struct ffmpeg_input *input = private->input;
++
++	int len = 0;
++	int got_frame = 0;
++
++ 	if (input->curr_pkt_size <= 0) {
++		return -1;
++ 	}
++ 
++ 	AVPacket avpkt;
++ 	av_new_packet(&avpkt, input->curr_pkt_size);
++ 	memcpy(avpkt.data, input->curr_pkt_buf, input->curr_pkt_size);
++ 	len = avcodec_decode_audio4(cc, frame, &got_frame, &avpkt);
++ 	ffmpeg_packet_unref(&avpkt);
++
++	if (len < 0) {
++		input->curr_pkt_size = 0;
++		return -1;
++	}
++
++	input->curr_pkt_size -= len;
++	input->curr_pkt_buf += len;
++
++	return !got_frame;
++}
++
++static int ffmpeg_send_packet(AVCodecContext *cc, AVPacket *pkt)
++{
++	struct ffmpeg_private *private = cc->opaque;
++	struct ffmpeg_input *input = private->input;
++
++	if (pkt) {
++		input->curr_pkt_size = pkt->size;
++		input->curr_pkt_buf = pkt->data;
++	}
++
++	return 0;
++}
++#endif
++
+ static struct ffmpeg_input *ffmpeg_input_create(void)
+ {
+ 	struct ffmpeg_input *input = xnew(struct ffmpeg_input, 1);
+@@ -110,12 +163,13 @@
+ 	}
+ 	input->curr_pkt_size = 0;
+ 	input->curr_pkt_buf = input->pkt.data;
++	input->eof = false;
+ 	return input;
+ }
+ 
+ static void ffmpeg_input_free(struct ffmpeg_input *input)
+ {
+-	av_free_packet(&input->pkt);
++	ffmpeg_packet_unref(&input->pkt);
+ 	free(input);
+ }
+ 
+@@ -157,112 +211,79 @@
+ 
+ 	av_log_set_level(AV_LOG_QUIET);
+ 
+-#if (LIBAVFORMAT_VERSION_INT <= ((50<<16) + (4<<8) + 0))
+-	avcodec_init();
+-	register_avcodec(&wmav1_decoder);
+-	register_avcodec(&wmav2_decoder);
+-
+-	/* libavformat versions <= 50.4.0 have asf_init().  From SVN revision
+-	 * 5697->5707 of asf.c, this function was removed, preferring the use of
+-	 * explicit calls.  Note that version 50.5.0 coincides with SVN revision
+-	 * 5729, so there is a window of incompatibility for revisions 5707 and 5720
+-	 * of asf.c.
+-	 */
+-	asf_init();
+-
+-	/* Uncomment this for shorten (.shn) support.
+-	   register_avcodec(&shorten_decoder);
+-	   raw_init();
+-	 */
+-
+-	register_protocol(&file_protocol);
+-#else
+ 	/* We could register decoders explicitly to save memory, but we have to
+ 	 * be careful about compatibility. */
+ 	av_register_all();
+-#endif
+ }
+ 
+ static int ffmpeg_open(struct input_plugin_data *ip_data)
+ {
+-	struct ffmpeg_private *priv;
++	struct ffmpeg_private *priv = NULL;
+ 	int err = 0;
+-	int i;
+ 	int stream_index = -1;
+ 	int64_t channel_layout = 0;
+-	AVCodec *codec;
++	AVCodec *codec = NULL;
+ 	AVCodecContext *cc = NULL;
+ 	AVFormatContext *ic = NULL;
+ 	SwrContext *swr = NULL;
+ 
+ 	ffmpeg_init();
+ 
+-#if (LIBAVFORMAT_VERSION_INT <= ((53<<16)+(2<<8)+0))
+-	err = av_open_input_file(&ic, ip_data->filename, NULL, 0, NULL);
+-#else
+ 	err = avformat_open_input(&ic, ip_data->filename, NULL, NULL);
+-#endif
+ 	if (err < 0) {
+ 		d_print("av_open failed: %d\n", err);
+ 		return -IP_ERROR_FILE_FORMAT;
+ 	}
+ 
+ 	do {
+-#if (LIBAVFORMAT_VERSION_INT <= ((53<<16)+(5<<8)+0))
+-		err = av_find_stream_info(ic);
+-#else
+ 		err = avformat_find_stream_info(ic, NULL);
+-#endif
+ 		if (err < 0) {
+ 			d_print("unable to find stream info: %d\n", err);
+ 			err = -IP_ERROR_FILE_FORMAT;
+ 			break;
+ 		}
+ 
+-		for (i = 0; i < ic->nb_streams; i++) {
+-			cc = ic->streams[i]->codec;
+-			if (cc->codec_type == AVMEDIA_TYPE_AUDIO) {
+-				stream_index = i;
+-				break;
++		err = av_find_best_stream(ic, AVMEDIA_TYPE_AUDIO, -1, -1, &codec, 0);
++		if (err < 0) {
++			if (err == AVERROR_STREAM_NOT_FOUND) {
++				d_print("could not find audio stream\n");
++				err = -IP_ERROR_FILE_FORMAT;
++			} else if (err == AVERROR_DECODER_NOT_FOUND) {
++				d_print("codec not found\n");
++				err = -IP_ERROR_UNSUPPORTED_FILE_TYPE;
++			} else {
++				err = -IP_ERROR_INTERNAL;
+ 			}
+-		}
+-
+-		if (stream_index == -1) {
+-			d_print("could not find audio stream\n");
+-			err = -IP_ERROR_FILE_FORMAT;
+-			break;
+-		}
+-
+-		codec = avcodec_find_decoder(cc->codec_id);
+-		if (!codec) {
+-			d_print("codec not found: %d, %s\n", cc->codec_id, cc->codec_name);
+-			err = -IP_ERROR_UNSUPPORTED_FILE_TYPE;
++			break;
++		}
++		stream_index = err;
++
++		cc = avcodec_alloc_context3(codec);
++		if (!cc) {
++			d_print("could not allocate decodec context\n");
++			err = -IP_ERROR_INTERNAL;
++			break;
++		}
++		if (ffmpeg_initialize_context(cc, ic->streams[stream_index]) < 0) {
++			d_print("could not initialize decodec context\n");
++			err = -IP_ERROR_INTERNAL;
+ 			break;
+ 		}
+ 
+ 		if (codec->capabilities & CODEC_CAP_TRUNCATED)
+ 			cc->flags |= CODEC_FLAG_TRUNCATED;
+ 
+-#if (LIBAVCODEC_VERSION_INT < ((53<<16)+(8<<8)+0))
+-		if (avcodec_open(cc, codec) < 0) {
+-#else
+ 		if (avcodec_open2(cc, codec, NULL) < 0) {
+-#endif
+-			d_print("could not open codec: %d, %s\n", cc->codec_id, cc->codec_name);
++			d_print("could not open codec: %d, %s\n", cc->codec_id,
++					avcodec_get_name(cc->codec_id));
+ 			err = -IP_ERROR_UNSUPPORTED_FILE_TYPE;
+ 			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.) */
+-#if (LIBAVCODEC_VERSION_INT < ((53<<16)+(25<<8)+0))
+-		av_close_input_file(ic);
+-#else
++		ffmpeg_free_context(&cc);
+ 		avformat_close_input(&ic);
+-#endif
+ 		return err;
+ 	}
+ 
+@@ -270,19 +291,17 @@
+ 	priv->codec_context = cc;
+ 	priv->input_context = ic;
+ 	priv->codec = codec;
+-	priv->stream_index = stream_index;
+ 	priv->input = ffmpeg_input_create();
+ 	if (priv->input == NULL) {
+-		avcodec_close(cc);
+-#if (LIBAVCODEC_VERSION_INT < ((53<<16)+(25<<8)+0))
+-		av_close_input_file(ic);
+-#else
++		ffmpeg_free_context(&cc);
+ 		avformat_close_input(&ic);
+-#endif
+ 		free(priv);
+ 		return -IP_ERROR_INTERNAL;
+ 	}
++	priv->input->stream_index = stream_index;
+ 	priv->output = ffmpeg_output_create();
++
++	cc->opaque = priv;
+ 
+ 	/* Prepare for resampling. */
+ 	swr = swr_alloc();
+@@ -314,9 +333,7 @@
+ #ifdef WORDS_BIGENDIAN
+ 	ip_data->sf |= sf_bigendian(1);
+ #endif
+-#if (LIBAVCODEC_VERSION_INT > ((52<<16)+(1<<8)+0))
+ 	channel_layout = cc->channel_layout;
+-#endif
+ 	channel_map_init_waveex(cc->channels, channel_layout, ip_data->channel_map);
+ 	return 0;
+ }
+@@ -325,12 +342,8 @@
+ {
+ 	struct ffmpeg_private *priv = ip_data->private;
+ 
+-	avcodec_close(priv->codec_context);
+-#if (LIBAVCODEC_VERSION_INT < ((53<<16)+(25<<8)+0))
+-	av_close_input_file(priv->input_context);
+-#else
++	ffmpeg_free_context(&priv->codec_context);
+ 	avformat_close_input(&priv->input_context);
+-#endif
+ 	swr_free(&priv->swr);
+ 	ffmpeg_input_free(priv->input);
+ 	ffmpeg_output_free(priv->output);
+@@ -339,117 +352,75 @@
+ 	return 0;
+ }
+ 
+-/*
+- * 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,
+-			      struct ffmpeg_output *output, SwrContext *swr)
+-{
+-#if (LIBAVCODEC_VERSION_INT >= ((53<<16) + (25<<8) + 0))
+-	AVFrame *frame = avcodec_alloc_frame();
+-	int got_frame;
+-#endif
++static int ffmpeg_fill_buffer(AVFormatContext *ic, AVCodecContext *cc,
++		struct ffmpeg_input *input, struct ffmpeg_output *output, SwrContext *swr)
++{
++	AVFrame *frame = ffmpeg_frame_alloc();
++	int res = -IP_ERROR_INTERNAL;
++
+ 	while (1) {
+-#if (LIBAVCODEC_VERSION_INT < ((53<<16) + (25<<8) + 0))
+-		/* frame_size specifies the size of output->buffer for
+-		 * avcodec_decode_audio2. */
+-		int frame_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
+-#endif
+-		int len;
+-
+-		if (input->curr_pkt_size <= 0) {
+-			av_free_packet(&input->pkt);
+-			if (av_read_frame(ic, &input->pkt) < 0) {
+-				/* Force EOF once we can read no longer. */
+-#if (LIBAVCODEC_VERSION_INT >= ((53<<16) + (25<<8) + 0))
+-				avcodec_free_frame(&frame);
+-#endif
+-				return 0;
++		if (!ffmpeg_receive_frame(cc, frame)) {
++			res = swr_convert(swr,
++					  &output->buffer,
++					  frame->nb_samples,
++					  (const uint8_t **)frame->extended_data,
++					  frame->nb_samples);
++			if (res < 0) {
++				res = -IP_ERROR_INTERNAL;
++				break;
+ 			}
+-			input->curr_pkt_size = input->pkt.size;
+-			input->curr_pkt_buf = input->pkt.data;
++			output->buffer_pos = output->buffer;
++			output->buffer_used_len = res * cc->channels * sizeof(int16_t);
++			res = output->buffer_used_len;
++			break;
++		}
++
++		if (input->eof) {
++			res = 0;
++			break;
++		}
++
++		ffmpeg_packet_unref(&input->pkt);
++		res = av_read_frame(ic, &input->pkt);
++
++		if (res < 0) {
++			if (res == AVERROR_EOF) {
++				ffmpeg_send_packet(cc, NULL);
++				input->eof = true;
++				continue;
++			} else {
++				res = 0;
++				break;
++			}
++		}
++
++		if (input->pkt.stream_index == input->stream_index) {
+ 			input->curr_size += input->pkt.size;
+ 			input->curr_duration += input->pkt.duration;
+-			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);
+-#elif (LIBAVCODEC_VERSION_INT < ((53<<16) + (25<<8) + 0))
+-		{
+-			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);
+-		}
+-#else
+-		{
+-			AVPacket avpkt;
+-			av_new_packet(&avpkt, input->curr_pkt_size);
+-			memcpy(avpkt.data, input->curr_pkt_buf, input->curr_pkt_size);
+-			len = avcodec_decode_audio4(cc, frame, &got_frame, &avpkt);
+-			av_free_packet(&avpkt);
+-		}
+-#endif
+-		if (len < 0) {
+-			/* this is often reached when seeking, not sure why */
+-			input->curr_pkt_size = 0;
+-			continue;
+-		}
+-		input->curr_pkt_size -= len;
+-		input->curr_pkt_buf += len;
+-#if (LIBAVCODEC_VERSION_INT < ((53<<16) + (25<<8) + 0))
+-		if (frame_size > 0) {
+-			output->buffer_pos = output->buffer;
+-			output->buffer_used_len = frame_size;
+-			return frame_size;
+-		}
+-#else
+-		if (got_frame) {
+-			int res = swr_convert(swr,
+-					&output->buffer,
+-					frame->nb_samples,
+-					(const uint8_t **)frame->extended_data,
+-					frame->nb_samples);
+-			if (res < 0)
+-				res = 0;
+-			output->buffer_pos = output->buffer;
+-			output->buffer_used_len = res * cc->channels * sizeof(int16_t);
+-			avcodec_free_frame(&frame);
+-			return output->buffer_used_len;
+-		}
+-#endif
+-	}
+-	/* This should never get here. */
+-	return -IP_ERROR_INTERNAL;
++			if (ffmpeg_send_packet(cc, &input->pkt)) {
++				res = -IP_ERROR_INTERNAL;
++				break;
++			}
++		}
++	}
++
++	ffmpeg_frame_free(&frame);
++	return res;
+ }
+ 
+ static int ffmpeg_read(struct input_plugin_data *ip_data, char *buffer, int count)
+ {
+ 	struct ffmpeg_private *priv = ip_data->private;
+ 	struct ffmpeg_output *output = priv->output;
+-	int rc;
+-	int out_size;
+ 
+ 	if (output->buffer_used_len == 0) {
+-		rc = ffmpeg_fill_buffer(priv->input_context, priv->codec_context,
++		int rc = ffmpeg_fill_buffer(priv->input_context, priv->codec_context,
+ 				priv->input, priv->output, priv->swr);
+ 		if (rc <= 0) {
+ 			return rc;
+ 		}
+ 	}
+-	out_size = min(output->buffer_used_len, count);
++	int out_size = min(output->buffer_used_len, count);
+ 	memcpy(buffer, output->buffer_pos, out_size);
+ 	output->buffer_used_len -= out_size;
+ 	output->buffer_pos += out_size;
+@@ -459,30 +430,15 @@
+ static int ffmpeg_seek(struct input_plugin_data *ip_data, double offset)
+ {
+ 	struct ffmpeg_private *priv = ip_data->private;
+-	AVStream *st = priv->input_context->streams[priv->stream_index];
+-	int ret;
+-
+-	/* There is a bug that was fixed in ffmpeg revision 5099 that affects seeking.
+-	 * Apparently, the stream's timebase was not used consistently in asf.c.
+-	 * Prior to 5099, ASF seeking assumed seconds as inputs.  There is a
+-	 * window of incompatibility, since avformat's version was not updated at
+-	 * the same time.  Instead, the transition to 50.3.0 occurred at
+-	 * revision 5028. */
+-#if (LIBAVFORMAT_VERSION_INT < ((50<<16)+(3<<8)+0))
+-	int64_t pts = (int64_t) offset;
+-#else
++	AVStream *st = priv->input_context->streams[priv->input->stream_index];
++
+ 	int64_t pts = av_rescale_q(offset * AV_TIME_BASE, AV_TIME_BASE_Q, st->time_base);
+-#endif
+-
+-#if (LIBAVFORMAT_VERSION_INT >= ((53<<16) + (25<<8) + 0))
+-	{
+-		avcodec_flush_buffers(priv->codec_context);
+-		/* Force reading a new packet in next ffmpeg_fill_buffer(). */
+-		priv->input->curr_pkt_size = 0;
+-	}
+-#endif
+-
+-	ret = av_seek_frame(priv->input_context, priv->stream_index, pts, 0);
++
++	avcodec_flush_buffers(priv->codec_context);
++	/* Force reading a new packet in next ffmpeg_fill_buffer(). */
++	priv->input->curr_pkt_size = 0;
++
++	int ret = av_seek_frame(priv->input_context, priv->input->stream_index, pts, 0);
+ 
+ 	if (ret < 0) {
+ 		return -IP_ERROR_FUNCTION_NOT_SUPPORTED;
+@@ -492,56 +448,31 @@
+ 	}
+ }
+ 
+-#if (LIBAVFORMAT_VERSION_INT < ((52<<16)+(31<<8)+0))
+-/* Return new i. */
+-static int set_comment(struct keyval *comment, int i, const char *key, const char *val)
+-{
+-	if (val[0] == 0) {
+-		return i;
+-	}
+-	comment[i].key = xstrdup(key);
+-	comment[i].val = xstrdup(val);
+-	return i + 1;
+-}
+-#endif
+-
+-static int ffmpeg_read_comments(struct input_plugin_data *ip_data, struct keyval **comments)
++static void ffmpeg_read_metadata(struct growing_keyvals *c, AVDictionary *metadata)
++{
++	AVDictionaryEntry *tag = NULL;
++
++	while ((tag = av_dict_get(metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
++		if (tag->value[0])
++			comments_add_const(c, tag->key, tag->value);
++	}
++}
++
++static int ffmpeg_read_comments(struct input_plugin_data *ip_data,
++		struct keyval **comments)
+ {
+ 	struct ffmpeg_private *priv = ip_data->private;
+ 	AVFormatContext *ic = priv->input_context;
+ 
+-#if (LIBAVFORMAT_VERSION_INT < ((52<<16)+(31<<8)+0))
+-	char buff[16];
+-	int i = 0;
+-
+-	*comments = keyvals_new(NUM_FFMPEG_KEYS);
+-
+-	i = set_comment(*comments, i, "artist", ic->author);
+-	i = set_comment(*comments, i, "album", ic->album);
+-	i = set_comment(*comments, i, "title", ic->title);
+-	i = set_comment(*comments, i, "genre", ic->genre);
+-
+-	if (ic->year != 0) {
+-		snprintf(buff, sizeof(buff), "%d", ic->year);
+-		i = set_comment(*comments, i, "date", buff);
+-	}
+-
+-	if (ic->track != 0) {
+-		snprintf(buff, sizeof(buff), "%d", ic->track);
+-		i = set_comment(*comments, i, "tracknumber", buff);
+-	}
+-#else
+ 	GROWING_KEYVALS(c);
+-	AVDictionaryEntry *tag = NULL;
+-
+-	while ((tag = av_dict_get(ic->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
+-		if (tag && tag->value[0])
+-			comments_add_const(&c, tag->key, tag->value);
++
++	ffmpeg_read_metadata(&c, ic->metadata);
++	for (unsigned i = 0; i < ic->nb_streams; i++) {
++		ffmpeg_read_metadata(&c, ic->streams[i]->metadata);
+ 	}
+ 
+ 	keyvals_terminate(&c);
+ 	*comments = c.keyvals;
+-#endif
+ 
+ 	return 0;
+ }
+@@ -562,13 +493,11 @@
+ static long ffmpeg_current_bitrate(struct input_plugin_data *ip_data)
+ {
+ 	struct ffmpeg_private *priv = ip_data->private;
+-	AVStream *st = priv->input_context->streams[priv->stream_index];
++	AVStream *st = priv->input_context->streams[priv->input->stream_index];
+ 	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 == FFMPEG_CODEC_ID_APE)
+ 		return -1;
+-#endif
+ 	if (priv->input->curr_duration > 0) {
+ 		double seconds = priv->input->curr_duration * av_q2d(st->time_base);
+ 		bitrate = (8 * priv->input->curr_size) / seconds;
+@@ -584,31 +513,12 @@
+ 	return xstrdup(priv->codec->name);
+ }
+ 
+-#if (LIBAVCODEC_VERSION_INT < ((52<<16)+(104<<8)+0))
+-static const char *codec_profile_to_str(int profile)
+-{
+-#if (LIBAVCODEC_VERSION_INT >= ((51<<16)+(41<<8)+0))
+-	switch (profile) {
+-	case FF_PROFILE_AAC_MAIN:	return "Main";
+-	case FF_PROFILE_AAC_LOW:	return "LC";
+-	case FF_PROFILE_AAC_SSR:	return "SSR";
+-	case FF_PROFILE_AAC_LTP:	return "LTP";
+-	}
+-#endif
+-	return NULL;
+-}
+-#endif
+-
+ static char *ffmpeg_codec_profile(struct input_plugin_data *ip_data)
+ {
+ 	struct ffmpeg_private *priv = ip_data->private;
+-	const char *profile;
+-
+-#if (LIBAVCODEC_VERSION_INT < ((52<<16)+(104<<8)+0))
+-	profile = codec_profile_to_str(priv->codec_context->profile);
+-#else
+-	profile = av_get_profile_name(priv->codec, priv->codec_context->profile);
+-#endif
++
++	const char *profile = av_get_profile_name(priv->codec,
++			priv->codec_context->profile);
+ 
+ 	return profile ? xstrdup(profile) : NULL;
+ }
+@@ -626,16 +536,15 @@
+ 	.codec_profile = ffmpeg_codec_profile
+ };
+ 
+-const int ip_priority = 30;
++const int ip_priority = 300;
+ const char *const ip_extensions[] = {
+-	"ac3", "aif", "aifc", "aiff", "ape", "au", "mka", "shn", "tta", "wma",
+-	/* also supported by other plugins */
+-	"aac", "fla", "flac", "m4a", "m4b", "mp+", "mp2", "mp3", "mp4", "mpc",
+-	"mpp", "ogg", "wav", "wv",
++	"aa", "aac", "ac3", "aif", "aifc", "aiff", "ape", "au", "fla", "flac",
++	"m4a", "m4b", "mka", "mkv", "mp+", "mp2", "mp3", "mp4", "mpc", "mpp",
++	"ogg", "shn", "tak", "tta", "wav", "webm", "wma", "wv",
+ #ifdef USE_FALLBACK_IP
+ 	"*",
+ #endif
+ 	NULL
+ };
+ const char *const ip_mime_types[] = { NULL };
+-const char * const ip_options[] = { NULL };
++const char *const ip_options[] = { NULL };


More information about the rpmfusion-commits mailing list