Merge pull request #39 from chme/playqueuefix

Fixes for UpNext playqueue
This commit is contained in:
ejurgensen 2014-07-26 22:17:59 +02:00
commit 33c4c4858c
2 changed files with 79 additions and 35 deletions

View File

@ -1447,8 +1447,8 @@ dacp_reply_playqueueedit_add(struct evhttp_request *req, struct evbuffer *evbuf,
sort = "album"; sort = "album";
} }
// only use queryfilter if mode is not equal 3 (play next) or 5 (add to up next) // only use queryfilter if mode is not equal 0 (add to up next), 3 (play next) or 5 (add to up next)
queuefilter = (mode == 3 || mode == 5) ? NULL : evhttp_find_header(query, "queuefilter"); queuefilter = (mode == 0 || mode == 3 || mode == 5) ? NULL : evhttp_find_header(query, "queuefilter");
querymodifier = evhttp_find_header(query, "query-modifier"); querymodifier = evhttp_find_header(query, "query-modifier");
if (!querymodifier || (strcmp(querymodifier, "containers") != 0)) if (!querymodifier || (strcmp(querymodifier, "containers") != 0))

View File

@ -469,6 +469,9 @@ player_get_current_pos(uint64_t *pos, struct timespec *ts, int commit)
static void static void
playback_abort(void); playback_abort(void);
static int
queue_clear(struct player_command *cmd);
static void static void
player_laudio_status_cb(enum laudio_state status) player_laudio_status_cb(enum laudio_state status)
{ {
@ -655,6 +658,8 @@ player_queue_make(struct query_params *qp, const char *sort)
q_head->pl_prev = q_tail; q_head->pl_prev = q_tail;
q_tail->pl_next = q_head; q_tail->pl_next = q_head;
q_head->shuffle_prev = q_tail;
q_tail->shuffle_next = q_head;
return q_head; return q_head;
} }
@ -821,9 +826,12 @@ player_queue_make_daap(struct player_source **head, const char *query, const cha
} }
else else
{ {
DPRINTF(E_LOG, L_PLAYER, "Unknown queuefilter: %s\n", queuefilter); DPRINTF(E_LOG, L_PLAYER, "Unknown queuefilter %s\n", queuefilter);
return -1; // If the queuefilter is unkown, ignore it and use the query parameter instead to build the sql query
id = 0;
qp.type = Q_ITEMS;
qp.filter = daap_query_parse_sql(query);
} }
} }
else else
@ -971,8 +979,11 @@ source_stop(struct player_source *ps)
} }
} }
static struct player_source * /*
source_shuffle(struct player_source *head) * Shuffles the items between head and tail (excluding head and tail)
*/
static void
source_shuffle(struct player_source *head, struct player_source *tail)
{ {
struct player_source *ps; struct player_source *ps;
struct player_source **ps_array; struct player_source **ps_array;
@ -980,34 +991,55 @@ source_shuffle(struct player_source *head)
int i; int i;
if (!head) if (!head)
return NULL; return;
ps = head; if (!tail)
return;
if (!shuffle)
{
ps = head;
do
{
ps->shuffle_next = ps->pl_next;
ps->shuffle_prev = ps->pl_prev;
ps = ps->pl_next;
}
while (ps != head);
}
// Count items in queue (excluding head and tail)
ps = head->shuffle_next;
nitems = 0; nitems = 0;
do while (ps != tail)
{ {
nitems++; nitems++;
ps = ps->pl_next; ps = ps->shuffle_next;
} }
while (ps != head);
// Do not reshuffle queue with one item
if (nitems < 1)
return;
// Construct array for number of items in queue
ps_array = (struct player_source **)malloc(nitems * sizeof(struct player_source *)); ps_array = (struct player_source **)malloc(nitems * sizeof(struct player_source *));
if (!ps_array) if (!ps_array)
{ {
DPRINTF(E_LOG, L_PLAYER, "Could not allocate memory for shuffle array\n"); DPRINTF(E_LOG, L_PLAYER, "Could not allocate memory for shuffle array\n");
return NULL; return;
} }
ps = head; // Fill array with items in queue (excluding head and tail)
ps = head->shuffle_next;
i = 0; i = 0;
do do
{ {
ps_array[i] = ps; ps_array[i] = ps;
ps = ps->pl_next; ps = ps->shuffle_next;
i++; i++;
} }
while (ps != head); while (ps != tail);
shuffle_ptr(&shuffle_rng, (void **)ps_array, nitems); shuffle_ptr(&shuffle_rng, (void **)ps_array, nitems);
@ -1022,29 +1054,39 @@ source_shuffle(struct player_source *head)
ps->shuffle_next = ps_array[i + 1]; ps->shuffle_next = ps_array[i + 1];
} }
ps_array[0]->shuffle_prev = ps_array[nitems - 1]; // Insert shuffled items between head and tail
ps_array[nitems - 1]->shuffle_next = ps_array[0]; ps_array[0]->shuffle_prev = head;
ps_array[nitems - 1]->shuffle_next = tail;
ps = ps_array[0]; head->shuffle_next = ps_array[0];
tail->shuffle_prev = ps_array[nitems - 1];
free(ps_array); free(ps_array);
return ps; return;
} }
static void static void
source_reshuffle(void) source_reshuffle(void)
{ {
struct player_source *ps; struct player_source *head;
struct player_source *tail;
ps = source_shuffle(source_head);
if (!ps)
return;
if (cur_streaming) if (cur_streaming)
shuffle_head = cur_streaming; head = cur_streaming;
else else
shuffle_head = ps; head = source_head;
if (repeat == REPEAT_ALL)
tail = head;
else if (shuffle)
tail = shuffle_head;
else
tail = source_head;
source_shuffle(head, tail);
if (repeat == REPEAT_ALL)
shuffle_head = head;
} }
/* Helper */ /* Helper */
@ -2179,6 +2221,8 @@ playback_abort(void)
else else
source_stop(cur_streaming); source_stop(cur_streaming);
queue_clear(NULL);
cur_playing = NULL; cur_playing = NULL;
cur_streaming = NULL; cur_streaming = NULL;
@ -3378,10 +3422,7 @@ queue_add(struct player_command *cmd)
struct player_source *ps_tail; struct player_source *ps_tail;
ps = cmd->arg.ps; ps = cmd->arg.ps;
ps_shuffle = ps;
ps_shuffle = source_shuffle(ps);
if (!ps_shuffle)
ps_shuffle = ps;
if (source_head) if (source_head)
{ {
@ -3411,6 +3452,9 @@ queue_add(struct player_command *cmd)
shuffle_head = ps_shuffle; shuffle_head = ps_shuffle;
} }
if (shuffle)
source_reshuffle();
if (cur_plid != 0) if (cur_plid != 0)
cur_plid = 0; cur_plid = 0;
@ -3425,10 +3469,7 @@ queue_add_next(struct player_command *cmd)
struct player_source *ps_playing; struct player_source *ps_playing;
ps = cmd->arg.ps; ps = cmd->arg.ps;
ps_shuffle = ps;
ps_shuffle = source_shuffle(ps);
if (!ps_shuffle)
ps_shuffle = ps;
if (source_head && cur_streaming) if (source_head && cur_streaming)
{ {
@ -3452,6 +3493,9 @@ queue_add_next(struct player_command *cmd)
shuffle_head = ps_shuffle; shuffle_head = ps_shuffle;
} }
if (shuffle)
source_reshuffle();
if (cur_plid != 0) if (cur_plid != 0)
cur_plid = 0; cur_plid = 0;