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:
parent
6b96f5d566
commit
05cde5810a
@ -322,20 +322,16 @@ faad_decoder_decode(faacDecHandle decoder, struct decoder_buffer *buffer,
|
||||
* file is invalid.
|
||||
*/
|
||||
static float
|
||||
faad_get_file_time_float(const char *file)
|
||||
faad_get_file_time_float(struct input_stream *is)
|
||||
{
|
||||
struct decoder_buffer *buffer;
|
||||
float length;
|
||||
faacDecHandle decoder;
|
||||
faacDecConfigurationPtr config;
|
||||
struct input_stream is;
|
||||
|
||||
if (!input_stream_open(&is, file, NULL))
|
||||
return -1;
|
||||
|
||||
buffer = decoder_buffer_new(NULL, &is,
|
||||
buffer = decoder_buffer_new(NULL, is,
|
||||
FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS);
|
||||
length = faad_song_duration(buffer, &is);
|
||||
length = faad_song_duration(buffer, is);
|
||||
|
||||
if (length < 0) {
|
||||
bool ret;
|
||||
@ -357,7 +353,6 @@ faad_get_file_time_float(const char *file)
|
||||
}
|
||||
|
||||
decoder_buffer_free(buffer);
|
||||
input_stream_close(&is);
|
||||
|
||||
return length;
|
||||
}
|
||||
@ -368,12 +363,12 @@ faad_get_file_time_float(const char *file)
|
||||
* file is invalid.
|
||||
*/
|
||||
static int
|
||||
faad_get_file_time(const char *file)
|
||||
faad_get_file_time(struct input_stream *is)
|
||||
{
|
||||
int file_time = -1;
|
||||
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;
|
||||
|
||||
return file_time;
|
||||
@ -493,15 +488,13 @@ faad_stream_decode(struct decoder *mpd_decoder, struct input_stream *is)
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (file_time < 0) {
|
||||
g_debug("Failed to get total song time from: %s", file);
|
||||
if (file_time < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tag = tag_new();
|
||||
tag->time = file_time;
|
||||
@ -516,7 +509,7 @@ static const char *const faad_mime_types[] = {
|
||||
const struct decoder_plugin faad_decoder_plugin = {
|
||||
.name = "faad",
|
||||
.stream_decode = faad_stream_decode,
|
||||
.tag_dup = faad_tag_dup,
|
||||
.stream_tag = faad_stream_tag,
|
||||
.suffixes = faad_suffixes,
|
||||
.mime_types = faad_mime_types,
|
||||
};
|
||||
|
@ -426,28 +426,21 @@ static bool ffmpeg_tag_internal(struct ffmpeg_context *ctx)
|
||||
}
|
||||
|
||||
//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;
|
||||
bool ret;
|
||||
|
||||
if (!input_stream_open(&input, file, NULL)) {
|
||||
g_warning("failed to open %s\n", file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx.decoder = NULL;
|
||||
ctx.tag = tag_new();
|
||||
|
||||
ret = ffmpeg_helper(&input, ffmpeg_tag_internal, &ctx);
|
||||
ret = ffmpeg_helper(is, ffmpeg_tag_internal, &ctx);
|
||||
if (!ret) {
|
||||
tag_free(ctx.tag);
|
||||
ctx.tag = NULL;
|
||||
}
|
||||
|
||||
input_stream_close(&input);
|
||||
|
||||
return ctx.tag;
|
||||
}
|
||||
|
||||
@ -553,7 +546,7 @@ const struct decoder_plugin ffmpeg_decoder_plugin = {
|
||||
.name = "ffmpeg",
|
||||
.init = ffmpeg_init,
|
||||
.stream_decode = ffmpeg_decode,
|
||||
.tag_dup = ffmpeg_tag,
|
||||
.stream_tag = ffmpeg_stream_tag,
|
||||
.suffixes = ffmpeg_suffixes,
|
||||
.mime_types = ffmpeg_mime_types
|
||||
};
|
||||
|
@ -914,21 +914,18 @@ static void mp3_data_finish(struct mp3_data *data)
|
||||
}
|
||||
|
||||
/* 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;
|
||||
int ret;
|
||||
|
||||
if (!input_stream_open(&input_stream, file, NULL))
|
||||
return -1;
|
||||
mp3_data_init(&data, NULL, &input_stream);
|
||||
mp3_data_init(&data, NULL, is);
|
||||
if (!mp3_decode_first_frame(&data, NULL, NULL))
|
||||
ret = -1;
|
||||
else
|
||||
ret = data.total_time + 0.5;
|
||||
mp3_data_finish(&data);
|
||||
input_stream_close(&input_stream);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1222,16 +1219,15 @@ mp3_decode(struct decoder *decoder, struct input_stream *input_stream)
|
||||
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;
|
||||
int total_time;
|
||||
|
||||
total_time = mp3_total_file_time(file);
|
||||
if (total_time < 0) {
|
||||
g_debug("Failed to get total song time from: %s", file);
|
||||
total_time = mad_decoder_total_file_time(is);
|
||||
if (total_time < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tag = tag_new();
|
||||
tag->time = total_time;
|
||||
@ -1245,7 +1241,7 @@ const struct decoder_plugin mad_decoder_plugin = {
|
||||
.name = "mad",
|
||||
.init = mp3_plugin_init,
|
||||
.stream_decode = mp3_decode,
|
||||
.tag_dup = mp3_tag_dup,
|
||||
.stream_tag = mad_decoder_stream_tag,
|
||||
.suffixes = mp3_suffixes,
|
||||
.mime_types = mp3_mime_types
|
||||
};
|
||||
|
@ -149,31 +149,23 @@ mod_decode(struct decoder *decoder, struct input_stream *is)
|
||||
ModPlug_Unload(f);
|
||||
}
|
||||
|
||||
static struct tag *mod_tagdup(const char *file)
|
||||
static struct tag *
|
||||
modplug_stream_tag(struct input_stream *is)
|
||||
{
|
||||
ModPlugFile *f;
|
||||
struct tag *ret = NULL;
|
||||
GByteArray *bdatas;
|
||||
char *title;
|
||||
struct input_stream is;
|
||||
|
||||
if (!input_stream_open(&is, file, NULL)) {
|
||||
g_warning("cant open file %s\n", file);
|
||||
bdatas = mod_loadfile(NULL, is);
|
||||
if (!bdatas)
|
||||
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);
|
||||
g_byte_array_free(bdatas, TRUE);
|
||||
if (!f) {
|
||||
g_warning("could not decode file %s\n", file);
|
||||
if (f == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = tag_new();
|
||||
ret->time = ModPlug_GetLength(f) / 1000;
|
||||
|
||||
@ -184,8 +176,6 @@ static struct tag *mod_tagdup(const char *file)
|
||||
|
||||
ModPlug_Unload(f);
|
||||
|
||||
input_stream_close(&is);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -199,6 +189,6 @@ static const char *const mod_suffixes[] = {
|
||||
const struct decoder_plugin modplug_decoder_plugin = {
|
||||
.name = "modplug",
|
||||
.stream_decode = mod_decode,
|
||||
.tag_dup = mod_tagdup,
|
||||
.stream_tag = modplug_stream_tag,
|
||||
.suffixes = mod_suffixes,
|
||||
};
|
||||
|
@ -337,13 +337,12 @@ mp4_decode(struct decoder *mpd_decoder, struct input_stream *input_stream)
|
||||
}
|
||||
|
||||
static struct tag *
|
||||
mp4_tag_dup(const char *file)
|
||||
mp4_stream_tag(struct input_stream *is)
|
||||
{
|
||||
struct tag *ret = NULL;
|
||||
struct input_stream input_stream;
|
||||
struct mp4_context ctx = {
|
||||
.decoder = NULL,
|
||||
.input_stream = &input_stream,
|
||||
.input_stream = is,
|
||||
};
|
||||
mp4ff_callback_t callback = {
|
||||
.read = mp4_read,
|
||||
@ -356,21 +355,13 @@ mp4_tag_dup(const char *file)
|
||||
int32_t scale;
|
||||
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);
|
||||
if (!mp4fh) {
|
||||
input_stream_close(&input_stream);
|
||||
if (mp4fh == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
track = mp4_get_aac_track(mp4fh, NULL, NULL, NULL);
|
||||
if (track < 0) {
|
||||
mp4ff_close(mp4fh);
|
||||
input_stream_close(&input_stream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -379,7 +370,6 @@ mp4_tag_dup(const char *file)
|
||||
scale = mp4ff_time_scale(mp4fh, track);
|
||||
if (scale < 0) {
|
||||
mp4ff_close(mp4fh);
|
||||
input_stream_close(&input_stream);
|
||||
tag_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
@ -415,7 +405,6 @@ mp4_tag_dup(const char *file)
|
||||
}
|
||||
|
||||
mp4ff_close(mp4fh);
|
||||
input_stream_close(&input_stream);
|
||||
|
||||
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 = {
|
||||
.name = "mp4",
|
||||
.stream_decode = mp4_decode,
|
||||
.tag_dup = mp4_tag_dup,
|
||||
.stream_tag = mp4_stream_tag,
|
||||
.suffixes = mp4_suffixes,
|
||||
.mime_types = mp4_mime_types,
|
||||
};
|
||||
|
@ -275,9 +275,8 @@ mpcdec_decode(struct decoder *mpd_decoder, struct input_stream *is)
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
mpc_reader reader;
|
||||
@ -287,10 +286,7 @@ mpcdec_get_file_duration(const char *file)
|
||||
mpc_streaminfo info;
|
||||
struct mpc_decoder_data data;
|
||||
|
||||
if (!input_stream_open(&is, file, NULL))
|
||||
return -1;
|
||||
|
||||
data.is = &is;
|
||||
data.is = is;
|
||||
data.decoder = NULL;
|
||||
|
||||
reader.read = mpc_read_cb;
|
||||
@ -303,16 +299,12 @@ mpcdec_get_file_duration(const char *file)
|
||||
#ifdef MPC_IS_OLD_API
|
||||
mpc_streaminfo_init(&info);
|
||||
|
||||
if (mpc_streaminfo_read(&info, &reader) != ERROR_CODE_OK) {
|
||||
input_stream_close(&is);
|
||||
if (mpc_streaminfo_read(&info, &reader) != ERROR_CODE_OK)
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
demux = mpc_demux_init(&reader);
|
||||
if (demux == NULL) {
|
||||
input_stream_close(&is);
|
||||
if (demux == NULL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
mpc_demux_get_info(demux, &info);
|
||||
mpc_demux_exit(demux);
|
||||
@ -320,21 +312,17 @@ mpcdec_get_file_duration(const char *file)
|
||||
|
||||
total_time = mpc_streaminfo_get_length(&info);
|
||||
|
||||
input_stream_close(&is);
|
||||
|
||||
return total_time;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (total_time < 0) {
|
||||
g_debug("Failed to get duration of file: %s", file);
|
||||
if (total_time < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tag = tag_new();
|
||||
tag->time = total_time;
|
||||
@ -346,6 +334,6 @@ static const char *const mpcdec_suffixes[] = { "mpc", NULL };
|
||||
const struct decoder_plugin mpcdec_decoder_plugin = {
|
||||
.name = "mpcdec",
|
||||
.stream_decode = mpcdec_decode,
|
||||
.tag_dup = mpcdec_tag_dup,
|
||||
.stream_tag = mpcdec_stream_tag,
|
||||
.suffixes = mpcdec_suffixes,
|
||||
};
|
||||
|
@ -243,33 +243,20 @@ fail:
|
||||
|
||||
/* public functions: */
|
||||
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;
|
||||
struct flac_data data;
|
||||
struct tag *tag;
|
||||
|
||||
if (!input_stream_open(&input_stream, file, &error)) {
|
||||
if (error != NULL) {
|
||||
g_warning("%s", error->message);
|
||||
g_error_free(error);
|
||||
}
|
||||
|
||||
if (ogg_stream_type_detect(is) != FLAC)
|
||||
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
|
||||
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();
|
||||
|
||||
@ -278,7 +265,6 @@ oggflac_tag_dup(const char *file)
|
||||
decoder = full_decoder_init_and_read_metadata(&data, 1);
|
||||
|
||||
oggflac_cleanup(decoder);
|
||||
input_stream_close(&input_stream);
|
||||
|
||||
if (tag_is_defined(data.tag)) {
|
||||
tag = data.tag;
|
||||
@ -362,7 +348,7 @@ static const char *const oggflac_mime_types[] = {
|
||||
const struct decoder_plugin oggflac_decoder_plugin = {
|
||||
.name = "oggflac",
|
||||
.stream_decode = oggflac_decode,
|
||||
.tag_dup = oggflac_tag_dup,
|
||||
.stream_tag = oggflac_stream_tag,
|
||||
.suffixes = oggflac_suffixes,
|
||||
.mime_types = oggflac_mime_types
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user