decoder: switch a bunch of plugins to stream_tag()

This patch changes the following decoder plugins to implement
stream_tag() instead of tag_dup():

 faad, ffmpeg, mad, modplug, mp4ff, mpcdec, oggflac

This simplifies their code, because they do not need to take care of
opening/closing the stream.
This commit is contained in:
Max Kellermann 2009-12-31 18:20:08 +01:00
parent 6b96f5d566
commit 05cde5810a
7 changed files with 45 additions and 110 deletions

View File

@ -322,20 +322,16 @@ faad_decoder_decode(faacDecHandle decoder, struct decoder_buffer *buffer,
* file is invalid. * file is invalid.
*/ */
static float static float
faad_get_file_time_float(const char *file) faad_get_file_time_float(struct input_stream *is)
{ {
struct decoder_buffer *buffer; struct decoder_buffer *buffer;
float length; float length;
faacDecHandle decoder; faacDecHandle decoder;
faacDecConfigurationPtr config; faacDecConfigurationPtr config;
struct input_stream is;
if (!input_stream_open(&is, file, NULL)) buffer = decoder_buffer_new(NULL, is,
return -1;
buffer = decoder_buffer_new(NULL, &is,
FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS); FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS);
length = faad_song_duration(buffer, &is); length = faad_song_duration(buffer, is);
if (length < 0) { if (length < 0) {
bool ret; bool ret;
@ -357,7 +353,6 @@ faad_get_file_time_float(const char *file)
} }
decoder_buffer_free(buffer); decoder_buffer_free(buffer);
input_stream_close(&is);
return length; return length;
} }
@ -368,12 +363,12 @@ faad_get_file_time_float(const char *file)
* file is invalid. * file is invalid.
*/ */
static int static int
faad_get_file_time(const char *file) faad_get_file_time(struct input_stream *is)
{ {
int file_time = -1; int file_time = -1;
float length; float length;
if ((length = faad_get_file_time_float(file)) >= 0) if ((length = faad_get_file_time_float(is)) >= 0)
file_time = length + 0.5; file_time = length + 0.5;
return file_time; return file_time;
@ -493,15 +488,13 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
} }
static struct tag * static struct tag *
faad_tag_dup(const char *file) faad_stream_tag(struct input_stream *is)
{ {
int file_time = faad_get_file_time(file); int file_time = faad_get_file_time(is);
struct tag *tag; struct tag *tag;
if (file_time < 0) { if (file_time < 0)
g_debug("Failed to get total song time from: %s", file);
return NULL; return NULL;
}
tag = tag_new(); tag = tag_new();
tag->time = file_time; tag->time = file_time;
@ -516,7 +509,7 @@ static const char *const faad_mime_types[] = {
const struct decoder_plugin faad_decoder_plugin = { const struct decoder_plugin faad_decoder_plugin = {
.name = "faad", .name = "faad",
.stream_decode = faad_stream_decode, .stream_decode = faad_stream_decode,
.tag_dup = faad_tag_dup, .stream_tag = faad_stream_tag,
.suffixes = faad_suffixes, .suffixes = faad_suffixes,
.mime_types = faad_mime_types, .mime_types = faad_mime_types,
}; };

View File

@ -426,28 +426,21 @@ static bool ffmpeg_tag_internal(struct ffmpeg_context *ctx)
} }
//no tag reading in ffmpeg, check if playable //no tag reading in ffmpeg, check if playable
static struct tag *ffmpeg_tag(const char *file) static struct tag *
ffmpeg_stream_tag(struct input_stream *is)
{ {
struct input_stream input;
struct ffmpeg_context ctx; struct ffmpeg_context ctx;
bool ret; bool ret;
if (!input_stream_open(&input, file, NULL)) {
g_warning("failed to open %s\n", file);
return NULL;
}
ctx.decoder = NULL; ctx.decoder = NULL;
ctx.tag = tag_new(); ctx.tag = tag_new();
ret = ffmpeg_helper(&input, ffmpeg_tag_internal, &ctx); ret = ffmpeg_helper(is, ffmpeg_tag_internal, &ctx);
if (!ret) { if (!ret) {
tag_free(ctx.tag); tag_free(ctx.tag);
ctx.tag = NULL; ctx.tag = NULL;
} }
input_stream_close(&input);
return ctx.tag; return ctx.tag;
} }
@ -553,7 +546,7 @@ const struct decoder_plugin ffmpeg_decoder_plugin = {
.name = "ffmpeg", .name = "ffmpeg",
.init = ffmpeg_init, .init = ffmpeg_init,
.stream_decode = ffmpeg_decode, .stream_decode = ffmpeg_decode,
.tag_dup = ffmpeg_tag, .stream_tag = ffmpeg_stream_tag,
.suffixes = ffmpeg_suffixes, .suffixes = ffmpeg_suffixes,
.mime_types = ffmpeg_mime_types .mime_types = ffmpeg_mime_types
}; };

View File

@ -914,21 +914,18 @@ static void mp3_data_finish(struct mp3_data *data)
} }
/* this is primarily used for getting total time for tags */ /* this is primarily used for getting total time for tags */
static int mp3_total_file_time(const char *file) static int
mad_decoder_total_file_time(struct input_stream *is)
{ {
struct input_stream input_stream;
struct mp3_data data; struct mp3_data data;
int ret; int ret;
if (!input_stream_open(&input_stream, file, NULL)) mp3_data_init(&data, NULL, is);
return -1;
mp3_data_init(&data, NULL, &input_stream);
if (!mp3_decode_first_frame(&data, NULL, NULL)) if (!mp3_decode_first_frame(&data, NULL, NULL))
ret = -1; ret = -1;
else else
ret = data.total_time + 0.5; ret = data.total_time + 0.5;
mp3_data_finish(&data); mp3_data_finish(&data);
input_stream_close(&input_stream);
return ret; return ret;
} }
@ -1222,16 +1219,15 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream)
mp3_data_finish(&data); mp3_data_finish(&data);
} }
static struct tag *mp3_tag_dup(const char *file) static struct tag *
mad_decoder_stream_tag(struct input_stream *is)
{ {
struct tag *tag; struct tag *tag;
int total_time; int total_time;
total_time = mp3_total_file_time(file); total_time = mad_decoder_total_file_time(is);
if (total_time < 0) { if (total_time < 0)
g_debug("Failed to get total song time from: %s", file);
return NULL; return NULL;
}
tag = tag_new(); tag = tag_new();
tag->time = total_time; tag->time = total_time;
@ -1245,7 +1241,7 @@ const struct decoder_plugin mad_decoder_plugin = {
.name = "mad", .name = "mad",
.init = mp3_plugin_init, .init = mp3_plugin_init,
.stream_decode = mp3_decode, .stream_decode = mp3_decode,
.tag_dup = mp3_tag_dup, .stream_tag = mad_decoder_stream_tag,
.suffixes = mp3_suffixes, .suffixes = mp3_suffixes,
.mime_types = mp3_mime_types .mime_types = mp3_mime_types
}; };

View File

@ -149,31 +149,23 @@ mod_decode(struct decoder *decoder, struct input_stream *is)
ModPlug_Unload(f); ModPlug_Unload(f);
} }
static struct tag *mod_tagdup(const char *file) static struct tag *
modplug_stream_tag(struct input_stream *is)
{ {
ModPlugFile *f; ModPlugFile *f;
struct tag *ret = NULL; struct tag *ret = NULL;
GByteArray *bdatas; GByteArray *bdatas;
char *title; char *title;
struct input_stream is;
if (!input_stream_open(&is, file, NULL)) { bdatas = mod_loadfile(NULL, is);
g_warning("cant open file %s\n", file); if (!bdatas)
return NULL; return NULL;
}
bdatas = mod_loadfile(NULL, &is);
if (!bdatas) {
g_warning("cant load file %s\n", file);
return NULL;
}
f = ModPlug_Load(bdatas->data, bdatas->len); f = ModPlug_Load(bdatas->data, bdatas->len);
g_byte_array_free(bdatas, TRUE); g_byte_array_free(bdatas, TRUE);
if (!f) { if (f == NULL)
g_warning("could not decode file %s\n", file);
return NULL; return NULL;
}
ret = tag_new(); ret = tag_new();
ret->time = ModPlug_GetLength(f) / 1000; ret->time = ModPlug_GetLength(f) / 1000;
@ -184,8 +176,6 @@ static struct tag *mod_tagdup(const char *file)
ModPlug_Unload(f); ModPlug_Unload(f);
input_stream_close(&is);
return ret; return ret;
} }
@ -199,6 +189,6 @@ static const char *const mod_suffixes[] = {
const struct decoder_plugin modplug_decoder_plugin = { const struct decoder_plugin modplug_decoder_plugin = {
.name = "modplug", .name = "modplug",
.stream_decode = mod_decode, .stream_decode = mod_decode,
.tag_dup = mod_tagdup, .stream_tag = modplug_stream_tag,
.suffixes = mod_suffixes, .suffixes = mod_suffixes,
}; };

View File

@ -337,13 +337,12 @@ mp4_decode(struct decoder *mpd_decoder, struct input_stream *input_stream)
} }
static struct tag * static struct tag *
mp4_tag_dup(const char *file) mp4_stream_tag(struct input_stream *is)
{ {
struct tag *ret = NULL; struct tag *ret = NULL;
struct input_stream input_stream;
struct mp4_context ctx = { struct mp4_context ctx = {
.decoder = NULL, .decoder = NULL,
.input_stream = &input_stream, .input_stream = is,
}; };
mp4ff_callback_t callback = { mp4ff_callback_t callback = {
.read = mp4_read, .read = mp4_read,
@ -356,21 +355,13 @@ mp4_tag_dup(const char *file)
int32_t scale; int32_t scale;
int i; int i;
if (!input_stream_open(&input_stream, file, NULL)) {
g_warning("Failed to open file: %s", file);
return NULL;
}
mp4fh = mp4ff_open_read(&callback); mp4fh = mp4ff_open_read(&callback);
if (!mp4fh) { if (mp4fh == NULL)
input_stream_close(&input_stream);
return NULL; return NULL;
}
track = mp4_get_aac_track(mp4fh, NULL, NULL, NULL); track = mp4_get_aac_track(mp4fh, NULL, NULL, NULL);
if (track < 0) { if (track < 0) {
mp4ff_close(mp4fh); mp4ff_close(mp4fh);
input_stream_close(&input_stream);
return NULL; return NULL;
} }
@ -379,7 +370,6 @@ mp4_tag_dup(const char *file)
scale = mp4ff_time_scale(mp4fh, track); scale = mp4ff_time_scale(mp4fh, track);
if (scale < 0) { if (scale < 0) {
mp4ff_close(mp4fh); mp4ff_close(mp4fh);
input_stream_close(&input_stream);
tag_free(ret); tag_free(ret);
return NULL; return NULL;
} }
@ -415,7 +405,6 @@ mp4_tag_dup(const char *file)
} }
mp4ff_close(mp4fh); mp4ff_close(mp4fh);
input_stream_close(&input_stream);
return ret; return ret;
} }
@ -426,7 +415,7 @@ static const char *const mp4_mime_types[] = { "audio/mp4", "audio/m4a", NULL };
const struct decoder_plugin mp4ff_decoder_plugin = { const struct decoder_plugin mp4ff_decoder_plugin = {
.name = "mp4", .name = "mp4",
.stream_decode = mp4_decode, .stream_decode = mp4_decode,
.tag_dup = mp4_tag_dup, .stream_tag = mp4_stream_tag,
.suffixes = mp4_suffixes, .suffixes = mp4_suffixes,
.mime_types = mp4_mime_types, .mime_types = mp4_mime_types,
}; };

