aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-11-10 19:01:38 +0100
committerMax Kellermann <max@duempel.org>2009-11-14 00:47:22 +0100
commit719990b1c5db93ccdc21e5f91e98ed9e8540ade1 (patch)
treeef03f58f54767b73c4c8d267e7b0008938863a17
parentf47bb8c1db91b50be95c4d5dd301728e38c57274 (diff)
downloadmpd-719990b1c5db93ccdc21e5f91e98ed9e8540ade1.tar.gz
mpd-719990b1c5db93ccdc21e5f91e98ed9e8540ade1.tar.xz
mpd-719990b1c5db93ccdc21e5f91e98ed9e8540ade1.zip
decoder: use audio_format_init_checked()
Let the audio_check library verify the audio format in all (relevant, i.e. non-hardcoded) plugins.
-rw-r--r--Makefile.am2
-rw-r--r--src/decoder/_flac_common.c18
-rw-r--r--src/decoder/audiofile_plugin.c16
-rw-r--r--src/decoder/faad_plugin.c49
-rw-r--r--src/decoder/ffmpeg_plugin.c14
-rw-r--r--src/decoder/mad_plugin.c18
-rw-r--r--src/decoder/mikmod_plugin.c2
-rw-r--r--src/decoder/modplug_plugin.c2
-rw-r--r--src/decoder/mp4ff_plugin.c16
-rw-r--r--src/decoder/mpcdec_plugin.c14
-rw-r--r--src/decoder/mpg123_decoder_plugin.c9
-rw-r--r--src/decoder/sidplay_plugin.cxx1
-rw-r--r--src/decoder/sndfile_decoder_plugin.c10
-rwxr-xr-xsrc/decoder/vorbis_plugin.c13
-rw-r--r--src/decoder/wavpack_plugin.c25
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;
}