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:
parent
f47bb8c1db
commit
719990b1c5
@ -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) \
|
||||
|
@ -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,
|
||||
if (!audio_format_init_checked(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);
|
||||
data->stream_info.channels, &error)) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "config.h"
|
||||
#include "decoder_api.h"
|
||||
#include "decoder_buffer.h"
|
||||
#include "audio_check.h"
|
||||
|
||||
#define AAC_MAX_CHANNELS 6
|
||||
|
||||
@ -36,6 +37,15 @@ static const unsigned adts_sample_rates[] =
|
||||
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
|
||||
* 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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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) *
|
||||
|
@ -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) *
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user