add loop enabling code
[omnplay] / src / omnplay.cpp
index 9adc1b2..c58a33f 100644 (file)
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
 #endif
@@ -133,7 +137,7 @@ static void* omnplay_thread_proc(void* data)
     if(player->app->players.path[0])
     {
         pthread_mutex_lock(&player->app->players.lock);
-//        r = OmPlrClipSetDirectory((OmPlrHandle)player->handle, player->app->players.path);
+        r = OmPlrClipSetDirectory((OmPlrHandle)player->handle, player->app->players.path);
         pthread_mutex_unlock(&player->app->players.lock);
 
         if(r)
@@ -225,8 +229,9 @@ static omnplay_player_t *get_player_at_pos(omnplay_instance_t* app, int pos)
     return NULL;
 };
 
-static void omnplay_cue(omnplay_instance_t* app)
+static void omnplay_ctl(omnplay_instance_t* app, control_buttons_t button)
 {
+    int i, r;
     int idx, start, stop;
     omnplay_player_t *player;
 
@@ -258,22 +263,122 @@ static void omnplay_cue(omnplay_instance_t* app)
         return;
     };
 
-    /* 1. stop */
     pthread_mutex_lock(&app->players.lock);
-    OmPlrStop((OmPlrHandle)player->handle);
-    player->playlist_start = -1;
-    player->playlist_count = -1;
-    pthread_mutex_unlock(&app->players.lock);
 
-    /* 2. detach previous clips */
-    pthread_mutex_lock(&app->players.lock);
-    OmPlrDetachAllClips((OmPlrHandle)player->handle);
-    pthread_mutex_unlock(&app->players.lock);
+    if(BUTTON_PLAYER_STOP == button || BUTTON_PLAYER_CUE == button)
+    {
+        /* stop */
+        OmPlrStop((OmPlrHandle)player->handle);
 
-    // http://research.m1stereo.tv/viewvc-int/viewvc.cgi/Ingest2Srv/trunk/SrvPlayCtl.cpp?view=markup
+        /* detach previous clips */
+        player->playlist_start = -1;
+        player->playlist_count = -1;
+        OmPlrDetachAllClips((OmPlrHandle)player->handle);
+    };
 
-    pthread_mutex_unlock(&app->playlist.lock);
+    if(BUTTON_PLAYER_CUE == button)
+    {
+        int o, c, p = 0;
+
+        /* Attach clips to timeline */
+        for(i = start, c = 0, o = 0; i <= stop; i++)
+        {
+            OmPlrClipInfo clip;
+
+            /* get clip info */
+            clip.maxMsTracks = 0; 
+            clip.size = sizeof(clip);
+            r = OmPlrClipGetInfo((OmPlrHandle)player->handle, app->playlist.item[i].id, &clip);
+
+            if(!r)
+            {
+                unsigned int l;
+
+                fprintf(stderr, "OmPlrClipGetInfo(%s): firstFrame=%d, lastFrame=%d\n",
+                    app->playlist.item[i].id, clip.firstFrame, clip.lastFrame);
+
+                /* should we fix playlist clip timings */
+                if(!(
+                    app->playlist.item[i].in >= clip.firstFrame &&
+                    app->playlist.item[i].in + app->playlist.item[i].dur <= clip.lastFrame) ||
+                    !app->playlist.item[i].dur)
+                {
+                    fprintf(stderr, "cue: item [%s] will be updated [%d;%d]->[%d;%d]\n",
+                        app->playlist.item[i].id,
+                        app->playlist.item[i].in, app->playlist.item[i].dur,
+                        clip.firstFrame, clip.lastFrame - clip.firstFrame);
+
+                    app->playlist.item[i].in = clip.firstFrame;
+                    app->playlist.item[i].dur = clip.lastFrame - clip.firstFrame;
+                    omnplay_playlist_draw_item(app, i);
+                };
+
+                r = OmPlrAttach((OmPlrHandle)player->handle,
+                    app->playlist.item[i].id,
+                    app->playlist.item[i].in,
+                    app->playlist.item[i].in + app->playlist.item[i].dur,
+                    0, omPlrShiftModeAfter, &l);
+            };
+
+            if(r)
+            {
+                fprintf(stderr, "cue: failed with %d, %s\n", r, OmPlrGetErrorString((OmPlrError)r));
+                app->playlist.item[i].omn_idx = -1;
+                app->playlist.item[i].omn_offset = -1;
+            }
+            else
+            {
+                app->playlist.item[i].omn_idx = c;
+                app->playlist.item[i].omn_offset = o;
+
+                /* save selected item offset */
+                if(i == idx) p = o;
+
+                c++;
+                o += app->playlist.item[i].dur;
+            };
+        };
+
+        if(c)
+        {
+            OmPlrStatus hs;
+
+            /* Set timeline min/max */
+            OmPlrSetMinPosMin((OmPlrHandle)player->handle);
+            OmPlrSetMaxPosMax((OmPlrHandle)player->handle);
+
+            /* Set timeline position */
+            hs.minPos = 0;
+            hs.size = sizeof(OmPlrStatus);
+            OmPlrGetPlayerStatus((OmPlrHandle)player->handle, &hs);
+            OmPlrSetPos((OmPlrHandle)player->handle, hs.minPos + p);
+
+            /* setup loop */
+            if(app->playlist.item[start].type & OMNPLAY_PLAYLIST_BLOCK_LOOP)
+                OmPlrLoop((OmPlrHandle)player->handle, hs.minPos, hs.maxPos);
 
+            /* Cue */
+            OmPlrCuePlay((OmPlrHandle)player->handle, 0.0);
+            OmPlrPlay((OmPlrHandle)player->handle, 0.0);
+
+            player->playlist_start = start;
+            player->playlist_count = stop - start + 1;
+        };
+    };
+
+    if(BUTTON_PLAYER_PLAY == button)
+    {
+        /* play */
+        OmPlrPlay((OmPlrHandle)player->handle, 1.0);
+    };
+
+    if(BUTTON_PLAYER_PAUSE == button)
+        /* pause */
+        OmPlrPlay((OmPlrHandle)player->handle, 0.0);
+
+    pthread_mutex_unlock(&app->players.lock);
+
+    pthread_mutex_unlock(&app->playlist.lock);
 };
 
 static gboolean omnplay_button_click(omnplay_instance_t* app, control_buttons_t button)
