[vlc-commits] [Git][videolan/vlc][master] 5 commits: input: add input_GetItemDuration function to calculate input thread item duration

Steve Lhomme (@robUx4) gitlab at videolan.org
Mon Sep 16 14:10:03 UTC 2024



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
20ca1dd6 by Ayush Dey at 2024-09-16T13:56:19+00:00
input: add input_GetItemDuration function to calculate input thread item duration

Reverts commit c86e464f and bf5b6d59

Add the input_GetItemDuration function, which calculates the duration of a
track item based on the start and stop times stored in the input thread's private
data. If the stop time is not set, the function considers the provided duration
as the stop time; otherwise, it calculates the duration using the start and stop times.

Call input_GetItemDuration for retrieving the updated duration of the current track
item. The calculated duration is then used to set the player's length accurately.

- - - - -
05c91910 by Ayush Dey at 2024-09-16T13:56:19+00:00
player: add data member `start_offset` in struct vlc_player_timer

This data member `start_offset` will be used in the next commit to store the
start time(which will act as as offset) of the current track so that the current
timestamp is adjusted accordingly.

- - - - -
0cc2d8be by Ayush Dey at 2024-09-16T13:56:19+00:00
player: pass `start_offset` to vlc_player_UpdateTimer() and store it in the player timer

Update the callers of `vlc_player_UpdateTimer()` to pass an additional `start_offset` argument,
representing the start time of the current input item (acting as an offset). Modify the
`vlc_player_UpdateTimer()` function to store this start timing in the player timer, ensuring
accurate tracking of the playback start position.

This change helps maintain correct timing information, particularly when dealing with segmented
tracks or CUE files, by ensuring the player's timer aligns with the actual start time of the input.

- - - - -
d1431101 by Ayush Dey at 2024-09-16T13:56:19+00:00
input: add offset during seek by position operation

Calculate the updated position by adding offset according to the current
track duration.

- - - - -
cc638083 by Ayush Dey at 2024-09-16T13:56:19+00:00
input: add offset during seek by time operation

Add an offset of `priv->i_start` during the seek by time operation to correctly account
for the start time of individual segmented tracks. Modify the initial value passed to
`input_SetTime()` to 0, as the start offset (`priv->i_start`) has already been considered.

These changes ensure accurate timing and seek behavior in media files containing segmented tracks,
such as those defined by CUE files, by aligning the seek position with the actual timing of individual
segments.

- - - - -


6 changed files:

- src/input/input.c
- src/input/input_internal.h
- src/input/parse.c
- src/player/input.c
- src/player/player.h
- src/player/timer.c


Changes:

=====================================
src/input/input.c
=====================================
@@ -556,7 +556,7 @@ static int MainLoopTryRepeat( input_thread_t *p_input )
 
     /* Seek to start position */
     if( priv->i_start > 0 )
-        input_SetTime( p_input, priv->i_start, false );
+        input_SetTime( p_input, 0, false );
     else
         input_SetPosition( p_input, 0.0f, false );
 
@@ -926,7 +926,7 @@ static void SetStopStart( input_thread_t * p_input )
         msg_Dbg( p_input, "starting at time: %"PRId64"s",
                  SEC_FROM_VLC_TICK(priv->i_start) );
 
