From 44401158e8198635de1e1f7a4369113179b8937b Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 4 Jan 2012 21:46:54 +0100 Subject: input/ffmpeg: define AV_VERSION_INT if not present Support ancient ffmpeg versions. --- src/input/ffmpeg_input_plugin.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/input/ffmpeg_input_plugin.c b/src/input/ffmpeg_input_plugin.c index 0a6be29bc..27698a14b 100644 --- a/src/input/ffmpeg_input_plugin.c +++ b/src/input/ffmpeg_input_plugin.c @@ -32,6 +32,10 @@ #undef G_LOG_DOMAIN #define G_LOG_DOMAIN "input_ffmpeg" +#ifndef AV_VERSION_INT +#define AV_VERSION_INT(a, b, c) (a<<16 | b<<8 | c) +#endif + struct input_ffmpeg { struct input_stream base; -- cgit v1.2.3 From 56257f072bd6b55c9eacf08e1875d45e45635a89 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 9 May 2011 18:22:59 +0200 Subject: input/ffmpeg: use the new AVIOContext API URLContext is deprecated. --- NEWS | 2 ++ src/input/ffmpeg_input_plugin.c | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 8a2f11be6..0e3d24dd5 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ ver 0.16.7 (2011/??/??) +* input: + - ffmpeg: support libavformat 0.7 * output: - httpd: fix excessive buffering - openal: force 16 bit playback, as 8 bit doesn't work diff --git a/src/input/ffmpeg_input_plugin.c b/src/input/ffmpeg_input_plugin.c index 27698a14b..8ff66c5b4 100644 --- a/src/input/ffmpeg_input_plugin.c +++ b/src/input/ffmpeg_input_plugin.c @@ -39,7 +39,11 @@ struct input_ffmpeg { struct input_stream base; +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,0,0) + AVIOContext *h; +#else URLContext *h; +#endif bool eof; }; @@ -50,6 +54,17 @@ ffmpeg_quark(void) return g_quark_from_static_string("ffmpeg"); } +static inline bool +input_ffmpeg_supported(void) +{ +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,0,0) + void *opaque = NULL; + return avio_enum_protocols(&opaque, 0) != NULL; +#else + return av_protocol_next(NULL) != NULL; +#endif +} + static bool input_ffmpeg_init(G_GNUC_UNUSED const struct config_param *param, G_GNUC_UNUSED GError **error_r) @@ -58,7 +73,7 @@ input_ffmpeg_init(G_GNUC_UNUSED const struct config_param *param, #if LIBAVFORMAT_VERSION_MAJOR >= 52 /* disable this plugin if there's no registered protocol */ - if (av_protocol_next(NULL) == NULL) { + if (!input_ffmpeg_supported()) { g_set_error(error_r, ffmpeg_quark(), 0, "No protocol"); return false; @@ -84,7 +99,11 @@ input_ffmpeg_open(const char *uri, GError **error_r) i = g_new(struct input_ffmpeg, 1); input_stream_init(&i->base, &input_plugin_ffmpeg, uri); +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,0,0) + int ret = avio_open(&i->h, uri, AVIO_FLAG_READ); +#else int ret = url_open(&i->h, uri, URL_RDONLY); +#endif if (ret != 0) { g_free(i); g_set_error(error_r, ffmpeg_quark(), ret, @@ -95,8 +114,13 @@ input_ffmpeg_open(const char *uri, GError **error_r) i->eof = false; i->base.ready = true; +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,0,0) + i->base.seekable = (i->h->seekable & AVIO_SEEKABLE_NORMAL) != 0; + i->base.size = avio_size(i->h); +#else i->base.seekable = !i->h->is_streamed; i->base.size = url_filesize(i->h); +#endif /* hack to make MPD select the "ffmpeg" decoder plugin - since avio.h doesn't tell us the MIME type of the resource, we @@ -113,7 +137,11 @@ input_ffmpeg_read(struct input_stream *is, void *ptr, size_t size, { struct input_ffmpeg *i = (struct input_ffmpeg *)is; +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,0,0) + int ret = avio_read(i->h, ptr, size); +#else int ret = url_read(i->h, ptr, size); +#endif if (ret <= 0) { if (ret < 0) g_set_error(error_r, ffmpeg_quark(), 0, @@ -132,7 +160,11 @@ input_ffmpeg_close(struct input_stream *is) { struct input_ffmpeg *i = (struct input_ffmpeg *)is; +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,0,0) + avio_close(i->h); +#else url_close(i->h); +#endif input_stream_deinit(&i->base); g_free(i); } @@ -150,7 +182,11 @@ input_ffmpeg_seek(struct input_stream *is, goffset offset, int whence, G_GNUC_UNUSED GError **error_r) { struct input_ffmpeg *i = (struct input_ffmpeg *)is; +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,0,0) + int64_t ret = avio_seek(i->h, offset, whence); +#else int64_t ret = url_seek(i->h, offset, whence); +#endif if (ret >= 0) { i->eof = false; -- cgit v1.2.3 From 76fcf258982f69fd1e4aec7bda99b81b9ccb3e95 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 9 May 2011 21:16:43 +0200 Subject: decoder/ffmpeg: use AVIOContext instead of ByteIOContext --- NEWS | 2 ++ src/decoder/ffmpeg_decoder_plugin.c | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/NEWS b/NEWS index 0e3d24dd5..4c36ab798 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ ver 0.16.7 (2011/??/??) * input: - ffmpeg: support libavformat 0.7 +* decoder: + - ffmpeg: support libavformat 0.7 * output: - httpd: fix excessive buffering - openal: force 16 bit playback, as 8 bit doesn't work diff --git a/src/decoder/ffmpeg_decoder_plugin.c b/src/decoder/ffmpeg_decoder_plugin.c index 34a6b3ebd..9a3961b50 100644 --- a/src/decoder/ffmpeg_decoder_plugin.c +++ b/src/decoder/ffmpeg_decoder_plugin.c @@ -126,11 +126,19 @@ mpd_ffmpeg_stream_open(struct decoder *decoder, struct input_stream *input) struct mpd_ffmpeg_stream *stream = g_new(struct mpd_ffmpeg_stream, 1); stream->decoder = decoder; stream->input = input; +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(52,101,0) + stream->io = avio_alloc_context(stream->buffer, sizeof(stream->buffer), + false, stream, + mpd_ffmpeg_stream_read, NULL, + input->seekable + ? mpd_ffmpeg_stream_seek : NULL); +#else stream->io = av_alloc_put_byte(stream->buffer, sizeof(stream->buffer), false, stream, mpd_ffmpeg_stream_read, NULL, input->seekable ? mpd_ffmpeg_stream_seek : NULL); +#endif if (stream->io == NULL) { g_free(stream); return NULL; -- cgit v1.2.3 From fbf3edf07d55d722b114e5e33d02cb63ece6b627 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 9 May 2011 21:17:09 +0200 Subject: decoder/ffpmeg: don't use av_metadata_conv() in ffmpeg 0.7 It's a no-op and deprecated. --- src/decoder/ffmpeg_decoder_plugin.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/decoder/ffmpeg_decoder_plugin.c b/src/decoder/ffmpeg_decoder_plugin.c index 9a3961b50..6a746f94a 100644 --- a/src/decoder/ffmpeg_decoder_plugin.c +++ b/src/decoder/ffmpeg_decoder_plugin.c @@ -568,7 +568,9 @@ ffmpeg_stream_tag(struct input_stream *is) : 0; #if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(31<<8)+0) +#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52,101,0) av_metadata_conv(f, NULL, f->iformat->metadata_conv); +#endif for (unsigned i = 0; i < sizeof(ffmpeg_tag_maps)/sizeof(ffmpeg_tag_map); i++) { int idx = ffmpeg_find_audio_stream(f); -- cgit v1.2.3 From 21caca4aeac78e6c791e6440e2003b2ab32bd37c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 4 Jan 2012 21:41:28 +0100 Subject: decoder/ffmpeg: use avcodec_open2() on newer ffmpeg versions avcodec_open() has been deprecated. --- src/decoder/ffmpeg_decoder_plugin.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/decoder/ffmpeg_decoder_plugin.c b/src/decoder/ffmpeg_decoder_plugin.c index 6a746f94a..de545bded 100644 --- a/src/decoder/ffmpeg_decoder_plugin.c +++ b/src/decoder/ffmpeg_decoder_plugin.c @@ -433,7 +433,12 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input) values into AVCodecContext.channels - a change that will be reverted later by avcodec_decode_audio3() */ - if (avcodec_open(codec_context, codec)<0) { +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53,6,0) + const int open_result = avcodec_open2(codec_context, codec, NULL); +#else + const int open_result = avcodec_open(codec_context, codec); +#endif + if (open_result < 0) { g_warning("Could not open codec\n"); av_close_input_stream(format_context); mpd_ffmpeg_stream_close(stream); -- cgit v1.2.3 From 0d3ec9c324b616c2487e4ebdc9b8a1f14e6329f8 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 23 Feb 2011 09:01:53 +0100 Subject: configure.ac: disable -Wno-deprecated-declarations --- configure.ac | 1 - 1 file changed, 1 deletion(-) diff --git a/configure.ac b/configure.ac index 8d3f3c1e4..de4daf4b0 100644 --- a/configure.ac +++ b/configure.ac @@ -1496,7 +1496,6 @@ if test x$GCC = xyes then MPD_CHECK_FLAG([-Wall]) MPD_CHECK_FLAG([-Wextra]) - MPD_CHECK_FLAG([-Wno-deprecated-declarations]) MPD_CHECK_FLAG([-Wmissing-prototypes]) MPD_CHECK_FLAG([-Wshadow]) MPD_CHECK_FLAG([-Wpointer-arith]) -- cgit v1.2.3 From 531948358bcd2e24a5e90eb7ad1aafc5f1dbf065 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 4 Jan 2012 21:54:54 +0100 Subject: decoder/ffmpeg: include libavutil/mathematics.h Needed for av_rescale_q() in ffmpeg 0.8. --- src/decoder/ffmpeg_decoder_plugin.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/decoder/ffmpeg_decoder_plugin.c b/src/decoder/ffmpeg_decoder_plugin.c index de545bded..83628c5dd 100644 --- a/src/decoder/ffmpeg_decoder_plugin.c +++ b/src/decoder/ffmpeg_decoder_plugin.c @@ -41,6 +41,7 @@ #include #include #include +#include #endif #undef G_LOG_DOMAIN -- cgit v1.2.3 From 4e6bc77a7012f8eaf4d498d215af60c52d30496c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 4 Jan 2012 22:10:38 +0100 Subject: decoder/ffmpeg: use avcodec_decode_audio4(), support libavcodec 0.8 --- NEWS | 2 +- src/decoder/ffmpeg_decoder_plugin.c | 59 ++++++++++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 4c36ab798..2f5efe8d7 100644 --- a/NEWS +++ b/NEWS @@ -2,7 +2,7 @@ ver 0.16.7 (2011/??/??) * input: - ffmpeg: support libavformat 0.7 * decoder: - - ffmpeg: support libavformat 0.7 + - ffmpeg: support libavformat 0.7, libavcodec 0.8 * output: - httpd: fix excessive buffering - openal: force 16 bit playback, as 8 bit doesn't work diff --git a/src/decoder/ffmpeg_decoder_plugin.c b/src/decoder/ffmpeg_decoder_plugin.c index 83628c5dd..1be26d9a0 100644 --- a/src/decoder/ffmpeg_decoder_plugin.c +++ b/src/decoder/ffmpeg_decoder_plugin.c @@ -208,6 +208,7 @@ ffmpeg_find_audio_stream(const AVFormatContext *format_context) return -1; } +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53,25,0) /** * On some platforms, libavcodec wants the output buffer aligned to 16 * bytes (because it uses SSE/Altivec internally). This function @@ -222,6 +223,7 @@ align16(void *p, size_t *length_p) *length_p -= add; return (char *)p + add; } +#endif G_GNUC_CONST static double @@ -241,6 +243,40 @@ time_to_ffmpeg(double t, const AVRational time_base) time_base); } +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53,25,0) +/** + * Copy PCM data from a AVFrame to an interleaved buffer. + */ +static int +copy_interleave_frame(const AVCodecContext *codec_context, + const AVFrame *frame, + uint8_t *buffer, size_t buffer_size) +{ + int plane_size; + const int data_size = + av_samples_get_buffer_size(&plane_size, + codec_context->channels, + frame->nb_samples, + codec_context->sample_fmt, 1); + if (buffer_size < (size_t)data_size) + /* buffer is too small - shouldn't happen */ + return AVERROR(EINVAL); + + if (av_sample_fmt_is_planar(codec_context->sample_fmt) && + codec_context->channels > 1) { + for (int i = 0, channels = codec_context->channels; + i < channels; i++) { + memcpy(buffer, frame->extended_data[i], plane_size); + buffer += plane_size; + } + } else { + memcpy(buffer, frame->extended_data[0], data_size); + } + + return data_size; +} +#endif + static enum decoder_command ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is, const AVPacket *packet, @@ -258,9 +294,15 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is, int packet_size = packet->size; #endif +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53,25,0) + uint8_t aligned_buffer[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2 + 16]; + const size_t buffer_size = sizeof(aligned_buffer); +#else + /* libavcodec < 0.8 needs an aligned buffer */ uint8_t audio_buf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2 + 16]; size_t buffer_size = sizeof(audio_buf); int16_t *aligned_buffer = align16(audio_buf, &buffer_size); +#endif enum decoder_command cmd = DECODE_COMMAND_NONE; while ( @@ -271,7 +313,22 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is, #endif cmd == DECODE_COMMAND_NONE) { int audio_size = buffer_size; -#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52,25,0) +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(53,25,0) + AVFrame frame; + int got_frame = 0; + int len = avcodec_decode_audio4(codec_context, + &frame, &got_frame, + &packet2); + if (len >= 0 && got_frame) { + audio_size = copy_interleave_frame(codec_context, + &frame, + aligned_buffer, + buffer_size); + if (audio_size < 0) + len = audio_size; + } else if (len >= 0) + len = -1; +#elif LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52,25,0) int len = avcodec_decode_audio3(codec_context, aligned_buffer, &audio_size, &packet2); -- cgit v1.2.3 From abd1949825896bd38202eb17029ca93fb3863103 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 5 Jan 2012 00:02:46 +0100 Subject: decoder/ffmpeg: support libavformat 0.8 --- NEWS | 2 +- src/decoder/ffmpeg_decoder_plugin.c | 48 +++++++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 2f5efe8d7..8b2949a23 100644 --- a/NEWS +++ b/NEWS @@ -2,7 +2,7 @@ ver 0.16.7 (2011/??/??) * input: - ffmpeg: support libavformat 0.7 * decoder: - - ffmpeg: support libavformat 0.7, libavcodec 0.8 + - ffmpeg: support libavformat 0.8, libavcodec 0.8 * output: - httpd: fix excessive buffering - openal: force 16 bit playback, as 8 bit doesn't work diff --git a/src/decoder/ffmpeg_decoder_plugin.c b/src/decoder/ffmpeg_decoder_plugin.c index 1be26d9a0..d8650e2f7 100644 --- a/src/decoder/ffmpeg_decoder_plugin.c +++ b/src/decoder/ffmpeg_decoder_plugin.c @@ -443,9 +443,19 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input) return; } - if (av_find_stream_info(format_context)<0) { +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,2,0) + const int find_result = + avformat_find_stream_info(format_context, NULL); +#else + const int find_result = av_find_stream_info(format_context); +#endif + if (find_result < 0) { g_warning("Couldn't find stream info\n"); +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,17,0) + avformat_close_input(&format_context); +#else av_close_input_stream(format_context); +#endif mpd_ffmpeg_stream_close(stream); return; } @@ -453,7 +463,11 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input) int audio_stream = ffmpeg_find_audio_stream(format_context); if (audio_stream == -1) { g_warning("No audio stream inside\n"); +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,17,0) + avformat_close_input(&format_context); +#else av_close_input_stream(format_context); +#endif mpd_ffmpeg_stream_close(stream); return; } @@ -468,7 +482,11 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input) if (!codec) { g_warning("Unsupported audio codec\n"); +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,17,0) + avformat_close_input(&format_context); +#else av_close_input_stream(format_context); +#endif mpd_ffmpeg_stream_close(stream); return; } @@ -481,7 +499,11 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input) codec_context->channels, &error)) { g_warning("%s", error->message); g_error_free(error); +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,17,0) + avformat_close_input(&format_context); +#else av_close_input_stream(format_context); +#endif mpd_ffmpeg_stream_close(stream); return; } @@ -498,7 +520,11 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input) #endif if (open_result < 0) { g_warning("Could not open codec\n"); +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,17,0) + avformat_close_input(&format_context); +#else av_close_input_stream(format_context); +#endif mpd_ffmpeg_stream_close(stream); return; } @@ -542,7 +568,11 @@ ffmpeg_decode(struct decoder *decoder, struct input_stream *input) } while (cmd != DECODE_COMMAND_STOP); avcodec_close(codec_context); +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,17,0) + avformat_close_input(&format_context); +#else av_close_input_stream(format_context); +#endif mpd_ffmpeg_stream_close(stream); } @@ -618,8 +648,18 @@ ffmpeg_stream_tag(struct input_stream *is) return NULL; } - if (av_find_stream_info(f) < 0) { +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,2,0) + const int find_result = + avformat_find_stream_info(f, NULL); +#else + const int find_result = av_find_stream_info(f); +#endif + if (find_result < 0) { +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,17,0) + avformat_close_input(&f); +#else av_close_input_stream(f); +#endif mpd_ffmpeg_stream_close(stream); return NULL; } @@ -667,7 +707,11 @@ ffmpeg_stream_tag(struct input_stream *is) #endif +#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(53,17,0) + avformat_close_input(&f); +#else av_close_input_stream(f); +#endif mpd_ffmpeg_stream_close(stream); return tag; -- cgit v1.2.3