From 48dee11ecb5cc6c4006f8dcc47ca4c7cf57b8b0e Mon Sep 17 00:00:00 2001 From: Maksym Veremeyenko Date: Wed, 27 Jun 2012 16:15:32 +0300 Subject: [PATCH] minimal status monitoring added --- src/Makefile.am | 1 + src/instance.h | 1 - src/player.c | 178 ++++++++++++++++++++++++++++++++++++++----------------- src/playlist.c | 26 ++++++++- src/playlist.h | 43 +++++++++++++ src/ui.c | 53 ++++++++++++++++ src/ui.h | 2 + 7 files changed, 247 insertions(+), 57 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 4bd2cde..16224b8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \ diff --git a/src/instance.h b/src/instance.h index 8cd0378..8c6d1fb 100644 --- a/src/instance.h +++ b/src/instance.h @@ -119,7 +119,6 @@ struct instance_desc; typedef struct player_desc { int idx; -// char name[PATH_MAX]; int unit; void* handle; GThread* thread; diff --git a/src/player.c b/src/player.c index bd456b6..03746fa 100644 --- a/src/player.c +++ b/src/player.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -35,79 +36,141 @@ #include #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); }; diff --git a/src/playlist.c b/src/playlist.c index f2416a7..4ff0a4b 100644 --- a/src/playlist.c +++ b/src/playlist.c @@ -28,10 +28,32 @@ #include #include -#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 diff --git a/src/playlist.h b/src/playlist.h index 9a9ac58..fe9e22b 100644 --- a/src/playlist.h +++ b/src/playlist.h @@ -1,6 +1,49 @@ +/* + * playlist.h -- GTK+ 2 melted gui + * Copyright (C) 2012 Maksym Veremeyenko + * + * 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 */ diff --git a/src/ui.c b/src/ui.c index c3d75d2..824272b 100644 --- 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(); +}; diff --git a/src/ui.h b/src/ui.h index 475400d..ed3d19b 100644 --- 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 -- 1.7.4.4