View File

@ -275,9 +275,8 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is)
} }
static float static float
mpcdec_get_file_duration(const char *file) mpcdec_get_file_duration(struct input_stream *is)
{ {
struct input_stream is;
float total_time = -1; float total_time = -1;
mpc_reader reader; mpc_reader reader;
@ -287,10 +286,7 @@ mpcdec_get_file_duration(const char *file)
mpc_streaminfo info; mpc_streaminfo info;
struct mpc_decoder_data data; struct mpc_decoder_data data;
if (!input_stream_open(&is, file, NULL)) data.is = is;
return -1;
data.is = &is;
data.decoder = NULL; data.decoder = NULL;
reader.read = mpc_read_cb; reader.read = mpc_read_cb;
@ -303,16 +299,12 @@ mpcdec_get_file_duration(const char *file)
#ifdef MPC_IS_OLD_API #ifdef MPC_IS_OLD_API
mpc_streaminfo_init(&info); mpc_streaminfo_init(&info);
if (mpc_streaminfo_read(&info, &reader) != ERROR_CODE_OK) { if (mpc_streaminfo_read(&info, &reader) != ERROR_CODE_OK)
input_stream_close(&is);
return -1; return -1;
}
#else #else
demux = mpc_demux_init(&reader); demux = mpc_demux_init(&reader);
if (demux == NULL) { if (demux == NULL)
input_stream_close(&is);
return -1; return -1;
}
mpc_demux_get_info(demux, &info); mpc_demux_get_info(demux, &info);
mpc_demux_exit(demux); mpc_demux_exit(demux);
@ -320,21 +312,17 @@ mpcdec_get_file_duration(const char *file)
total_time = mpc_streaminfo_get_length(&info); total_time = mpc_streaminfo_get_length(&info);
input_stream_close(&is);
return total_time; return total_time;
} }
static struct tag * static struct tag *
mpcdec_tag_dup(const char *file) mpcdec_stream_tag(struct input_stream *is)
{ {
float total_time = mpcdec_get_file_duration(file); float total_time = mpcdec_get_file_duration(is);
struct tag *tag; struct tag *tag;
if (total_time < 0) { if (total_time < 0)
g_debug("Failed to get duration of file: %s", file);
return NULL; return NULL;
}
tag = tag_new(); tag = tag_new();
tag->time = total_time; tag->time = total_time;
@ -346,6 +334,6 @@ static const char *const mpcdec_suffixes[] = { "mpc", NULL };
const struct decoder_plugin mpcdec_decoder_plugin = { const struct decoder_plugin mpcdec_decoder_plugin = {
.name = "mpcdec", .name = "mpcdec",
.stream_decode = mpcdec_decode, .stream_decode = mpcdec_decode,
.tag_dup = mpcdec_tag_dup, .stream_tag = mpcdec_stream_tag,
.suffixes = mpcdec_suffixes, .suffixes = mpcdec_suffixes,
}; };

View File

@ -243,33 +243,20 @@ fail:
/* public functions: */ /* public functions: */
static struct tag * static struct tag *
oggflac_tag_dup(const char *file) oggflac_stream_tag(struct input_stream *is)
{ {
GError *error = NULL;
struct input_stream input_stream;
OggFLAC__SeekableStreamDecoder *decoder; OggFLAC__SeekableStreamDecoder *decoder;
struct flac_data data; struct flac_data data;
struct tag *tag; struct tag *tag;
if (!input_stream_open(&input_stream, file, &error)) { if (ogg_stream_type_detect(is) != FLAC)
if (error != NULL) {
g_warning("%s", error->message);
g_error_free(error);
}
return NULL; return NULL;
}
if (ogg_stream_type_detect(&input_stream) != FLAC) {
input_stream_close(&input_stream);
return NULL;
}
/* rewind the stream, because ogg_stream_type_detect() has /* rewind the stream, because ogg_stream_type_detect() has
moved it */ moved it */
input_stream_seek(&input_stream, 0, SEEK_SET, NULL); input_stream_seek(is, 0, SEEK_SET, NULL);
flac_data_init(&data, NULL, &input_stream); flac_data_init(&data, NULL, is);
data.tag = tag_new(); data.tag = tag_new();
@ -278,7 +265,6 @@ oggflac_tag_dup(const char *file)
decoder = full_decoder_init_and_read_metadata(&data, 1); decoder = full_decoder_init_and_read_metadata(&data, 1);
oggflac_cleanup(decoder); oggflac_cleanup(decoder);
input_stream_close(&input_stream);
if (tag_is_defined(data.tag)) { if (tag_is_defined(data.tag)) {
tag = data.tag; tag = data.tag;
@ -362,7 +348,7 @@ static const char *const oggflac_mime_types[] = {
const struct decoder_plugin oggflac_decoder_plugin = { const struct decoder_plugin oggflac_decoder_plugin = {
.name = "oggflac", .name = "oggflac",
.stream_decode = oggflac_decode, .stream_decode = oggflac_decode,
.tag_dup = oggflac_tag_dup, .stream_tag = oggflac_stream_tag,
.suffixes = oggflac_suffixes, .suffixes = oggflac_suffixes,
.mime_types = oggflac_mime_types .mime_types = oggflac_mime_types
}; };