XMMS2
|
00001 /* XMMS2 - X Music Multiplexer System 00002 * Copyright (C) 2003-2009 XMMS2 Team 00003 * 00004 * PLUGINS ARE NOT CONSIDERED TO BE DERIVED WORK !!! 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 */ 00016 00017 00018 00019 00020 /** @file 00021 * This file controls the mediainfo reader thread. 00022 * 00023 */ 00024 00025 #include <stdlib.h> 00026 00027 #include "xmms/xmms_log.h" 00028 #include "xmms/xmms_ipc.h" 00029 #include "xmmspriv/xmms_mediainfo.h" 00030 #include "xmmspriv/xmms_medialib.h" 00031 #include "xmmspriv/xmms_xform.h" 00032 00033 00034 #include <glib.h> 00035 00036 /** @defgroup MediaInfoReader MediaInfoReader 00037 * @ingroup XMMSServer 00038 * @brief The mediainfo reader. 00039 * 00040 * When a item is added to the playlist the mediainfo reader will 00041 * start extracting the information from this entry and update it 00042 * if additional information is found. 00043 * @{ 00044 */ 00045 00046 struct xmms_mediainfo_reader_St { 00047 xmms_object_t object; 00048 00049 GThread *thread; 00050 GMutex *mutex; 00051 GCond *cond; 00052 00053 gboolean running; 00054 }; 00055 00056 static void xmms_mediainfo_reader_stop (xmms_object_t *o); 00057 static gpointer xmms_mediainfo_reader_thread (gpointer data); 00058 00059 00060 /** 00061 * Start a new mediainfo reader thread 00062 */ 00063 00064 xmms_mediainfo_reader_t * 00065 xmms_mediainfo_reader_start (void) 00066 { 00067 xmms_mediainfo_reader_t *mrt; 00068 00069 mrt = xmms_object_new (xmms_mediainfo_reader_t, 00070 xmms_mediainfo_reader_stop); 00071 00072 xmms_ipc_object_register (XMMS_IPC_OBJECT_MEDIAINFO_READER, 00073 XMMS_OBJECT (mrt)); 00074 00075 xmms_ipc_broadcast_register (XMMS_OBJECT (mrt), 00076 XMMS_IPC_SIGNAL_MEDIAINFO_READER_STATUS); 00077 xmms_ipc_signal_register (XMMS_OBJECT (mrt), 00078 XMMS_IPC_SIGNAL_MEDIAINFO_READER_UNINDEXED); 00079 00080 mrt->mutex = g_mutex_new (); 00081 mrt->cond = g_cond_new (); 00082 mrt->running = TRUE; 00083 mrt->thread = g_thread_create (xmms_mediainfo_reader_thread, mrt, TRUE, NULL); 00084 00085 return mrt; 00086 } 00087 00088 /** 00089 * Kill the mediainfo reader thread 00090 */ 00091 00092 static void 00093 xmms_mediainfo_reader_stop (xmms_object_t *o) 00094 { 00095 xmms_mediainfo_reader_t *mir = (xmms_mediainfo_reader_t *) o; 00096 00097 g_mutex_lock (mir->mutex); 00098 mir->running = FALSE; 00099 g_cond_signal (mir->cond); 00100 g_mutex_unlock (mir->mutex); 00101 00102 xmms_ipc_broadcast_unregister (XMMS_IPC_SIGNAL_MEDIAINFO_READER_STATUS); 00103 xmms_ipc_signal_unregister (XMMS_IPC_SIGNAL_MEDIAINFO_READER_UNINDEXED); 00104 xmms_ipc_object_unregister (XMMS_IPC_OBJECT_MEDIAINFO_READER); 00105 00106 g_thread_join (mir->thread); 00107 00108 g_cond_free (mir->cond); 00109 g_mutex_free (mir->mutex); 00110 } 00111 00112 /** 00113 * Wake the reader thread and start process the entries. 00114 */ 00115 00116 void 00117 xmms_mediainfo_reader_wakeup (xmms_mediainfo_reader_t *mr) 00118 { 00119 g_return_if_fail (mr); 00120 00121 g_mutex_lock (mr->mutex); 00122 g_cond_signal (mr->cond); 00123 g_mutex_unlock (mr->mutex); 00124 } 00125 00126 /** @} */ 00127 00128 static gpointer 00129 xmms_mediainfo_reader_thread (gpointer data) 00130 { 00131 GList *goal_format; 00132 GTimeVal timeval; 00133 xmms_stream_type_t *f; 00134 guint num = 0; 00135 00136 xmms_mediainfo_reader_t *mrt = (xmms_mediainfo_reader_t *) data; 00137 00138 xmms_object_emit_f (XMMS_OBJECT (mrt), 00139 XMMS_IPC_SIGNAL_MEDIAINFO_READER_STATUS, 00140 XMMSV_TYPE_INT32, 00141 XMMS_MEDIAINFO_READER_STATUS_RUNNING); 00142 00143 00144 f = _xmms_stream_type_new (NULL, 00145 XMMS_STREAM_TYPE_MIMETYPE, 00146 "audio/pcm", 00147 XMMS_STREAM_TYPE_END); 00148 goal_format = g_list_prepend (NULL, f); 00149 00150 while (mrt->running) { 00151 xmms_medialib_session_t *session; 00152 xmmsc_medialib_entry_status_t prev_status; 00153 guint lmod = 0; 00154 xmms_medialib_entry_t entry; 00155 xmms_xform_t *xform; 00156 00157 session = xmms_medialib_begin_write (); 00158 entry = xmms_medialib_entry_not_resolved_get (session); 00159 XMMS_DBG ("got %d as not resolved", entry); 00160 00161 if (!entry) { 00162 xmms_medialib_end (session); 00163 00164 xmms_object_emit_f (XMMS_OBJECT (mrt), 00165 XMMS_IPC_SIGNAL_MEDIAINFO_READER_STATUS, 00166 XMMSV_TYPE_INT32, 00167 XMMS_MEDIAINFO_READER_STATUS_IDLE); 00168 00169 g_mutex_lock (mrt->mutex); 00170 g_cond_wait (mrt->cond, mrt->mutex); 00171 g_mutex_unlock (mrt->mutex); 00172 00173 num = 0; 00174 00175 xmms_object_emit_f (XMMS_OBJECT (mrt), 00176 XMMS_IPC_SIGNAL_MEDIAINFO_READER_STATUS, 00177 XMMSV_TYPE_INT32, 00178 XMMS_MEDIAINFO_READER_STATUS_RUNNING); 00179 continue; 00180 } 00181 00182 prev_status = xmms_medialib_entry_property_get_int (session, entry, XMMS_MEDIALIB_ENTRY_PROPERTY_STATUS); 00183 xmms_medialib_entry_status_set (session, entry, XMMS_MEDIALIB_ENTRY_STATUS_RESOLVING); 00184 00185 lmod = xmms_medialib_entry_property_get_int (session, entry, XMMS_MEDIALIB_ENTRY_PROPERTY_LMOD); 00186 00187 if (num == 0) { 00188 xmms_object_emit_f (XMMS_OBJECT (mrt), 00189 XMMS_IPC_SIGNAL_MEDIAINFO_READER_UNINDEXED, 00190 XMMSV_TYPE_INT32, 00191 xmms_medialib_num_not_resolved (session)); 00192 num = 10; 00193 } else { 00194 num--; 00195 } 00196 00197 xmms_medialib_end (session); 00198 xform = xmms_xform_chain_setup (entry, goal_format, TRUE); 00199 00200 if (!xform) { 00201 if (prev_status == XMMS_MEDIALIB_ENTRY_STATUS_NEW) { 00202 xmms_medialib_entry_remove (entry); 00203 } else { 00204 session = xmms_medialib_begin_write (); 00205 xmms_medialib_entry_status_set (session, entry, XMMS_MEDIALIB_ENTRY_STATUS_NOT_AVAILABLE); 00206 xmms_medialib_end (session); 00207 xmms_medialib_entry_send_update (entry); 00208 } 00209 continue; 00210 } 00211 00212 xmms_object_unref (xform); 00213 g_get_current_time (&timeval); 00214 00215 session = xmms_medialib_begin_write (); 00216 xmms_medialib_entry_status_set (session, entry, XMMS_MEDIALIB_ENTRY_STATUS_OK); 00217 xmms_medialib_entry_property_set_int (session, entry, 00218 XMMS_MEDIALIB_ENTRY_PROPERTY_ADDED, 00219 timeval.tv_sec); 00220 xmms_medialib_end (session); 00221 xmms_medialib_entry_send_update (entry); 00222 00223 } 00224 00225 g_list_free (goal_format); 00226 xmms_object_unref (f); 00227 00228 return NULL; 00229 }