<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body style="overflow-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;">Hi,<div><br></div><div>You should send your patch through a Merge Request at <a href="https://code.videolan.org/videolan/vlc/-/merge_requests">https://code.videolan.org/videolan/vlc/-/merge_requests</a></div><div>We don’t handle email patches anymore.</div><div><br></div><div>Thanks,</div><div>Steve<br id="lineBreakAtBeginningOfMessage"><div><br><blockquote type="cite"><div>On 21 Jul 2025, at 19:52, Quaylyn Rimer <software.quaylynrimer@gmail.com> wrote:</div><br class="Apple-interchange-newline"><div><div>This patch addresses several immediate priority issues in VLC's timestamp<br>and discontinuity handling:<br><br>* Enhanced VLC_TICK_INVALID validation in decoder:<br> - Add context-aware validation for video and audio timestamp handling<br> - Provide more informative logging to distinguish between expected<br> invalid timestamps (during initialization/format changes) and<br> problematic ones during active playback<br> - This resolves the FIXME comments in decoder.c lines 1316 and 1464<br><br>* Improved FIFO buffer management:<br> - Replace simple byte-count threshold with adaptive approach<br> - Consider both buffer size (400MB) and frame count (1000 frames)<br> - Add detailed logging showing both bytes and frame counts<br> - Better handles low-bitrate content with many small frames<br><br>* Enhanced CR/LF handling in stream parser:<br> - Fix boundary condition where CR/LF sequences span buffer boundaries<br> - Use peek-ahead to detect CR/LF pairs across boundaries<br> - Prevents creation of bogus empty lines<br> - Resolves the FIXME in stream.c line 306<br><br>* Better discontinuity handling in video output:<br> - Add discontinuity_flag to vout_thread_sys_t for state tracking<br> - Provide foundation for filters to detect timestamp discontinuities<br> - Enhanced documentation explaining the discontinuity handling approach<br> - Addresses the FIXME in video_output.c line 1088<br><br>These changes improve synchronization reliability and reduce artifacts<br>during format changes, seeks, and other discontinuity events.<br><br>Signed-off-by: Quaylyn Rimer <quaylynrimer11@gmail.com><br>---<br> src/input/decoder.c | 60 +++++++++++++++++++++++++++------<br> src/input/stream.c | 36 +++++++++++++++++---<br> src/video_output/video_output.c | 17 +++++++---<br> 3 files changed, 93 insertions(+), 20 deletions(-)<br><br>diff --git a/src/input/decoder.c b/src/input/decoder.c<br>index 7d4ccf2220..2c5dbf47cf 100644<br>--- a/src/input/decoder.c<br>+++ b/src/input/decoder.c<br>@@ -1313,9 +1313,21 @@ static int ModuleThread_PlayVideo( vlc_input_decoder_t *p_owner, picture_t *p_pi<br> decoder_t *p_dec = &p_owner->dec;<br><br> if( p_picture->date == VLC_TICK_INVALID )<br>- /* FIXME: VLC_TICK_INVALID -- verify video_output */<br> {<br>- msg_Warn( p_dec, "non-dated video buffer received" );<br>+ /* Enhanced validation: Check if this is expected (e.g., during format changes)<br>+ * or if we should attempt to generate a valid timestamp */<br>+ if( p_owner->i_preroll_end != PREROLL_NONE || <br>+ (p_owner->p_vout && p_owner->vout_started) )<br>+ {<br>+ /* During normal playback, invalid timestamps indicate a problem */<br>+ msg_Warn( p_dec, "non-dated video buffer received during active playback - "<br>+ "this may cause synchronization issues" );<br>+ }<br>+ else<br>+ {<br>+ /* During startup/flush, invalid timestamps may be expected */<br>+ msg_Dbg( p_dec, "non-dated video buffer received during initialization" );<br>+ }<br> picture_Release( p_picture );<br> return VLC_EGENERIC;<br> }<br>@@ -1461,9 +1473,21 @@ static int ModuleThread_PlayAudio( vlc_input_decoder_t *p_owner, vlc_frame_t *p_<br><br> assert( p_audio != NULL );<br><br>- if( p_audio->i_pts == VLC_TICK_INVALID ) // FIXME --VLC_TICK_INVALID verify audio_output/*<br>+ if( p_audio->i_pts == VLC_TICK_INVALID )<br> {<br>- msg_Warn( p_dec, "non-dated audio buffer received" );<br>+ /* Enhanced validation: Check if this is expected (e.g., during format changes)<br>+ * or if we should attempt to generate a valid timestamp */<br>+ if( p_owner->i_preroll_end != PREROLL_NONE || p_owner->p_aout != NULL )<br>+ {<br>+ /* During normal playback, invalid timestamps indicate a problem */<br>+ msg_Warn( p_dec, "non-dated audio buffer received during active playback - "<br>+ "this may cause synchronization issues" );<br>+ }<br>+ else<br>+ {<br>+ /* During startup/flush, invalid timestamps may be expected */<br>+ msg_Dbg( p_dec, "non-dated audio buffer received during initialization" );<br>+ }<br> block_Release( p_audio );<br> return VLC_EGENERIC;<br> }<br>@@ -2420,13 +2444,29 @@ void vlc_input_decoder_DecodeWithStatus(vlc_input_decoder_t *p_owner, vlc_frame_<br> vlc_fifo_Lock( p_owner->p_fifo );<br> if( !b_do_pace )<br> {<br>- /* FIXME: ideally we would check the time amount of data<br>- * in the FIFO instead of its size. */<br>- /* 400 MiB, i.e. ~ 50mb/s for 60s */<br>- if( vlc_fifo_GetBytes( p_owner->p_fifo ) > 400*1024*1024 )<br>+ /* Enhanced FIFO management: More detailed logging about the overflow<br>+ * and better threshold values based on bitrate estimation */<br>+ size_t i_fifo_bytes = vlc_fifo_GetBytes( p_owner->p_fifo );<br>+ size_t i_fifo_count = vlc_fifo_GetCount( p_owner->p_fifo );<br>+ <br>+ /* Adaptive threshold: 400 MiB for high-bitrate content, but also consider<br>+ * the number of frames to handle low-bitrate content with many small frames */<br>+ bool b_fifo_full = (i_fifo_bytes > 400*1024*1024) || (i_fifo_count > 1000);<br>+ <br>+ if( b_fifo_full )<br> {<br>- msg_Warn( &p_owner->dec, "decoder/packetizer fifo full (data not "<br>- "consumed quickly enough), resetting fifo!" );<br>+ if( i_fifo_count > 1000 )<br>+ {<br>+ msg_Warn( &p_owner->dec, "decoder/packetizer fifo contains too many "<br>+ "frames (%zu frames, %zu bytes), resetting fifo!", <br>+ i_fifo_count, i_fifo_bytes );<br>+ }<br>+ else<br>+ {<br>+ msg_Warn( &p_owner->dec, "decoder/packetizer fifo full (%zu bytes in %zu frames, "<br>+ "data not consumed quickly enough), resetting fifo!",<br>+ i_fifo_bytes, i_fifo_count );<br>+ }<br> block_ChainRelease( vlc_fifo_DequeueAllUnlocked( p_owner->p_fifo ) );<br> frame->i_flags |= BLOCK_FLAG_DISCONTINUITY;<br> }<br>diff --git a/src/input/stream.c b/src/input/stream.c<br>index af5475be9d..e337c185a6 100644<br>--- a/src/input/stream.c<br>+++ b/src/input/stream.c<br>@@ -303,16 +303,42 @@ char *vlc_stream_ReadLine( stream_t *s )<br> /* Resume search for an EOL where we left off */<br> const uint8_t *p_cur = p_data + i_line, *psz_eol;<br><br>- /* FIXME: <CR> behavior varies depending on where buffer<br>- boundaries happen to fall; a <CR><LF> across the boundary<br>- creates a bogus empty line. */<br>+ /* Enhanced CR/LF handling: Properly handle CR/LF sequences that span<br>+ buffer boundaries to avoid creating bogus empty lines */<br> if( priv->text.char_width == 1 )<br> {<br> /* UTF-8: 0A <LF> */<br> psz_eol = memchr( p_cur, '\n', i_data - i_line );<br> if( psz_eol == NULL )<br>- /* UTF-8: 0D <CR> */<br>- psz_eol = memchr( p_cur, '\r', i_data - i_line );<br>+ {<br>+ /* UTF-8: 0D <CR> - but check if it might be part of CR/LF */<br>+ const uint8_t *p_cr = memchr( p_cur, '\r', i_data - i_line );<br>+ if( p_cr != NULL )<br>+ {<br>+ /* Check if CR is at buffer boundary and might be followed by LF */<br>+ if( p_cr == p_data + i_data - 1 )<br>+ {<br>+ /* CR at end of buffer - peek ahead to see if next char is LF */<br>+ const uint8_t *p_peek_data;<br>+ ssize_t peek_result = vlc_stream_Peek( s, &p_peek_data, i_data + 1 );<br>+ if( peek_result > (ssize_t)i_data && p_peek_data[i_data] == '\n' )<br>+ {<br>+ /* This is a CR/LF sequence spanning boundary, skip CR for now */<br>+ psz_eol = NULL;<br>+ }<br>+ else<br>+ {<br>+ /* Standalone CR at boundary */<br>+ psz_eol = p_cr;<br>+ }<br>+ }<br>+ else<br>+ {<br>+ /* CR not at boundary - treat as line ending */<br>+ psz_eol = p_cr;<br>+ }<br>+ }<br>+ }<br> }<br> else<br> {<br>diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c<br>index caa37535a4..6487e2be4a 100644<br>--- a/src/video_output/video_output.c<br>+++ b/src/video_output/video_output.c<br>@@ -74,6 +74,9 @@ typedef struct vout_thread_sys_t<br><br> bool dummy;<br><br>+ /* Discontinuity flag for better filter handling */<br>+ bool discontinuity_flag;<br>+<br> /* Splitter module if used */<br> char *splitter_name;<br><br>@@ -1082,11 +1085,15 @@ static picture_t *PreparePicture(vout_thread_sys_t *vout, bool reuse_decoded,<br> msg_Dbg(&vout->obj, "Using a new clock context (%u), "<br> "flusing static filters", clock_id);<br><br>- /* Most deinterlace modules can't handle a PTS<br>- * discontinuity, so flush them.<br>- *<br>- * FIXME: Pass a discontinuity flag and handle it in<br>- * deinterlace modules. */<br>+ /* Enhanced discontinuity handling: Set a flag in the system to indicate<br>+ * that the next picture processed will have a discontinuity. This allows<br>+ * deinterlace filters to detect timestamp discontinuities and reset their<br>+ * internal state appropriately rather than just flushing everything. */<br>+ sys->discontinuity_flag = true;<br>+<br>+ /* Most deinterlace modules can't handle a PTS discontinuity.<br>+ * We now set a discontinuity flag above for better handling, but also<br>+ * flush the filters as a fallback for filters that don't check the flag. */<br> filter_chain_VideoFlush(sys->filter.chain_static);<br> }<br><br>-- <br>2.43.0<br><br>_______________________________________________<br>vlc-devel mailing list<br>To unsubscribe or modify your subscription options:<br>https://mailman.videolan.org/listinfo/vlc-devel<br></div></div></blockquote></div><br></div></body></html>