[vlc-devel] [RFC] libvlc: support setting seek mode

Zhao Zhili quinkblack at foxmail.com
Thu Jun 14 13:00:10 CEST 2018


---
 include/vlc/libvlc_media_player.h | 17 ++++++++++++++---
 include/vlc_input.h               |  9 +++++++++
 lib/media_player.c                | 17 +++++++++++++++--
 src/input/input.c                 | 25 ++++++++++++++++++++++---
 src/input/var.c                   |  3 +++
 5 files changed, 63 insertions(+), 8 deletions(-)

diff --git a/include/vlc/libvlc_media_player.h b/include/vlc/libvlc_media_player.h
index 9ef1dde..eb4d0ab 100644
--- a/include/vlc/libvlc_media_player.h
+++ b/include/vlc/libvlc_media_player.h
@@ -780,14 +780,22 @@ LIBVLC_API libvlc_time_t libvlc_media_player_get_length( libvlc_media_player_t *
  */
 LIBVLC_API libvlc_time_t libvlc_media_player_get_time( libvlc_media_player_t *p_mi );
 
+typedef enum libvlc_media_player_seek_mode_t {
+    libvlc_seek_mode_auto = 0,
+    libvlc_seek_mode_precise,
+    libvlc_seek_mode_fast
+} libvlc_media_player_seek_mode_t;
+
 /**
  * Set the movie time (in ms). This has no effect if no media is being played.
- * Not all formats and protocols support this.
+ * Not all formats and protocols support this. i_seek_mode is only a hint.
  *
  * \param p_mi the Media Player
+ * \param i_seek_mode values of libvlc_media_player_seek_mode_t
  * \param i_time the movie time (in ms).
  */
-LIBVLC_API void libvlc_media_player_set_time( libvlc_media_player_t *p_mi, libvlc_time_t i_time );
+LIBVLC_API void libvlc_media_player_set_time( libvlc_media_player_t *p_mi,
+                                              libvlc_time_t i_time, int i_seek_mode );
 
 /**
  * Get movie position as percentage between 0.0 and 1.0.
@@ -801,11 +809,14 @@ LIBVLC_API float libvlc_media_player_get_position( libvlc_media_player_t *p_mi )
  * Set movie position as percentage between 0.0 and 1.0.
  * This has no effect if playback is not enabled.
  * This might not work depending on the underlying input format and protocol.
+ * i_seek_mode is only a hint.
  *
  * \param p_mi the Media Player
+ * \param i_seek_mode values of libvlc_media_player_seek_mode_t
  * \param f_pos the position
  */
-LIBVLC_API void libvlc_media_player_set_position( libvlc_media_player_t *p_mi, float f_pos );
+LIBVLC_API void libvlc_media_player_set_position( libvlc_media_player_t *p_mi,
+                                                  float f_pos, int i_seek_mode );
 
 /**
  * Set movie chapter (if applicable).
diff --git a/include/vlc_input.h b/include/vlc_input.h
index 16c566a..ed1f542 100644
--- a/include/vlc_input.h
+++ b/include/vlc_input.h
@@ -490,6 +490,15 @@ enum input_query_e
     INPUT_MODIFY_PCR_SYSTEM,/* arg1=int absolute, arg2=mtime_t      res=can fail */
 };
 
