XMMS2

src/xmms/mediainfo.c

Go to the documentation of this file.
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 }