[vlc-commits] [Git][videolan/vlc][3.0.x] demux: ts: check pcr offset with value prior matching sync code
Jean-Baptiste Kempf (@jbk)
gitlab at videolan.org
Mon Dec 13 09:30:54 UTC 2021
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 <fcvlcdev at free.fr>
- - - - -
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.
More information about the vlc-commits
mailing list