diff options
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | src/decoder/_flac_common.c | 18 | ||||
-rw-r--r-- | src/decoder/audiofile_plugin.c | 16 | ||||
-rw-r--r-- | src/decoder/faad_plugin.c | 49 | ||||
-rw-r--r-- | src/decoder/ffmpeg_plugin.c | 14 | ||||
-rw-r--r-- | src/decoder/mad_plugin.c | 18 | ||||
-rw-r--r-- | src/decoder/mikmod_plugin.c | 2 | ||||
-rw-r--r-- | src/decoder/modplug_plugin.c | 2 | ||||
-rw-r--r-- | src/decoder/mp4ff_plugin.c | 16 | ||||
-rw-r--r-- | src/decoder/mpcdec_plugin.c | 14 | ||||
-rw-r--r-- | src/decoder/mpg123_decoder_plugin.c | 9 | ||||
-rw-r--r-- | src/decoder/sidplay_plugin.cxx | 1 | ||||
-rw-r--r-- | src/decoder/sndfile_decoder_plugin.c | 10 | ||||
-rwxr-xr-x | src/decoder/vorbis_plugin.c | 13 | ||||
-rw-r--r-- | src/decoder/wavpack_plugin.c | 25 |
15 files changed, 124 insertions, 85 deletions
diff --git a/Makefile.am b/Makefile.am index a61621b5f..dfe145635 100644 --- a/Makefile.am +++ b/Makefile.am @@ -789,6 +789,7 @@ test_run_decoder_SOURCES = test/run_decoder.c \ src/replay_gain.c \ src/uri.c \ src/fd_util.c \ + src/audio_check.c \ $(ARCHIVE_SRC) \ $(INPUT_SRC) \ $(TAG_SRC) \ @@ -809,6 +810,7 @@ test_read_tags_SOURCES = test/read_tags.c \ src/replay_gain.c \ src/uri.c \ src/fd_util.c \ + src/audio_check.c \ $(ARCHIVE_SRC) \ $(INPUT_SRC) \ $(TAG_SRC) \ diff --git a/src/decoder/_flac_common.c b/src/decoder/_flac_common.c index 77483efcb..213516524 100644 --- a/src/decoder/_flac_common.c +++ b/src/decoder/_flac_common.c @@ -25,6 +25,7 @@ #include "_flac_common.h" #include "flac_metadata.h" #include "flac_pcm.h" +#include "audio_check.h" #include <glib.h> @@ -63,20 +64,19 @@ bool flac_data_get_audio_format(struct flac_data *data, struct audio_format *audio_format) { + GError *error = NULL; + if (!data->have_stream_info) { g_warning("no STREAMINFO packet found"); return false; } - audio_format_init(audio_format, data->stream_info.sample_rate, - data->stream_info.bits_per_sample, - data->stream_info.channels); - - if (!audio_format_valid(audio_format)) { - g_warning("Invalid audio format: %u:%u:%u\n", - audio_format->sample_rate, - audio_format->bits, - audio_format->channels); + if (!audio_format_init_checked(audio_format, + data->stream_info.sample_rate, + data->stream_info.bits_per_sample, + data->stream_info.channels, &error)) { + g_warning("%s", error->message); + g_error_free(error); return false; } diff --git a/src/decoder/audiofile_plugin.c b/src/decoder/audiofile_plugin.c index ca096c06e..058f87813 100644 --- a/src/decoder/audiofile_plugin.c +++ b/src/decoder/audiofile_plugin.c @@ -19,6 +19,7 @@ #include "config.h" #include "decoder_api.h" +#include "audio_check.h" #include <audiofile.h> #include <af_vfs.h> @@ -103,6 +104,7 @@ setup_virtual_fops(struct input_stream *stream) static void audiofile_stream_decode(struct decoder *decoder, struct input_stream *is) { + GError *error = NULL; AFvirtualfile *vf; int fs, frame_count; AFfilehandle af_fp; @@ -138,13 +140,13 @@ audiofile_stream_decode(struct decoder *decoder, struct input_stream *is) AF_SAMPFMT_TWOSCOMP, bits); afGetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits); - audio_format_init(&audio_format, afGetRate(af_fp, AF_DEFAULT_TRACK), - bits, afGetVirtualChannels(af_fp, AF_DEFAULT_TRACK)); - - if (!audio_format_valid(&audio_format)) { - g_warning("Invalid audio format: %u:%u:%u\n", - audio_format.sample_rate, audio_format.bits, - audio_format.channels); + if (!audio_format_init_checked(&audio_format, + afGetRate(af_fp, AF_DEFAULT_TRACK), + bits, + afGetVirtualChannels(af_fp, AF_DEFAULT_TRACK), + &error)) { + g_warning("%s", error->message); + g_error_free(error); afCloseFile(af_fp); return; } diff --git a/src/decoder/faad_plugin.c b/src/decoder/faad_plugin.c index 73a8a85b9..55df15555 100644 --- a/src/decoder/faad_plugin.c +++ b/src/decoder/faad_plugin.c @@ -20,6 +20,7 @@ #include "config.h" #include "decoder_api.h" #include "decoder_buffer.h" +#include "audio_check.h" #define AAC_MAX_CHANNELS 6 @@ -37,6 +38,15 @@ static const unsigned adts_sample_rates[] = }; /** + * The GLib quark used for errors reported by this plugin. + */ +static inline GQuark +faad_decoder_quark(void) +{ + return g_quark_from_static_string("faad"); +} + +/** * Check whether the buffer head is an AAC frame, and return the frame * length. Returns 0 if it is not a frame. */ @@ -232,7 +242,7 @@ faad_song_duration(struct decoder_buffer *buffer, struct input_stream *is) */ static bool faad_decoder_init(faacDecHandle decoder, struct decoder_buffer *buffer, - struct audio_format *audio_format) + struct audio_format *audio_format, GError **error_r) { union { /* deconst hack for libfaad */ @@ -247,28 +257,33 @@ faad_decoder_init(faacDecHandle decoder, struct decoder_buffer *buffer, /* neaacdec.h declares all arguments as "unsigned long", but internally expects uint32_t pointers. To avoid gcc warnings, use this workaround. */ - unsigned long *sample_rate_r = (unsigned long *)(void *)&sample_rate; + unsigned long *sample_rate_p = (unsigned long *)(void *)&sample_rate; #else - uint32_t *sample_rate_r = &sample_rate; + uint32_t *sample_rate_p = &sample_rate; #endif u.in = decoder_buffer_read(buffer, &length); - if (u.in == NULL) + if (u.in == NULL) { + g_set_error(error_r, faad_decoder_quark(), 0, + "Empty file"); return false; + } nbytes = faacDecInit(decoder, u.out, #ifdef HAVE_FAAD_BUFLEN_FUNCS length, #endif - sample_rate_r, &channels); - if (nbytes < 0) + sample_rate_p, &channels); + if (nbytes < 0) { + g_set_error(error_r, faad_decoder_quark(), 0, + "Not an AAC stream"); return false; + } decoder_buffer_consume(buffer, nbytes); - audio_format_init(audio_format, sample_rate, 16, channels); - - return true; + return audio_format_init_checked(audio_format, sample_rate, + 16, channels, error_r); } /** @@ -334,8 +349,8 @@ faad_get_file_time_float(const char *file) decoder_buffer_fill(buffer); - ret = faad_decoder_init(decoder, buffer, &audio_format); - if (ret && audio_format_valid(&audio_format)) + ret = faad_decoder_init(decoder, buffer, &audio_format, NULL); + if (ret) length = 0; faacDecClose(decoder); @@ -367,6 +382,7 @@ faad_get_file_time(const char *file) static void faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is) { + GError *error = NULL; float file_time; float total_time = 0; faacDecHandle decoder; @@ -404,15 +420,10 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is) /* initialize it */ - ret = faad_decoder_init(decoder, buffer, &audio_format); + ret = faad_decoder_init(decoder, buffer, &audio_format, &error); if (!ret) { - g_warning("Error not a AAC stream.\n"); - faacDecClose(decoder); - return; - } - - if (!audio_format_valid(&audio_format)) { - g_warning("invalid audio format\n"); + g_warning("%s", error->message); + g_error_free(error); faacDecClose(decoder); return; } diff --git a/src/decoder/ffmpeg_plugin.c b/src/decoder/ffmpeg_plugin.c index 41fc70908..3c96848bb 100644 --- a/src/decoder/ffmpeg_plugin.c +++ b/src/decoder/ffmpeg_plugin.c @@ -19,6 +19,7 @@ #include "config.h" #include "decoder_api.h" +#include "audio_check.h" #include <glib.h> @@ -260,6 +261,7 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is, static bool ffmpeg_decode_internal(struct ffmpeg_context *ctx) { + GError *error = NULL; struct decoder *decoder = ctx->decoder; AVCodecContext *codec_context = ctx->codec_context; AVFormatContext *format_context = ctx->format_context; @@ -281,13 +283,11 @@ ffmpeg_decode_internal(struct ffmpeg_context *ctx) /* XXX fixme 16-bit for older ffmpeg (13 Aug 2007) */ bits = (uint8_t) 16; #endif - audio_format_init(&audio_format, codec_context->sample_rate, bits, - codec_context->channels); - - if (!audio_format_valid(&audio_format)) { - g_warning("Invalid audio format: %u:%u:%u\n", - audio_format.sample_rate, audio_format.bits, - audio_format.channels); + if (!audio_format_init_checked(&audio_format, + codec_context->sample_rate, bits, + codec_context->channels, &error)) { + g_warning("%s", error->message); + g_error_free(error); return false; } diff --git a/src/decoder/mad_plugin.c b/src/decoder/mad_plugin.c index d8231014f..da93fe45b 100644 --- a/src/decoder/mad_plugin.c +++ b/src/decoder/mad_plugin.c @@ -21,6 +21,7 @@ #include "decoder_api.h" #include "conf.h" #include "tag_id3.h" +#include "audio_check.h" #include <assert.h> #include <unistd.h> @@ -1174,6 +1175,7 @@ static void mp3_decode(struct decoder *decoder, struct input_stream *input_stream) { struct mp3_data data; + GError *error = NULL; struct tag *tag = NULL; struct replay_gain_info *replay_gain_info = NULL; struct audio_format audio_format; @@ -1185,8 +1187,20 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream) return; } - audio_format_init(&audio_format, data.frame.header.samplerate, 24, - MAD_NCHANNELS(&data.frame.header)); + if (!audio_format_init_checked(&audio_format, + data.frame.header.samplerate, 24, + MAD_NCHANNELS(&data.frame.header), + &error)) { + g_warning("%s", error->message); + g_error_free(error); + + if (tag != NULL) + tag_free(tag); + if (replay_gain_info != NULL) + replay_gain_info_free(replay_gain_info); + mp3_data_finish(&data); + return; + } decoder_initialized(decoder, &audio_format, data.input_stream->seekable, data.total_time); diff --git a/src/decoder/mikmod_plugin.c b/src/decoder/mikmod_plugin.c index 1d5be2970..c01395772 100644 --- a/src/decoder/mikmod_plugin.c +++ b/src/decoder/mikmod_plugin.c @@ -22,6 +22,7 @@ #include <glib.h> #include <mikmod.h> +#include <assert.h> #undef G_LOG_DOMAIN #define G_LOG_DOMAIN "mikmod" @@ -177,6 +178,7 @@ mod_decode(struct decoder *decoder, const char *path) } audio_format_init(&audio_format, 44100, 16, 2); + assert(audio_format_valid(&audio_format)); secPerByte = 1.0 / ((audio_format.bits * audio_format.channels / 8.0) * diff --git a/src/decoder/modplug_plugin.c b/src/decoder/modplug_plugin.c index 7781511b6..1d373a466 100644 --- a/src/decoder/modplug_plugin.c +++ b/src/decoder/modplug_plugin.c @@ -22,6 +22,7 @@ #include <glib.h> #include <modplug.h> +#include <assert.h> #undef G_LOG_DOMAIN #define G_LOG_DOMAIN "modplug" @@ -123,6 +124,7 @@ mod_decode(struct decoder *decoder, struct input_stream *is) } audio_format_init(&audio_format, 44100, 16, 2); + assert(audio_format_valid(&audio_format)); sec_perbyte = 1.0 / ((audio_format.bits * audio_format.channels / 8.0) * diff --git a/src/decoder/mp4ff_plugin.c b/src/decoder/mp4ff_plugin.c index 2905438e2..70ca4bdc3 100644 --- a/src/decoder/mp4ff_plugin.c +++ b/src/decoder/mp4ff_plugin.c @@ -19,6 +19,7 @@ #include "config.h" #include "decoder_api.h" +#include "audio_check.h" #include <glib.h> @@ -110,6 +111,7 @@ mp4_faad_new(mp4ff_t *mp4fh, int *track_r, struct audio_format *audio_format) int track; uint32_t sample_rate; unsigned char channels; + GError *error = NULL; decoder = faacDecOpen(); @@ -130,18 +132,16 @@ mp4_faad_new(mp4ff_t *mp4fh, int *track_r, struct audio_format *audio_format) return NULL; } - *track_r = track; - audio_format_init(audio_format, sample_rate, 16, channels); - - if (!audio_format_valid(audio_format)) { - g_warning("Invalid audio format: %u:%u:%u\n", - audio_format->sample_rate, - audio_format->bits, - audio_format->channels); + if (!audio_format_init_checked(audio_format, sample_rate, 16, channels, + &error)) { + g_warning("%s", error->message); + g_error_free(error); faacDecClose(decoder); return NULL; } + *track_r = track; + return decoder; } diff --git a/src/decoder/mpcdec_plugin.c b/src/decoder/mpcdec_plugin.c index b7c5af5f8..761073e36 100644 --- a/src/decoder/mpcdec_plugin.c +++ b/src/decoder/mpcdec_plugin.c @@ -19,6 +19,7 @@ #include "config.h" #include "decoder_api.h" +#include "audio_check.h" #ifdef MPC_IS_OLD_API #include <mpcdec/mpcdec.h> @@ -27,6 +28,7 @@ #endif #include <glib.h> +#include <assert.h> #include <unistd.h> #undef G_LOG_DOMAIN @@ -140,6 +142,7 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is) #endif mpc_reader reader; mpc_streaminfo info; + GError *error = NULL; struct audio_format audio_format; struct mpc_decoder_data data; @@ -193,16 +196,13 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is) mpc_demux_get_info(demux, &info); #endif - audio_format_init(&audio_format, info.sample_freq, 24, info.channels); - - if (!audio_format_valid(&audio_format)) { + if (!audio_format_init_checked(&audio_format, info.sample_freq, 16, + info.channels, &error)) { + g_warning("%s", error->message); + g_error_free(error); #ifndef MPC_IS_OLD_API mpc_demux_exit(demux); #endif - g_warning("Invalid audio format: %u:%u:%u\n", - audio_format.sample_rate, - audio_format.bits, - audio_format.channels); return; } diff --git a/src/decoder/mpg123_decoder_plugin.c b/src/decoder/mpg123_decoder_plugin.c index 20d9c4a54..922e56484 100644 --- a/src/decoder/mpg123_decoder_plugin.c +++ b/src/decoder/mpg123_decoder_plugin.c @@ -19,6 +19,7 @@ #include "config.h" /* must be first for large file support */ #include "decoder_api.h" +#include "audio_check.h" #include <glib.h> @@ -54,6 +55,7 @@ static bool mpd_mpg123_open(mpg123_handle *handle, const char *path_fs, struct audio_format *audio_format) { + GError *gerror = NULL; char *path_dup; int error; int channels, encoding; @@ -85,9 +87,10 @@ mpd_mpg123_open(mpg123_handle *handle, const char *path_fs, return false; } - audio_format_init(audio_format, rate, 16, channels); - if (!audio_format_valid(audio_format)) { - g_warning("invalid audio format"); + if (!audio_format_init_checked(audio_format, rate, 16, + channels, &gerror)) { + g_warning("%s", gerror->message); + g_error_free(gerror); return false; } diff --git a/src/decoder/sidplay_plugin.cxx b/src/decoder/sidplay_plugin.cxx index b200eee3b..b6e557e08 100644 --- a/src/decoder/sidplay_plugin.cxx +++ b/src/decoder/sidplay_plugin.cxx @@ -278,6 +278,7 @@ sidplay_file_decode(struct decoder *decoder, const char *path_fs) struct audio_format audio_format; audio_format_init(&audio_format, 48000, 16, 2); + assert(audio_format_valid(&audio_format)); decoder_initialized(decoder, &audio_format, true, (float)song_len); diff --git a/src/decoder/sndfile_decoder_plugin.c b/src/decoder/sndfile_decoder_plugin.c index c5ac651a3..84835c449 100644 --- a/src/decoder/sndfile_decoder_plugin.c +++ b/src/decoder/sndfile_decoder_plugin.c @@ -19,6 +19,7 @@ #include "config.h" #include "decoder_api.h" +#include "audio_check.h" #include <sndfile.h> @@ -109,6 +110,7 @@ time_to_frame(float t, const struct audio_format *audio_format) static void sndfile_stream_decode(struct decoder *decoder, struct input_stream *is) { + GError *error = NULL; SNDFILE *sf; SF_INFO info; struct audio_format audio_format; @@ -128,10 +130,10 @@ sndfile_stream_decode(struct decoder *decoder, struct input_stream *is) /* for now, always read 32 bit samples. Later, we could lower MPD's CPU usage by reading 16 bit samples with sf_readf_short() on low-quality source files. */ - audio_format_init(&audio_format, info.samplerate, 32, info.channels); - - if (!audio_format_valid(&audio_format)) { - g_warning("invalid audio format"); + if (!audio_format_init_checked(&audio_format, info.samplerate, 32, + info.channels, &error)) { + g_warning("%s", error->message); + g_error_free(error); return; } diff --git a/src/decoder/vorbis_plugin.c b/src/decoder/vorbis_plugin.c index 71d38c3ba..3a41869a0 100755 --- a/src/decoder/vorbis_plugin.c +++ b/src/decoder/vorbis_plugin.c @@ -19,6 +19,7 @@ #include "config.h" #include "_ogg_common.h" +#include "audio_check.h" #include "uri.h" #ifndef HAVE_TREMOR @@ -264,6 +265,7 @@ static void vorbis_stream_decode(struct decoder *decoder, struct input_stream *input_stream) { + GError *error = NULL; OggVorbis_File vf; ov_callbacks callbacks; struct vorbis_decoder_data data; @@ -309,13 +311,10 @@ vorbis_stream_decode(struct decoder *decoder, return; } - audio_format_init(&audio_format, vi->rate, 16, vi->channels); - - if (!audio_format_valid(&audio_format)) { - g_warning("Invalid audio format: %u:%u:%u\n", - audio_format.sample_rate, - audio_format.bits, - audio_format.channels); + if (!audio_format_init_checked(&audio_format, vi->rate, 16, + vi->channels, &error)) { + g_warning("%s", error->message); + g_error_free(error); return; } diff --git a/src/decoder/wavpack_plugin.c b/src/decoder/wavpack_plugin.c index c784d51db..9b32a79f2 100644 --- a/src/decoder/wavpack_plugin.c +++ b/src/decoder/wavpack_plugin.c @@ -19,6 +19,7 @@ #include "config.h" #include "decoder_api.h" +#include "audio_check.h" #include "path.h" #include "utils.h" @@ -130,6 +131,8 @@ static void wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek, struct replay_gain_info *replay_gain_info) { + GError *error = NULL; + unsigned bits; struct audio_format audio_format; format_samples_t format_samples; char chunk[CHUNK_SIZE]; @@ -138,24 +141,22 @@ wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek, int bytes_per_sample, output_sample_size; int position; - audio_format_init(&audio_format, WavpackGetSampleRate(wpc), - WavpackGetBitsPerSample(wpc), - WavpackGetNumChannels(wpc)); + bits = WavpackGetBitsPerSample(wpc); /* round bitwidth to 8-bit units */ - audio_format.bits = (audio_format.bits + 7) & (~7); + bits = (bits + 7) & (~7); /* MPD handles max 32-bit samples */ - if (audio_format.bits > 32) - audio_format.bits = 32; + if (bits > 32) + bits = 32; if ((WavpackGetMode(wpc) & MODE_FLOAT) == MODE_FLOAT) - audio_format.bits = 24; + bits = 24; - if (!audio_format_valid(&audio_format)) { - g_warning("Invalid audio format: %u:%u:%u\n", - audio_format.sample_rate, - audio_format.bits, - audio_format.channels); + if (!audio_format_init_checked(&audio_format, + WavpackGetSampleRate(wpc), bits, + WavpackGetNumChannels(wpc), &error)) { + g_warning("%s", error->message); + g_error_free(error); return; } |