decoder: use audio_format_init_checked()
Let the audio_check library verify the audio format in all (relevant, i.e. non-hardcoded) plugins.
This commit is contained in:
		| @@ -789,6 +789,7 @@ test_run_decoder_SOURCES = test/run_decoder.c \ | |||||||
| 	src/replay_gain.c \ | 	src/replay_gain.c \ | ||||||
| 	src/uri.c \ | 	src/uri.c \ | ||||||
| 	src/fd_util.c \ | 	src/fd_util.c \ | ||||||
|  | 	src/audio_check.c \ | ||||||
| 	$(ARCHIVE_SRC) \ | 	$(ARCHIVE_SRC) \ | ||||||
| 	$(INPUT_SRC) \ | 	$(INPUT_SRC) \ | ||||||
| 	$(TAG_SRC) \ | 	$(TAG_SRC) \ | ||||||
| @@ -809,6 +810,7 @@ test_read_tags_SOURCES = test/read_tags.c \ | |||||||
| 	src/replay_gain.c \ | 	src/replay_gain.c \ | ||||||
| 	src/uri.c \ | 	src/uri.c \ | ||||||
| 	src/fd_util.c \ | 	src/fd_util.c \ | ||||||
|  | 	src/audio_check.c \ | ||||||
| 	$(ARCHIVE_SRC) \ | 	$(ARCHIVE_SRC) \ | ||||||
| 	$(INPUT_SRC) \ | 	$(INPUT_SRC) \ | ||||||
| 	$(TAG_SRC) \ | 	$(TAG_SRC) \ | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ | |||||||
| #include "_flac_common.h" | #include "_flac_common.h" | ||||||
| #include "flac_metadata.h" | #include "flac_metadata.h" | ||||||
| #include "flac_pcm.h" | #include "flac_pcm.h" | ||||||
|  | #include "audio_check.h" | ||||||
|  |  | ||||||
| #include <glib.h> | #include <glib.h> | ||||||
|  |  | ||||||
| @@ -63,20 +64,19 @@ bool | |||||||
| flac_data_get_audio_format(struct flac_data *data, | flac_data_get_audio_format(struct flac_data *data, | ||||||
| 			   struct audio_format *audio_format) | 			   struct audio_format *audio_format) | ||||||
| { | { | ||||||
|  | 	GError *error = NULL; | ||||||
|  |  | ||||||
| 	if (!data->have_stream_info) { | 	if (!data->have_stream_info) { | ||||||
| 		g_warning("no STREAMINFO packet found"); | 		g_warning("no STREAMINFO packet found"); | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	audio_format_init(audio_format, data->stream_info.sample_rate, | 	if (!audio_format_init_checked(audio_format, | ||||||
|  | 				       data->stream_info.sample_rate, | ||||||
| 				       data->stream_info.bits_per_sample, | 				       data->stream_info.bits_per_sample, | ||||||
| 			  data->stream_info.channels); | 				       data->stream_info.channels, &error)) { | ||||||
|  | 		g_warning("%s", error->message); | ||||||
| 	if (!audio_format_valid(audio_format)) { | 		g_error_free(error); | ||||||
| 		g_warning("Invalid audio format: %u:%u:%u\n", |  | ||||||
| 			  audio_format->sample_rate, |  | ||||||
| 			  audio_format->bits, |  | ||||||
| 			  audio_format->channels); |  | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ | |||||||
|  |  | ||||||
| #include "config.h" | #include "config.h" | ||||||
| #include "decoder_api.h" | #include "decoder_api.h" | ||||||
|  | #include "audio_check.h" | ||||||
|  |  | ||||||
| #include <audiofile.h> | #include <audiofile.h> | ||||||
| #include <af_vfs.h> | #include <af_vfs.h> | ||||||
| @@ -103,6 +104,7 @@ setup_virtual_fops(struct input_stream *stream) | |||||||
| static void | static void | ||||||
| audiofile_stream_decode(struct decoder *decoder, struct input_stream *is) | audiofile_stream_decode(struct decoder *decoder, struct input_stream *is) | ||||||
| { | { | ||||||
|  | 	GError *error = NULL; | ||||||
| 	AFvirtualfile *vf; | 	AFvirtualfile *vf; | ||||||
| 	int fs, frame_count; | 	int fs, frame_count; | ||||||
| 	AFfilehandle af_fp; | 	AFfilehandle af_fp; | ||||||
| @@ -138,13 +140,13 @@ audiofile_stream_decode(struct decoder *decoder, struct input_stream *is) | |||||||
| 	                         AF_SAMPFMT_TWOSCOMP, bits); | 	                         AF_SAMPFMT_TWOSCOMP, bits); | ||||||
| 	afGetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits); | 	afGetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits); | ||||||
|  |  | ||||||
| 	audio_format_init(&audio_format, afGetRate(af_fp, AF_DEFAULT_TRACK), | 	if (!audio_format_init_checked(&audio_format, | ||||||
| 			  bits, afGetVirtualChannels(af_fp, AF_DEFAULT_TRACK));  | 				       afGetRate(af_fp, AF_DEFAULT_TRACK), | ||||||
|  | 				       bits, | ||||||
| 	if (!audio_format_valid(&audio_format)) { | 				       afGetVirtualChannels(af_fp, AF_DEFAULT_TRACK), | ||||||
| 		g_warning("Invalid audio format: %u:%u:%u\n", | 				       &error)) { | ||||||
| 			  audio_format.sample_rate, audio_format.bits, | 		g_warning("%s", error->message); | ||||||
| 			  audio_format.channels); | 		g_error_free(error); | ||||||
| 		afCloseFile(af_fp); | 		afCloseFile(af_fp); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -20,6 +20,7 @@ | |||||||
| #include "config.h" | #include "config.h" | ||||||
| #include "decoder_api.h" | #include "decoder_api.h" | ||||||
| #include "decoder_buffer.h" | #include "decoder_buffer.h" | ||||||
|  | #include "audio_check.h" | ||||||
|  |  | ||||||
| #define AAC_MAX_CHANNELS	6 | #define AAC_MAX_CHANNELS	6 | ||||||
|  |  | ||||||
| @@ -36,6 +37,15 @@ static const unsigned adts_sample_rates[] = | |||||||
| 	16000, 12000, 11025, 8000, 7350, 0, 0, 0 | 	16000, 12000, 11025, 8000, 7350, 0, 0, 0 | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 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 |  * Check whether the buffer head is an AAC frame, and return the frame | ||||||
|  * length.  Returns 0 if it is not a 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 | static bool | ||||||
| faad_decoder_init(faacDecHandle decoder, struct decoder_buffer *buffer, | faad_decoder_init(faacDecHandle decoder, struct decoder_buffer *buffer, | ||||||
| 		  struct audio_format *audio_format) | 		  struct audio_format *audio_format, GError **error_r) | ||||||
| { | { | ||||||
| 	union { | 	union { | ||||||
| 		/* deconst hack for libfaad */ | 		/* 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 | 	/* neaacdec.h declares all arguments as "unsigned long", but | ||||||
| 	   internally expects uint32_t pointers.  To avoid gcc | 	   internally expects uint32_t pointers.  To avoid gcc | ||||||
| 	   warnings, use this workaround. */ | 	   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 | #else | ||||||
| 	uint32_t *sample_rate_r = &sample_rate; | 	uint32_t *sample_rate_p = &sample_rate; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| 	u.in = decoder_buffer_read(buffer, &length); | 	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; | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	nbytes = faacDecInit(decoder, u.out, | 	nbytes = faacDecInit(decoder, u.out, | ||||||
| #ifdef HAVE_FAAD_BUFLEN_FUNCS | #ifdef HAVE_FAAD_BUFLEN_FUNCS | ||||||
| 			     length, | 			     length, | ||||||
| #endif | #endif | ||||||
| 			     sample_rate_r, &channels); | 			     sample_rate_p, &channels); | ||||||
| 	if (nbytes < 0) | 	if (nbytes < 0) { | ||||||
|  | 		g_set_error(error_r, faad_decoder_quark(), 0, | ||||||
|  | 			    "Not an AAC stream"); | ||||||
| 		return false; | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	decoder_buffer_consume(buffer, nbytes); | 	decoder_buffer_consume(buffer, nbytes); | ||||||
|  |  | ||||||
| 	audio_format_init(audio_format, sample_rate, 16, channels); | 	return audio_format_init_checked(audio_format, sample_rate, | ||||||
|  | 					 16, channels, error_r); | ||||||
| 	return true; |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -334,8 +349,8 @@ faad_get_file_time_float(const char *file) | |||||||
|  |  | ||||||
| 		decoder_buffer_fill(buffer); | 		decoder_buffer_fill(buffer); | ||||||
|  |  | ||||||
| 		ret = faad_decoder_init(decoder, buffer, &audio_format); | 		ret = faad_decoder_init(decoder, buffer, &audio_format, NULL); | ||||||
| 		if (ret && audio_format_valid(&audio_format)) | 		if (ret) | ||||||
| 			length = 0; | 			length = 0; | ||||||
|  |  | ||||||
| 		faacDecClose(decoder); | 		faacDecClose(decoder); | ||||||
| @@ -367,6 +382,7 @@ faad_get_file_time(const char *file) | |||||||
| static void | static void | ||||||
| faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is) | faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is) | ||||||
| { | { | ||||||
|  | 	GError *error = NULL; | ||||||
| 	float file_time; | 	float file_time; | ||||||
| 	float total_time = 0; | 	float total_time = 0; | ||||||
| 	faacDecHandle decoder; | 	faacDecHandle decoder; | ||||||
| @@ -404,15 +420,10 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is) | |||||||
|  |  | ||||||
| 	/* initialize it */ | 	/* initialize it */ | ||||||
|  |  | ||||||
| 	ret = faad_decoder_init(decoder, buffer, &audio_format); | 	ret = faad_decoder_init(decoder, buffer, &audio_format, &error); | ||||||
| 	if (!ret) { | 	if (!ret) { | ||||||
| 		g_warning("Error not a AAC stream.\n"); | 		g_warning("%s", error->message); | ||||||
| 		faacDecClose(decoder); | 		g_error_free(error); | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (!audio_format_valid(&audio_format)) { |  | ||||||
| 		g_warning("invalid audio format\n"); |  | ||||||
| 		faacDecClose(decoder); | 		faacDecClose(decoder); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ | |||||||
|  |  | ||||||
| #include "config.h" | #include "config.h" | ||||||
| #include "decoder_api.h" | #include "decoder_api.h" | ||||||
|  | #include "audio_check.h" | ||||||
|  |  | ||||||
| #include <glib.h> | #include <glib.h> | ||||||
|  |  | ||||||
| @@ -260,6 +261,7 @@ ffmpeg_send_packet(struct decoder *decoder, struct input_stream *is, | |||||||
| static bool | static bool | ||||||
| ffmpeg_decode_internal(struct ffmpeg_context *ctx) | ffmpeg_decode_internal(struct ffmpeg_context *ctx) | ||||||
| { | { | ||||||
|  | 	GError *error = NULL; | ||||||
| 	struct decoder *decoder = ctx->decoder; | 	struct decoder *decoder = ctx->decoder; | ||||||
| 	AVCodecContext *codec_context = ctx->codec_context; | 	AVCodecContext *codec_context = ctx->codec_context; | ||||||
| 	AVFormatContext *format_context = ctx->format_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) */ | 	/* XXX fixme 16-bit for older ffmpeg (13 Aug 2007) */ | ||||||
| 	bits = (uint8_t) 16; | 	bits = (uint8_t) 16; | ||||||
| #endif | #endif | ||||||
| 	audio_format_init(&audio_format, codec_context->sample_rate, bits, | 	if (!audio_format_init_checked(&audio_format, | ||||||
| 			  codec_context->channels); | 				       codec_context->sample_rate, bits, | ||||||
|  | 				       codec_context->channels, &error)) { | ||||||
| 	if (!audio_format_valid(&audio_format)) { | 		g_warning("%s", error->message); | ||||||
| 		g_warning("Invalid audio format: %u:%u:%u\n", | 		g_error_free(error); | ||||||
| 			  audio_format.sample_rate, audio_format.bits, |  | ||||||
| 			  audio_format.channels); |  | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,6 +21,7 @@ | |||||||
| #include "decoder_api.h" | #include "decoder_api.h" | ||||||
| #include "conf.h" | #include "conf.h" | ||||||
| #include "tag_id3.h" | #include "tag_id3.h" | ||||||
|  | #include "audio_check.h" | ||||||
|  |  | ||||||
| #include <assert.h> | #include <assert.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| @@ -1174,6 +1175,7 @@ static void | |||||||
| mp3_decode(struct decoder *decoder, struct input_stream *input_stream) | mp3_decode(struct decoder *decoder, struct input_stream *input_stream) | ||||||
| { | { | ||||||
| 	struct mp3_data data; | 	struct mp3_data data; | ||||||
|  | 	GError *error = NULL; | ||||||
| 	struct tag *tag = NULL; | 	struct tag *tag = NULL; | ||||||
| 	struct replay_gain_info *replay_gain_info = NULL; | 	struct replay_gain_info *replay_gain_info = NULL; | ||||||
| 	struct audio_format audio_format; | 	struct audio_format audio_format; | ||||||
| @@ -1185,8 +1187,20 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream) | |||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	audio_format_init(&audio_format, data.frame.header.samplerate, 24, | 	if (!audio_format_init_checked(&audio_format, | ||||||
| 			  MAD_NCHANNELS(&data.frame.header)); | 				       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, | 	decoder_initialized(decoder, &audio_format, | ||||||
| 			    data.input_stream->seekable, data.total_time); | 			    data.input_stream->seekable, data.total_time); | ||||||
|   | |||||||
| @@ -22,6 +22,7 @@ | |||||||
|  |  | ||||||
| #include <glib.h> | #include <glib.h> | ||||||
| #include <mikmod.h> | #include <mikmod.h> | ||||||
|  | #include <assert.h> | ||||||
|  |  | ||||||
| #undef G_LOG_DOMAIN | #undef G_LOG_DOMAIN | ||||||
| #define G_LOG_DOMAIN "mikmod" | #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); | 	audio_format_init(&audio_format, 44100, 16, 2); | ||||||
|  | 	assert(audio_format_valid(&audio_format)); | ||||||
|  |  | ||||||
| 	secPerByte = | 	secPerByte = | ||||||
| 	    1.0 / ((audio_format.bits * audio_format.channels / 8.0) * | 	    1.0 / ((audio_format.bits * audio_format.channels / 8.0) * | ||||||
|   | |||||||
| @@ -22,6 +22,7 @@ | |||||||
|  |  | ||||||
| #include <glib.h> | #include <glib.h> | ||||||
| #include <modplug.h> | #include <modplug.h> | ||||||
|  | #include <assert.h> | ||||||
|  |  | ||||||
| #undef G_LOG_DOMAIN | #undef G_LOG_DOMAIN | ||||||
| #define G_LOG_DOMAIN "modplug" | #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); | 	audio_format_init(&audio_format, 44100, 16, 2); | ||||||
|  | 	assert(audio_format_valid(&audio_format)); | ||||||
|  |  | ||||||
| 	sec_perbyte = | 	sec_perbyte = | ||||||
| 	    1.0 / ((audio_format.bits * audio_format.channels / 8.0) * | 	    1.0 / ((audio_format.bits * audio_format.channels / 8.0) * | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ | |||||||
|  |  | ||||||
| #include "config.h" | #include "config.h" | ||||||
| #include "decoder_api.h" | #include "decoder_api.h" | ||||||
|  | #include "audio_check.h" | ||||||
|  |  | ||||||
| #include <glib.h> | #include <glib.h> | ||||||
|  |  | ||||||
| @@ -110,6 +111,7 @@ mp4_faad_new(mp4ff_t *mp4fh, int *track_r, struct audio_format *audio_format) | |||||||
| 	int track; | 	int track; | ||||||
| 	uint32_t sample_rate; | 	uint32_t sample_rate; | ||||||
| 	unsigned char channels; | 	unsigned char channels; | ||||||
|  | 	GError *error = NULL; | ||||||
|  |  | ||||||
| 	decoder = faacDecOpen(); | 	decoder = faacDecOpen(); | ||||||
|  |  | ||||||
| @@ -130,18 +132,16 @@ mp4_faad_new(mp4ff_t *mp4fh, int *track_r, struct audio_format *audio_format) | |||||||
| 		return NULL; | 		return NULL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	*track_r = track; | 	if (!audio_format_init_checked(audio_format, sample_rate, 16, channels, | ||||||
| 	audio_format_init(audio_format, sample_rate, 16, channels); | 				       &error)) { | ||||||
|  | 		g_warning("%s", error->message); | ||||||
| 	if (!audio_format_valid(audio_format)) { | 		g_error_free(error); | ||||||
| 		g_warning("Invalid audio format: %u:%u:%u\n", |  | ||||||
| 			  audio_format->sample_rate, |  | ||||||
| 			  audio_format->bits, |  | ||||||
| 			  audio_format->channels); |  | ||||||
| 		faacDecClose(decoder); | 		faacDecClose(decoder); | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	*track_r = track; | ||||||
|  |  | ||||||
| 	return decoder; | 	return decoder; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ | |||||||
|  |  | ||||||
| #include "config.h" | #include "config.h" | ||||||
| #include "decoder_api.h" | #include "decoder_api.h" | ||||||
|  | #include "audio_check.h" | ||||||
|  |  | ||||||
| #ifdef MPC_IS_OLD_API | #ifdef MPC_IS_OLD_API | ||||||
| #include <mpcdec/mpcdec.h> | #include <mpcdec/mpcdec.h> | ||||||
| @@ -27,6 +28,7 @@ | |||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #include <glib.h> | #include <glib.h> | ||||||
|  | #include <assert.h> | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
|  |  | ||||||
| #undef G_LOG_DOMAIN | #undef G_LOG_DOMAIN | ||||||
| @@ -140,6 +142,7 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is) | |||||||
| #endif | #endif | ||||||
| 	mpc_reader reader; | 	mpc_reader reader; | ||||||
| 	mpc_streaminfo info; | 	mpc_streaminfo info; | ||||||
|  | 	GError *error = NULL; | ||||||
| 	struct audio_format audio_format; | 	struct audio_format audio_format; | ||||||
|  |  | ||||||
| 	struct mpc_decoder_data data; | 	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); | 	mpc_demux_get_info(demux, &info); | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| 	audio_format_init(&audio_format, info.sample_freq, 24, info.channels); | 	if (!audio_format_init_checked(&audio_format, info.sample_freq, 16, | ||||||
|  | 				       info.channels, &error)) { | ||||||
| 	if (!audio_format_valid(&audio_format)) { | 		g_warning("%s", error->message); | ||||||
|  | 		g_error_free(error); | ||||||
| #ifndef MPC_IS_OLD_API | #ifndef MPC_IS_OLD_API | ||||||
| 		mpc_demux_exit(demux); | 		mpc_demux_exit(demux); | ||||||
| #endif | #endif | ||||||
| 		g_warning("Invalid audio format: %u:%u:%u\n", |  | ||||||
| 			  audio_format.sample_rate, |  | ||||||
| 			  audio_format.bits, |  | ||||||
| 			  audio_format.channels); |  | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ | |||||||
|  |  | ||||||
| #include "config.h" /* must be first for large file support */ | #include "config.h" /* must be first for large file support */ | ||||||
| #include "decoder_api.h" | #include "decoder_api.h" | ||||||
|  | #include "audio_check.h" | ||||||
|  |  | ||||||
| #include <glib.h> | #include <glib.h> | ||||||
|  |  | ||||||
| @@ -54,6 +55,7 @@ static bool | |||||||
| mpd_mpg123_open(mpg123_handle *handle, const char *path_fs, | mpd_mpg123_open(mpg123_handle *handle, const char *path_fs, | ||||||
| 		struct audio_format *audio_format) | 		struct audio_format *audio_format) | ||||||
| { | { | ||||||
|  | 	GError *gerror = NULL; | ||||||
| 	char *path_dup; | 	char *path_dup; | ||||||
| 	int error; | 	int error; | ||||||
| 	int channels, encoding; | 	int channels, encoding; | ||||||
| @@ -85,9 +87,10 @@ mpd_mpg123_open(mpg123_handle *handle, const char *path_fs, | |||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	audio_format_init(audio_format, rate, 16, channels); | 	if (!audio_format_init_checked(audio_format, rate, 16, | ||||||
| 	if (!audio_format_valid(audio_format)) { | 				       channels, &gerror)) { | ||||||
| 		g_warning("invalid audio format"); | 		g_warning("%s", gerror->message); | ||||||
|  | 		g_error_free(gerror); | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -278,6 +278,7 @@ sidplay_file_decode(struct decoder *decoder, const char *path_fs) | |||||||
|  |  | ||||||
| 	struct audio_format audio_format; | 	struct audio_format audio_format; | ||||||
| 	audio_format_init(&audio_format, 48000, 16, 2); | 	audio_format_init(&audio_format, 48000, 16, 2); | ||||||
|  | 	assert(audio_format_valid(&audio_format)); | ||||||
|  |  | ||||||
| 	decoder_initialized(decoder, &audio_format, true, (float)song_len); | 	decoder_initialized(decoder, &audio_format, true, (float)song_len); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ | |||||||
|  |  | ||||||
| #include "config.h" | #include "config.h" | ||||||
| #include "decoder_api.h" | #include "decoder_api.h" | ||||||
|  | #include "audio_check.h" | ||||||
|  |  | ||||||
| #include <sndfile.h> | #include <sndfile.h> | ||||||
|  |  | ||||||
| @@ -109,6 +110,7 @@ time_to_frame(float t, const struct audio_format *audio_format) | |||||||
| static void | static void | ||||||
| sndfile_stream_decode(struct decoder *decoder, struct input_stream *is) | sndfile_stream_decode(struct decoder *decoder, struct input_stream *is) | ||||||
| { | { | ||||||
|  | 	GError *error = NULL; | ||||||
| 	SNDFILE *sf; | 	SNDFILE *sf; | ||||||
| 	SF_INFO info; | 	SF_INFO info; | ||||||
| 	struct audio_format audio_format; | 	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 | 	/* for now, always read 32 bit samples.  Later, we could lower | ||||||
| 	   MPD's CPU usage by reading 16 bit samples with | 	   MPD's CPU usage by reading 16 bit samples with | ||||||
| 	   sf_readf_short() on low-quality source files. */ | 	   sf_readf_short() on low-quality source files. */ | ||||||
| 	audio_format_init(&audio_format, info.samplerate, 32, info.channels); | 	if (!audio_format_init_checked(&audio_format, info.samplerate, 32, | ||||||
|  | 				       info.channels, &error)) { | ||||||
| 	if (!audio_format_valid(&audio_format)) { | 		g_warning("%s", error->message); | ||||||
| 		g_warning("invalid audio format"); | 		g_error_free(error); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ | |||||||
|  |  | ||||||
| #include "config.h" | #include "config.h" | ||||||
| #include "_ogg_common.h" | #include "_ogg_common.h" | ||||||
|  | #include "audio_check.h" | ||||||
| #include "uri.h" | #include "uri.h" | ||||||
|  |  | ||||||
| #ifndef HAVE_TREMOR | #ifndef HAVE_TREMOR | ||||||
| @@ -264,6 +265,7 @@ static void | |||||||
| vorbis_stream_decode(struct decoder *decoder, | vorbis_stream_decode(struct decoder *decoder, | ||||||
| 		     struct input_stream *input_stream) | 		     struct input_stream *input_stream) | ||||||
| { | { | ||||||
|  | 	GError *error = NULL; | ||||||
| 	OggVorbis_File vf; | 	OggVorbis_File vf; | ||||||
| 	ov_callbacks callbacks; | 	ov_callbacks callbacks; | ||||||
| 	struct vorbis_decoder_data data; | 	struct vorbis_decoder_data data; | ||||||
| @@ -309,13 +311,10 @@ vorbis_stream_decode(struct decoder *decoder, | |||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	audio_format_init(&audio_format, vi->rate, 16, vi->channels); | 	if (!audio_format_init_checked(&audio_format, vi->rate, 16, | ||||||
|  | 				       vi->channels, &error)) { | ||||||
| 	if (!audio_format_valid(&audio_format)) { | 		g_warning("%s", error->message); | ||||||
| 		g_warning("Invalid audio format: %u:%u:%u\n", | 		g_error_free(error); | ||||||
| 			  audio_format.sample_rate, |  | ||||||
| 			  audio_format.bits, |  | ||||||
| 			  audio_format.channels); |  | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ | |||||||
|  |  | ||||||
| #include "config.h" | #include "config.h" | ||||||
| #include "decoder_api.h" | #include "decoder_api.h" | ||||||
|  | #include "audio_check.h" | ||||||
| #include "path.h" | #include "path.h" | ||||||
| #include "utils.h" | #include "utils.h" | ||||||
|  |  | ||||||
| @@ -130,6 +131,8 @@ static void | |||||||
| wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek, | wavpack_decode(struct decoder *decoder, WavpackContext *wpc, bool can_seek, | ||||||
| 	       struct replay_gain_info *replay_gain_info) | 	       struct replay_gain_info *replay_gain_info) | ||||||
| { | { | ||||||
|  | 	GError *error = NULL; | ||||||
|  | 	unsigned bits; | ||||||
| 	struct audio_format audio_format; | 	struct audio_format audio_format; | ||||||
| 	format_samples_t format_samples; | 	format_samples_t format_samples; | ||||||
| 	char chunk[CHUNK_SIZE]; | 	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 bytes_per_sample, output_sample_size; | ||||||
| 	int position; | 	int position; | ||||||
|  |  | ||||||
| 	audio_format_init(&audio_format, WavpackGetSampleRate(wpc), | 	bits = WavpackGetBitsPerSample(wpc); | ||||||
| 			  WavpackGetBitsPerSample(wpc),  |  | ||||||
| 			  WavpackGetNumChannels(wpc)); |  | ||||||
|  |  | ||||||
| 	/* round bitwidth to 8-bit units */ | 	/* round bitwidth to 8-bit units */ | ||||||
| 	audio_format.bits = (audio_format.bits + 7) & (~7); | 	bits = (bits + 7) & (~7); | ||||||
| 	/* MPD handles max 32-bit samples */ | 	/* MPD handles max 32-bit samples */ | ||||||
| 	if (audio_format.bits > 32) | 	if (bits > 32) | ||||||
| 		audio_format.bits = 32; | 		bits = 32; | ||||||
|  |  | ||||||
| 	if ((WavpackGetMode(wpc) & MODE_FLOAT) == MODE_FLOAT) | 	if ((WavpackGetMode(wpc) & MODE_FLOAT) == MODE_FLOAT) | ||||||
| 		audio_format.bits = 24; | 		bits = 24; | ||||||
|  |  | ||||||
| 	if (!audio_format_valid(&audio_format)) { | 	if (!audio_format_init_checked(&audio_format, | ||||||
| 		g_warning("Invalid audio format: %u:%u:%u\n", | 				       WavpackGetSampleRate(wpc), bits, | ||||||
| 			  audio_format.sample_rate, | 				       WavpackGetNumChannels(wpc), &error)) { | ||||||
| 			  audio_format.bits, | 		g_warning("%s", error->message); | ||||||
| 			  audio_format.channels); | 		g_error_free(error); | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Max Kellermann
					Max Kellermann