summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2011-10-01 10:33:47 +0200
committerGravatar waker <wakeroid@gmail.com>2011-10-01 10:33:47 +0200
commitecafc1687513de35d080a9b4be14022e885a95e1 (patch)
tree83afbacdd59323cd788aecbb6c1754c10c96b874
parent76f14028b56a1cdb6627b0db0e6af0a74a9b76f3 (diff)
added experimental support for metadata overrides.
for example field "!NAME" will override field ":NAME", but will not be stored so after player restart, the field will be restored to original :NAME
-rw-r--r--deadbeef.h8
-rw-r--r--metacache.c2
-rw-r--r--playlist.c88
-rw-r--r--playlist.h4
-rw-r--r--plmeta.c38
-rw-r--r--plugins.c1
6 files changed, 89 insertions, 52 deletions
diff --git a/deadbeef.h b/deadbeef.h
index 3605c09b..74d17993 100644
--- a/deadbeef.h
+++ b/deadbeef.h
@@ -726,16 +726,20 @@ typedef struct {
int (*dsp_preset_save) (const char *fname, struct ddb_dsp_context_s *head);
void (*dsp_preset_free) (struct ddb_dsp_context_s *head);
- // new 1.2 APIs
+ // ******* new 1.2 APIs ********
ddb_playlist_t *(*plt_alloc) (const char *title);
void (*plt_free) (ddb_playlist_t *plt);
- //int (*plt_insert) (ddb_playlist_t *plt, int before);
+
void (*plt_set_fast_mode) (ddb_playlist_t *plt, int fast);
int (*plt_is_fast_mode) (ddb_playlist_t *plt);
+
const char * (*metacache_add_string) (const char *str);
void (*metacache_remove_string) (const char *str);
void (*metacache_ref) (const char *str);
void (*metacache_unref) (const char *str);
+
+ // this function must return original un-overriden value (ignoring the keys prefixed with '!')
+ const char *(*pl_find_meta_raw) (DB_playItem_t *it, const char *key);
} DB_functions_t;
enum {
diff --git a/metacache.c b/metacache.c
index 13616516..e7fa1619 100644
--- a/metacache.c
+++ b/metacache.c
@@ -117,7 +117,7 @@ metacache_remove_string (const char *str) {
void
metacache_ref (const char *str) {
- uint32_t *refc = (uint32_t)(str-5);
+ uint32_t *refc = (uint32_t *)(str-5);
*refc++;
}
diff --git a/playlist.c b/playlist.c
index 68accc38..4ed52836 100644
--- a/playlist.c
+++ b/playlist.c
@@ -145,7 +145,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(%s) has refc=%d at delete time\033[37;0m\n", it, pl_find_meta (it, ":URI"), pl_find_meta (it, "track"), 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);
}
}
@@ -1060,11 +1060,11 @@ 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);
+ const char *filetype = pl_find_meta_raw (origin, ":FILETYPE");
+ after = plt_process_cue_track (playlist, after, 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 (%p)\n", after);
}
@@ -1108,8 +1108,8 @@ 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);
+ const char *filetype = pl_find_meta_raw (origin, ":FILETYPE");
+ after = plt_process_cue_track (playlist, after, 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 (after) {
trace ("last track endsample: %d\n", numsamples-1);
after->endsample = numsamples-1;
@@ -1127,7 +1127,7 @@ plt_insert_cue_from_buffer (playlist_t *playlist, playItem_t *after, playItem_t
// 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);
@@ -1139,7 +1139,7 @@ plt_insert_cue_from_buffer (playlist_t *playlist, playItem_t *after, playItem_t
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);
@@ -1894,7 +1894,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 {
@@ -1973,7 +1973,7 @@ void
pl_item_ref (playItem_t *it) {
LOCK;
it->_refc++;
- //fprintf (stderr, "\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;
}
@@ -1997,12 +1997,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;
@@ -2107,7 +2107,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;
@@ -2115,7 +2115,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) {
@@ -2147,7 +2147,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 = "";
}
@@ -2184,7 +2184,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++;
@@ -2193,7 +2193,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
}
@@ -2698,7 +2698,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 {
@@ -2725,7 +2725,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;
}
@@ -2794,7 +2794,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++;
@@ -2984,7 +2984,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 = "?";
}
@@ -2992,15 +2992,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) {
@@ -3027,28 +3027,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;
@@ -3065,19 +3065,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)));
@@ -3095,7 +3095,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++;
@@ -3105,7 +3105,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;
@@ -3152,7 +3152,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)
@@ -3177,7 +3177,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) {
@@ -3314,14 +3314,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;
}
@@ -3663,7 +3663,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) {
@@ -3685,7 +3685,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]) {
diff --git a/playlist.h b/playlist.h
index 2f9a9d6a..a517930b 100644
--- a/playlist.h
+++ b/playlist.h
@@ -244,9 +244,13 @@ pl_append_meta (playItem_t *it, const char *key, const char *value);
// must be used in explicit pl_lock/unlock block
// that makes it possible to avoid copying metadata on every access
+// pl_find_meta may return overriden value (where the key is prefixed with '!')
const char *
pl_find_meta (playItem_t *it, const char *key);
+const char *
+pl_find_meta_raw (playItem_t *it, const char *key);
+
int
pl_find_meta_int (playItem_t *it, const char *key, int def);
diff --git a/plmeta.c b/plmeta.c
index 21de208c..6f667a89 100644
--- a/plmeta.c
+++ b/plmeta.c
@@ -41,10 +41,10 @@ pl_add_meta (playItem_t *it, const char *key, const char *value) {
return;
}
// find end of normal metadata
- if (!normaltail && (m->key[0] == ':' || m->key[0] == '_')) {
+ if (!normaltail && (m->key[0] == ':' || m->key[0] == '_' || m->key[0] == '!')) {
normaltail = tail;
propstart = m;
- if (key[0] != ':' && key[0] != '_') {
+ if (key[0] != ':' && key[0] != '_' && key[0] != '!') {
break;
}
}
@@ -63,7 +63,7 @@ pl_add_meta (playItem_t *it, const char *key, const char *value) {
m->key = metacache_add_string (key);
m->value = metacache_add_string (value);
- if (key[0] == ':' || key[0] == '_') {
+ if (key[0] == ':' || key[0] == '_' || key[0] == '!') {
if (tail) {
tail->next = m;
}
@@ -86,7 +86,7 @@ pl_add_meta (playItem_t *it, const char *key, const char *value) {
void
pl_append_meta (playItem_t *it, const char *key, const char *value) {
pl_lock ();
- const char *old = pl_find_meta (it, key);
+ const char *old = pl_find_meta_raw (it, key);
if (old && (!strcasecmp (key, "cuesheet") || !strcasecmp (key, "log"))) {
pl_unlock ();
@@ -192,6 +192,34 @@ const char *
pl_find_meta (playItem_t *it, const char *key) {
pl_lock ();
DB_metaInfo_t *m = it->meta;
+
+ if (key && key[0] == ':') {
+ // try to find an override
+ while (m) {
+ if (m->key[0] == '!' && !strcasecmp (key+1, m->key+1)) {
+ pl_unlock ();
+ return m->value;
+ }
+ m = m->next;
+ }
+ }
+
+ m = it->meta;
+ while (m) {
+ if (!strcasecmp (key, m->key)) {
+ pl_unlock ();
+ return m->value;
+ }
+ m = m->next;
+ }
+ pl_unlock ();
+ return NULL;
+}
+
+const char *
+pl_find_meta_raw (playItem_t *it, const char *key) {
+ pl_lock ();
+ DB_metaInfo_t *m = it->meta;
while (m) {
if (!strcasecmp (key, m->key)) {
pl_unlock ();
@@ -257,7 +285,7 @@ pl_delete_all_meta (playItem_t *it) {
DB_metaInfo_t *prev = NULL;
while (m) {
DB_metaInfo_t *next = m->next;
- if (m->key[0] == ':') {
+ if (m->key[0] == ':' || m->key[0] == '_' || m->key[0] == '!') {
prev = m;
}
else {
diff --git a/plugins.c b/plugins.c
index ff110913..d41b0777 100644
--- a/plugins.c
+++ b/plugins.c
@@ -328,6 +328,7 @@ static DB_functions_t deadbeef_api = {
.metacache_remove_string = metacache_remove_string,
.metacache_ref = metacache_ref,
.metacache_unref = metacache_unref,
+ .pl_find_meta_raw = (const char *(*) (DB_playItem_t *it, const char *key))pl_find_meta_raw,
};
DB_functions_t *deadbeef = &deadbeef_api;