diff --git a/INSTALL b/INSTALL index 2a4a4c3c4..29a23d361 100644 --- a/INSTALL +++ b/INSTALL @@ -119,9 +119,6 @@ For AdLib playback. despotify - https://github.com/SimonKagstrom/despotify For Spotify playback. -MP4v2 - https://code.google.com/p/mp4v2/ -For MP4 playback. You will need FAAD2. - Optional Miscellaneous Dependencies ----------------------------------- diff --git a/Makefile.am b/Makefile.am index 72b6a0ca4..874e37d10 100644 --- a/Makefile.am +++ b/Makefile.am @@ -828,7 +828,6 @@ libdecoder_a_CPPFLAGS = $(AM_CPPFLAGS) \ $(WAVPACK_CFLAGS) \ $(MAD_CFLAGS) \ $(MPG123_CFLAGS) \ - $(MP4V2_CFLAGS) \ $(OPUS_CFLAGS) \ $(FFMPEG_CFLAGS) \ $(MPCDEC_CFLAGS) \ @@ -848,7 +847,6 @@ DECODER_LIBS = \ $(WAVPACK_LIBS) \ $(MAD_LIBS) \ $(MPG123_LIBS) \ - $(MP4V2_LIBS) \ $(OPUS_LIBS) \ $(FFMPEG_LIBS2) \ $(MPCDEC_LIBS) \ @@ -963,12 +961,6 @@ noinst_LIBRARIES += libmodplug_decoder_plugin.a DECODER_LIBS += libmodplug_decoder_plugin.a $(MODPLUG_LIBS) endif -if HAVE_MP4V2 -libdecoder_a_SOURCES += \ - src/decoder/plugins/Mp4v2DecoderPlugin.cxx \ - src/decoder/plugins/Mp4v2DecoderPlugin.hxx -endif - if ENABLE_SIDPLAY libdecoder_a_SOURCES += \ src/decoder/plugins/SidplayDecoderPlugin.cxx \ diff --git a/NEWS b/NEWS index fb5fd19b5..7d04d528c 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ ver 0.19.5 (not yet released) * decoder - dsdiff, dsf, opus: fix deadlock while seeking + - mp4v2: remove because of incompatible license ver 0.19.4 (2014/11/18) * protocol diff --git a/configure.ac b/configure.ac index 5a44fa5c8..f8d100331 100644 --- a/configure.ac +++ b/configure.ac @@ -496,11 +496,6 @@ AC_ARG_ENABLE(modplug, [enable modplug decoder plugin]),, enable_modplug=auto) -AC_ARG_ENABLE(mp4v2, - AS_HELP_STRING([--enable-mp4v2], - [enable libmp4v2 decoder plugin]),, - enable_mp4v2=auto) - AC_ARG_ENABLE(mpc, AS_HELP_STRING([--enable-mpc], [disable musepack (MPC) support (default: auto)]),, @@ -1264,24 +1259,6 @@ if test x$enable_modplug = xyes; then fi AM_CONDITIONAL(HAVE_MODPLUG, test x$enable_modplug = xyes) -dnl -------------------------------- libmp4v2 --------------------------------- -if test x$enable_aac = xyes; then - MPD_AUTO_LIB(mp4v2, MP4V2, mp4v2, MP4Create, [-lmp4v2], [], - [mp4v2], [libmp4v2 not found]) - - if test x$enable_mp4v2 = xyes; then - AC_DEFINE(HAVE_MP4V2, 1, [Define to use libmp4v2 for MP4 decoding]) - fi -else - if test x$enable_mp4v2 = xyes; then - AC_MSG_ERROR([MP4V2 requires AAC!]) - fi - - enable_mp4v2=no -fi - -AM_CONDITIONAL(HAVE_MP4V2, test x$enable_mp4v2 = xyes) - dnl -------------------------------- libopus ---------------------------------- MPD_AUTO_PKG(opus, OPUS, [opus ogg], [opus decoder plugin], [libopus not found]) @@ -1868,7 +1845,6 @@ printf '\n\t' results(sndfile, [libsndfile]) results(mikmod, [MikMod]) results(modplug, [MODPLUG]) -results(mp4v2, [MP4V2]) results(mad, [MAD]) results(mpg123, [MPG123]) results(mpc, [Musepack]) diff --git a/src/decoder/DecoderList.cxx b/src/decoder/DecoderList.cxx index 0a31d9eac..cd6881ce2 100644 --- a/src/decoder/DecoderList.cxx +++ b/src/decoder/DecoderList.cxx @@ -37,7 +37,6 @@ #include "plugins/MadDecoderPlugin.hxx" #include "plugins/SndfileDecoderPlugin.hxx" #include "plugins/Mpg123DecoderPlugin.hxx" -#include "plugins/Mp4v2DecoderPlugin.hxx" #include "plugins/WildmidiDecoderPlugin.hxx" #include "plugins/MikmodDecoderPlugin.hxx" #include "plugins/ModplugDecoderPlugin.hxx" @@ -55,9 +54,6 @@ const struct DecoderPlugin *const decoder_plugins[] = { #ifdef HAVE_MPG123 &mpg123_decoder_plugin, #endif -#ifdef HAVE_MP4V2 - &mp4v2_decoder_plugin, -#endif #ifdef ENABLE_VORBIS_DECODER &vorbis_decoder_plugin, #endif diff --git a/src/decoder/plugins/Mp4v2DecoderPlugin.cxx b/src/decoder/plugins/Mp4v2DecoderPlugin.cxx deleted file mode 100644 index 34bccd243..000000000 --- a/src/decoder/plugins/Mp4v2DecoderPlugin.cxx +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright (C) 2003-2014 The Music Player Daemon Project - * http://www.musicpd.org - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" /* must be first for large file support */ -#include "Mp4v2DecoderPlugin.hxx" -#include "../DecoderAPI.hxx" -#include "CheckAudioFormat.hxx" -#include "tag/TagHandler.hxx" -#include "fs/Path.hxx" -#include "util/Error.hxx" -#include "util/Domain.hxx" -#include "Log.hxx" - -#include -#include - -#include -#include - -static constexpr Domain mp4v2_decoder_domain("mp4v2"); - -static MP4TrackId -mp4_get_aac_track(MP4FileHandle handle, NeAACDecHandle decoder, - AudioFormat &audio_format, Error &error) -{ - unsigned long sample_rate; - - const MP4TrackId tracks = MP4GetNumberOfTracks(handle); - - for (MP4TrackId id = 1; id <= tracks; id++) { - const char* track_type = MP4GetTrackType(handle, id); - - if (track_type == 0) - continue; - - const auto obj_type = MP4GetTrackEsdsObjectTypeId(handle, id); - - if (obj_type == MP4_INVALID_AUDIO_TYPE) - continue; - if (obj_type == MP4_MPEG4_AUDIO_TYPE) { - const auto mpeg_type = MP4GetTrackAudioMpeg4Type(handle, id); - if (!MP4_IS_MPEG4_AAC_AUDIO_TYPE(mpeg_type)) - continue; - } else if (!MP4_IS_AAC_AUDIO_TYPE(obj_type)) - continue; - - if (decoder == nullptr) - /* found audio track, no decoder */ - return id; - - unsigned char *buff = nullptr; - unsigned buff_size = 0; - - if (!MP4GetTrackESConfiguration(handle, id, &buff, &buff_size)) - continue; - - uint8_t channels; - int32_t nbytes = NeAACDecInit(decoder, buff, buff_size, - &sample_rate, &channels); - - free(buff); - - if (nbytes < 0) - /* invalid stream */ - continue; - - if (!audio_format_init_checked(audio_format, sample_rate, - SampleFormat::S16, - channels, - error)) - continue; - - return id; - } - - error.Set(mp4v2_decoder_domain, "no valid aac track found"); - - return MP4_INVALID_TRACK_ID; -} - -static NeAACDecHandle -mp4_faad_new(MP4FileHandle handle, AudioFormat &audio_format, Error &error) -{ - const NeAACDecHandle decoder = NeAACDecOpen(); - const NeAACDecConfigurationPtr config = - NeAACDecGetCurrentConfiguration(decoder); - config->outputFormat = FAAD_FMT_16BIT; - config->downMatrix = 1; - config->dontUpSampleImplicitSBR = 0; - NeAACDecSetConfiguration(decoder, config); - - const auto track = mp4_get_aac_track(handle, decoder, audio_format, error); - - if (track == MP4_INVALID_TRACK_ID) { - NeAACDecClose(decoder); - return nullptr; - } - - return decoder; -} - -static void -mp4_file_decode(Decoder &mpd_decoder, Path path_fs) -{ - const MP4FileHandle handle = MP4Read(path_fs.c_str()); - - if (handle == MP4_INVALID_FILE_HANDLE) { - FormatError(mp4v2_decoder_domain, - "unable to open file"); - return; - } - - AudioFormat audio_format; - Error error; - const NeAACDecHandle decoder = mp4_faad_new(handle, audio_format, error); - - if (decoder == nullptr) { - LogError(error); - MP4Close(handle); - return; - } - - const MP4TrackId track = mp4_get_aac_track(handle, nullptr, audio_format, error); - - /* initialize the MPD core */ - - const MP4Timestamp scale = MP4GetTrackTimeScale(handle, track); - const SongTime duration = SongTime::FromScale(MP4GetTrackDuration(handle, track), - scale); - const MP4SampleId num_samples = MP4GetTrackNumberOfSamples(handle, track); - - decoder_initialized(mpd_decoder, audio_format, true, duration); - - /* the decoder loop */ - - DecoderCommand cmd = DecoderCommand::NONE; - - for (MP4SampleId sample = 1; - sample < num_samples && cmd != DecoderCommand::STOP; - sample++) { - unsigned char *data = nullptr; - unsigned int data_length = 0; - - if (cmd == DecoderCommand::SEEK) { - const MP4Timestamp offset = - decoder_seek_time(mpd_decoder).ToScale(scale); - - sample = MP4GetSampleIdFromTime(handle, track, offset, - false); - decoder_command_finished(mpd_decoder); - } - - /* read */ - if (MP4ReadSample(handle, track, sample, &data, &data_length) == 0) { - FormatError(mp4v2_decoder_domain, "unable to read sample"); - break; - } - - /* decode it */ - NeAACDecFrameInfo frame_info; - const void *const decoded = NeAACDecDecode(decoder, &frame_info, data, data_length); - - if (frame_info.error > 0) { - FormatWarning(mp4v2_decoder_domain, - "error decoding AAC stream: %s", - NeAACDecGetErrorMessage(frame_info.error)); - break; - } - - if (frame_info.channels != audio_format.channels) { - FormatDefault(mp4v2_decoder_domain, - "channel count changed from %u to %u", - audio_format.channels, frame_info.channels); - break; - } - - if (frame_info.samplerate != audio_format.sample_rate) { - FormatDefault(mp4v2_decoder_domain, - "sample rate changed from %u to %lu", - audio_format.sample_rate, - (unsigned long)frame_info.samplerate); - break; - } - - /* update bit rate and position */ - unsigned bit_rate = 0; - - if (frame_info.samples > 0) { - bit_rate = frame_info.bytesconsumed * 8.0 * - frame_info.channels * audio_format.sample_rate / - frame_info.samples / 1000 + 0.5; - } - - /* send PCM samples to MPD */ - - cmd = decoder_data(mpd_decoder, nullptr, decoded, - (size_t)frame_info.samples * 2, - bit_rate); - - free(data); - } - - /* cleanup */ - NeAACDecClose(decoder); - MP4Close(handle); -} - -static inline void -mp4_safe_invoke_tag(const struct tag_handler *handler, void *handler_ctx, - TagType tag, const char *value) -{ - if (value != nullptr) - tag_handler_invoke_tag(handler, handler_ctx, tag, value); -} - -static bool -mp4_scan_file(Path path_fs, - const struct tag_handler *handler, void *handler_ctx) -{ - const MP4FileHandle handle = MP4Read(path_fs.c_str()); - - if (handle == MP4_INVALID_FILE_HANDLE) - return false; - - AudioFormat tmp_audio_format; - Error error; - const MP4TrackId id = mp4_get_aac_track(handle, nullptr, tmp_audio_format, error); - - if (id == MP4_INVALID_TRACK_ID) { - LogError(error); - MP4Close(handle); - return false; - } - - const MP4Timestamp scale = MP4GetTrackTimeScale(handle, id); - const SongTime dur = - SongTime::FromScale(MP4GetTrackDuration(handle, id), - scale); - tag_handler_invoke_duration(handler, handler_ctx, dur); - - const MP4Tags* tags = MP4TagsAlloc(); - MP4TagsFetch(tags, handle); - - static constexpr struct { - const char *MP4Tags::*p; - TagType tag_type; - } mp4v2_tags[] = { - { &MP4Tags::name, TAG_NAME }, - { &MP4Tags::artist, TAG_ARTIST }, - { &MP4Tags::albumArtist, TAG_ALBUM_ARTIST }, - { &MP4Tags::album, TAG_ALBUM }, - { &MP4Tags::composer, TAG_COMPOSER }, - { &MP4Tags::comments, TAG_COMMENT }, - { &MP4Tags::genre, TAG_GENRE }, - { &MP4Tags::releaseDate, TAG_DATE }, - { &MP4Tags::sortArtist, TAG_ARTIST_SORT }, - { &MP4Tags::sortAlbumArtist, TAG_ALBUM_ARTIST_SORT }, - }; - - for (const auto &i : mp4v2_tags) - mp4_safe_invoke_tag(handler, handler_ctx, - i.tag_type, tags->*i.p); - - char buff[8]; /* tmp buffer for index to string. */ - if (tags->track != nullptr) { - sprintf(buff, "%d", tags->track->index); - tag_handler_invoke_tag(handler, handler_ctx, TAG_TRACK, buff); - } - - if (tags->disk != nullptr) { - sprintf(buff, "%d", tags->disk->index); - tag_handler_invoke_tag(handler, handler_ctx, TAG_DISC, buff); - } - - MP4TagsFree(tags); - MP4Close(handle); - - return true; -} - -static const char *const mp4_suffixes[] = { - "mp4", - "m4a", - /* "m4p", encrypted */ - /* "m4b", audio book */ - /* "m4r", ring tones */ - /* "m4v", video */ - nullptr -}; - -static const char *const mp4_mime_types[] = { - "application/mp4", - "application/m4a", - "audio/mp4", - "audio/m4a", - /* "audio/m4p", */ - /* "audio/m4b", */ - /* "audio/m4r", */ - /* "audio/m4v", */ - nullptr -}; - -const struct DecoderPlugin mp4v2_decoder_plugin = { - "mp4v2", - nullptr, - nullptr, - nullptr, - mp4_file_decode, - mp4_scan_file, - nullptr, - nullptr, - mp4_suffixes, - mp4_mime_types -}; diff --git a/src/decoder/plugins/Mp4v2DecoderPlugin.hxx b/src/decoder/plugins/Mp4v2DecoderPlugin.hxx deleted file mode 100644 index 57585dec4..000000000 --- a/src/decoder/plugins/Mp4v2DecoderPlugin.hxx +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2003-2014 The Music Player Daemon Project - * http://www.musicpd.org - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPD_DECODER_MP4V2_HXX -#define MPD_DECODER_MP4V2_HXX - -extern const struct DecoderPlugin mp4v2_decoder_plugin; - -#endif