From bef0ccf42abbb34da37ce7b3a9b3271a492731cc Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 30 Mar 2016 00:30:39 +0200 Subject: [PATCH 1/6] configure.ac: prepare for 0.19.15 --- NEWS | 2 ++ configure.ac | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 0762ce40e..a773fef64 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +ver 0.19.15 (not yet released) + ver 0.19.14 (2016/03/18) * decoder - dsdiff: fix off-by-one buffer overflow diff --git a/configure.ac b/configure.ac index 66621e6a0..c94c724dd 100644 --- a/configure.ac +++ b/configure.ac @@ -1,10 +1,10 @@ AC_PREREQ(2.60) -AC_INIT(mpd, 0.19.14, musicpd-dev-team@lists.sourceforge.net) +AC_INIT(mpd, 0.19.15, musicpd-dev-team@lists.sourceforge.net) VERSION_MAJOR=0 VERSION_MINOR=19 -VERSION_REVISION=14 +VERSION_REVISION=15 VERSION_EXTRA=0 AC_CONFIG_SRCDIR([src/Main.cxx]) From 53677172f24350e9cf55af86de49fe0568aaf78c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Thu, 17 Sep 2015 22:56:35 +0200 Subject: [PATCH 2/6] notify: use "constexpr" only with glibc The Mutex and Cond constructors are only "constexpr" with glibc, and this is what this #ifdef is about. Backport of commit 459a812a See http://bugs.musicpd.org/view.php?id=4511 --- NEWS | 1 + src/notify.hxx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index a773fef64..e01dd3a01 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,5 @@ ver 0.19.15 (not yet released) +* fix more build failures on non-glibc builds due to constexpr Mutex ver 0.19.14 (2016/03/18) * decoder diff --git a/src/notify.hxx b/src/notify.hxx index 3e62a0103..c96390b8a 100644 --- a/src/notify.hxx +++ b/src/notify.hxx @@ -28,7 +28,7 @@ struct notify { Cond cond; bool pending; -#if !defined(WIN32) && !defined(__NetBSD__) && !defined(__BIONIC__) +#ifdef __GLIBC__ constexpr #endif notify():pending(false) {} From 74dbaade6fae1f3e869ef5666d3c680f4d747f66 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 30 Mar 2016 00:58:48 +0200 Subject: [PATCH 3/6] decoder/Thread: use "ffmpeg" as fallback instead of "mad" Adds support for stream codecs which havn't been explicitly listed in ffmpeg_mime_types. --- NEWS | 2 ++ src/decoder/DecoderThread.cxx | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/NEWS b/NEWS index e01dd3a01..74c195275 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ ver 0.19.15 (not yet released) +* decoder + - ffmpeg: use as fallback instead of "mad" if no plugin matches * fix more build failures on non-glibc builds due to constexpr Mutex ver 0.19.14 (2016/03/18) diff --git a/src/decoder/DecoderThread.cxx b/src/decoder/DecoderThread.cxx index b4362a548..d5f73c3e3 100644 --- a/src/decoder/DecoderThread.cxx +++ b/src/decoder/DecoderThread.cxx @@ -255,7 +255,11 @@ decoder_run_stream_fallback(Decoder &decoder, InputStream &is) { const struct DecoderPlugin *plugin; +#ifdef HAVE_FFMPEG + plugin = decoder_plugin_from_name("ffmpeg"); +#else plugin = decoder_plugin_from_name("mad"); +#endif return plugin != nullptr && plugin->stream_decode != nullptr && decoder_stream_decode(*plugin, decoder, is); } From 807c72b2f15f53bd1ff1bbcbd32f5e172461c74f Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Tue, 12 Apr 2016 21:15:05 +0200 Subject: [PATCH 4/6] decoder/ffmpeg: use av_packet_unref() instead of av_free_packet() av_free_packet() was deprecated in FFmpeg 3.0. --- NEWS | 1 + src/decoder/plugins/FfmpegDecoderPlugin.cxx | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/NEWS b/NEWS index 74c195275..bd9c46968 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,6 @@ ver 0.19.15 (not yet released) * decoder + - ffmpeg: support FFmpeg 3.0 - ffmpeg: use as fallback instead of "mad" if no plugin matches * fix more build failures on non-glibc builds due to constexpr Mutex diff --git a/src/decoder/plugins/FfmpegDecoderPlugin.cxx b/src/decoder/plugins/FfmpegDecoderPlugin.cxx index 95525b626..fabc3327a 100644 --- a/src/decoder/plugins/FfmpegDecoderPlugin.cxx +++ b/src/decoder/plugins/FfmpegDecoderPlugin.cxx @@ -640,7 +640,11 @@ ffmpeg_decode(Decoder &decoder, InputStream &input) } else cmd = decoder_get_command(decoder); +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 25, 100) + av_packet_unref(&packet); +#else av_free_packet(&packet); +#endif if (cmd == DecoderCommand::SEEK) { int64_t where = From f243f615ef80ce4d45c21df34638521a8b0f187a Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 13 Apr 2016 09:01:54 +0200 Subject: [PATCH 5/6] decoder/ffmpeg: convert pointers to references --- src/decoder/plugins/FfmpegDecoderPlugin.cxx | 60 ++++++++++----------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/decoder/plugins/FfmpegDecoderPlugin.cxx b/src/decoder/plugins/FfmpegDecoderPlugin.cxx index fabc3327a..704cb6c84 100644 --- a/src/decoder/plugins/FfmpegDecoderPlugin.cxx +++ b/src/decoder/plugins/FfmpegDecoderPlugin.cxx @@ -199,10 +199,10 @@ ffmpeg_init(gcc_unused const config_param ¶m) } static int -ffmpeg_find_audio_stream(const AVFormatContext *format_context) +ffmpeg_find_audio_stream(const AVFormatContext &format_context) { - for (unsigned i = 0; i < format_context->nb_streams; ++i) - if (format_context->streams[i]->codec->codec_type == + for (unsigned i = 0; i < format_context.nb_streams; ++i) + if (format_context.streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) return i; @@ -276,22 +276,22 @@ copy_interleave_frame2(uint8_t *dest, uint8_t **src, * Copy PCM data from a AVFrame to an interleaved buffer. */ static int -copy_interleave_frame(const AVCodecContext *codec_context, - const AVFrame *frame, +copy_interleave_frame(const AVCodecContext &codec_context, + const AVFrame &frame, uint8_t **output_buffer, uint8_t **global_buffer, int *global_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); + codec_context.channels, + frame.nb_samples, + codec_context.sample_fmt, 1); if (data_size <= 0) return data_size; - if (av_sample_fmt_is_planar(codec_context->sample_fmt) && - codec_context->channels > 1) { + if (av_sample_fmt_is_planar(codec_context.sample_fmt) && + codec_context.channels > 1) { if(*global_buffer_size < data_size) { av_freep(global_buffer); @@ -303,12 +303,12 @@ copy_interleave_frame(const AVCodecContext *codec_context, *global_buffer_size = data_size; } *output_buffer = *global_buffer; - copy_interleave_frame2(*output_buffer, frame->extended_data, - frame->nb_samples, - codec_context->channels, - av_get_bytes_per_sample(codec_context->sample_fmt)); + copy_interleave_frame2(*output_buffer, frame.extended_data, + frame.nb_samples, + codec_context.channels, + av_get_bytes_per_sample(codec_context.sample_fmt)); } else { - *output_buffer = frame->extended_data[0]; + *output_buffer = frame.extended_data[0]; } return data_size; @@ -349,28 +349,28 @@ PtsToPcmFrame(uint64_t pts, const AVStream &stream, */ static DecoderCommand ffmpeg_send_packet(Decoder &decoder, InputStream &is, - const AVPacket *packet, - AVCodecContext *codec_context, - const AVStream *stream, + const AVPacket &packet, + AVCodecContext &codec_context, + const AVStream &stream, AVFrame *frame, uint64_t min_frame, size_t pcm_frame_size, uint8_t **buffer, int *buffer_size) { size_t skip_bytes = 0; - const auto pts = StreamRelativePts(*packet, *stream); + const auto pts = StreamRelativePts(packet, stream); if (pts >= 0) { if (min_frame > 0) { - auto cur_frame = PtsToPcmFrame(pts, *stream, - *codec_context); + auto cur_frame = PtsToPcmFrame(pts, stream, + codec_context); if (cur_frame < min_frame) skip_bytes = pcm_frame_size * (min_frame - cur_frame); } else decoder_timestamp(decoder, - time_from_ffmpeg(pts, stream->time_base)); + time_from_ffmpeg(pts, stream.time_base)); } - AVPacket packet2 = *packet; + AVPacket packet2 = packet; uint8_t *output_buffer; @@ -378,12 +378,12 @@ ffmpeg_send_packet(Decoder &decoder, InputStream &is, while (packet2.size > 0 && cmd == DecoderCommand::NONE) { int audio_size = 0; int got_frame = 0; - int len = avcodec_decode_audio4(codec_context, + int len = avcodec_decode_audio4(&codec_context, frame, &got_frame, &packet2); if (len >= 0 && got_frame) { audio_size = copy_interleave_frame(codec_context, - frame, + *frame, &output_buffer, buffer, buffer_size); if (audio_size < 0) @@ -417,7 +417,7 @@ ffmpeg_send_packet(Decoder &decoder, InputStream &is, cmd = decoder_data(decoder, is, data, audio_size, - codec_context->bit_rate / 1000); + codec_context.bit_rate / 1000); } return cmd; } @@ -535,7 +535,7 @@ ffmpeg_decode(Decoder &decoder, InputStream &input) return; } - int audio_stream = ffmpeg_find_audio_stream(format_context); + int audio_stream = ffmpeg_find_audio_stream(*format_context); if (audio_stream == -1) { LogError(ffmpeg_domain, "No audio stream inside"); avformat_close_input(&format_context); @@ -631,8 +631,8 @@ ffmpeg_decode(Decoder &decoder, InputStream &input) if (packet.stream_index == audio_stream) { cmd = ffmpeg_send_packet(decoder, input, - &packet, codec_context, - av_stream, + packet, *codec_context, + *av_stream, frame, min_frame, audio_format.GetFrameSize(), &interleaved_buffer, &interleaved_buffer_size); @@ -713,7 +713,7 @@ ffmpeg_scan_stream(InputStream &is, } ffmpeg_scan_dictionary(f->metadata, handler, handler_ctx); - int idx = ffmpeg_find_audio_stream(f); + int idx = ffmpeg_find_audio_stream(*f); if (idx >= 0) ffmpeg_scan_dictionary(f->streams[idx]->metadata, handler, handler_ctx); From 70495aada1a1e655b24173ca77d20c71af0dbc8c Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 13 Apr 2016 09:04:51 +0200 Subject: [PATCH 6/6] decoder/ffmpeg: don't copy the AVPacket in ffmpeg_send_packet() Reduce some overhead. It is not necessary to copy the object. --- src/decoder/plugins/FfmpegDecoderPlugin.cxx | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/decoder/plugins/FfmpegDecoderPlugin.cxx b/src/decoder/plugins/FfmpegDecoderPlugin.cxx index 704cb6c84..640445007 100644 --- a/src/decoder/plugins/FfmpegDecoderPlugin.cxx +++ b/src/decoder/plugins/FfmpegDecoderPlugin.cxx @@ -349,7 +349,7 @@ PtsToPcmFrame(uint64_t pts, const AVStream &stream, */ static DecoderCommand ffmpeg_send_packet(Decoder &decoder, InputStream &is, - const AVPacket &packet, + AVPacket &&packet, AVCodecContext &codec_context, const AVStream &stream, AVFrame *frame, @@ -370,17 +370,15 @@ ffmpeg_send_packet(Decoder &decoder, InputStream &is, time_from_ffmpeg(pts, stream.time_base)); } - AVPacket packet2 = packet; - uint8_t *output_buffer; DecoderCommand cmd = DecoderCommand::NONE; - while (packet2.size > 0 && cmd == DecoderCommand::NONE) { + while (packet.size > 0 && cmd == DecoderCommand::NONE) { int audio_size = 0; int got_frame = 0; int len = avcodec_decode_audio4(&codec_context, frame, &got_frame, - &packet2); + &packet); if (len >= 0 && got_frame) { audio_size = copy_interleave_frame(codec_context, *frame, @@ -397,8 +395,8 @@ ffmpeg_send_packet(Decoder &decoder, InputStream &is, break; } - packet2.data += len; - packet2.size -= len; + packet.data += len; + packet.size -= len; if (audio_size <= 0) continue; @@ -631,7 +629,8 @@ ffmpeg_decode(Decoder &decoder, InputStream &input) if (packet.stream_index == audio_stream) { cmd = ffmpeg_send_packet(decoder, input, - packet, *codec_context, + std::move(packet), + *codec_context, *av_stream, frame, min_frame, audio_format.GetFrameSize(),