minimal status monitoring added
authorMaksym Veremeyenko <verem@m1stereo.tv>
Wed, 27 Jun 2012 13:15:32 +0000 (16:15 +0300)
committerMaksym Veremeyenko <verem@m1stereo.tv>
Wed, 27 Jun 2012 13:15:32 +0000 (16:15 +0300)
src/Makefile.am
src/instance.h
src/player.c
src/playlist.c
src/playlist.h
src/ui.c
src/ui.h

index 4bd2cde..16224b8 100644 (file)
@@ -22,6 +22,7 @@ melted_gui_SOURCES = \
        ui.c ui.h ui_utils.h \
        ui_buttons.c ui_buttons.h \
        player.c player.h \
+       playlist.c playlist.h \
        opts.c opts.h
 # \
 #      playlist.c \
index 8cd0378..8c6d1fb 100644 (file)
@@ -119,7 +119,6 @@ struct instance_desc;
 typedef struct player_desc
 {
     int idx;
-//    char name[PATH_MAX];
     int unit;
     void* handle;
     GThread* thread;
index bd456b6..03746fa 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include <string.h>
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
 #include <mvcp/mvcp_remote.h>
 
 #include "player.h"
+#include "ui.h"
+#include "timecode.h"
 
-static void* player_thread_proc(void* data)
+static char* status_to_text(mvcp_status status)
 {
-    int r;
-    int playlist_start_prev = 0;
-//    OmPlrStatus st_curr, st_prev;
-    player_t* player = (player_t*)data;
-
-    g_warning("omnplay_thread_proc\n");
+    switch(status->status)
+    {
+        case unit_offline:      return "offline";       break;
+        case unit_undefined:    return "undefined";     break;
+        case unit_not_loaded:   return "unloaded";      break;
+        case unit_stopped:      return "stopped";       break;
+        case unit_playing:      return "playing";       break;
+        case unit_paused:       return "paused";        break;
+        case unit_disconnected: return "disconnect";    break;
+        case unit_unknown:      return "unknown";       break;
+    }
+    return "unknown";
+}
+
+typedef struct player_handle_desc
+{
+    mvcp_parser parser;
+    mvcp conn;
+} player_handle_t;
 
-//    memset(&st_curr, 0, sizeof(OmPlrStatus));
-//    memset(&st_prev, 0, sizeof(OmPlrStatus));
+static void player_update_status(player_t* player, mvcp_status_t *status_prev , mvcp_status_t *status_curr,
+    int *playlist_start_prev)
+{
+    int idx;
+    char tc_cur[32], tc_rem[32], *state, status[32], *clip;
 
-    /* connect */
-    pthread_mutex_lock(&player->app->players.lock);
-//    r = OmPlrOpen(player->host, player->name, (OmPlrHandle*)&player->handle);
-    pthread_mutex_unlock(&player->app->players.lock);
-    if(r)
+    if(status_curr->status == unit_disconnected)
     {
-//        g_warning("ERROR: OmPlrOpen(%s, %s) failed with 0x%.8X\n",
-//            player->host, player->name, r);
+        tc_cur[0] = 0;
+        tc_rem[0] = 0;
+        clip = "";
+        state = "";
+        strcpy(status, "OFFLINE");
+    }
+    else
+    {
+        int p = status_curr->start + (status_curr->position - status_curr->in);
 
-        return (void*)r;
+        frames2tc(p, 25.0, tc_cur);
+        frames2tc(status_curr->dur - p, 25.0, tc_rem);
+        clip = status_curr->clip;
+        state = status_to_text(status_curr);
+        strcpy(status, "ONLINE");
     };
 
-    /* setup to do not reconnect */
-    pthread_mutex_lock(&player->app->players.lock);
-//    OmPlrSetRetryOpen((OmPlrHandle)player->handle, 0);
-    pthread_mutex_unlock(&player->app->players.lock);
+    ui_update_player(player, tc_cur, tc_rem, state, status, clip);
 
-    /* setup directory */
-//    if(player->app->players.path[0])
+    /* update remaining time of playlist's item */
+    pthread_mutex_lock(&player->app->playlist.lock);
+    pthread_mutex_lock(&player->app->players.lock);
+    if(player->playlist_length)
     {
-        pthread_mutex_lock(&player->app->players.lock);
-//        r = OmPlrClipSetDirectory((OmPlrHandle)player->handle, player->app->players.path);
-        pthread_mutex_unlock(&player->app->players.lock);
+        /* clear remain on "previous" item */
+        if((status_curr->clip_index != status_prev->clip_index && 1 != player->playlist_length) ||
+            (*playlist_start_prev != player->playlist_start))
+        {
+            tc_rem[0] = 0;
+            idx = playlist_item_index /* find_index_of_playlist_item */(player->app, *playlist_start_prev, status_prev->clip_index);
+            if(idx >= 0)
+                ui_playlist_draw_item_rem(player->app, idx, tc_rem);
+        };
 
-        if(r)
+        /* update current item */
+        idx = playlist_item_index /* find_index_of_playlist_item */(player->app, player->playlist_start, status_curr->clip_index);
+        if(idx >= 0)
         {
-//            g_warning("ERROR: OmPlrClipSetDirectory(%s) failed with 0x%.8X\n",
-//                player->app->players.path, r);
+            /* reset value */
+            tc_rem[0] = 0;
 
-            pthread_mutex_lock(&player->app->players.lock);
-//            OmPlrClose((OmPlrHandle)player->handle);
-            pthread_mutex_unlock(&player->app->players.lock);
+            /* for play and cue calc new value */
+            if(status_curr->status == unit_stopped || status_curr->status == unit_playing || status_curr->status == unit_paused)
+                frames2tc(status_curr->out - status_curr->position, 25.0, tc_rem);
 
-            return (void*)r;
+            /* setup that value */
+            ui_playlist_draw_item_rem(player->app, idx, tc_rem);
         };
     };
+    pthread_mutex_unlock(&player->app->players.lock);
+    pthread_mutex_unlock(&player->app->playlist.lock);
+};
 
-    /* endless loop */
-    for(r = 0 ; !player->app->f_exit && !r;)
-    {
-        /* sleep */
-#ifdef _WIN32
-        Sleep(100);
-#else
-        usleep(100000);
-#endif
+static void* player_thread_proc(void* data)
+{
+    int r, f;
+    int playlist_start_prev = 0;
+    mvcp_status_t status_curr, status_prev;
+    player_t* player = (player_t*)data;
+    player_handle_t* handle = player->handle;
+    mvcp_notifier notifier = mvcp_get_notifier(handle->conn);
 
-        /* get status */
+    g_warning("player_thread_proc: started\n");
+
+//    memset(&st_curr, 0, sizeof(OmPlrStatus));
+//    memset(&st_prev, 0, sizeof(OmPlrStatus));
+
+    /* endless reconnect loop */
+    for(; !player->app->f_exit;)
+    {
+        /* connect */
         pthread_mutex_lock(&player->app->players.lock);
-//        st_curr.size = sizeof(OmPlrStatus);
-//        r = OmPlrGetPlayerStatus((OmPlrHandle)player->handle, &st_curr);
-        pthread_mutex_unlock(&player->app->players.lock);
+        if(mvcp_connect(handle->conn) == mvcp_ok)
+        {
+            g_warning("player_thread_proc: failed to connect to server\n");
+            sleep(1);
+            continue;
+        };
 
-        if(r)
-            g_warning("ERROR: OmPlrGetPlayerStatus failed with 0x%.8X\n", r);
-        else
+        /* status request loop */
+        for(r = 0, f = 0; !player->app->f_exit && !r;)
         {
-//            omnplay_update_status(player, &st_prev , &st_curr, &playlist_start_prev);
-//            playlist_start_prev = player->playlist_start;
-//            memcmp(&st_curr, &st_prev, sizeof(OmPlrStatus));
+            /* wait for any event from notifier */
+            mvcp_notifier_wait(notifier, &status_curr);
+
+            /* get status for our unit */
+            if(player->unit != status_curr.unit)
+                mvcp_notifier_get(notifier, &status_curr, player->unit);
+
+            /* notify about exit from loop and reconnect */
+            if(status_curr.status == unit_disconnected)
+                r = 1;
+
+            /* do we need to update status */
+            if(!memcmp(&status_curr, &status_prev, sizeof(mvcp_status_t)) || !f)
+            {
+            };
+
+            f = 1;
+            player_update_status(player, &status_prev , &status_curr, &playlist_start_prev);
+            playlist_start_prev = player->playlist_start;
+            status_prev = status_curr;
         };
     };
 
@@ -121,14 +184,19 @@ static void* player_thread_proc(void* data)
 
 void player_run(instance_t* app, int idx)
 {
-    mvcp_parser parser = mvcp_parser_init_remote(app->players.host, 5250);
-    mvcp command = mvcp_init(parser);
-
+    player_handle_t* handle = malloc(sizeof(player_handle_t));
+    handle->parser = mvcp_parser_init_remote(app->players.host, 5250);
+    handle->conn = mvcp_init(handle->parser);
+    app->players.item[idx].handle = handle;
     app->players.item[idx].thread = g_thread_create(
         player_thread_proc, &app->players.item[idx], TRUE, NULL);
 };
 
 void player_stop(instance_t* app, int idx)
 {
+    player_handle_t* handle = app->players.item[idx].handle;
     g_thread_join(app->players.item[idx].thread);
+    mvcp_close(handle->conn);
+    mvcp_parser_close(handle->parser);
+    free(handle);
 };
index f2416a7..4ff0a4b 100644 (file)
 #include <gdk/gdkkeysyms.h>
 #include <pthread.h>
 
-#include "omnplay.h"
+#include "playlist.h"
 #include "ui.h"
 #include "timecode.h"
 
+int playlist_item_index(instance_t* app, int start, int idx)
+{
+    if(start < 0 || start >= app->playlist.count)
+        return -1;
+
+    while(1)
+    {
+        if(app->playlist.item[start].omn_idx == idx)
+            return start;
+
+        if(app->playlist.item[start].type & PLAYLIST_BLOCK_END)
+            break;
+
+        start++;
+    };
+
+    return -1;
+};
+
+
+#if 0
+
 static int load_file_ply(omnplay_instance_t* app, char* filename)
 {
     FILE* f;
@@ -436,3 +458,5 @@ void omnplay_playlist_draw_item_rem(omnplay_instance_t* app, int idx, char* rem)
 
     gtk_tree_model_foreach(GTK_TREE_MODEL(list_store), omnplay_playlist_draw_item_rem_proc, item);
 };
+
+#endif
index 9a9ac58..fe9e22b 100644 (file)
@@ -1,6 +1,49 @@
+/*
+ * playlist.h -- GTK+ 2 melted gui
+ * Copyright (C) 2012 Maksym Veremeyenko <verem@m1stereo.tv>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef PLAYLIST_H
+#define PLAYLIST_H
+
+#include "instance.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/*
+    find local playlist index by given start search position value and remote playlist item index
+    used to associate remote item with local
+ */
+int playlist_item_index(instance_t* app, int start, int idx);
+
+#if 0
 void omnplay_playlist_load(omnplay_instance_t* app);
 void omnplay_playlist_save(omnplay_instance_t* app);
 void omnplay_playlist_relink(omnplay_instance_t* app);
 void omnplay_playlist_draw(omnplay_instance_t* app);
 void omnplay_playlist_draw_item(omnplay_instance_t* app, int idx);
 void omnplay_playlist_draw_item_rem(omnplay_instance_t* app, int idx, char* rem);
+#endif
+
+#ifdef __cplusplus
+};
+#endif /* __cplusplus */
+
+#endif /* PLAYLIST_H */
index c3d75d2..824272b 100644 (file)
--- a/src/ui.c
+++ b/src/ui.c
@@ -733,3 +733,56 @@ int ui_playlist_item_dialog(instance_t* app, playlist_item_t* item)
 
     return r;
 };
+
+/********************************************************************************/
+
+void ui_update_player(player_t* player, char *tc_cur, char *tc_rem, char *state, char *status, char *clip)
+{
+    /* update status in status page */
+    gdk_threads_enter();
+    gtk_label_set_text(GTK_LABEL (player->label_tc_cur), tc_cur);
+    gtk_label_set_text(GTK_LABEL (player->label_tc_rem), tc_rem);
+    gtk_label_set_text(GTK_LABEL (player->label_state), state);
+    gtk_label_set_text(GTK_LABEL (player->label_status), status);
+    gtk_label_set_text(GTK_LABEL (player->label_clip), clip);
+    gdk_flush();
+    gdk_threads_leave();
+};
+
+static gboolean ui_playlist_draw_item_rem_proc(
+    GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer user_data)
+{
+    int i;
+    void** args                 = (void**)user_data;
+    GtkListStore *list_store    = (GtkListStore *)args[1];
+    int idx                     = (int)args[2];
+    char* rem                   = (char*)args[3];
+
+    gtk_tree_model_get(model, iter, 7, &i, -1);
+
+    if(i != idx) return FALSE;
+
+    gtk_list_store_set(list_store, iter, 0, rem, -1);
+
+    return TRUE;
+};
+
+void ui_playlist_draw_item_rem(instance_t* app, int idx, char* rem)
+{
+    void* item[4];
+    GtkListStore *list_store;
+
+    gdk_threads_enter();
+
+    list_store = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(app->playlist_grid)));
+
+    item[0] = (void*)app;
+    item[1] = (void*)list_store;
+    item[2] = (void*)idx;
+    item[3] = (void*)rem;
+
+    gtk_tree_model_foreach(GTK_TREE_MODEL(list_store), ui_playlist_draw_item_rem_proc, item);
+
+    gdk_flush();
+    gdk_threads_leave();
+};
index 475400d..ed3d19b 100644 (file)
--- a/src/ui.h
+++ b/src/ui.h
@@ -28,6 +28,8 @@ extern "C"
 #endif /* __cplusplus */
 
 GtkWidget* ui_create(instance_t* app);
+void ui_update_player(player_t* player, char *tc_cur, char *tc_rem, char *state, char *status, char *clip);
+void ui_playlist_draw_item_rem(instance_t* app, int idx, char* rem);
 //int ui_playlist_item_dialog(omnplay_instance_t* app, playlist_item_t* item);
 
 #ifdef __cplusplus