-        input_SetTime( p_input, priv->i_start, false );
+        input_SetTime( p_input, 0, false );
     }
     if( priv->i_stop > 0 && priv->i_stop <= priv->i_start )
     {
@@ -1943,7 +1943,19 @@ static bool Control( input_thread_t *p_input,
 
             /* Reset the decoders states and clock sync (before calling the demuxer */
             es_out_Control(&priv->p_es_out->out, ES_OUT_RESET_PCR);
-            if( demux_SetPosition( priv->master->p_demux, param.pos.f_val,
+            vlc_tick_t i_length = InputSourceGetLength(priv->master, priv->p_item);
+            double f_val;
+            if( i_length > 0 )
+            {
+                /* Calculate the updated position according to the current track duration */
+                if (priv->i_stop != 0)
+                    f_val = (priv->i_start + param.pos.f_val * (priv->i_stop - priv->i_start)) / i_length;
+                else
+                    f_val = (priv->i_start + param.pos.f_val * (i_length - priv->i_start)) / i_length;
+            }
+            else
+                f_val = param.pos.f_val;
+            if( demux_SetPosition( priv->master->p_demux, f_val,
                                    !param.pos.b_fast_seek ) )
             {
                 msg_Err( p_input, "INPUT_CONTROL_SET_POSITION "
@@ -1973,7 +1985,7 @@ static bool Control( input_thread_t *p_input,
             /* Reset the decoders states and clock sync (before calling the demuxer */
             es_out_Control(&priv->p_es_out->out, ES_OUT_RESET_PCR);
 
-            i_ret = demux_SetTime( priv->master->p_demux, param.time.i_val,
+            i_ret = demux_SetTime( priv->master->p_demux, priv->i_start + param.time.i_val,
                                    !param.time.b_fast_seek );
             if( i_ret )
             {
@@ -1981,7 +1993,7 @@ static bool Control( input_thread_t *p_input,
                 /* Emulate it with a SET_POS */
                 if( i_length > 0 )
                 {
-                    double f_pos = (double)param.time.i_val / (double)i_length;
+                    double f_pos = (double)(priv->i_start + param.time.i_val) / (double)i_length;
                     i_ret = demux_SetPosition( priv->master->p_demux, f_pos,
                                                !param.time.b_fast_seek );
                 }
@@ -3484,15 +3496,14 @@ bool input_CanPaceControl(input_thread_t *input)
     return priv->master->b_can_pace_control;
 }
 
-void input_SetItemDuration(input_thread_t *input, vlc_tick_t duration)
+vlc_tick_t input_GetItemDuration(input_thread_t *input, vlc_tick_t duration)
 {
     input_thread_private_t *priv = input_priv(input);
-    input_item_t *item = input_GetItem(input);
 
     if( priv->i_stop == 0 ) /* consider `duration` as stop time, if stop-time not set */
         duration -= priv->i_start;
     else /* calculate duration based on start-time and stop-time */
         duration = priv->i_stop - priv->i_start;
 
-    input_item_SetDuration(item, duration);
+    return duration;
 }
\ No newline at end of file


=====================================
src/input/input_internal.h
=====================================
@@ -640,15 +640,20 @@ input_attachment_t *input_GetAttachment(input_thread_t *input, const char *name)
 bool input_CanPaceControl(input_thread_t *input);
 
 /**
- * Set the duration of the input item.
+ * Calculates the duration of the item in an input thread.
  *
- * This function sets the duration of the input item associated with the input thread.
- * It uses the 'start-time' and 'stop-time' values to calculate the track duration.
+ * This function determines the duration of a track item based on the start and 
+ * stop times stored in the input thread's private data. If the stop time is not 
+ * set (i.e., equals zero), the function considers the given `duration` as the 
+ * stop time and calculates the effective duration based on the start time. 
+ * Otherwise, it calculates the duration using the set start and stop times.
  *
- * @param input The input thread object.
- * @param duration The duration to be set, in vlc_tick_t units.
+ * @param input   Pointer to the input_thread_t object.
+ * @param duration The initial duration value, used if the stop time is not set.
+ *
+ * @return The calculated duration based on the start and stop times.
  */
-void input_SetItemDuration(input_thread_t *input, vlc_tick_t duration);
+vlc_tick_t input_GetItemDuration(input_thread_t *input, vlc_tick_t duration);
 
 /* Bound pts_delay */
 #define INPUT_PTS_DELAY_MAX VLC_TICK_FROM_SEC(60)


=====================================
src/input/parse.c
=====================================
@@ -56,8 +56,11 @@ input_item_parser_InputEvent(input_thread_t *input,
     switch (event->type)
     {
         case INPUT_EVENT_TIMES:
-            input_SetItemDuration(input, event->times.length);
+        {
+            vlc_tick_t duration = input_GetItemDuration(input, event->times.length);
+            input_item_SetDuration(input_GetItem(input), duration);
             break;
+        }
         case INPUT_EVENT_STATE:
             parser->state = event->state.value;
             break;


=====================================
src/player/input.c
=====================================
@@ -862,6 +862,7 @@ input_thread_Events(input_thread_t *input_thread,
 {
     struct vlc_player_input *input = user_data;
     vlc_player_t *player = input->player;
+    input_thread_private_t *priv = input_priv(input_thread);
 
     assert(input_thread == input->thread);
 
@@ -881,7 +882,7 @@ input_thread_Events(input_thread_t *input_thread,
                                    event->output_clock.master, &point,
                                    VLC_TICK_INVALID,
                                    event->output_clock.frame_rate,
-                                   event->output_clock.frame_rate_base);
+                                   event->output_clock.frame_rate_base, 0);
         }
         else
         {
@@ -916,6 +917,7 @@ input_thread_Events(input_thread_t *input_thread,
         {
             bool changed = false;
             vlc_tick_t system_date = VLC_TICK_INVALID;
+            vlc_tick_t duration = input_GetItemDuration(input->thread, event->times.length);
 
             if (event->times.time != VLC_TICK_INVALID
              && (input->time != event->times.time
@@ -930,10 +932,10 @@ input_thread_Events(input_thread_t *input_thread,
 
                 vlc_player_input_UpdateTime(input);
             }
-            if (input->length != event->times.length)
+            if (input->length != duration)
             {
-                input->length = event->times.length;
-                input_SetItemDuration(input->thread, event->times.length);
+                input->length = duration;
+                input_item_SetDuration(input_GetItem(input->thread), duration);
                 vlc_player_SendEvent(player, on_length_changed, input->length);
                 changed = true;
             }
@@ -955,7 +957,7 @@ input_thread_Events(input_thread_t *input_thread,
                     .system_date = system_date,
                 };
                 vlc_player_UpdateTimer(player, NULL, false, &point,
-                                       input->normal_time, 0, 0);
+                                       input->normal_time, 0, 0, priv->i_start);
             }
             break;
         }


=====================================
src/player/player.h
=====================================
@@ -218,6 +218,7 @@ struct vlc_player_timer
     vlc_tick_t input_length;
     vlc_tick_t input_normal_time;
     vlc_tick_t last_ts;
+    vlc_tick_t start_offset;
     double input_position;
 
     vlc_tick_t seek_ts;
@@ -489,7 +490,8 @@ vlc_player_UpdateTimer(vlc_player_t *player, vlc_es_id_t *es_source,
                        bool es_source_is_master,
                        const struct vlc_player_timer_point *point,
                        vlc_tick_t normal_time,
-                       unsigned frame_rate, unsigned frame_rate_base);
+                       unsigned frame_rate, unsigned frame_rate_base,
+                       vlc_tick_t start_offset);
 
 void
 vlc_player_RemoveTimerSource(vlc_player_t *player, vlc_es_id_t *es_source);


=====================================
src/player/timer.c
=====================================
@@ -34,6 +34,7 @@ vlc_player_ResetTimer(vlc_player_t *player)
     player->timer.input_length = VLC_TICK_INVALID;
     player->timer.input_normal_time = VLC_TICK_0;
     player->timer.last_ts = VLC_TICK_INVALID;
+    player->timer.start_offset = 0;
     player->timer.input_position = 0;
     player->timer.smpte_source.smpte.last_framenum = ULONG_MAX;
     player->timer.seek_ts = VLC_TICK_INVALID;
@@ -318,7 +319,7 @@ vlc_player_UpdateTimerSource(vlc_player_t *player,
     assert(player->timer.input_normal_time >= VLC_TICK_0);
 
     source->point.rate = rate;
-    source->point.ts = ts - player->timer.input_normal_time + VLC_TICK_0;
+    source->point.ts = ts - player->timer.input_normal_time - player->timer.start_offset + VLC_TICK_0;
     source->point.length = player->timer.input_length;
 
     /* Put an invalid date for the first point in order to disable
@@ -330,7 +331,7 @@ vlc_player_UpdateTimerSource(vlc_player_t *player,
         source->point.system_date = system_date;
 
     if (source->point.length != VLC_TICK_INVALID)
-        source->point.position = (ts - player->timer.input_normal_time)
+        source->point.position = (ts - player->timer.input_normal_time - player->timer.start_offset)
                                / (double) source->point.length;
     else
         source->point.position = player->timer.input_position;
@@ -434,7 +435,8 @@ vlc_player_UpdateTimer(vlc_player_t *player, vlc_es_id_t *es_source,
                        bool es_source_is_master,
                        const struct vlc_player_timer_point *point,
                        vlc_tick_t normal_time,
-                       unsigned frame_rate, unsigned frame_rate_base)
+                       unsigned frame_rate, unsigned frame_rate_base,
+                       vlc_tick_t start_offset)
 {
     assert(point);
     /* A null source can't be the master */
@@ -459,6 +461,8 @@ vlc_player_UpdateTimer(vlc_player_t *player, vlc_es_id_t *es_source,
             player->timer.last_ts = VLC_TICK_INVALID;
             force_update = true;
         }
+        if (start_offset > 0)
+            player->timer.start_offset = start_offset;
         /* Will likely be overridden by non input source */
         player->timer.input_position = point->position;
 



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/161998de282bfdbcbb196713cf46fc2ec62c42f0...cc638083ce4afd18d9f352516b6c20fdc4903d6b

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/161998de282bfdbcbb196713cf46fc2ec62c42f0...cc638083ce4afd18d9f352516b6c20fdc4903d6b
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list