XMMS2
src/xmms/mediainfo.c
Go to the documentation of this file.
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 }