[vlc-commits] [Git][videolan/vlc][master] 3 commits: decoder: handle potential DecoderWaitUnblock return
Thomas Guillem (@tguillem)
gitlab at videolan.org
Fri Nov 24 20:00:00 UTC 2023
Thomas Guillem pushed to branch master at VideoLAN / VLC
Commits:
8a967f0d by Thomas Guillem at 2023-11-24T19:27:58+00:00
decoder: handle potential DecoderWaitUnblock return
If a wait failed (in case of flush for example, cf. next commit), the
current frame should not be displayed.
- - - - -
3f1bf4e4 by Thomas Guillem at 2023-11-24T19:27:58+00:00
decoder: cancel DecoderWaitUnblock on Flush()
This fixes clock being updated by a point that was decoded just before a flush.
- - - - -
5e9747b6 by Thomas Guillem at 2023-11-24T19:27:58+00:00
test: player: also test without master source
Add a new test: test_src_player_monotonic_clock, same than
test_src_player but with a monotonic clock.
But with one restriction on "test_timers", cf. comment.
- - - - -
3 changed files:
- src/input/decoder.c
- test/Makefile.am
- test/src/player/player.c
Changes:
=====================================
src/input/decoder.c
=====================================
@@ -1029,7 +1029,7 @@ static void RequestReload( vlc_input_decoder_t *p_owner )
atomic_compare_exchange_strong( &p_owner->reload, &expected, RELOAD_DECODER );
}
-static void DecoderWaitUnblock( vlc_input_decoder_t *p_owner )
+static int DecoderWaitUnblock( vlc_input_decoder_t *p_owner )
{
vlc_fifo_Assert(p_owner->p_fifo);
@@ -1039,8 +1039,17 @@ static void DecoderWaitUnblock( vlc_input_decoder_t *p_owner )
vlc_cond_signal( &p_owner->wait_acknowledge );
}
- while( p_owner->b_waiting && p_owner->b_has_data )
+ while (p_owner->b_waiting && p_owner->b_has_data && !p_owner->flushing)
vlc_fifo_WaitCond(p_owner->p_fifo, &p_owner->wait_request);
+
+ if (p_owner->flushing)
+ {
+ p_owner->b_has_data = false;
+ vlc_cond_signal(&p_owner->wait_acknowledge);
+ return VLC_ENOENT;
+ }
+
+ return VLC_SUCCESS;
}
static inline void DecoderUpdatePreroll( vlc_tick_t *pi_preroll, const vlc_frame_t *p )
@@ -1350,7 +1359,12 @@ static int ModuleThread_PlayVideo( vlc_input_decoder_t *p_owner, picture_t *p_pi
}
else
{
- DecoderWaitUnblock( p_owner );
+ int ret = DecoderWaitUnblock(p_owner);
+ if (ret != VLC_SUCCESS)
+ {
+ picture_Release(p_picture);
+ return ret;
+ }
}
if( unlikely(p_owner->paused) && likely(p_owner->frames_countdown > 0) )
@@ -1487,7 +1501,12 @@ static int ModuleThread_PlayAudio( vlc_input_decoder_t *p_owner, vlc_frame_t *p_
vlc_aout_stream_Flush( p_astream );
}
- DecoderWaitUnblock( p_owner );
+ int ret = DecoderWaitUnblock(p_owner);
+ if (ret != VLC_SUCCESS)
+ {
+ block_Release(p_audio);
+ return ret;
+ }
int status = vlc_aout_stream_Play( p_astream, p_audio );
if( status == AOUT_DEC_CHANGED )
@@ -1550,10 +1569,10 @@ static void ModuleThread_PlaySpu( vlc_input_decoder_t *p_owner, subpicture_t *p_
/* */
vlc_fifo_Lock(p_owner->p_fifo);
- DecoderWaitUnblock( p_owner );
+ int ret = DecoderWaitUnblock(p_owner);
vlc_fifo_Unlock(p_owner->p_fifo);
- if( p_subpic->i_start == VLC_TICK_INVALID )
+ if (ret != VLC_SUCCESS || p_subpic->i_start == VLC_TICK_INVALID)
{
subpicture_Delete( p_subpic );
return;
@@ -2538,6 +2557,23 @@ void vlc_input_decoder_Flush( vlc_input_decoder_t *p_owner )
}
}
vlc_fifo_Signal( p_owner->p_fifo );
+
+ if (unlikely(p_owner->b_waiting && p_owner->b_has_data))
+ {
+ /* Signal the output thread to stop waiting from DecoderWaitUnblock()
+ * and to discard the current frame (via 'flushing' = true). */
+ vlc_cond_signal(&p_owner->wait_request);
+
+ /* Flushing is fully asynchronous, but we need to wait for the output
+ * thread to unblock in DecoderWaitUnblock() otherwise there are no
+ * ways to know if the frame referenced when waiting comes from before
+ * or after the flush. Waiting here is almost instantaneous since we
+ * are sure that the output thread is waiting in DecoderWaitUnblock().
+ */
+ while (p_owner->b_has_data)
+ vlc_fifo_WaitCond(p_owner->p_fifo, &p_owner->wait_acknowledge);
+ }
+
vlc_fifo_Unlock( p_owner->p_fifo );
if (vlc_input_decoder_IsSynchronous(p_owner))
=====================================
test/Makefile.am
=====================================
@@ -32,6 +32,7 @@ check_PROGRAMS = \
test_src_input_thumbnail \
test_src_input_decoder \
test_src_player \
+ test_src_player_monotonic_clock \
test_src_interface_dialog \
test_src_media_source \
test_src_misc_bits \
@@ -179,6 +180,9 @@ test_src_input_thumbnail_SOURCES = src/input/thumbnail.c
test_src_input_thumbnail_LDADD = $(LIBVLCCORE) $(LIBVLC)
test_src_player_SOURCES = src/player/player.c
test_src_player_LDADD = $(LIBVLCCORE) $(LIBVLC) $(LIBM)
+test_src_player_monotonic_clock_SOURCES = src/player/player.c
+test_src_player_monotonic_clock_CFLAGS = $(AM_CFLAGS) -DTEST_CLOCK_MONOTONIC
+test_src_player_monotonic_clock_LDADD = $(LIBVLCCORE) $(LIBVLC) $(LIBM)
test_src_misc_bits_SOURCES = src/misc/bits.c
test_src_misc_bits_LDADD = $(LIBVLC)
test_src_misc_epg_SOURCES = src/misc/epg.c
=====================================
test/src/player/player.c
=====================================
@@ -2186,6 +2186,9 @@ ctx_init(struct ctx *ctx, enum ctx_flags flags)
(flags & DISABLE_VIDEO) ? "--no-video" : "--video",
(flags & DISABLE_AUDIO) ? "--no-audio" : "--audio",
"--text-renderer=tdummy",
+#ifdef TEST_CLOCK_MONOTONIC
+ "--clock-master=monotonic",
+#endif
};
libvlc_instance_t *vlc = libvlc_new(ARRAY_SIZE(argv), argv);
assert(vlc);
@@ -2425,6 +2428,12 @@ test_timers_playback(struct ctx *ctx, struct timer_state timers[],
}
}
+/* If there is no master source, we can't known which sources (audio or video)
+ * will feed the timer. Indeed the first source that trigger a clock update
+ * will be used as a timer source (and audio/video goes through decoder threads
+ * and output threads, adding more uncertainty). */
+#ifndef TEST_CLOCK_MONOTONIC
+
/* Assertions for the regular timer that received all update points */
if (track_count != 0)
{
@@ -2474,6 +2483,7 @@ test_timers_playback(struct ctx *ctx, struct timer_state timers[],
}
}
}
+#endif
if (track_count > 0)
test_timers_assert_smpte(&timers[SMPTE_TIMER_IDX], length, fps, false, 3);
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/597400f16506461777ae74173ef208b6d77e614d...5e9747b6db6973ed8af0e20512f547b6ec1900a8
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/597400f16506461777ae74173ef208b6d77e614d...5e9747b6db6973ed8af0e20512f547b6ec1900a8
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