summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-01-11 20:41:38 +0100
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2010-01-11 20:41:38 +0100
commit1c328c9601ff4d9771ba1bf99f0f42c3caf32297 (patch)
tree1b960a7586346ddb4d3b7babe9e31733454cf337
parent8f873b3b3a992da897a029a1cf19b32168440f39 (diff)
runtime linking of playlist tracks to decoder plugins is done via strings instead of pointers (to allow easy unloading of decoders)
-rw-r--r--cdumb.c2
-rw-r--r--cgme.c2
-rw-r--r--csid.cpp2
-rw-r--r--deadbeef.h8
-rw-r--r--main.c7
-rw-r--r--playlist.c38
-rw-r--r--playlist.h3
-rw-r--r--plugins.c60
-rw-r--r--plugins.h12
-rw-r--r--plugins/adplug/adplug-db.cpp2
-rw-r--r--plugins/cdda/cdda.c2
-rw-r--r--plugins/ffap/ffap.c2
-rw-r--r--plugins/ffmpeg/ffmpeg.c2
-rw-r--r--plugins/flac/flac.c2
-rw-r--r--plugins/gtkui/callbacks.c5
-rw-r--r--plugins/gtkui/gtkui.c60
-rw-r--r--plugins/mpgmad/mpgmad.c4
-rw-r--r--plugins/sndfile/sndfile.c2
-rw-r--r--plugins/vorbis/vorbis.c4
-rw-r--r--plugins/vtx/vtx.c2
-rw-r--r--plugins/wavpack/wavpack.c2
-rw-r--r--streamer.c65
-rw-r--r--streamer.h3
23 files changed, 192 insertions, 99 deletions
diff --git a/cdumb.c b/cdumb.c
index 549063ad..1b85450f 100644
--- a/cdumb.c
+++ b/cdumb.c
@@ -773,7 +773,7 @@ cdumb_insert (DB_playItem_t *after, const char *fname) {
return NULL;
}
DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder = &plugin;
+ it->decoder_id = deadbeef->plug_get_decoder_id (plugin.id);
it->fname = strdup (fname);
DUMB_IT_SIGDATA * itsd = duh_get_it_sigdata(duh);
if (itsd->name[0]) {
diff --git a/cgme.c b/cgme.c
index 26e2e027..f89f9175 100644
--- a/cgme.c
+++ b/cgme.c
@@ -114,7 +114,7 @@ cgme_insert (DB_playItem_t *after, const char *fname) {
const char *ret = gme_track_info (emu, &inf, i);
if (!ret) {
DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder = &plugin;
+ it->decoder_id = deadbeef->plug_get_decoder_id (plugin.id);
it->fname = strdup (fname);
char str[1024];
if (inf.song[0]) {
diff --git a/csid.cpp b/csid.cpp
index b6903c92..b0e4d6e4 100644
--- a/csid.cpp
+++ b/csid.cpp
@@ -528,7 +528,7 @@ csid_insert (DB_playItem_t *after, const char *fname) {
for (int s = 0; s < tunes; s++) {
if (tune->selectSong (s+1)) {
DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder = &plugin;
+ it->decoder_id = deadbeef->plug_get_decoder_id (plugin.id);
it->fname = strdup (fname);
it->tracknum = s;
SidTuneInfo sidinfo;
diff --git a/deadbeef.h b/deadbeef.h
index bfa4b9ba..98e0ca96 100644
--- a/deadbeef.h
+++ b/deadbeef.h
@@ -65,6 +65,8 @@ extern "C" {
.plugin.api_vmajor = DB_API_VERSION_MAJOR,\
.plugin.api_vminor = DB_API_VERSION_MINOR,
+#define MAX_OUTPUT_PLUGINS 30
+
////////////////////////////
// playlist structures
@@ -77,7 +79,8 @@ extern "C" {
// these are "public" fields, available to plugins
typedef struct {
char *fname; // full pathname
- struct DB_decoder_s *decoder; // codec to use with this file
+// struct DB_decoder_s *decoder; // codec to use with this file
+ const char *decoder_id;
int tracknum; // used for stuff like sid, nsf, cue (will be ignored by most codecs)
int startsample; // start sample of track, or -1 for auto
int endsample; // end sample of track, or -1 for auto
@@ -246,6 +249,7 @@ typedef struct {
int (*streamer_read) (char *bytes, int size);
void (*streamer_set_bitrate) (int bitrate);
int (*streamer_get_apx_bitrate) (void);
+ struct DB_decoder_s *(*streamer_get_current_decoder) (void);
// process control
const char *(*get_config_dir) (void);
void (*quit) (void);
@@ -376,6 +380,8 @@ typedef struct {
struct DB_output_s **(*plug_get_output_list) (void);
struct DB_plugin_s **(*plug_get_list) (void);
int (*plug_activate) (struct DB_plugin_s *p, int activate);
+ const char * (*plug_get_decoder_id) (const char *id);
+ void (*plug_remove_decoder_id) (const char *id);
} DB_functions_t;
// base plugin interface
diff --git a/main.c b/main.c
index e4b672b5..73552cb6 100644
--- a/main.c
+++ b/main.c
@@ -127,7 +127,8 @@ server_exec_command_line (const char *cmdline, int len, char *sendback, int sbsi
}
if (sendback) {
playItem_t *curr = streamer_get_playing_track ();
- if (curr && curr->decoder) {
+ DB_decoder_t *dec = streamer_get_current_decoder ();
+ if (curr && dec) {
const char np[] = "nowplaying ";
memcpy (sendback, np, sizeof (np)-1);
pl_format_title (curr, sendback+sizeof(np)-1, sbsize-sizeof(np)+1, -1, parg);
@@ -139,7 +140,8 @@ server_exec_command_line (const char *cmdline, int len, char *sendback, int sbsi
else {
char out[2048];
playItem_t *curr = streamer_get_playing_track ();
- if (curr && curr->decoder) {
+ DB_decoder_t *dec = streamer_get_current_decoder ();
+ if (curr && dec) {
pl_format_title (curr, out, sizeof (out), -1, parg);
}
else {
@@ -589,6 +591,7 @@ main (int argc, char *argv[]) {
conf_free ();
messagepump_free ();
plt_free ();
+ plug_free_decoder_ids ();
sigterm_handled = 1;
fprintf (stderr, "hej-hej!\n");
return 0;
diff --git a/playlist.c b/playlist.c
index fff1dbb9..62ea6a7a 100644
--- a/playlist.c
+++ b/playlist.c
@@ -254,7 +254,7 @@ pl_cue_parse_time (const char *p) {
}
static playItem_t *
-pl_process_cue_track (playItem_t *after, const char *fname, playItem_t **prev, char *track, char *index00, char *index01, char *pregap, char *title, char *performer, char *albumtitle, char *genre, char *date, struct DB_decoder_s *decoder, const char *ftype, int samplerate) {
+pl_process_cue_track (playItem_t *after, const char *fname, playItem_t **prev, char *track, char *index00, char *index01, char *pregap, char *title, char *performer, char *albumtitle, char *genre, char *date, const char *decoder_id, const char *ftype, int samplerate) {
if (!track[0]) {
return after;
}
@@ -318,7 +318,7 @@ pl_process_cue_track (playItem_t *after, const char *fname, playItem_t **prev, c
}
playItem_t *it = malloc (sizeof (playItem_t));
memset (it, 0, sizeof (playItem_t));
- it->decoder = decoder;
+ it->decoder_id = plug_get_decoder_id (decoder_id);
it->fname = strdup (fname);
it->tracknum = atoi (track);
it->startsample = index01[0] ? f_index01 * samplerate : 0;
@@ -404,7 +404,7 @@ pl_insert_cue_from_buffer (playItem_t *after, playItem_t *origin, const uint8_t
}
else if (!strncmp (p, "TRACK ", 6)) {
// add previous track
- after = pl_process_cue_track (after, origin->fname, &prev, track, index00, index01, pregap, title, performer, albumtitle, genre, date, origin->decoder, origin->filetype, samplerate);
+ after = pl_process_cue_track (after, origin->fname, &prev, track, index00, index01, pregap, title, performer, albumtitle, genre, date, origin->decoder_id, origin->filetype, samplerate);
track[0] = 0;
title[0] = 0;
pregap[0] = 0;
@@ -430,7 +430,7 @@ pl_insert_cue_from_buffer (playItem_t *after, playItem_t *origin, const uint8_t
// fprintf (stderr, "got unknown line:\n%s\n", p);
}
}
- after = pl_process_cue_track (after, origin->fname, &prev, track, index00, index01, pregap, title, performer, albumtitle, genre, date, origin->decoder, origin->filetype, samplerate);
+ after = pl_process_cue_track (after, origin->fname, &prev, track, index00, index01, pregap, title, performer, albumtitle, genre, date, origin->decoder_id, origin->filetype, samplerate);
if (after) {
trace ("last track endsample: %d\n", numsamples-1);
after->endsample = numsamples-1;
@@ -723,7 +723,7 @@ pl_insert_file (playItem_t *after, const char *fname, int *pabort, int (*cb)(pla
}
if (detect_on_access && *p == ':') {
playItem_t *it = pl_item_alloc ();
- it->decoder = NULL;
+ it->decoder_id = NULL;
it->fname = strdup (fname);
it->filetype = "content";
it->_duration = -1;
@@ -950,7 +950,7 @@ pl_insert_item (playItem_t *after, playItem_t *it) {
void
pl_item_copy (playItem_t *out, playItem_t *it) {
out->fname = strdup (it->fname);
- out->decoder = it->decoder;
+ out->decoder_id = it->decoder_id;
out->tracknum = it->tracknum;
out->startsample = it->startsample;
out->endsample = it->endsample;
@@ -1136,12 +1136,12 @@ pl_save (const char *fname) {
if (fwrite (it->fname, 1, l, fp) != l) {
goto save_fail;
}
- if (it->decoder) {
- ll = strlen (it->decoder->id);
+ if (it->decoder_id) {
+ ll = strlen (it->decoder_id);
if (fwrite (&ll, 1, 1, fp) != 1) {
goto save_fail;
}
- if (fwrite (it->decoder->id, 1, ll, fp) != ll) {
+ if (fwrite (it->decoder_id, 1, ll, fp) != ll) {
goto save_fail;
}
}
@@ -1226,7 +1226,6 @@ save_fail:
int
pl_load (const char *fname) {
pl_free ();
- DB_decoder_t **decoders = plug_get_decoder_list ();
uint8_t majorver;
uint8_t minorver;
playItem_t *it = NULL;
@@ -1287,17 +1286,13 @@ pl_load (const char *fname) {
goto load_fail;
}
decoder[ll] = 0;
- for (int c = 0; decoders[c]; c++) {
- if (!strcmp (decoder, decoders[c]->id)) {
- it->decoder = decoders[c];
- }
- }
+ it->decoder_id = plug_get_decoder_id (decoder);
// if (!it->decoder) {
// goto load_fail;
// }
}
else {
- it->decoder = NULL;
+ it->decoder_id = NULL;
}
// tracknum
if (fread (&l, 1, 2, fp) != 2) {
@@ -1332,11 +1327,12 @@ pl_load (const char *fname) {
if (!strcmp (ftype, "content")) {
it->filetype = "content";
}
- else {
- if (it->decoder && it->decoder->filetypes) {
- for (int i = 0; it->decoder->filetypes[i]; i++) {
- if (!strcasecmp (it->decoder->filetypes[i], ftype)) {
- it->filetype = it->decoder->filetypes[i];
+ else if (it->decoder_id) {
+ DB_decoder_t *dec = plug_get_decoder_for_id (it->decoder_id);
+ if (dec && dec->filetypes) {
+ for (int i = 0; dec->filetypes[i]; i++) {
+ if (!strcasecmp (dec->filetypes[i], ftype)) {
+ it->filetype = dec->filetypes[i];
break;
}
}
diff --git a/playlist.h b/playlist.h
index 26824f68..59c67139 100644
--- a/playlist.h
+++ b/playlist.h
@@ -31,7 +31,8 @@ typedef struct metaInfo_s {
typedef struct playItem_s {
char *fname; // full pathname
- struct DB_decoder_s *decoder; // codec to use with this file
+// struct DB_decoder_s *decoder; // codec to use with this file
+ const char *decoder_id;
int tracknum; // used for stuff like sid, nsf, cue (will be ignored by most codecs)
int startsample;
int endsample;
diff --git a/plugins.c b/plugins.c
index 633b85fe..8ce57d92 100644
--- a/plugins.c
+++ b/plugins.c
@@ -70,6 +70,7 @@ static DB_functions_t deadbeef_api = {
.streamer_read = streamer_read,
.streamer_set_bitrate = streamer_set_bitrate,
.streamer_get_apx_bitrate = streamer_get_apx_bitrate,
+ .streamer_get_current_decoder = streamer_get_current_decoder,
// process control
.get_config_dir = plug_get_config_dir,
.quit = plug_quit,
@@ -173,6 +174,8 @@ static DB_functions_t deadbeef_api = {
.plug_get_output_list = plug_get_output_list,
.plug_get_list = plug_get_list,
.plug_activate = plug_activate,
+ .plug_get_decoder_id = plug_get_decoder_id,
+ .plug_remove_decoder_id = plug_remove_decoder_id,
};
DB_functions_t *deadbeef = &deadbeef_api;
@@ -203,7 +206,6 @@ DB_decoder_t *g_decoder_plugins[MAX_DECODER_PLUGINS+1];
#define MAX_VFS_PLUGINS 10
DB_vfs_t *g_vfs_plugins[MAX_VFS_PLUGINS+1];
-#define MAX_OUTPUT_PLUGINS 10
DB_output_t *g_output_plugins[MAX_OUTPUT_PLUGINS+1];
DB_output_t *output_plugin = NULL;
@@ -730,3 +732,59 @@ plug_reinit_sound (void) {
p_play ();
}
}
+
+// list of all unique decoder ids used in current session
+static char *decoder_ids[MAX_OUTPUT_PLUGINS];
+
+const char *
+plug_get_decoder_id (const char *id) {
+ int i;
+ char **lastnull = NULL;
+ for (i = 0; i < MAX_OUTPUT_PLUGINS; i++) {
+ if (decoder_ids[i] && !strcmp (id, decoder_ids[i])) {
+ return decoder_ids[i];
+ }
+ else if (!lastnull && !decoder_ids[i]) {
+ lastnull = &decoder_ids[i];
+ }
+ }
+ if (!lastnull) {
+ return NULL;
+ }
+ char *newid = strdup (id);
+ *lastnull = newid;
+ return newid;
+}
+
+void
+plug_remove_decoder_id (const char *id) {
+ int i;
+ for (i = 0; i < MAX_OUTPUT_PLUGINS; i++) {
+ if (decoder_ids[i] && !strcmp (decoder_ids[i], id)) {
+ free (decoder_ids[i]);
+ decoder_ids[i] = NULL;
+ }
+ }
+}
+
+void
+plug_free_decoder_ids (void) {
+ int i;
+ for (i = 0; i < MAX_OUTPUT_PLUGINS; i++) {
+ if (decoder_ids[i]) {
+ free (decoder_ids[i]);
+ decoder_ids[i] = NULL;
+ }
+ }
+}
+
+DB_decoder_t *
+plug_get_decoder_for_id (const char *id) {
+ DB_decoder_t **plugins = plug_get_decoder_list ();
+ for (int c = 0; plugins[c]; c++) {
+ if (!strcmp (id, plugins[c]->id)) {
+ return plugins[c];
+ }
+ }
+ return NULL;
+}
diff --git a/plugins.h b/plugins.h
index 5efb593e..39380640 100644
--- a/plugins.h
+++ b/plugins.h
@@ -118,4 +118,16 @@ plug_reinit_sound (void);
int
plug_select_output (void);
+const char *
+plug_get_decoder_id (const char *id);
+
+void
+plug_remove_decoder_id (const char *id);
+
+void
+plug_free_decoder_ids (void);
+
+DB_decoder_t *
+plug_get_decoder_for_id (const char *id);
+
#endif // __PLUGINS_H
diff --git a/plugins/adplug/adplug-db.cpp b/plugins/adplug/adplug-db.cpp
index 9ce7ed0e..ba95739f 100644
--- a/plugins/adplug/adplug-db.cpp
+++ b/plugins/adplug/adplug-db.cpp
@@ -214,7 +214,7 @@ adplug_insert (DB_playItem_t *after, const char *fname) {
for (int i = 0; i < subsongs; i++) {
// prepare track for addition
DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder = &adplug_plugin;
+ it->decoder_id = deadbeef->plug_get_decoder_id (adplug_plugin.id);
it->fname = strdup (fname);
it->filetype = adplug_get_extension (fname);
it->tracknum = i;
diff --git a/plugins/cdda/cdda.c b/plugins/cdda/cdda.c
index a93fcf26..40764d0d 100644
--- a/plugins/cdda/cdda.c
+++ b/plugins/cdda/cdda.c
@@ -268,7 +268,7 @@ insert_single_track (CdIo_t* cdio, DB_playItem_t *after, const char* file, int t
sector_count = cdio_get_track_sec_count (cdio, track_nr);
DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder = &plugin;
+ it->decoder_id = deadbeef->plug_get_decoder_id (plugin.id);
it->fname = strdup (tmp);
it->filetype = "cdda";
deadbeef->pl_set_item_duration (it, (float)sector_count / 75.0);
diff --git a/plugins/ffap/ffap.c b/plugins/ffap/ffap.c
index c0b40ec4..89499d70 100644
--- a/plugins/ffap/ffap.c
+++ b/plugins/ffap/ffap.c
@@ -1682,7 +1682,7 @@ ffap_insert (DB_playItem_t *after, const char *fname) {
float duration = ape_ctx.totalsamples / (float)ape_ctx.samplerate;
DB_playItem_t *it = NULL;
it = deadbeef->pl_item_alloc ();
- it->decoder = &plugin;
+ it->decoder_id = deadbeef->plug_get_decoder_id (plugin.id);
it->fname = strdup (fname);
it->filetype = "APE";
deadbeef->pl_set_item_duration (it, duration);
diff --git a/plugins/ffmpeg/ffmpeg.c b/plugins/ffmpeg/ffmpeg.c
index d6f10b62..7db09b48 100644
--- a/plugins/ffmpeg/ffmpeg.c
+++ b/plugins/ffmpeg/ffmpeg.c
@@ -432,7 +432,7 @@ ffmpeg_insert (DB_playItem_t *after, const char *fname) {
}
DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder = &plugin;
+ it->decoder_id = deadbeef->plug_get_decoder_id (plugin.id);
it->fname = strdup (fname);
it->filetype = filetype;
diff --git a/plugins/flac/flac.c b/plugins/flac/flac.c
index d3424831..5b325ac9 100644
--- a/plugins/flac/flac.c
+++ b/plugins/flac/flac.c
@@ -576,7 +576,7 @@ cflac_insert (DB_playItem_t *after, const char *fname) {
FLAC__stream_decoder_set_md5_checking(decoder, 0);
FLAC__stream_decoder_set_metadata_respond_all (decoder);
it = deadbeef->pl_item_alloc ();
- it->decoder = &plugin;
+ it->decoder_id = deadbeef->plug_get_decoder_id (plugin.id);
it->fname = strdup (fname);
cb.it = it;
if (skip > 0) {
diff --git a/plugins/gtkui/callbacks.c b/plugins/gtkui/callbacks.c
index b1c1aff9..09b5b03d 100644
--- a/plugins/gtkui/callbacks.c
+++ b/plugins/gtkui/callbacks.c
@@ -1005,7 +1005,8 @@ seekbar_draw (GtkWidget *widget) {
return;
}
DB_playItem_t *trk = deadbeef->streamer_get_playing_track ();
- if (!trk->decoder || deadbeef->pl_get_item_duration (trk) < 0) {
+ DB_decoder_t *dec = deadbeef->streamer_get_current_decoder ();
+ if (!dec || deadbeef->pl_get_item_duration (trk) < 0) {
clearlooks_rounded_rectangle (cr, 2, widget->allocation.height/2-4, widget->allocation.width-4, 8, 4, 0xff);
theme_set_cairo_source_rgb (cr, COLO_SEEKBAR_FRONT);
cairo_stroke (cr);
@@ -1024,7 +1025,7 @@ seekbar_draw (GtkWidget *widget) {
pos = x;
}
else {
- if (trk->decoder && deadbeef->pl_get_item_duration (trk) > 0) {
+ if (dec && deadbeef->pl_get_item_duration (trk) > 0) {
pos = deadbeef->streamer_get_playpos () / deadbeef->pl_get_item_duration (trk);
pos *= widget->allocation.width;
}
diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c
index 73ca9670..4fa1cddb 100644
--- a/plugins/gtkui/gtkui.c
+++ b/plugins/gtkui/gtkui.c
@@ -81,38 +81,40 @@ update_songinfo (gpointer ctx) {
snprintf (sbtext_new, sizeof (sbtext_new), "Stopped | %d tracks | %s total playtime", deadbeef->pl_getcount (PL_MAIN), totaltime_str);
songpos = 0;
}
- else if (track->decoder) {
+ else {
// codec_lock ();
- DB_decoder_t *c = track->decoder;
- float playpos = deadbeef->streamer_get_playpos ();
- int minpos = playpos / 60;
- int secpos = playpos - minpos * 60;
- int mindur = duration / 60;
- int secdur = duration - mindur * 60;
-
- const char *mode = c->info.channels == 1 ? "Mono" : "Stereo";
- int samplerate = c->info.samplerate;
- int bitspersample = c->info.bps;
- songpos = playpos;
-// codec_unlock ();
-
- char t[100];
- if (duration >= 0) {
- snprintf (t, sizeof (t), "%d:%02d", mindur, secdur);
- }
- else {
- strcpy (t, "-:--");
- }
-
- char sbitrate[20] = "";
+ DB_decoder_t *c = deadbeef->streamer_get_current_decoder ();
+ if (c) {
+ float playpos = deadbeef->streamer_get_playpos ();
+ int minpos = playpos / 60;
+ int secpos = playpos - minpos * 60;
+ int mindur = duration / 60;
+ int secdur = duration - mindur * 60;
+
+ const char *mode = c->info.channels == 1 ? "Mono" : "Stereo";
+ int samplerate = c->info.samplerate;
+ int bitspersample = c->info.bps;
+ songpos = playpos;
+ // codec_unlock ();
+
+ char t[100];
+ if (duration >= 0) {
+ snprintf (t, sizeof (t), "%d:%02d", mindur, secdur);
+ }
+ else {
+ strcpy (t, "-:--");
+ }
+
+ char sbitrate[20] = "";
#if 1
- int bitrate = deadbeef->streamer_get_apx_bitrate ();
- if (bitrate > 0) {
- snprintf (sbitrate, sizeof (sbitrate), "| %d kbps ", bitrate);
- }
+ int bitrate = deadbeef->streamer_get_apx_bitrate ();
+ if (bitrate > 0) {
+ snprintf (sbitrate, sizeof (sbitrate), "| %d kbps ", bitrate);
+ }
#endif
- const char *spaused = deadbeef->get_output ()->state () == OUTPUT_STATE_PAUSED ? "Paused | " : "";
- snprintf (sbtext_new, sizeof (sbtext_new), "%s%s %s| %dHz | %d bit | %s | %d:%02d / %s | %d tracks | %s total playtime", spaused, track->filetype ? track->filetype:"-", sbitrate, samplerate, bitspersample, mode, minpos, secpos, t, deadbeef->pl_getcount (PL_MAIN), totaltime_str);
+ const char *spaused = deadbeef->get_output ()->state () == OUTPUT_STATE_PAUSED ? "Paused | " : "";
+ snprintf (sbtext_new, sizeof (sbtext_new), "%s%s %s| %dHz | %d bit | %s | %d:%02d / %s | %d tracks | %s total playtime", spaused, track->filetype ? track->filetype:"-", sbitrate, samplerate, bitspersample, mode, minpos, secpos, t, deadbeef->pl_getcount (PL_MAIN), totaltime_str);
+ }
}
if (strcmp (sbtext_new, sb_text)) {
diff --git a/plugins/mpgmad/mpgmad.c b/plugins/mpgmad/mpgmad.c
index 0dec44d0..49754dfa 100644
--- a/plugins/mpgmad/mpgmad.c
+++ b/plugins/mpgmad/mpgmad.c
@@ -956,7 +956,7 @@ cmp3_insert (DB_playItem_t *after, const char *fname) {
}
if (fp->vfs->streaming) {
DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder = &plugin;
+ it->decoder_id = deadbeef->plug_get_decoder_id (plugin.id);
it->fname = strdup (fname);
deadbeef->fclose (fp);
deadbeef->pl_add_meta (it, "title", NULL);
@@ -1020,7 +1020,7 @@ cmp3_insert (DB_playItem_t *after, const char *fname) {
}
}
DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder = &plugin;
+ it->decoder_id = deadbeef->plug_get_decoder_id (plugin.id);
it->fname = strdup (fname);
deadbeef->rewind (fp);
diff --git a/plugins/sndfile/sndfile.c b/plugins/sndfile/sndfile.c
index 99f717cc..72864c56 100644
--- a/plugins/sndfile/sndfile.c
+++ b/plugins/sndfile/sndfile.c
@@ -205,7 +205,7 @@ sndfile_insert (DB_playItem_t *after, const char *fname) {
float duration = (float)totalsamples / samplerate;
DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder = &plugin;
+ it->decoder_id = deadbeef->plug_get_decoder_id (plugin.id);
it->fname = strdup (fname);
it->filetype = "wav";
deadbeef->pl_set_item_duration (it, duration);
diff --git a/plugins/vorbis/vorbis.c b/plugins/vorbis/vorbis.c
index 9a631a73..d0620d6e 100644
--- a/plugins/vorbis/vorbis.c
+++ b/plugins/vorbis/vorbis.c
@@ -337,7 +337,7 @@ cvorbis_insert (DB_playItem_t *after, const char *fname) {
}
if (fp->vfs->streaming) {
DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder = &plugin;
+ it->decoder_id = deadbeef->plug_get_decoder_id (plugin.id);
it->fname = strdup (fname);
it->filetype = "OggVorbis";
deadbeef->pl_set_item_duration (it, -1);
@@ -367,7 +367,7 @@ cvorbis_insert (DB_playItem_t *after, const char *fname) {
int totalsamples = ov_pcm_total (&vorbis_file, -1);
DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder = &plugin;
+ it->decoder_id = deadbeef->plug_get_decoder_id (plugin.id);
it->fname = strdup (fname);
it->filetype = "OggVorbis";
deadbeef->pl_set_item_duration (it, duration);
diff --git a/plugins/vtx/vtx.c b/plugins/vtx/vtx.c
index cbf63e61..93c4155e 100644
--- a/plugins/vtx/vtx.c
+++ b/plugins/vtx/vtx.c
@@ -242,7 +242,7 @@ vtx_insert (DB_playItem_t *after, const char *fname) {
DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder = &plugin;
+ it->decoder_id = deadbeef->plug_get_decoder_id (plugin.id);
it->fname = strdup (fname);
it->filetype = filetypes[0];
diff --git a/plugins/wavpack/wavpack.c b/plugins/wavpack/wavpack.c
index ab876b97..ca494d85 100644
--- a/plugins/wavpack/wavpack.c
+++ b/plugins/wavpack/wavpack.c
@@ -226,7 +226,7 @@ wv_insert (DB_playItem_t *after, const char *fname) {
float duration = (float)totalsamples / samplerate;
DB_playItem_t *it = deadbeef->pl_item_alloc ();
- it->decoder = &plugin;
+ it->decoder_id = deadbeef->plug_get_decoder_id (plugin.id);
it->fname = strdup (fname);
it->filetype = "wv";
deadbeef->pl_set_item_duration (it, duration);
diff --git a/streamer.c b/streamer.c
index 7e3c33ca..d84922e0 100644
--- a/streamer.c
+++ b/streamer.c
@@ -82,11 +82,14 @@ static int last_bitrate = -1; // last bitrate of current song
static int prevtrack_samplerate = -1;
+// copies of current playing and streaming tracks
playItem_t str_playing_song;
playItem_t str_streaming_song;
// remember pointers to original instances of playitems
static playItem_t *orig_playing_song;
static playItem_t *orig_streaming_song;
+// current decoder
+static DB_decoder_t *str_current_decoder;
static int streamer_buffering;
@@ -140,15 +143,17 @@ streamer_set_current (playItem_t *it) {
}
#endif
trace ("streamer_set_current %p, buns=%d\n", it);
- if(str_streaming_song.decoder) {
- str_streaming_song.decoder->free ();
+ if(str_current_decoder) {
+ str_current_decoder->free ();
+ str_current_decoder = NULL;
pl_item_free (&str_streaming_song);
}
orig_streaming_song = it;
if (!it) {
goto success;
}
- if (!it->decoder && it->filetype && !strcmp (it->filetype, "content")) {
+ DB_decoder_t *dec = NULL;
+ if (!it->decoder_id && it->filetype && !strcmp (it->filetype, "content")) {
// try to get content-type
DB_FILE *fp = streamer_file = vfs_fopen (it->fname);
const char *plug = NULL;
@@ -167,24 +172,26 @@ streamer_set_current (playItem_t *it) {
vfs_fclose (fp);
}
if (plug) {
- DB_decoder_t **decoders = plug_get_decoder_list ();
- // match by decoder
- for (int i = 0; decoders[i]; i++) {
- if (!strcmp (decoders[i]->id, plug)) {
- it->decoder = decoders[i];
- it->filetype = decoders[i]->filetypes[0];
- }
+ dec = plug_get_decoder_for_id (plug);
+ if (dec) {
+ it->decoder_id = plug_get_decoder_id (plug);
+ it->filetype = dec->filetypes[0];
}
}
}
- if (it->decoder) {
+ else if (it->decoder_id) {
+ dec = plug_get_decoder_for_id (it->decoder_id);
+ }
+ if (dec) {
+ str_current_decoder = dec;
streamer_lock ();
streamer_unlock ();
- int ret = it->decoder->init (DB_PLAYITEM (it));
+ int ret = str_current_decoder->init (DB_PLAYITEM (it));
streamer_lock ();
streamer_unlock ();
pl_item_copy (&str_streaming_song, it);
if (ret < 0) {
+ str_current_decoder = NULL;
trace ("decoder->init returned %d\n", ret);
trace ("orig_playing_song = %p\n", orig_playing_song);
if (orig_playing_song == it) {
@@ -194,7 +201,7 @@ streamer_set_current (playItem_t *it) {
return ret;
}
else {
- trace ("bps=%d, channels=%d, samplerate=%d\n", it->decoder->info.bps, it->decoder->info.channels, it->decoder->info.samplerate);
+ trace ("bps=%d, channels=%d, samplerate=%d\n", dec->info.bps, dec->info.channels, dec->info.samplerate);
}
streamer_reset (0); // reset SRC
}
@@ -318,7 +325,7 @@ streamer_thread (void *ctx) {
trace ("nextsong=-2\n");
nextsong = -1;
p_stop ();
- if (str_playing_song.decoder) {
+ if (str_current_decoder) {
trace ("sending songfinished to plugins [1]\n");
plug_trigger_event (DB_EV_SONGFINISHED, 0);
}
@@ -349,7 +356,7 @@ streamer_thread (void *ctx) {
messagepump_push (M_SONGCHANGED, 0, from, to);
bytes_until_next_song = -1;
// plugin will get pointer to str_playing_song
- if (str_playing_song.decoder) {
+ if (str_current_decoder) {
trace ("sending songfinished to plugins [2]\n");
plug_trigger_event (DB_EV_SONGFINISHED, 0);
}
@@ -371,9 +378,9 @@ streamer_thread (void *ctx) {
plug_trigger_event (DB_EV_SONGSTARTED, 0);
playpos = 0;
// change samplerate
- if (prevtrack_samplerate != str_playing_song.decoder->info.samplerate) {
- plug_get_output ()->change_rate (str_playing_song.decoder->info.samplerate);
- prevtrack_samplerate = str_playing_song.decoder->info.samplerate;
+ if (prevtrack_samplerate != str_current_decoder->info.samplerate) {
+ plug_get_output ()->change_rate (str_current_decoder->info.samplerate);
+ prevtrack_samplerate = str_current_decoder->info.samplerate;
}
}
@@ -385,8 +392,8 @@ streamer_thread (void *ctx) {
if (orig_playing_song != orig_streaming_song) {
trace ("streamer already switched to next track\n");
// restart playing from new position
- if(str_streaming_song.decoder) {
- str_streaming_song.decoder->free ();
+ if(str_current_decoder) {
+ str_current_decoder->free ();
pl_item_free (&str_streaming_song);
}
orig_streaming_song = orig_playing_song;
@@ -397,7 +404,7 @@ streamer_thread (void *ctx) {
if (trk != -1) {
messagepump_push (M_TRACKCHANGED, 0, trk, 0);
}
- int ret = str_streaming_song.decoder->init (DB_PLAYITEM (orig_streaming_song));
+ int ret = str_current_decoder->init (DB_PLAYITEM (orig_streaming_song));
if (ret < 0) {
streamer_buffering = 0;
if (trk != -1) {
@@ -416,15 +423,15 @@ streamer_thread (void *ctx) {
if (trk != -1) {
messagepump_push (M_TRACKCHANGED, 0, trk, 0);
}
- if (str_playing_song.decoder && str_playing_song._duration > 0) {
+ if (str_current_decoder && str_playing_song._duration > 0) {
streamer_lock ();
streambuffer_fill = 0;
streambuffer_pos = 0;
codec_lock ();
codecleft = 0;
codec_unlock ();
- if (str_playing_song.decoder->seek (pos) >= 0) {
- playpos = str_playing_song.decoder->info.readpos;
+ if (str_current_decoder->seek (pos) >= 0) {
+ playpos = str_current_decoder->info.readpos;
}
last_bitrate = -1;
avg_bitrate = -1;
@@ -467,8 +474,8 @@ streamer_thread (void *ctx) {
}
// stop streaming song
- if(str_streaming_song.decoder) {
- str_streaming_song.decoder->free ();
+ if(str_current_decoder) {
+ str_current_decoder->free ();
}
pl_item_free (&str_streaming_song);
pl_item_free (&str_playing_song);
@@ -663,7 +670,7 @@ streamer_read_async (char *bytes, int size) {
for (;;) {
int bytesread = 0;
codec_lock ();
- DB_decoder_t *decoder = str_streaming_song.decoder;
+ DB_decoder_t *decoder = str_current_decoder;
if (!decoder) {
// means there's nothing left to stream, so just do nothing
codec_unlock ();
@@ -1162,3 +1169,7 @@ streamer_get_current (void) {
return orig_playing_song;
}
+struct DB_decoder_s *
+streamer_get_current_decoder (void) {
+ return str_current_decoder;
+}
diff --git a/streamer.h b/streamer.h
index 1c31098b..a74eeb7a 100644
--- a/streamer.h
+++ b/streamer.h
@@ -98,4 +98,7 @@ streamer_move_randomsong (void);
playItem_t *
streamer_get_current (void);
+struct DB_decoder_s *
+streamer_get_current_decoder (void);
+
#endif // __STREAMER_H