]> git.sesse.net Git - vlc/blobdiff - src/control/media_instance.c
control/media_instance.c: Implement get/set chapter. (Patch by Enrique Osuna).
[vlc] / src / control / media_instance.c
index 7d1ca6fa3eba712f51982a74be22303508de0b28..718f3a9192df6285fc2698caabc0c9d258118d87 100644 (file)
 #include <vlc/libvlc.h>
 #include <vlc_demux.h>
 #include <vlc_input.h>
-#include "input/input_internal.h"
 #include "libvlc_internal.h"
+#include "libvlc.h"
 
 /*
  * Release the associated input thread
  *
  * Object lock is NOT held.
  */
-static void release_input_thread( libvlc_media_instance_t *p_mi ) 
+static void release_input_thread( libvlc_media_instance_t *p_mi )
 {
     input_thread_t *p_input_thread;
-    vlc_bool_t should_destroy;
 
     if( !p_mi || p_mi->i_input_id == -1 )
         return;
@@ -48,17 +47,15 @@ static void release_input_thread( libvlc_media_instance_t *p_mi )
 
     if( !p_input_thread )
         return;
-    
     /* release for previous vlc_object_get */
     vlc_object_release( p_input_thread );
 
-    should_destroy = p_input_thread->i_refcount == 1;
-
     /* release for initial p_input_thread yield (see _new()) */
     vlc_object_release( p_input_thread );
 
     /* No one is tracking this input_thread appart us. Destroy it */
-    if( should_destroy )
+    if( p_mi->b_own_its_input_thread )
     {
         /* We owned this one */
         input_StopThread( p_input_thread );
@@ -69,7 +66,7 @@ static void release_input_thread( libvlc_media_instance_t *p_mi )
     {
         /* XXX: hack the playlist doesn't retain the input thread,
          * so we did it for the playlist (see _new_from_input_thread),
-         * revert that here. */
+         * revert that here. This will be deleted with the playlist API */
         vlc_object_release( p_input_thread );
     }
 }
@@ -81,7 +78,7 @@ static void release_input_thread( libvlc_media_instance_t *p_mi )
  * Object lock is held.
  */
 input_thread_t *libvlc_get_input_thread( libvlc_media_instance_t *p_mi,
-                                         libvlc_exception_t *p_e ) 
+                                         libvlc_exception_t *p_e )
 {
     input_thread_t *p_input_thread;
 
@@ -149,7 +146,7 @@ input_position_changed( vlc_object_t * p_this, char const * psz_cmd,
 {
     libvlc_media_instance_t * p_mi = p_userdata;
     vlc_value_t val;
-    
     if (!strcmp(psz_cmd, "intf" /* "-change" no need to go further */))
     {
         input_thread_t * p_input = (input_thread_t *)p_this;
@@ -199,6 +196,7 @@ libvlc_media_instance_new( libvlc_instance_t * p_libvlc_instance,
      *   operation the refcount is 0, the object is destroyed.
      * - Accessor _retain increase the refcount by 1 (XXX: to implement) */
     p_mi->i_refcount = 1;
+    p_mi->b_own_its_input_thread = VLC_TRUE;
     /* object_lock strategy:
      * - No lock held in constructor
      * - Lock when accessing all variable this lock is held
@@ -215,6 +213,12 @@ libvlc_media_instance_new( libvlc_instance_t * p_libvlc_instance,
  
     libvlc_event_manager_register_event_type( p_mi->p_event_manager,
             libvlc_MediaInstanceReachedEnd, p_e );
+    libvlc_event_manager_register_event_type( p_mi->p_event_manager,
+            libvlc_MediaInstancePaused, p_e );
+    libvlc_event_manager_register_event_type( p_mi->p_event_manager,
+            libvlc_MediaInstancePlayed, p_e );
+    libvlc_event_manager_register_event_type( p_mi->p_event_manager,
+            libvlc_MediaInstancePositionChanged, p_e );
 
     return p_mi;
 }
@@ -262,7 +266,7 @@ libvlc_media_instance_t * libvlc_media_instance_new_from_input_thread(
 
     p_mi->p_md = libvlc_media_descriptor_new_from_input_item(
                     p_libvlc_instance,
-                    p_input->p->input.p_item, p_e );
+                    input_GetItem( p_input ), p_e );
 
     if( !p_mi->p_md )
     {
@@ -271,7 +275,8 @@ libvlc_media_instance_t * libvlc_media_instance_new_from_input_thread(
     }
 
     p_mi->i_input_id = p_input->i_object_id;
-    
+    p_mi->b_own_its_input_thread = VLC_FALSE;
+
     /* will be released in media_instance_release() */
     vlc_object_yield( p_input );
 
@@ -302,6 +307,7 @@ void libvlc_media_instance_destroy( libvlc_media_instance_t *p_mi )
     if( libvlc_exception_raised( &p_e ) )
     {
         libvlc_event_manager_release( p_mi->p_event_manager );
+        libvlc_exception_clear( &p_e );
         free( p_mi );
         return; /* no need to worry about no input thread */
     }
@@ -323,7 +329,7 @@ void libvlc_media_instance_release( libvlc_media_instance_t *p_mi )
         return;
 
     vlc_mutex_lock( &p_mi->object_lock );
-    
     p_mi->i_refcount--;
 
     if( p_mi->i_refcount > 0 )
@@ -334,10 +340,10 @@ void libvlc_media_instance_release( libvlc_media_instance_t *p_mi )
     vlc_mutex_unlock( &p_mi->object_lock );
     vlc_mutex_destroy( &p_mi->object_lock );
 
-    libvlc_event_manager_release( p_mi->p_event_manager );
-    
     release_input_thread( p_mi );
 
+    libvlc_event_manager_release( p_mi->p_event_manager );
     libvlc_media_descriptor_release( p_mi->p_md );
 
     free( p_mi );
@@ -353,6 +359,7 @@ void libvlc_media_instance_retain( libvlc_media_instance_t *p_mi )
 
     p_mi->i_refcount++;
 }
+
 /**************************************************************************
  * Set the Media descriptor associated with the instance
  **************************************************************************/
@@ -381,7 +388,7 @@ void libvlc_media_instance_set_media_descriptor(
 
     libvlc_media_descriptor_retain( p_md );
     p_mi->p_md = p_md;
-    
     /* The policy here is to ignore that we were created using a different
      * libvlc_instance, because we don't really care */
     p_mi->p_libvlc_instance = p_md->p_libvlc_instance;
@@ -427,13 +434,10 @@ void libvlc_media_instance_play( libvlc_media_instance_t *p_mi,
 {
     input_thread_t * p_input_thread;
 
-    if( (p_input_thread = libvlc_get_input_thread( p_mi, p_e )) ) 
+    if( (p_input_thread = libvlc_get_input_thread( p_mi, p_e )) )
     {
-        /* A thread alread exists, send it a play message */        
-        vlc_value_t val;
-        val.i_int = PLAYING_S;
-
-        input_Control( p_input_thread, INPUT_CONTROL_SET_STATE, PLAYING_S );
+        /* A thread alread exists, send it a play message */
+        input_Control( p_input_thread, INPUT_SET_STATE, PLAYING_S );
         vlc_object_release( p_input_thread );
         return;
     }
@@ -442,7 +446,7 @@ void libvlc_media_instance_play( libvlc_media_instance_t *p_mi,
     libvlc_exception_clear( p_e );
 
     vlc_mutex_lock( &p_mi->object_lock );
-    
     if( !p_mi->p_md )
     {
         libvlc_exception_raise( p_e, "no associated media descriptor" );
@@ -476,16 +480,12 @@ void libvlc_media_instance_play( libvlc_media_instance_t *p_mi,
 void libvlc_media_instance_pause( libvlc_media_instance_t *p_mi,
                                   libvlc_exception_t *p_e )
 {
-    input_thread_t * p_input_thread;
-    vlc_value_t val;
-    val.i_int = PAUSE_S;
-
-    p_input_thread = libvlc_get_input_thread( p_mi, p_e );
+    input_thread_t * p_input_thread = libvlc_get_input_thread( p_mi, p_e );
 
     if( !p_input_thread )
         return;
 
-    input_Control( p_input_thread, INPUT_CONTROL_SET_STATE, val );
+    input_Control( p_input_thread, INPUT_SET_STATE, PAUSE_S );
     vlc_object_release( p_input_thread );
 }
 
@@ -564,7 +564,7 @@ void libvlc_media_instance_set_time(
 void libvlc_media_instance_set_position(
                                 libvlc_media_instance_t *p_mi,
                                 float position,
-                                libvlc_exception_t *p_e ) 
+                                libvlc_exception_t *p_e )
 {
     input_thread_t *p_input_thread;
     vlc_value_t val;
@@ -595,41 +595,83 @@ float libvlc_media_instance_get_position(
     return val.f_float;
 }
 
-float libvlc_media_instance_get_fps(
+void libvlc_media_instance_set_chapter(
                                  libvlc_media_instance_t *p_mi,
-                                 libvlc_exception_t *p_e) 
+                                 int chapter,
+                                 libvlc_exception_t *p_e )
 {
-    double f_fps = 0.0;
     input_thread_t *p_input_thread;
+    vlc_value_t val;
+    val.i_int = chapter;
+
+    p_input_thread = libvlc_get_input_thread ( p_mi, p_e);
+    if( !p_input_thread )
+        return;
+
+    var_Set( p_input_thread, "chapter", val );
+    vlc_object_release( p_input_thread );
+}
+
+int libvlc_media_instance_get_chapter(
+                                 libvlc_media_instance_t *p_mi,
+                                 libvlc_exception_t *p_e )
+{
+    input_thread_t *p_input_thread;
+    vlc_value_t val;
 
     p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
     if( !p_input_thread )
-        return 0.0;
+        return -1.0;
 
-    if( (NULL == p_input_thread->p->input.p_demux)
-        || demux2_Control( p_input_thread->p->input.p_demux, DEMUX_GET_FPS, &f_fps )
-        || f_fps < 0.1 )
-    {
-        vlc_object_release( p_input_thread );
-        return 0.0;
-    }
-    else
+    var_Get( p_input_thread, "chapter", &val );
+    vlc_object_release( p_input_thread );
+
+    return val.i_int;
+}
+
+int libvlc_media_instance_get_chapter_count(
+                                 libvlc_media_instance_t *p_mi,
+                                 libvlc_exception_t *p_e )
+{
+    input_thread_t *p_input_thread;
+    vlc_value_t val;
+
+    p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
+    if( !p_input_thread )
+        return -1.0;
+
+    var_Change( p_input_thread, "chapter", VLC_VAR_CHOICESCOUNT, &val, NULL );
+    vlc_object_release( p_input_thread );
+
+    return val.i_int;
+}
+
+float libvlc_media_instance_get_fps(
+                                 libvlc_media_instance_t *p_mi,
+                                 libvlc_exception_t *p_e)
+{
+    input_thread_t *p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
+    double f_fps = 0.0;
+
+    if( p_input_thread )
     {
+        if( input_Control( p_input_thread, INPUT_GET_VIDEO_FPS, &f_fps ) )
+            f_fps = 0.0;
         vlc_object_release( p_input_thread );
-        return( f_fps );
     }
+    return f_fps;
 }
 
 vlc_bool_t libvlc_media_instance_will_play(
                                  libvlc_media_instance_t *p_mi,
-                                 libvlc_exception_t *p_e) 
+                                 libvlc_exception_t *p_e)
 {
     input_thread_t *p_input_thread =
                             libvlc_get_input_thread ( p_mi, p_e);
     if ( !p_input_thread )
         return VLC_FALSE;
 
-    if ( !p_input_thread->b_die && !p_input_thread->b_dead ) 
+    if ( !p_input_thread->b_die && !p_input_thread->b_dead )
     {
         vlc_object_release( p_input_thread );
         return VLC_TRUE;
@@ -641,7 +683,7 @@ vlc_bool_t libvlc_media_instance_will_play(
 void libvlc_media_instance_set_rate(
                                  libvlc_media_instance_t *p_mi,
                                  float rate,
-                                 libvlc_exception_t *p_e ) 
+                                 libvlc_exception_t *p_e )
 {
     input_thread_t *p_input_thread;
     vlc_value_t val;
@@ -676,7 +718,18 @@ float libvlc_media_instance_get_rate(
     return (float)1000.0f/val.i_int;
 }
 
-int libvlc_media_instance_get_state(
+static const libvlc_state_t vlc_to_libvlc_state[] =
+{
+    [INIT_S]        = libvlc_Opening,
+    [OPENING_S]     = libvlc_Opening,
+    [BUFFERING_S]   = libvlc_Buffering,    
+    [PLAYING_S]     = libvlc_Playing,    
+    [PAUSE_S]       = libvlc_Paused,    
+    [END_S]         = libvlc_Ended,    
+    [ERROR_S]       = libvlc_Error,    
+};
+
+libvlc_state_t libvlc_media_instance_get_state(
                                  libvlc_media_instance_t *p_mi,
                                  libvlc_exception_t *p_e )
 {
@@ -685,10 +738,13 @@ int libvlc_media_instance_get_state(
 
     p_input_thread = libvlc_get_input_thread ( p_mi, p_e );
     if ( !p_input_thread )
-        return 0;
+        return libvlc_Stopped;
 
     var_Get( p_input_thread, "state", &val );
     vlc_object_release( p_input_thread );
 
-    return val.i_int;
+    if( val.i_int < 0 || val.i_int > 6 )
+        return libvlc_Stopped;
+
+    return vlc_to_libvlc_state[val.i_int];
 }