+/**
+ * Input seek mode
+ */
+enum input_seek_mode_e {
+    INPUT_SEEK_MODE_AUTO = 0,
+    INPUT_SEEK_MODE_PRECISE,
+    INPUT_SEEK_MODE_FAST
+};
+
 /** @}*/
 
 /*****************************************************************************
diff --git a/lib/media_player.c b/lib/media_player.c
index cd9d3ee..3bd8f07 100644
--- a/lib/media_player.c
+++ b/lib/media_player.c
@@ -1325,8 +1325,14 @@ libvlc_time_t libvlc_media_player_get_time( libvlc_media_player_t *p_mi )
     return i_time;
 }
 
+static_assert(libvlc_seek_mode_auto == (int)INPUT_SEEK_MODE_AUTO &&
+        libvlc_seek_mode_precise == (int)INPUT_SEEK_MODE_PRECISE &&
+        libvlc_seek_mode_fast == (int)INPUT_SEEK_MODE_FAST,
+        "Mismatch between libvlc_media_player_seek_mode_t and input_seek_mode_e");
+
 void libvlc_media_player_set_time( libvlc_media_player_t *p_mi,
-                                   libvlc_time_t i_time )
+                                   libvlc_time_t i_time,
+                                   int i_seek_mode )
 {
     input_thread_t *p_input_thread;
 
@@ -1334,12 +1340,16 @@ void libvlc_media_player_set_time( libvlc_media_player_t *p_mi,
     if( !p_input_thread )
         return;
 
+    assert(i_seek_mode >= libvlc_seek_mode_auto &&
+           i_seek_mode <= libvlc_seek_mode_fast);
+    var_SetInteger( p_input_thread, "seek-mode", i_seek_mode );
     var_SetInteger( p_input_thread, "time", to_mtime(i_time) );
     vlc_object_release( p_input_thread );
 }
 
 void libvlc_media_player_set_position( libvlc_media_player_t *p_mi,
-                                       float position )
+                                       float position,
+                                       int i_seek_mode )
 {
     input_thread_t *p_input_thread;
 
@@ -1347,6 +1357,9 @@ void libvlc_media_player_set_position( libvlc_media_player_t *p_mi,
     if( !p_input_thread )
         return;
 
+    assert(i_seek_mode >= libvlc_seek_mode_auto &&
+           i_seek_mode <= libvlc_seek_mode_fast);
+    var_SetInteger( p_input_thread, "seek-mode", i_seek_mode );
     var_SetFloat( p_input_thread, "position", position );
     vlc_object_release( p_input_thread );
 }
diff --git a/src/input/input.c b/src/input/input.c
index a413683..e075be4 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -1854,10 +1854,20 @@ static bool Control( input_thread_t *p_input,
                 f_pos = 0.f;
             else if( f_pos > 1.f )
                 f_pos = 1.f;
+
+            bool b_precise;
+            int seek_mode = var_GetInteger( p_input, "seek-mode" );
+            if( seek_mode == INPUT_SEEK_MODE_PRECISE )
+                b_precise = true;
+            else if( seek_mode == INPUT_SEEK_MODE_FAST )
+                b_precise = false;
+            else
+                b_precise = !input_priv(p_input)->b_fast_seek;
+
             /* Reset the decoders states and clock sync (before calling the demuxer */
             es_out_Control( input_priv(p_input)->p_es_out, ES_OUT_RESET_PCR );
             if( demux_Control( input_priv(p_input)->master->p_demux, DEMUX_SET_POSITION,
-                               (double) f_pos, !input_priv(p_input)->b_fast_seek ) )
+                               (double) f_pos, b_precise ) )
             {
                 msg_Err( p_input, "INPUT_CONTROL_SET_POSITION "
                          "%2.1f%% failed", (double)(f_pos * 100.f) );
@@ -1888,12 +1898,21 @@ static bool Control( input_thread_t *p_input,
             if( i_time < 0 )
                 i_time = 0;
 
+            bool b_precise;
+            int seek_mode = var_GetInteger( p_input, "seek-mode" );
+            if( seek_mode == INPUT_SEEK_MODE_PRECISE )
+                b_precise = true;
+            else if( seek_mode == INPUT_SEEK_MODE_FAST )
+                b_precise = false;
+            else
+                b_precise = !input_priv(p_input)->b_fast_seek;
+
             /* Reset the decoders states and clock sync (before calling the demuxer */
             es_out_Control( input_priv(p_input)->p_es_out, ES_OUT_RESET_PCR );
 
             i_ret = demux_Control( input_priv(p_input)->master->p_demux,
                                    DEMUX_SET_TIME, i_time,
-                                   !input_priv(p_input)->b_fast_seek );
+                                   b_precise );
             if( i_ret )
             {
                 int64_t i_length;
@@ -1905,7 +1924,7 @@ static bool Control( input_thread_t *p_input,
                     double f_pos = (double)i_time / (double)i_length;
                     i_ret = demux_Control( input_priv(p_input)->master->p_demux,
                                             DEMUX_SET_POSITION, f_pos,
-                                            !input_priv(p_input)->b_fast_seek );
+                                            b_precise );
                 }
             }
             if( i_ret )
diff --git a/src/input/var.c b/src/input/var.c
index 04c8cb0..ea6a961 100644
--- a/src/input/var.c
+++ b/src/input/var.c
@@ -147,6 +147,9 @@ void input_ControlVarInit ( input_thread_t *p_input )
     var_Create( p_input, "time", VLC_VAR_INTEGER );
     var_Create( p_input, "time-offset", VLC_VAR_INTEGER );    /* relative */
 
+    var_Create( p_input, "seek-mode", VLC_VAR_INTEGER );
+    var_SetInteger( p_input, "seek-mode", INPUT_SEEK_MODE_AUTO );
+
     /* Bookmark */
     var_Create( p_input, "bookmark", VLC_VAR_INTEGER | VLC_VAR_ISCOMMAND );
     var_Change( p_input, "bookmark", VLC_VAR_SETTEXT, _("Bookmark") );
-- 
2.9.5



More information about the vlc-devel mailing list