@@ -283,6 +388,7 @@ static gboolean omnplay_button_click(omnplay_instance_t* app, control_buttons_t
         case BUTTON_PLAYLIST_ITEM_ADD:
         case BUTTON_PLAYLIST_ITEM_DEL:
         case BUTTON_PLAYLIST_ITEM_EDIT:
+            break;
         case BUTTON_PLAYLIST_LOAD:
             omnplay_playlist_load(app);
             break;
@@ -291,13 +397,16 @@ static gboolean omnplay_button_click(omnplay_instance_t* app, control_buttons_t
             break;
         case BUTTON_PLAYLIST_BLOCK_SINGLE:
         case BUTTON_PLAYLIST_BLOCK_LOOP:
+            break;
         case BUTTON_PLAYLIST_ITEM_UP:
         case BUTTON_PLAYLIST_ITEM_DOWN:
+            break;
         case BUTTON_PLAYER_CUE:
-            omnplay_cue(app);
         case BUTTON_PLAYER_PLAY:
         case BUTTON_PLAYER_PAUSE:
         case BUTTON_PLAYER_STOP:
+            omnplay_ctl(app, button);
+            break;
         case BUTTON_LIBRARY_ADD:
         case BUTTON_LIBRARY_REFRESH:
             break;
@@ -321,12 +430,15 @@ static gboolean on_button_click(GtkWidget *button, gpointer user_data)
 void omnplay_init(omnplay_instance_t* app)
 {
     int i;
+    pthread_mutexattr_t attr;
+
+    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
 
     gtk_signal_connect( GTK_OBJECT( app->window ), "destroy",
         GTK_SIGNAL_FUNC(on_main_window_delete_event), app);
 
     /* create lock */
-    pthread_mutex_init(&app->players.lock, NULL);
+    pthread_mutex_init(&app->players.lock, &attr);
 
     /* create a omneon status thread */
     for(i = 0; i < app->players.count; i++)
@@ -334,7 +446,7 @@ void omnplay_init(omnplay_instance_t* app)
             omnplay_thread_proc, &app->players.item[i]);
 
     /* create lock */
-    pthread_mutex_init(&app->playlist.lock, NULL);
+    pthread_mutex_init(&app->playlist.lock, &attr);
 
     /* attach buttons click */
     for(i = 1; i < BUTTON_LAST; i++)