resindvd: send angles-changed messages when appropriate
authorJan Schmidt <thaytan@noraisin.net>
Tue, 5 May 2009 12:14:47 +0000 (13:14 +0100)
committerJan Schmidt <thaytan@noraisin.net>
Wed, 6 May 2009 20:21:37 +0000 (21:21 +0100)
When the current angle changes, or the number of available angles changes,
send an angles-changed message to let the app know.

ext/resindvd/resindvdsrc.c
ext/resindvd/resindvdsrc.h

index ab0fdef..35cf8e1 100644 (file)
@@ -391,6 +391,9 @@ rsn_dvdsrc_start (RsnBaseSrc * bsrc)
 
   src->active_button = -1;
 
+  src->angles_changed = FALSE;
+  src->n_angles = 0;
+
   src->cur_spu_phys_stream = -1;
   src->cur_spu_forced_only = FALSE;
   memset (src->cur_clut, 0, sizeof (guint32) * 16);
@@ -859,6 +862,7 @@ rsn_dvdsrc_step (resinDvdSrc * src, gboolean have_dvd_lock)
       break;
     case DVDNAV_CELL_CHANGE:{
       dvdnav_cell_change_event_t *event = (dvdnav_cell_change_event_t *) data;
+      gint n_angles, cur;
 
       src->pgc_duration = MPEGTIME_TO_GSTTIME (event->pgc_length);
       /* event->cell_start has the wrong time - it doesn't handle
@@ -874,6 +878,12 @@ rsn_dvdsrc_step (resinDvdSrc * src, gboolean have_dvd_lock)
 
       rsn_dvdsrc_prepare_streamsinfo_event (src);
 
+      if (dvdnav_get_angle_info (src->dvdnav, &cur,
+              &n_angles) == DVDNAV_STATUS_OK && src->n_angles != n_angles) {
+        src->angles_changed = TRUE;
+        src->n_angles = n_angles;
+      }
+
       break;
     }
     case DVDNAV_SPU_CLUT_CHANGE:
@@ -998,6 +1008,7 @@ rsn_dvdsrc_create (RsnPushSrc * psrc, GstBuffer ** outbuf)
   GstEvent *spu_select_event = NULL;
   GstEvent *audio_select_event = NULL;
   GstEvent *highlight_event = NULL;
+  GstMessage *angles_msg = NULL;
 
   *outbuf = NULL;
 
@@ -1020,6 +1031,18 @@ rsn_dvdsrc_create (RsnPushSrc * psrc, GstBuffer ** outbuf)
   clut_event = src->clut_event;
   src->clut_event = NULL;
 
+  if (src->angles_changed) {
+    gint cur, agls;
+    if (dvdnav_get_angle_info (src->dvdnav, &cur, &agls) == DVDNAV_STATUS_OK) {
+
+      angles_msg =
+          gst_navigation_message_new_angles_changed (GST_OBJECT_CAST (src),
+          cur, agls);
+      src->n_angles = agls;
+    }
+    src->angles_changed = FALSE;
+  }
+
   g_mutex_unlock (src->dvd_lock);
 
   /* Push in-band events now that we've dropped the dvd_lock, before
@@ -1089,6 +1112,10 @@ rsn_dvdsrc_create (RsnPushSrc * psrc, GstBuffer ** outbuf)
     gst_pad_push_event (GST_BASE_SRC_PAD (src), highlight_event);
   }
 
+  if (angles_msg) {
+    gst_element_post_message (GST_ELEMENT_CAST (src), angles_msg);
+  }
+
   return ret;
 }
 
@@ -1172,7 +1199,6 @@ static RsnNavResult
 rsn_dvdsrc_do_command (resinDvdSrc * src, GstNavigationCommand command)
 {
   RsnNavResult result = RSN_NAV_RESULT_NONE;
-  gint new_angle = 0;
 
   switch (command) {
     case GST_NAVIGATION_COMMAND_DVD_MENU:
@@ -1213,6 +1239,7 @@ rsn_dvdsrc_do_command (resinDvdSrc * src, GstNavigationCommand command)
 
     case GST_NAVIGATION_COMMAND_PREV_ANGLE:{
       gint32 cur, agls;
+      gint new_angle = 0;
       if (dvdnav_get_angle_info (src->dvdnav, &cur, &agls) == DVDNAV_STATUS_OK) {
         if (cur > 0 &&
             dvdnav_angle_change (src->dvdnav, cur - 1) == DVDNAV_STATUS_OK) {
@@ -1222,11 +1249,16 @@ rsn_dvdsrc_do_command (resinDvdSrc * src, GstNavigationCommand command)
           new_angle = agls;
         }
         /* Angle switches are seamless and involve no branching */
+        if (new_angle) {
+          src->angles_changed = TRUE;
+          GST_INFO_OBJECT (src, "Switched to angle %d", new_angle);
+        }
       }
       break;
     }
     case GST_NAVIGATION_COMMAND_NEXT_ANGLE:{
       gint32 cur, agls;
+      gint new_angle = 0;
       if (dvdnav_get_angle_info (src->dvdnav, &cur, &agls) == DVDNAV_STATUS_OK) {
         if (cur < agls
             && dvdnav_angle_change (src->dvdnav, cur + 1) == DVDNAV_STATUS_OK) {
@@ -1236,6 +1268,10 @@ rsn_dvdsrc_do_command (resinDvdSrc * src, GstNavigationCommand command)
           new_angle = 1;
         }
         /* Angle switches are seamless and involve no branching */
+        if (new_angle) {
+          src->angles_changed = TRUE;
+          GST_INFO_OBJECT (src, "Switched to angle %d", new_angle);
+        }
       }
       break;
     }
