XMMS2
|
00001 /* XMMS2 - X Music Multiplexer System 00002 * Copyright (C) 2003-2011 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 #include "xmmspriv/xmms_thread_name.h" 00033 00034 00035 #include <glib.h> 00036 00037 /** @defgroup MediaInfoReader MediaInfoReader 00038 * @ingroup XMMSServer 00039 * @brief The mediainfo reader. 00040 * 00041 * When a item is added to the playlist the mediainfo reader will 00042 * start extracting the information from this entry and update it 00043 * if additional information is found. 00044 * @{ 00045 */ 00046 00047 struct xmms_mediainfo_reader_St { 00048 xmms_object_t object; 00049 00050 GThread *thread; 00051 GMutex *mutex; 00052 GCond *cond; 00053 00054 gboolean running; 00055 }; 00056 00057 static void xmms_mediainfo_reader_stop (xmms_object_t *o); 00058 static gpointer xmms_mediainfo_reader_thread (gpointer data); 00059 00060 #include "mediainfo_ipc.c" 00061 00062 /** 00063 * Start a new mediainfo reader thread 00064 */ 00065 00066 xmms_mediainfo_reader_t * 00067 xmms_mediainfo_reader_start (void) 00068 { 00069 xmms_mediainfo_reader_t *mrt; 00070 00071 mrt = xmms_object_new (xmms_mediainfo_reader_t, 00072 xmms_mediainfo_reader_stop); 00073 00074 xmms_mediainfo_reader_register_ipc_commands (XMMS_OBJECT (mrt)); 00075 00076 mrt->mutex = g_mutex_new (); 00077 mrt->cond = g_cond_new (); 00078 mrt->running = TRUE; 00079 mrt->thread = g_thread_create (xmms_mediainfo_reader_thread, mrt, TRUE, NULL); 00080 00081 return mrt; 00082 } 00083 00084 /** 00085 * Kill the mediainfo reader thread 00086 */ 00087 00088 static void 00089 xmms_mediainfo_reader_stop (xmms_object_t *o) 00090 { 00091 xmms_mediainfo_reader_t *mir = (xmms_mediainfo_reader_t *) o; 00092 00093 g_mutex_lock (mir->mutex); 00094 mir->running = FALSE; 00095 g_cond_signal (mir->cond); 00096 g_mutex_unlock (mir->mutex); 00097 00098 xmms_mediainfo_reader_unregister_ipc_commands (); 00099 00100 g_thread_join (mir->thread); 00101 00102 g_cond_free (mir->cond); 00103 g_mutex_free (mir->mutex); 00104 } 00105 00106 /** 00107 * Wake the reader thread and start process the entries. 00108 */ 00109 00110 void 00111 xmms_mediainfo_reader_wakeup (xmms_mediainfo_reader_t *mr) 00112 { 00113 g_return_if_fail (mr); 00114 00115 g_mutex_lock (mr->mutex); 00116 g_cond_signal (mr->cond); 00117 g_mutex_unlock (mr->mutex); 00118 } 00119 00120 /** @} */ 00121 00122 static gpointer 00123 xmms_mediainfo_reader_thread (gpointer data) 00124 { 00125 GList *goal_format; 00126 GTimeVal timeval; 00127 xmms_stream_type_t *f; 00128 guint num = 0; 00129 00130 xmms_set_thread_name ("x2 media info"); 00131 00132 xmms_mediainfo_reader_t *mrt = (xmms_mediainfo_reader_t *) data; 00133 00134 xmms_object_emit_f (XMMS_OBJECT (mrt), 00135 XMMS_IPC_SIGNAL_MEDIAINFO_READER_STATUS, 00136 XMMSV_TYPE_INT32, 00137 XMMS_MEDIAINFO_READER_STATUS_RUNNING); 00138 00139 00140 f = _xmms_stream_type_new (XMMS_STREAM_TYPE_BEGIN, 00141 XMMS_STREAM_TYPE_MIMETYPE, 00142 "audio/pcm", 00143 XMMS_STREAM_TYPE_END); 00144 goal_format = g_list_prepend (NULL, f); 00145 00146 while (mrt->running) { 00147 xmms_medialib_session_t *session; 00148 xmmsc_medialib_entry_status_t prev_status; 00149 guint lmod = 0; 00150 xmms_medialib_entry_t entry; 00151 xmms_xform_t *xform; 00152 00153 session = xmms_medialib_begin_write (); 00154 entry = xmms_medialib_entry_not_resolved_get (session); 00155 XMMS_DBG ("got %d as not resolved", entry); 00156 00157 if (!entry) { 00158 xmms_medialib_end (session); 00159 00160 xmms_object_emit_f (XMMS_OBJECT (mrt), 00161 XMMS_IPC_SIGNAL_MEDIAINFO_READER_STATUS, 00162 XMMSV_TYPE_INT32, 00163 XMMS_MEDIAINFO_READER_STATUS_IDLE); 00164 00165 g_mutex_lock (mrt->mutex); 00166 g_cond_wait (mrt->cond, mrt->mutex); 00167 g_mutex_unlock (mrt->mutex); 00168 00169 num = 0; 00170 00171 xmms_object_emit_f (XMMS_OBJECT (mrt), 00172 XMMS_IPC_SIGNAL_MEDIAINFO_READER_STATUS, 00173 XMMSV_TYPE_INT32, 00174 XMMS_MEDIAINFO_READER_STATUS_RUNNING); 00175 continue; 00176 } 00177 00178 prev_status = xmms_medialib_entry_property_get_int (session, entry, XMMS_MEDIALIB_ENTRY_PROPERTY_STATUS); 00179 xmms_medialib_entry_status_set (session, entry, XMMS_MEDIALIB_ENTRY_STATUS_RESOLVING); 00180 00181 lmod = xmms_medialib_entry_property_get_int (session, entry, XMMS_MEDIALIB_ENTRY_PROPERTY_LMOD); 00182 00183 if (num == 0) { 00184 xmms_object_emit_f (XMMS_OBJECT (mrt), 00185 XMMS_IPC_SIGNAL_MEDIAINFO_READER_UNINDEXED, 00186 XMMSV_TYPE_INT32, 00187 xmms_medialib_num_not_resolved (session)); 00188 num = 10; 00189 } else { 00190 num--; 00191 } 00192 00193 xmms_medialib_end (session); 00194 xform = xmms_xform_chain_setup (entry, goal_format, TRUE); 00195 00196 if (!xform) { 00197 if (prev_status == XMMS_MEDIALIB_ENTRY_STATUS_NEW) { 00198 xmms_medialib_entry_remove (entry); 00199 } else { 00200 session = xmms_medialib_begin_write (); 00201 xmms_medialib_entry_status_set (session, entry, XMMS_MEDIALIB_ENTRY_STATUS_NOT_AVAILABLE); 00202 xmms_medialib_end (session); 00203 xmms_medialib_entry_send_update (entry); 00204 } 00205 continue; 00206 } 00207 00208 xmms_object_unref (xform); 00209 g_get_current_time (&timeval); 00210 00211 session = xmms_medialib_begin_write (); 00212 xmms_medialib_entry_status_set (session, entry, XMMS_MEDIALIB_ENTRY_STATUS_OK); 00213 xmms_medialib_entry_property_set_int (session, entry, 00214 XMMS_MEDIALIB_ENTRY_PROPERTY_ADDED, 00215 timeval.tv_sec); 00216 xmms_medialib_end (session); 00217 xmms_medialib_entry_send_update (entry); 00218 00219 } 00220 00221 g_list_free (goal_format); 00222 xmms_object_unref (f); 00223 00224 return NULL; 00225 }