Jean-Baptiste Kempf pushed to branch 3.0.x at VideoLAN / VLC
Commits: 2090e1ea by Francois Cartegnie at 2021-12-13T09:14:23+00:00 demux: ts: check pcr offset with value prior matching sync code otherwise the last value is always overwritten with a more recent one and triggers the dts < pcr case ref #25034 (cherry picked from commit 225e0bc09b847167433d49a591b25a8da4e7655f) Signed-off-by: Francois Cartegnie <[email protected]> - - - - - 3 changed files: - modules/demux/mpeg/ts.c - modules/demux/mpeg/ts_streams.c - modules/demux/mpeg/ts_streams_private.h Changes: ===================================== modules/demux/mpeg/ts.c ===================================== @@ -1447,7 +1447,8 @@ static void SendDataChain( demux_t *p_demux, ts_es_t *p_es, block_t *p_chain ) /**************************************************************************** * gathering stuff ****************************************************************************/ -static void ParsePESDataChain( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes ) +static void ParsePESDataChain( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes, + int64_t i_append_pcr ) { uint8_t header[34]; unsigned i_pes_size = 0; @@ -1606,19 +1607,20 @@ static void ParsePESDataChain( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes ) } /* Compute PCR/DTS offset if any */ + int64_t i_pcrref = i_append_pcr > VLC_TS_INVALID ? i_append_pcr : p_pmt->pcr.i_first; if( p_pmt->pcr.i_pcroffset == -1 && p_block->i_dts > VLC_TS_INVALID && - p_pmt->pcr.i_current > VLC_TS_INVALID && + i_pcrref > VLC_TS_INVALID && (p_es->fmt.i_cat == VIDEO_ES || p_es->fmt.i_cat == AUDIO_ES) ) { int64_t i_dts27 = TO_SCALE(p_block->i_dts); - i_dts27 = TimeStampWrapAround( p_pmt->pcr.i_first, i_dts27 ); - int64_t i_pcr = TimeStampWrapAround( p_pmt->pcr.i_first, p_pmt->pcr.i_current ); - if( i_dts27 < i_pcr ) + i_dts27 = TimeStampWrapAround( i_pcrref, i_dts27 ); + i_pcrref = TimeStampWrapAround( p_pmt->pcr.i_first, i_pcrref ); + if( i_dts27 + (CLOCK_FREQ/90000) < i_pcrref ) { - p_pmt->pcr.i_pcroffset = i_pcr - i_dts27 + 80000; + p_pmt->pcr.i_pcroffset = i_pcrref - i_dts27 + TO_SCALE_NZ(80000); msg_Warn( p_demux, "Broken stream: pid %d sends packets with dts %"PRId64 "us later than pcr, applying delay", - pid->i_pid, FROM_SCALE_NZ(p_pmt->pcr.i_pcroffset) ); + pid->i_pid, FROM_SCALE_NZ(i_pcrref - i_dts27) ); } else p_pmt->pcr.i_pcroffset = 0; } @@ -1670,7 +1672,8 @@ static void ParsePESDataChain( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes ) } } -static bool PushPESBlock( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, bool b_unit_start ) +static bool PushPESBlock( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, bool b_unit_start, + int64_t i_append_pcr ) { bool b_ret = false; ts_stream_t *p_pes = pid->u.p_stream; @@ -1683,10 +1686,13 @@ static bool PushPESBlock( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, bool p_pes->gather.i_data_size = 0; p_pes->gather.i_gathered = 0; p_pes->gather.pp_last = &p_pes->gather.p_data; - ParsePESDataChain( p_demux, pid, p_datachain ); + ParsePESDataChain( p_demux, pid, p_datachain, p_pes->gather.i_append_pcr ); b_ret = true; } + if( b_unit_start ) + p_pes->gather.i_append_pcr = i_append_pcr; + if( p_pkt == NULL ) return b_ret; @@ -1705,7 +1711,7 @@ static bool PushPESBlock( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, bool { /* re-enter in Flush above */ assert(p_pes->gather.p_data); - return PushPESBlock( p_demux, pid, NULL, true ); + return PushPESBlock( p_demux, pid, NULL, true, i_append_pcr ); } return b_ret; @@ -2300,7 +2306,7 @@ static void PCRCheckDTS( demux_t *p_demux, ts_pmt_t *p_pmt, mtime_t i_pcr) { msg_Warn( p_demux, "send queued data for pid %d: TS %"PRId64" <= PCR %"PRId64"\n", p_pid->i_pid, i_dts > VLC_TS_INVALID ? i_dts : i_pts, i_pcr); - PushPESBlock( p_demux, p_pid, NULL, true ); /* Flush */ + PushPESBlock( p_demux, p_pid, NULL, true, VLC_TS_INVALID ); /* Flush */ } } } @@ -2634,6 +2640,8 @@ static bool GatherPESData( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, size const bool b_unit_start = p_pkt->p_buffer[1]&0x40; bool b_ret = false; ts_stream_t *p_pes = pid->u.p_stream; + const ts_es_t *p_es = p_pes->p_es; + int64_t i_append_pcr = ( p_es && p_es->p_program ) ? p_es->p_program->pcr.i_current : -1; /* We have to gather it */ p_pkt->p_buffer += i_skip; @@ -2655,7 +2663,7 @@ static bool GatherPESData( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, size if( (p_pkt->i_flags & BLOCK_FLAG_SCRAMBLED) && p_demux->p_sys->b_valid_scrambling ) { block_Release( p_pkt ); - return PushPESBlock( p_demux, pid, NULL, true ); + return PushPESBlock( p_demux, pid, NULL, true, i_append_pcr ); } /* Data discontinuity, we need to drop or output currently @@ -2665,7 +2673,7 @@ static bool GatherPESData( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, size { p_pes->gather.i_saved = 0; /* Flush/output current */ - b_ret |= PushPESBlock( p_demux, pid, NULL, true ); + b_ret |= PushPESBlock( p_demux, pid, NULL, true, i_append_pcr ); /* Propagate to output block to notify packetizers/decoders */ if( p_pes->p_es ) p_pes->p_es->i_next_block_flags |= BLOCK_FLAG_DISCONTINUITY; @@ -2736,7 +2744,7 @@ static bool GatherPESData( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, size /* Append whole block */ if( likely(p_pkt->i_buffer <= i_remain || b_single_payload) ) { - b_ret |= PushPESBlock( p_demux, pid, p_pkt, p_pes->gather.p_data == NULL ); + b_ret |= PushPESBlock( p_demux, pid, p_pkt, p_pes->gather.p_data == NULL, i_append_pcr ); p_pkt = NULL; } else /* p_pkt->i_buffer > i_remain */ @@ -2747,7 +2755,7 @@ static bool GatherPESData( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, size block_Release( p_pkt ); return false; } - b_ret |= PushPESBlock( p_demux, pid, p_pkt, p_pes->gather.p_data == NULL ); + b_ret |= PushPESBlock( p_demux, pid, p_pkt, p_pes->gather.p_data == NULL, i_append_pcr ); p_pkt = p_split; b_first_sync_done = false; } @@ -2755,7 +2763,7 @@ static bool GatherPESData( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, size else /* if( p_pes->gather.i_data_size == 0 ) // see next packet */ { /* Append or finish current/start new PES depending on unit_start */ - b_ret |= PushPESBlock( p_demux, pid, p_pkt, b_unit_start ); + b_ret |= PushPESBlock( p_demux, pid, p_pkt, b_unit_start, i_append_pcr ); p_pkt = NULL; } } ===================================== modules/demux/mpeg/ts_streams.c ===================================== @@ -286,6 +286,7 @@ ts_stream_t *ts_stream_New( demux_t *p_demux, ts_pmt_t *p_program ) pes->gather.p_data = NULL; pes->gather.pp_last = &pes->gather.p_data; pes->gather.i_saved = 0; + pes->gather.i_append_pcr = VLC_TS_INVALID; pes->b_broken_PUSI_conformance = false; pes->b_always_receive = false; pes->p_sections_proc = NULL; ===================================== modules/demux/mpeg/ts_streams_private.h ===================================== @@ -125,6 +125,7 @@ struct ts_stream_t block_t **pp_last; uint8_t saved[5]; size_t i_saved; + int64_t i_append_pcr; } gather; bool b_always_receive; View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/2090e1ea9a6a6f34f614218eeaf667d428f2f9c7 -- View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/2090e1ea9a6a6f34f614218eeaf667d428f2f9c7 You're receiving this email because of your account on code.videolan.org.
_______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