@@ -1243,10 +1279,6 @@ rsn_dvdsrc_do_command (resinDvdSrc * src, GstNavigationCommand command)
       break;
   }
 
-  if (new_angle) {
-    GST_INFO_OBJECT (src, "Switched to angle %d", new_angle);
-  }
-
   return result;
 }
 
@@ -1258,6 +1290,7 @@ rsn_dvdsrc_handle_navigation_event (resinDvdSrc * src, GstEvent * event)
   RsnNavResult nav_res = RSN_NAV_RESULT_NONE;
   GstNavigationEventType etype = gst_navigation_event_get_type (event);
   GstMessage *mouse_over_msg = NULL;
+  GstMessage *angles_msg = NULL;
 
   switch (etype) {
     case GST_NAVIGATION_EVENT_KEY_PRESS:{
@@ -1438,6 +1471,18 @@ rsn_dvdsrc_handle_navigation_event (resinDvdSrc * src, GstEvent * event)
     hl_event = src->highlight_event;
     src->highlight_event = NULL;
 
+    if (src->angles_changed) {
+      gint cur, agls;
+      if (dvdnav_get_angle_info (src->dvdnav, &cur, &agls) == DVDNAV_STATUS_OK) {
+
+        angles_msg =
+            gst_navigation_message_new_angles_changed (GST_OBJECT_CAST (src),
+            cur, agls);
+        src->n_angles = agls;
+      }
+      src->angles_changed = FALSE;
+    }
+
     g_mutex_unlock (src->dvd_lock);
 
     if (hl_event) {
@@ -1451,6 +1496,10 @@ rsn_dvdsrc_handle_navigation_event (resinDvdSrc * src, GstEvent * event)
     gst_element_post_message (GST_ELEMENT_CAST (src), mouse_over_msg);
   }
 
+  if (angles_msg) {
+    gst_element_post_message (GST_ELEMENT_CAST (src), angles_msg);
+  }
+
   return TRUE;
 not_running:
   if (have_lock)
index 61fa5d1..bfcb749 100644 (file)
@@ -114,6 +114,8 @@ struct _resinDvdSrc
   GstEvent     *audio_select_event;
   GstEvent     *highlight_event;
 
+  gboolean      angles_changed;
+
   /* GList of NAV packets awaiting activation, and the
    * running times to activate them. */
   GSList *pending_nav_blocks;
@@ -129,6 +131,7 @@ struct _resinDvdSrc
   gint8         cur_spu_phys_stream;
   gboolean      cur_spu_forced_only;
   guint32       cur_clut[16];
+  gint          n_angles;
 };
 
 struct _resinDvdSrcClass