diff options
author | Alexey Yakovenko <wakeroid@gmail.com> | 2010-01-11 20:41:38 +0100 |
---|---|---|
committer | Alexey Yakovenko <wakeroid@gmail.com> | 2010-01-11 20:41:38 +0100 |
commit | 1c328c9601ff4d9771ba1bf99f0f42c3caf32297 (patch) | |
tree | 1b960a7586346ddb4d3b7babe9e31733454cf337 | |
parent | 8f873b3b3a992da897a029a1cf19b32168440f39 (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.c | 2 | ||||
-rw-r--r-- | cgme.c | 2 | ||||
-rw-r--r-- | csid.cpp | 2 | ||||
-rw-r--r-- | deadbeef.h | 8 | ||||
-rw-r--r-- | main.c | 7 | ||||
-rw-r--r-- | playlist.c | 38 | ||||
-rw-r--r-- | playlist.h | 3 | ||||
-rw-r--r-- | plugins.c | 60 | ||||
-rw-r--r-- | plugins.h | 12 | ||||
-rw-r--r-- | plugins/adplug/adplug-db.cpp | 2 | ||||
-rw-r--r-- | plugins/cdda/cdda.c | 2 | ||||
-rw-r--r-- | plugins/ffap/ffap.c | 2 | ||||
-rw-r--r-- | plugins/ffmpeg/ffmpeg.c | 2 | ||||
-rw-r--r-- | plugins/flac/flac.c | 2 | ||||
-rw-r--r-- | plugins/gtkui/callbacks.c | 5 | ||||
-rw-r--r-- | plugins/gtkui/gtkui.c | 60 | ||||
-rw-r--r-- | plugins/mpgmad/mpgmad.c | 4 | ||||
-rw-r--r-- | plugins/sndfile/sndfile.c | 2 | ||||
-rw-r--r-- | plugins/vorbis/vorbis.c | 4 | ||||
-rw-r--r-- | plugins/vtx/vtx.c | 2 | ||||
-rw-r--r-- | plugins/wavpack/wavpack.c | 2 | ||||
-rw-r--r-- | streamer.c | 65 | ||||
-rw-r--r-- | streamer.h | 3 |
23 files changed, 192 insertions, 99 deletions
@@ -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]) { @@ -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]) { @@ -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; @@ -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 @@ -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; @@ -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; } } @@ -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; @@ -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; +} @@ -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); @@ -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; +} @@ -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 |