summaryrefslogtreecommitdiff
path: root/playlist.c
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2011-10-23 11:50:41 +0200
committerGravatar waker <wakeroid@gmail.com>2011-10-23 11:50:41 +0200
commita9c813ddbda28a2d0beff104fe8cf80299292533 (patch)
tree5630dfd20c5e4484148dc4fde06fdb2a0e9aeefa /playlist.c
parent2f2937a5554d4cdca177eb546a0e0c449b16c700 (diff)
parent50208fdf54d7afaf8b42abc511ddc675b9475184 (diff)
Merge branch 'master' into devel
Conflicts: deadbeef.h metacache.c playlist.c plugins.c plugins/gtkui/Makefile.am plugins/gtkui/ddbcellrenderertextmultiline.c plugins/gtkui/ddbcellrenderertextmultiline.h plugins/gtkui/ddbequalizer.c plugins/gtkui/ddbequalizer.h plugins/gtkui/ddbseekbar.c plugins/gtkui/ddbseekbar.h plugins/gtkui/ddbtabstrip.c plugins/gtkui/fileman.c plugins/gtkui/gtkui.c plugins/gtkui/interface.c plugins/gtkui/plcommon.c plugins/gtkui/trkproperties.c
Diffstat (limited to 'playlist.c')
-rw-r--r--playlist.c160
1 files changed, 97 insertions, 63 deletions
diff --git a/playlist.c b/playlist.c
index da4ea15f..5acbf680 100644
--- a/playlist.c
+++ b/playlist.c
@@ -79,6 +79,7 @@
#define trace(fmt,...)
#define SKIP_BLANK_CUE_TRACKS 0
+#define MAX_CUE_TRACKS 99
#define min(x,y) ((x)<(y)?(x):(y))
@@ -145,7 +146,7 @@ pl_free (void) {
for (playItem_t *it = playlists_head->head[PL_MAIN]; it; it = it->next[PL_MAIN]) {
if (it->_refc > 1) {
- fprintf (stderr, "\033[0;31mWARNING: playitem %p %s has refc=%d at delete time\033[37;0m\n", it, pl_find_meta (it, ":URI"), it->_refc);
+ fprintf (stderr, "\033[0;31mWARNING: playitem %p %s(%s) has refc=%d at delete time\033[37;0m\n", it, pl_find_meta_raw (it, ":URI"), pl_find_meta_raw (it, "track"), it->_refc);
}
}
@@ -876,19 +877,19 @@ pl_cue_parse_time (const char *p) {
}
static playItem_t *
-plt_process_cue_track (playlist_t *playlist, playItem_t *after, const char *fname, playItem_t **prev, char *track, char *index00, char *index01, char *pregap, char *title, char *albumperformer, char *performer, char *albumtitle, char *genre, char *date, char *replaygain_album_gain, char *replaygain_album_peak, char *replaygain_track_gain, char *replaygain_track_peak, const char *decoder_id, const char *ftype, int samplerate) {
+plt_process_cue_track (playlist_t *playlist, const char *fname, playItem_t **prev, char *track, char *index00, char *index01, char *pregap, char *title, char *albumperformer, char *performer, char *albumtitle, char *genre, char *date, char *replaygain_album_gain, char *replaygain_album_peak, char *replaygain_track_gain, char *replaygain_track_peak, const char *decoder_id, const char *ftype, int samplerate) {
if (!track[0]) {
trace ("pl_process_cue_track: invalid track (file=%s, title=%s)\n", fname, title);
- return after;
+ return NULL;
}
if (!index00[0] && !index01[0]) {
trace ("pl_process_cue_track: invalid index (file=%s, title=%s, track=%s)\n", fname, title, track);
- return after;
+ return NULL;
}
#if SKIP_BLANK_CUE_TRACKS
if (!title[0]) {
trace ("pl_process_cue_track: invalid title (file=%s, title=%s, track=%s)\n", fname, title, track);
- return after;
+ return NULL;
}
#endif
// fix track number
@@ -917,7 +918,7 @@ plt_process_cue_track (playlist_t *playlist, playItem_t *after, const char *fnam
}
else {
trace ("pl_process_cue_track: invalid pregap or index01 (pregap=%s, index01=%s)\n", pregap, index01);
- return after;
+ return NULL;
}
(*prev)->endsample = (prevtime * samplerate) - 1;
plt_set_item_duration (playlist, *prev, (float)((*prev)->endsample - (*prev)->startsample + 1) / samplerate);
@@ -942,7 +943,7 @@ plt_process_cue_track (playlist_t *playlist, playItem_t *after, const char *fnam
if (!index01[0]) {
*prev = NULL;
trace ("pl_process_cue_track: invalid index01 (pregap=%s, index01=%s)\n", pregap, index01);
- return after;
+ return NULL;
}
playItem_t *it = pl_item_alloc_init (fname, decoder_id);
pl_set_meta_int (it, ":TRACKNUM", atoi (track));
@@ -986,8 +987,6 @@ plt_process_cue_track (playlist_t *playlist, playItem_t *after, const char *fnam
pl_set_item_replaygain (it, DDB_REPLAYGAIN_TRACKPEAK, atof (replaygain_track_peak));
}
it->_flags |= DDB_IS_SUBTRACK | DDB_TAG_CUESHEET;
- after = plt_insert_item (playlist, after, it);
- pl_item_unref (it);
*prev = it;
return it;
}
@@ -1011,6 +1010,11 @@ plt_insert_cue_from_buffer (playlist_t *playlist, playItem_t *after, playItem_t
char replaygain_album_peak[256] = "";
char replaygain_track_gain[256] = "";
char replaygain_track_peak[256] = "";
+ const char *filetype = pl_find_meta_raw (origin, ":FILETYPE");
+
+ playItem_t *cuetracks[MAX_CUE_TRACKS];
+ int ncuetracks = 0;
+
playItem_t *prev = NULL;
while (buffersize > 0) {
const uint8_t *p = buffer;
@@ -1060,12 +1064,17 @@ plt_insert_cue_from_buffer (playlist_t *playlist, playItem_t *after, playItem_t
pl_get_value_from_cue (p + 9, sizeof (date), date);
}
else if (!strncmp (p, "TRACK ", 6)) {
- trace ("cue: adding track: %s %s %s\n", pl_find_meta (origin, ":URI"), title, track);
+ trace ("cue: adding track: %s %s %s\n", pl_find_meta_raw (origin, ":URI"), title, track);
if (title[0]) {
// add previous track
- const char *filetype = pl_find_meta (origin, ":FILETYPE");
- after = plt_process_cue_track (playlist, after, pl_find_meta (origin, ":URI"), &prev, track, index00, index01, pregap, title, albumperformer, performer, albumtitle, genre, date, replaygain_album_gain, replaygain_album_peak, replaygain_track_gain, replaygain_track_peak, pl_find_meta (origin, ":DECODER"), filetype, samplerate);
- trace ("cue: added %p (%p)\n", after);
+ playItem_t *it = plt_process_cue_track (playlist, pl_find_meta_raw (origin, ":URI"), &prev, track, index00, index01, pregap, title, albumperformer, performer, albumtitle, genre, date, replaygain_album_gain, replaygain_album_peak, replaygain_track_gain, replaygain_track_peak, pl_find_meta_raw (origin, ":DECODER"), filetype, samplerate);
+ trace ("cue: added %p\n", it);
+ if (it) {
+ if (it->startsample >= numsamples || it->endsample >= numsamples) {
+ goto error;
+ }
+ cuetracks[ncuetracks++] = it;
+ }
}
track[0] = 0;
@@ -1108,34 +1117,57 @@ plt_insert_cue_from_buffer (playlist_t *playlist, playItem_t *after, playItem_t
UNLOCK;
return NULL;
}
- const char *filetype = pl_find_meta (origin, ":FILETYPE");
- after = plt_process_cue_track (playlist, after, pl_find_meta (origin, ":URI"), &prev, track, index00, index01, pregap, title, albumperformer, performer, albumtitle, genre, date, replaygain_album_gain, replaygain_album_peak, replaygain_track_gain, replaygain_track_peak, pl_find_meta (origin, ":DECODER"), filetype, samplerate);
- if (after) {
+ // handle last track
+ playItem_t *it = plt_process_cue_track (playlist, pl_find_meta_raw (origin, ":URI"), &prev, track, index00, index01, pregap, title, albumperformer, performer, albumtitle, genre, date, replaygain_album_gain, replaygain_album_peak, replaygain_track_gain, replaygain_track_peak, pl_find_meta_raw (origin, ":DECODER"), filetype, samplerate);
+ if (it) {
trace ("last track endsample: %d\n", numsamples-1);
- after->endsample = numsamples-1;
- plt_set_item_duration (playlist, after, (float)(after->endsample - after->startsample + 1) / samplerate);
+ it->endsample = numsamples-1;
+ if (it->endsample >= numsamples || it->startsample >= numsamples) {
+ goto error;
+ }
+ plt_set_item_duration (playlist, it, (float)(it->endsample - it->startsample + 1) / samplerate);
+ cuetracks[ncuetracks++] = it;
+ }
+
+ if (!ncuetracks) {
+ UNLOCK;
+ return NULL;
}
- // add caller ref
- if (after && after != ins) {
- pl_item_ref (after);
+
+ playItem_t *last = cuetracks[ncuetracks-1];
+ pl_item_ref (last);
+
+ for (int i = 0; i < ncuetracks; i++) {
+ after = plt_insert_item (playlist, after, cuetracks[i]);
+ pl_item_unref (cuetracks[i]);
}
- // copy metadata from embedded tags
playItem_t *first = ins ? ins->next[PL_MAIN] : playlist->head[PL_MAIN];
+ if (!first) {
+ UNLOCK;
+ return NULL;
+ }
+ // copy metadata from embedded tags
uint32_t f = pl_get_item_flags (origin);
f |= DDB_TAG_CUESHEET | DDB_IS_SUBTRACK;
- if (pl_find_meta (origin, "cuesheet")) {
+ if (pl_find_meta_raw (origin, "cuesheet")) {
f |= DDB_HAS_EMBEDDED_CUESHEET;
}
pl_set_item_flags (origin, f);
pl_items_copy_junk (origin, first, after);
UNLOCK;
return after;
+error:
+ for (int i = 0; i < ncuetracks; i++) {
+ pl_item_unref (cuetracks[i]);
+ }
+ UNLOCK;
+ return NULL;
}
playItem_t *
plt_insert_cue (playlist_t *plt, playItem_t *after, playItem_t *origin, int numsamples, int samplerate) {
trace ("pl_insert_cue numsamples=%d, samplerate=%d\n", numsamples, samplerate);
- const char *fname = pl_find_meta (origin, ":URI");
+ const char *fname = pl_find_meta_raw (origin, ":URI");
int len = strlen (fname);
char cuename[len+5];
strcpy (cuename, fname);
@@ -1170,6 +1202,7 @@ plt_insert_cue (playlist_t *plt, playItem_t *after, playItem_t *origin, int nums
return plt_insert_cue_from_buffer (plt, after, origin, buf, sz, numsamples, samplerate);
}
+#if 0
playItem_t *
plt_insert_m3u (playlist_t *plt, playItem_t *after, const char *fname, int *pabort, int (*cb)(playItem_t *it, void *data), void *user_data) {
trace ("enter pl_insert_m3u\n");
@@ -1426,6 +1459,7 @@ plt_insert_pls (playlist_t *playlist, playItem_t *after, const char *fname, int
}
return after;
}
+#endif
static int follow_symlinks = 0;
static int ignore_archives = 0;
@@ -1472,7 +1506,7 @@ plt_insert_file (playlist_t *playlist, playItem_t *after, const char *fname, int
else {
fn++;
}
-
+#if 0
// detect pls/m3u files
// they must be handled before checking for http://,
// so that remote playlist files referenced from other playlist files could
@@ -1484,6 +1518,7 @@ plt_insert_file (playlist_t *playlist, playItem_t *after, const char *fname, int
return plt_insert_pls (playlist, after, fname, pabort, cb, user_data);
}
+#endif
// add all posible streams as special-case:
// set decoder to NULL, and filetype to "content"
@@ -1718,10 +1753,9 @@ plt_remove_item (playlist_t *playlist, playItem_t *it) {
if (!no_remove_notify) {
streamer_song_removed_notify (it);
+ pl_playqueue_remove (it);
}
- pl_playqueue_remove (it);
-
// remove from both lists
LOCK;
for (int iter = PL_MAIN; iter <= PL_SEARCH; iter++) {
@@ -1887,7 +1921,7 @@ plt_insert_item (playlist_t *playlist, playItem_t *after, playItem_t *it) {
// shuffle
playItem_t *prev = it->prev[PL_MAIN];
- if (pl_order == PLAYBACK_ORDER_SHUFFLE_ALBUMS && prev && pl_find_meta (prev, "album") == pl_find_meta (it, "album") && pl_find_meta (prev, "artist") == pl_find_meta (it, "artist")) {
+ if (pl_order == PLAYBACK_ORDER_SHUFFLE_ALBUMS && prev && pl_find_meta_raw (prev, "album") == pl_find_meta_raw (it, "album") && pl_find_meta_raw (prev, "artist") == pl_find_meta_raw (it, "artist")) {
it->shufflerating = prev->shufflerating;
}
else {
@@ -1966,7 +2000,7 @@ void
pl_item_ref (playItem_t *it) {
LOCK;
it->_refc++;
- //trace ("\033[0;34m+it %p: refc=%d: %s\033[37;0m\n", it, it->_refc, pl_find_meta (it, ":URI"));
+ //fprintf (stderr, "\033[0;34m+it %p: refc=%d: %s\033[37;0m\n", it, it->_refc, pl_find_meta_raw (it, ":URI"));
UNLOCK;
}
@@ -1990,12 +2024,12 @@ void
pl_item_unref (playItem_t *it) {
LOCK;
it->_refc--;
- //trace ("\033[0;31m-it %p: refc=%d: %s\033[37;0m\n", it, it->_refc, pl_find_meta (it, ":URI"));
+ //trace ("\033[0;31m-it %p: refc=%d: %s\033[37;0m\n", it, it->_refc, pl_find_meta_raw (it, ":URI"));
if (it->_refc < 0) {
trace ("\033[0;31mplaylist: bad refcount on item %p\033[37;0m\n", it);
}
if (it->_refc <= 0) {
- //printf ("\033[0;31mdeleted %s\033[37;0m\n", pl_find_meta (it, ":URI"));
+ //printf ("\033[0;31mdeleted %s\033[37;0m\n", pl_find_meta_raw (it, ":URI"));
pl_item_free (it);
}
UNLOCK;
@@ -2100,7 +2134,7 @@ plt_save (playlist_t *plt, playItem_t *first, playItem_t *last, const char *fnam
uint16_t l;
uint8_t ll;
#if (PLAYLIST_MINOR_VER==2)
- const char *fname = pl_find_meta (it, ":URI");
+ const char *fname = pl_find_meta_raw (it, ":URI");
l = strlen (fname);
if (fwrite (&l, 1, 2, fp) != 2) {
goto save_fail;
@@ -2108,7 +2142,7 @@ plt_save (playlist_t *plt, playItem_t *first, playItem_t *last, const char *fnam
if (fwrite (fname, 1, l, fp) != l) {
goto save_fail;
}
- const char *decoder_id = pl_find_meta (it, ":DECODER");
+ const char *decoder_id = pl_find_meta_raw (it, ":DECODER");
if (decoder_id) {
ll = strlen (decoder_id);
if (fwrite (&ll, 1, 1, fp) != 1) {
@@ -2140,7 +2174,7 @@ plt_save (playlist_t *plt, playItem_t *first, playItem_t *last, const char *fnam
goto save_fail;
}
#if (PLAYLIST_MINOR_VER==2)
- const char *filetype = pl_find_meta (it, ":FILETYPE");
+ const char *filetype = pl_find_meta_raw (it, ":FILETYPE");
if (!filetype) {
filetype = "";
}
@@ -2177,7 +2211,7 @@ plt_save (playlist_t *plt, playItem_t *first, playItem_t *last, const char *fnam
int16_t nm = 0;
DB_metaInfo_t *m;
for (m = it->meta; m; m = m->next) {
- if (m->key[0] == '_') {
+ if (m->key[0] == '_' || m->key[0] == '!') {
continue; // skip reserved names
}
nm++;
@@ -2186,7 +2220,7 @@ plt_save (playlist_t *plt, playItem_t *first, playItem_t *last, const char *fnam
goto save_fail;
}
for (m = it->meta; m; m = m->next) {
- if (m->key[0] == '_') {
+ if (m->key[0] == '_' || m->key[0] == '!') {
continue; // skip reserved names
}
@@ -2691,7 +2725,7 @@ plt_reshuffle (playlist_t *playlist, playItem_t **ppmin, playItem_t **ppmax) {
playItem_t *pmax = NULL;
playItem_t *prev = NULL;
for (playItem_t *it = playlist->head[PL_MAIN]; it; it = it->next[PL_MAIN]) {
- if (pl_order == PLAYBACK_ORDER_SHUFFLE_ALBUMS && prev && pl_find_meta (prev, "album") == pl_find_meta (it, "album") && pl_find_meta (prev, "artist") == pl_find_meta (it, "artist")) {
+ if (pl_order == PLAYBACK_ORDER_SHUFFLE_ALBUMS && prev && pl_find_meta_raw (prev, "album") == pl_find_meta_raw (it, "album") && pl_find_meta_raw (prev, "artist") == pl_find_meta_raw (it, "artist")) {
it->shufflerating = prev->shufflerating;
}
else {
@@ -2718,7 +2752,7 @@ plt_reshuffle (playlist_t *playlist, playItem_t **ppmin, playItem_t **ppmax) {
void
plt_set_item_duration (playlist_t *playlist, playItem_t *it, float duration) {
LOCK;
- if (it->in_playlist) {
+ if (it->in_playlist && playlist) {
if (it->_duration > 0) {
playlist->totaltime -= it->_duration;
}
@@ -2787,7 +2821,7 @@ pl_format_item_queue (playItem_t *it, char *s, int size) {
LOCK;
*s = 0;
int initsize = size;
- const char *val = pl_find_meta (it, "_playing");
+ const char *val = pl_find_meta_raw (it, "_playing");
while (val && *val) {
while (*val && *val != '=') {
val++;
@@ -2977,7 +3011,7 @@ pl_format_title_int (const char *escape_chars, playItem_t *it, int idx, char *s,
l = min (l, sizeof (nm)-1);
strncpy (nm, fmt+1, l);
nm[l] = 0;
- meta = pl_find_meta (it, nm);
+ meta = pl_find_meta_raw (it, nm);
if (!meta) {
meta = "?";
}
@@ -2985,15 +3019,15 @@ pl_format_title_int (const char *escape_chars, playItem_t *it, int idx, char *s,
}
}
else if (*fmt == 'a') {
- meta = pl_find_meta (it, "artist");
+ meta = pl_find_meta_raw (it, "artist");
if (!meta) {
meta = "Unknown artist";
}
}
else if (*fmt == 't') {
- meta = pl_find_meta (it, "title");
+ meta = pl_find_meta_raw (it, "title");
if (!meta) {
- const char *f = pl_find_meta (it, ":URI");
+ const char *f = pl_find_meta_raw (it, ":URI");
if (f) {
const char *start = strrchr (f, '/');
if (start) {
@@ -3020,28 +3054,28 @@ pl_format_title_int (const char *escape_chars, playItem_t *it, int idx, char *s,
}
}
else if (*fmt == 'b') {
- meta = pl_find_meta (it, "album");
+ meta = pl_find_meta_raw (it, "album");
if (!meta) {
meta = "Unknown album";
}
}
else if (*fmt == 'B') {
- meta = pl_find_meta (it, "band");
+ meta = pl_find_meta_raw (it, "band");
if (!meta) {
- meta = pl_find_meta (it, "album artist");
+ meta = pl_find_meta_raw (it, "album artist");
if (!meta) {
- meta = pl_find_meta (it, "albumartist");
+ meta = pl_find_meta_raw (it, "albumartist");
if (!meta) {
- meta = pl_find_meta (it, "artist");
+ meta = pl_find_meta_raw (it, "artist");
}
}
}
}
else if (*fmt == 'C') {
- meta = pl_find_meta (it, "composer");
+ meta = pl_find_meta_raw (it, "composer");
}
else if (*fmt == 'n') {
- meta = pl_find_meta (it, "track");
+ meta = pl_find_meta_raw (it, "track");
if (meta) {
// check if it's numbers only
const char *p = meta;
@@ -3058,19 +3092,19 @@ pl_format_title_int (const char *escape_chars, playItem_t *it, int idx, char *s,
}
}
else if (*fmt == 'N') {
- meta = pl_find_meta (it, "numtracks");
+ meta = pl_find_meta_raw (it, "numtracks");
}
else if (*fmt == 'y') {
- meta = pl_find_meta (it, "year");
+ meta = pl_find_meta_raw (it, "year");
}
else if (*fmt == 'g') {
- meta = pl_find_meta (it, "genre");
+ meta = pl_find_meta_raw (it, "genre");
}
else if (*fmt == 'c') {
- meta = pl_find_meta (it, "comment");
+ meta = pl_find_meta_raw (it, "comment");
}
else if (*fmt == 'r') {
- meta = pl_find_meta (it, "copyright");
+ meta = pl_find_meta_raw (it, "copyright");
}
else if (*fmt == 'l') {
const char *value = (duration = pl_format_duration (it, duration, dur, sizeof (dur)));
@@ -3088,7 +3122,7 @@ pl_format_title_int (const char *escape_chars, playItem_t *it, int idx, char *s,
}
}
else if (*fmt == 'f') {
- const char *f = pl_find_meta (it, ":URI");
+ const char *f = pl_find_meta_raw (it, ":URI");
meta = strrchr (f, '/');
if (meta) {
meta++;
@@ -3098,7 +3132,7 @@ pl_format_title_int (const char *escape_chars, playItem_t *it, int idx, char *s,
}
}
else if (*fmt == 'F') {
- meta = pl_find_meta (it, ":URI");
+ meta = pl_find_meta_raw (it, ":URI");
}
else if (*fmt == 'T') {
char *t = tags;
@@ -3145,7 +3179,7 @@ pl_format_title_int (const char *escape_chars, playItem_t *it, int idx, char *s,
}
else if (*fmt == 'd') {
// directory
- const char *f = pl_find_meta (it, ":URI");
+ const char *f = pl_find_meta_raw (it, ":URI");
const char *end = strrchr (f, '/');
if (!end) {
meta = ""; // got relative path without folder (should not happen)
@@ -3170,7 +3204,7 @@ pl_format_title_int (const char *escape_chars, playItem_t *it, int idx, char *s,
}
}
else if (*fmt == 'D') {
- const char *f = pl_find_meta (it, ":URI");
+ const char *f = pl_find_meta_raw (it, ":URI");
// directory with path
const char *end = strrchr (f, '/');
if (!end) {
@@ -3307,14 +3341,14 @@ pl_sort_compare_str (playItem_t *a, playItem_t *b) {
int t1;
int t2;
const char *t;
- t = pl_find_meta (a, "track");
+ t = pl_find_meta_raw (a, "track");
if (t && !isdigit (*t)) {
t1 = 999999;
}
else {
t1 = t ? atoi (t) : -1;
}
- t = pl_find_meta (b, "track");
+ t = pl_find_meta_raw (b, "track");
if (t && !isdigit (*t)) {
t2 = 999999;
}
@@ -3656,7 +3690,7 @@ plt_search_process (playlist_t *playlist, const char *text) {
if (*text) {
DB_metaInfo_t *m = NULL;
for (m = it->meta; m; m = m->next) {
- if (m->key[0] == ':' || m->key[0] == '_') {
+ if (m->key[0] == ':' || m->key[0] == '_' || m->key[0] == '!') {
break;
}
if (m->key!=cuesheet && m->key!=log) {
@@ -3678,7 +3712,7 @@ plt_search_process (playlist_t *playlist, const char *text) {
}
}
else if (utfcasestr_fast (m->value, lc)) {
- //fprintf (stderr, "%s -> %s match (%s.%s)\n", text, m->value, pl_find_meta (it, ":URI"), m->key);
+ //fprintf (stderr, "%s -> %s match (%s.%s)\n", text, m->value, pl_find_meta_raw (it, ":URI"), m->key);
// add to list
it->next[PL_SEARCH] = NULL;
if (playlist->tail[PL_SEARCH]) {