static void xmms_xform_metadata_collect (xmms_xform_t *start, GString *namestr, gboolean rehashing) { metadata_festate_t info; gint times_played; gint last_started; GTimeVal now; info.entry = start->entry; info.session = xmms_medialib_begin_write (); times_played = xmms_medialib_entry_property_get_int (info.session, info.entry, XMMS_MEDIALIB_ENTRY_PROPERTY_TIMESPLAYED); /* times_played == -1 if we haven't played this entry yet. so after initial * metadata collection the mlib would have timesplayed = -1 if we didn't do * the following */ if (times_played < 0) { times_played = 0; } last_started = xmms_medialib_entry_property_get_int (info.session, info.entry, XMMS_MEDIALIB_ENTRY_PROPERTY_LASTSTARTED); xmms_medialib_entry_cleanup (info.session, info.entry); xmms_xform_metadata_collect_r (start, &info, namestr); xmms_medialib_entry_property_set_str (info.session, info.entry, XMMS_MEDIALIB_ENTRY_PROPERTY_CHAIN, namestr->str); xmms_medialib_entry_property_set_int (info.session, info.entry, XMMS_MEDIALIB_ENTRY_PROPERTY_TIMESPLAYED, times_played + (rehashing ? 0 : 1)); if (!rehashing || (rehashing && last_started)) { g_get_current_time (&now); xmms_medialib_entry_property_set_int (info.session, info.entry, XMMS_MEDIALIB_ENTRY_PROPERTY_LASTSTARTED, (rehashing ? last_started : now.tv_sec)); } xmms_medialib_entry_status_set (info.session, info.entry, XMMS_MEDIALIB_ENTRY_STATUS_OK); xmms_medialib_end (info.session); xmms_medialib_entry_send_update (info.entry); }
static void xmms_xform_metadata_update (xmms_xform_t *xform) { metadata_festate_t info; info.entry = xform->entry; info.session = xmms_medialib_begin_write (); xmms_xform_metadata_collect_one (xform, &info); xmms_medialib_end (info.session); xmms_medialib_entry_send_update (info.entry); }
gboolean xmms_medialib_session_commit (xmms_medialib_session_t *session) { GHashTableIter iter; gpointer key; if (!s4_commit (session->trans)) { xmms_medialib_session_free_full (session); return FALSE; } if (session->added != NULL) { g_hash_table_iter_init (&iter, session->added); while (g_hash_table_iter_next (&iter, &key, NULL)) { xmms_medialib_entry_send_added (session->medialib, GPOINTER_TO_INT (key)); if (session->updated != NULL) g_hash_table_remove (session->updated, key); } } if (session->removed != NULL) { g_hash_table_iter_init (&iter, session->removed); while (g_hash_table_iter_next (&iter, &key, NULL)) { xmms_medialib_entry_send_removed (session->medialib, GPOINTER_TO_INT (key)); if (session->updated != NULL) g_hash_table_remove (session->updated, key); } } if (session->updated != NULL) { g_hash_table_iter_init (&iter, session->updated); while (g_hash_table_iter_next (&iter, &key, NULL)) { xmms_medialib_entry_send_update (session->medialib, GPOINTER_TO_INT (key)); } } xmms_medialib_session_free (session); return TRUE; }
static void * xmms_output_filler (void *arg) { xmms_output_t *output = (xmms_output_t *)arg; xmms_xform_t *chain = NULL; gboolean last_was_kill = FALSE; char buf[4096]; xmms_error_t err; gint ret; xmms_error_reset (&err); g_mutex_lock (output->filler_mutex); while (output->filler_state != FILLER_QUIT) { if (output->filler_state == FILLER_STOP) { if (chain) { xmms_object_unref (chain); chain = NULL; } xmms_ringbuf_set_eos (output->filler_buffer, TRUE); g_cond_wait (output->filler_state_cond, output->filler_mutex); last_was_kill = FALSE; continue; } if (output->filler_state == FILLER_KILL) { if (chain) { xmms_object_unref (chain); chain = NULL; output->filler_state = FILLER_RUN; last_was_kill = TRUE; } else { output->filler_state = FILLER_STOP; } continue; } if (output->filler_state == FILLER_SEEK) { if (!chain) { XMMS_DBG ("Seek without chain, ignoring.."); output->filler_state = FILLER_STOP; continue; } ret = xmms_xform_this_seek (chain, output->filler_seek, XMMS_XFORM_SEEK_SET, &err); if (ret == -1) { XMMS_DBG ("Seeking failed: %s", xmms_error_message_get (&err)); } else { XMMS_DBG ("Seek ok! %d", ret); output->filler_skip = output->filler_seek - ret; if (output->filler_skip < 0) { XMMS_DBG ("Seeked %d samples too far! Updating position...", -output->filler_skip); output->filler_skip = 0; output->filler_seek = ret; } xmms_ringbuf_clear (output->filler_buffer); xmms_ringbuf_hotspot_set (output->filler_buffer, seek_done, NULL, output); } output->filler_state = FILLER_RUN; } if (!chain) { xmms_medialib_entry_t entry; xmms_output_song_changed_arg_t *arg; xmms_medialib_session_t *session; g_mutex_unlock (output->filler_mutex); entry = xmms_playlist_current_entry (output->playlist); if (!entry) { XMMS_DBG ("No entry from playlist!"); output->filler_state = FILLER_STOP; g_mutex_lock (output->filler_mutex); continue; } chain = xmms_xform_chain_setup (entry, output->format_list, FALSE); if (!chain) { session = xmms_medialib_begin_write (); if (xmms_medialib_entry_property_get_int (session, entry, XMMS_MEDIALIB_ENTRY_PROPERTY_STATUS) == XMMS_MEDIALIB_ENTRY_STATUS_NEW) { xmms_medialib_end (session); xmms_medialib_entry_remove (entry); } else { xmms_medialib_entry_status_set (session, entry, XMMS_MEDIALIB_ENTRY_STATUS_NOT_AVAILABLE); xmms_medialib_entry_send_update (entry); xmms_medialib_end (session); } if (!xmms_playlist_advance (output->playlist)) { XMMS_DBG ("End of playlist"); output->filler_state = FILLER_STOP; } g_mutex_lock (output->filler_mutex); continue; } arg = g_new0 (xmms_output_song_changed_arg_t, 1); arg->output = output; arg->chain = chain; arg->flush = last_was_kill; xmms_object_ref (chain); last_was_kill = FALSE; g_mutex_lock (output->filler_mutex); xmms_ringbuf_hotspot_set (output->filler_buffer, song_changed, song_changed_arg_free, arg); } xmms_ringbuf_wait_free (output->filler_buffer, sizeof (buf), output->filler_mutex); if (output->filler_state != FILLER_RUN) { XMMS_DBG ("State changed while waiting..."); continue; } g_mutex_unlock (output->filler_mutex); ret = xmms_xform_this_read (chain, buf, sizeof (buf), &err); g_mutex_lock (output->filler_mutex); if (ret > 0) { gint skip = MIN (ret, output->toskip); output->toskip -= skip; if (ret > skip) { xmms_ringbuf_write_wait (output->filler_buffer, buf + skip, ret - skip, output->filler_mutex); } } else { if (ret == -1) { /* print error */ xmms_error_reset (&err); } xmms_object_unref (chain); chain = NULL; if (!xmms_playlist_advance (output->playlist)) { XMMS_DBG ("End of playlist"); output->filler_state = FILLER_STOP; } } } g_mutex_unlock (output->filler_mutex); return NULL; }
static gpointer xmms_mediainfo_reader_thread (gpointer data) { GList *goal_format; GTimeVal timeval; xmms_stream_type_t *f; guint num = 0; xmms_mediainfo_reader_t *mrt = (xmms_mediainfo_reader_t *) data; xmms_object_emit_f (XMMS_OBJECT (mrt), XMMS_IPC_SIGNAL_MEDIAINFO_READER_STATUS, XMMSV_TYPE_INT32, XMMS_MEDIAINFO_READER_STATUS_RUNNING); f = _xmms_stream_type_new (NULL, XMMS_STREAM_TYPE_MIMETYPE, "audio/pcm", XMMS_STREAM_TYPE_END); goal_format = g_list_prepend (NULL, f); while (mrt->running) { xmms_medialib_session_t *session; xmmsc_medialib_entry_status_t prev_status; guint lmod = 0; xmms_medialib_entry_t entry; xmms_xform_t *xform; session = xmms_medialib_begin_write (); entry = xmms_medialib_entry_not_resolved_get (session); XMMS_DBG ("got %d as not resolved", entry); if (!entry) { xmms_medialib_end (session); xmms_object_emit_f (XMMS_OBJECT (mrt), XMMS_IPC_SIGNAL_MEDIAINFO_READER_STATUS, XMMSV_TYPE_INT32, XMMS_MEDIAINFO_READER_STATUS_IDLE); g_mutex_lock (mrt->mutex); g_cond_wait (mrt->cond, mrt->mutex); g_mutex_unlock (mrt->mutex); num = 0; xmms_object_emit_f (XMMS_OBJECT (mrt), XMMS_IPC_SIGNAL_MEDIAINFO_READER_STATUS, XMMSV_TYPE_INT32, XMMS_MEDIAINFO_READER_STATUS_RUNNING); continue; } prev_status = xmms_medialib_entry_property_get_int (session, entry, XMMS_MEDIALIB_ENTRY_PROPERTY_STATUS); xmms_medialib_entry_status_set (session, entry, XMMS_MEDIALIB_ENTRY_STATUS_RESOLVING); lmod = xmms_medialib_entry_property_get_int (session, entry, XMMS_MEDIALIB_ENTRY_PROPERTY_LMOD); if (num == 0) { xmms_object_emit_f (XMMS_OBJECT (mrt), XMMS_IPC_SIGNAL_MEDIAINFO_READER_UNINDEXED, XMMSV_TYPE_INT32, xmms_medialib_num_not_resolved (session)); num = 10; } else { num--; } xmms_medialib_end (session); xform = xmms_xform_chain_setup (entry, goal_format, TRUE); if (!xform) { if (prev_status == XMMS_MEDIALIB_ENTRY_STATUS_NEW) { xmms_medialib_entry_remove (entry); } else { session = xmms_medialib_begin_write (); xmms_medialib_entry_status_set (session, entry, XMMS_MEDIALIB_ENTRY_STATUS_NOT_AVAILABLE); xmms_medialib_end (session); xmms_medialib_entry_send_update (entry); } continue; } xmms_object_unref (xform); g_get_current_time (&timeval); session = xmms_medialib_begin_write (); xmms_medialib_entry_status_set (session, entry, XMMS_MEDIALIB_ENTRY_STATUS_OK); xmms_medialib_entry_property_set_int (session, entry, XMMS_MEDIALIB_ENTRY_PROPERTY_ADDED, timeval.tv_sec); xmms_medialib_end (session); xmms_medialib_entry_send_update (entry); } g_list_free (goal_format); xmms_object_unref (f); return NULL; }