[vlc-commits] [Git][videolan/vlc][master] 3 commits: demux: ogg: set reverse calculated pts for audio
Rémi Denis-Courmont (@Courmisch)
gitlab at videolan.org
Sun Jan 23 09:08:00 UTC 2022
Rémi Denis-Courmont pushed to branch master at VideoLAN / VLC
Commits:
659030cc by Francois Cartegnie at 2022-01-23T08:26:27+00:00
demux: ogg: set reverse calculated pts for audio
- - - - -
7b091b21 by Francois Cartegnie at 2022-01-23T08:26:27+00:00
demux: ogg: fix page reverse calculations
- - - - -
93a05605 by Francois Cartegnie at 2022-01-23T08:26:27+00:00
codec: vorbis: fallback on dts on missing pts
should always be pts == dts
- - - - -
2 changed files:
- modules/codec/vorbis.c
- modules/demux/ogg.c
Changes:
=====================================
modules/codec/vorbis.c
=====================================
@@ -476,10 +476,11 @@ static block_t *ProcessPacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
}
/* Date management */
- if( p_block->i_pts != VLC_TICK_INVALID &&
- p_block->i_pts != date_Get( &p_sys->end_date ) )
+ vlc_tick_t pts = p_block->i_pts != VLC_TICK_INVALID ? p_block->i_pts : p_block->i_dts;
+ if( pts != VLC_TICK_INVALID &&
+ pts != date_Get( &p_sys->end_date ) )
{
- date_Set( &p_sys->end_date, p_block->i_pts );
+ date_Set( &p_sys->end_date, pts );
}
if( date_Get( &p_sys->end_date ) == VLC_TICK_INVALID )
=====================================
modules/demux/ogg.c
=====================================
@@ -131,9 +131,9 @@ static int Control( demux_t *, int, va_list );
/* Bitstream manipulation */
static int Ogg_ReadPage ( demux_t *, ogg_page * );
-static void Ogg_DecodePacket ( demux_t *, logical_stream_t *, ogg_packet * );
+static void Ogg_DecodePacket ( demux_t *, logical_stream_t *, ogg_packet *, bool );
static unsigned Ogg_OpusPacketDuration( ogg_packet * );
-static void Ogg_QueueBlocks( demux_t *, logical_stream_t *, block_t * );
+static void Ogg_QueueBlocks( demux_t *, logical_stream_t *, block_t *, vlc_tick_t, bool );
static void Ogg_SendQueuedBlock( demux_t *, logical_stream_t * );
static inline bool Ogg_HasQueuedBlocks( const logical_stream_t *p_stream )
@@ -576,7 +576,7 @@ static int Demux( demux_t * p_demux )
}
}
- Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
+ Ogg_DecodePacket( p_demux, p_stream, &oggpacket, ogg_page_eos( &p_sys->current_page ) );
}
@@ -999,31 +999,19 @@ static void Ogg_SetNextFrame( demux_t *p_demux, logical_stream_t *p_stream,
}
}
-static vlc_tick_t Ogg_FixupOutputQueue( demux_t *p_demux, logical_stream_t *p_stream )
+static vlc_tick_t Ogg_FixupOutputQueue( demux_t *p_demux, logical_stream_t *p_stream,
+ vlc_tick_t i_enddts, bool b_eos )
{
- vlc_tick_t i_enddts = VLC_TICK_INVALID;
+ demux_sys_t *p_sys = p_demux->p_sys;
-#ifdef HAVE_LIBVORBIS
- long i_prev_blocksize = 0;
-#else
- VLC_UNUSED(p_demux);
-#endif
// PASS 1, set number of samples
unsigned i_total_samples = 0;
for( block_t *p_block = p_stream->queue.p_blocks; p_block; p_block = p_block->p_next )
{
- if( p_block->i_dts != VLC_TICK_INVALID )
- {
- i_enddts = p_block->i_dts;
- break;
- }
-
if( p_block->i_flags & BLOCK_FLAG_HEADER )
continue;
ogg_packet dumb_packet;
- dumb_packet.bytes = p_block->i_buffer;
- dumb_packet.packet = p_block->p_buffer;
switch( p_stream->fmt.i_codec )
{
@@ -1032,6 +1020,10 @@ static vlc_tick_t Ogg_FixupOutputQueue( demux_t *p_demux, logical_stream_t *p_st
p_stream->special.speex.i_framesperpacket;
break;
case VLC_CODEC_OPUS:
+ dumb_packet.bytes = p_block->i_buffer;
+ dumb_packet.packet = p_block->p_buffer;
+ /* Less complicated than Vorbis case below as packets samples count
+ * is known for every packet */
p_block->i_nb_samples = Ogg_OpusPacketDuration( &dumb_packet );
break;
#ifdef HAVE_LIBVORBIS
@@ -1042,13 +1034,30 @@ static vlc_tick_t Ogg_FixupOutputQueue( demux_t *p_demux, logical_stream_t *p_st
msg_Err( p_demux, "missing vorbis headers, can't compute block size" );
break;
}
+
+ if( p_block->p_next == NULL )
+ break;
+
+ /* Vorbis Hell
+ Samples are computed from N..N+1 window
+ We can set samples for packets up to N-1
+ Last packet is granule pos - total... but
+ that would be too easy without truncation
+ and beginning of stream cases.
+ If that's BOS, we need to truncate on start (negative samples)
+ If that's EOS, we need to truncate the end to match granule.
+ If that's both single page and not starting zero.. we're ***** */
+ dumb_packet.bytes = p_block->i_buffer;
+ dumb_packet.packet = p_block->p_buffer;
long i_blocksize = vorbis_packet_blocksize( p_stream->special.vorbis.p_info,
&dumb_packet );
- if ( i_prev_blocksize )
- p_block->i_nb_samples = ( i_blocksize + i_prev_blocksize ) / 4;
- else
- p_block->i_nb_samples = i_blocksize / 2;
- i_prev_blocksize = i_blocksize;
+ dumb_packet.bytes = p_block->p_next->i_buffer;
+ dumb_packet.packet = p_block->p_next->p_buffer;
+ long i_nextblocksize = vorbis_packet_blocksize( p_stream->special.vorbis.p_info,
+ &dumb_packet );
+ /* The spec has 3 specific cases depending on long/short prev/next blocksizes
+ ranging weights from 1/4 to 3/4... but everyone does A/4 + B/4 */
+ p_block->i_nb_samples = (i_blocksize + i_nextblocksize) / 4;
break;
}
#endif
@@ -1065,24 +1074,41 @@ static vlc_tick_t Ogg_FixupOutputQueue( demux_t *p_demux, logical_stream_t *p_st
{
date_t d = p_stream->dts;
date_Set( &d, i_enddts );
- i_enddts = date_Decrement( &d, i_total_samples );
+ date_Decrement( &d, i_total_samples );
+
+ /* truncate end */
+ if( b_eos && date_Get( &d ) < VLC_TICK_0 )
+ date_Set( &d, VLC_TICK_0 );
+
for( block_t *p_block = p_stream->queue.p_blocks; p_block; p_block = p_block->p_next )
{
- if( p_block->i_dts != VLC_TICK_INVALID )
- break;
if( p_block->i_flags & BLOCK_FLAG_HEADER )
continue;
p_block->i_dts = date_Get( &d );
- if( p_block->i_dts < VLC_TICK_0 )
+
+ /* truncate start */
+ if( !b_eos && p_block->i_dts < VLC_TICK_0 )
p_block->i_dts = VLC_TICK_0;
+
+ /* Last page in the stream case, truncate end */
+ if( b_eos && p_block->p_next == NULL )
+ p_block->i_dts = __MIN(p_block->i_dts, i_enddts);
+
+ if( p_sys->i_nzpcr_offset )
+ p_block->i_dts += p_sys->i_nzpcr_offset;
+
+ if( p_stream->fmt.i_cat == AUDIO_ES )
+ p_block->i_pts = p_block->i_dts;
date_Increment( &d, p_block->i_nb_samples );
}
+
} /* else can't do anything, no timestamped blocks in stream */
return i_enddts;
}
-static void Ogg_QueueBlocks( demux_t *p_demux, logical_stream_t *p_stream, block_t *p_block )
+static void Ogg_QueueBlocks( demux_t *p_demux, logical_stream_t *p_stream,
+ block_t *p_block, vlc_tick_t i_enddts, bool b_eos )
{
demux_sys_t *p_sys = p_demux->p_sys;
VLC_UNUSED(p_sys);
@@ -1095,10 +1121,12 @@ static void Ogg_QueueBlocks( demux_t *p_demux, logical_stream_t *p_stream, block
block_ChainLastAppend( &p_stream->queue.pp_append, p_block );
- if( p_stream->i_pcr == VLC_TICK_INVALID && p_block->i_dts != VLC_TICK_INVALID )
+ /* If we can have or compute block start from granule, it is set.
+ * Otherwise the end dts will be used for reverse calculation */
+ if( p_stream->i_pcr == VLC_TICK_INVALID && i_enddts != VLC_TICK_INVALID )
{
/* fixup queue */
- p_stream->i_pcr = Ogg_FixupOutputQueue( p_demux, p_stream );
+ p_stream->i_pcr = Ogg_FixupOutputQueue( p_demux, p_stream, i_enddts, b_eos );
}
DemuxDebug( msg_Dbg( p_demux, "%4.4s block queued > dts %"PRId64" spcr %"PRId64" pcr %"PRId64,
@@ -1186,7 +1214,7 @@ static bool Ogg_IsHeaderPacket( const logical_stream_t *p_stream,
****************************************************************************/
static void Ogg_DecodePacket( demux_t *p_demux,
logical_stream_t *p_stream,
- ogg_packet *p_oggpacket )
+ ogg_packet *p_oggpacket, bool b_eos )
{
demux_sys_t *p_sys = p_demux->p_sys;
block_t *p_block;
@@ -1357,6 +1385,8 @@ static void Ogg_DecodePacket( demux_t *p_demux,
}
vlc_tick_t i_dts = Ogg_GranuleToTime( p_stream, p_oggpacket->granulepos, true, false );
+ vlc_tick_t i_enddts = (i_dts == VLC_TICK_INVALID) ? Ogg_GranuleToTime( p_stream, p_oggpacket->granulepos, false, false )
+ : VLC_TICK_INVALID;
vlc_tick_t i_expected_dts = p_stream->b_interpolation_failed ? VLC_TICK_INVALID :
date_Get( &p_stream->dts ); /* Interpolated or previous end time */
if( i_dts == VLC_TICK_INVALID )
@@ -1495,7 +1525,7 @@ static void Ogg_DecodePacket( demux_t *p_demux,
memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
p_oggpacket->bytes - i_header_len );
- Ogg_QueueBlocks( p_demux, p_stream, p_block );
+ Ogg_QueueBlocks( p_demux, p_stream, p_block, i_enddts, b_eos );
}
static unsigned Ogg_OpusPacketDuration( ogg_packet *p_oggpacket )
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/4d00740e2c6c1c1e4b09a76ea611a5d380b2b48f...93a05605e1f40df745702ac7eb3a31c758d5f71c
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/4d00740e2c6c1c1e4b09a76ea611a5d380b2b48f...93a05605e1f40df745702ac7eb3a31c758d5f71c
You're receiving this email because of your account on code.videolan.org.
More information about the vlc-commits
mailing list