[vlc-commits] [Git][videolan/vlc][master] 2 commits: demux: ogg: move post seek handler on proper seek conditional branch
Steve Lhomme (@robUx4)
gitlab at videolan.org
Fri May 12 11:38:09 UTC 2023
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
767e13f7 by Francois Cartegnie at 2023-05-12T16:36:50+07:00
demux: ogg: move post seek handler on proper seek conditional branch
- - - - -
262ab17e by Francois Cartegnie at 2023-05-12T16:36:54+07:00
demux: ogg: limit discarded frames to pre-skip on bos
refs #19242
- - - - -
3 changed files:
- modules/demux/ogg.c
- modules/demux/ogg.h
- modules/demux/oggseek.c
Changes:
=====================================
modules/demux/ogg.c
=====================================
@@ -530,6 +530,17 @@ static int Demux( demux_t * p_demux )
}
}
+
+ if( ogg_page_granulepos( &p_sys->current_page ) == 0 && !p_stream->b_oggds )
+ p_stream->page_type = OGGPAGE_HEADER;
+ else if( p_stream->page_type == OGGPAGE_HEADER )
+ p_stream->page_type = OGGPAGE_FIRST;
+ else
+ p_stream->page_type = OGGPAGE_OTHER;
+
+ if( p_stream->page_type == OGGPAGE_FIRST && p_stream->fmt.i_codec == VLC_CODEC_OPUS )
+ p_stream->i_skip_frames = p_stream->i_pre_skip;
+
/* clear the finished flag if pages after eos (ex: after a seek) */
if ( ! ogg_page_eos( &p_sys->current_page ) && p_sys->p_skelstream != p_stream )
p_stream->b_finished = false;
@@ -576,15 +587,6 @@ static int Demux( demux_t * p_demux )
p_stream->i_data_start = vlc_stream_Tell( p_demux->s );
}
- if( p_stream->b_reinit )
- {
- p_stream->b_reinit = false;
- if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
- {
- p_stream->i_skip_frames = p_stream->i_pre_skip;
- }
- }
-
Ogg_DecodePacket( p_demux, p_stream, &oggpacket, ogg_page_eos( &p_sys->current_page ) );
}
@@ -629,8 +631,18 @@ static void Ogg_ResetStream( logical_stream_t *p_stream )
p_stream->special.vorbis.i_prev_blocksize = 0;
}
#endif
+ if( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
+ {
+
+ /* For Opus, trash the first 80 ms of decoded output as
+ well, to avoid blowing out speakers if we get unlucky.
+ Opus predicts content from prior frames, which can go
+ badly if we seek right where the stream goes from very
+ quiet to very loud. It will converge after a bit. */
+ if( p_stream->i_skip_frames < p_stream->i_pre_skip )
+ p_stream->i_skip_frames = __MAX( 80*48, p_stream->i_pre_skip );
+ }
/* we'll trash all the data until we find the next pcr */
- p_stream->b_reinit = true;
p_stream->i_pcr = VLC_TICK_INVALID;
p_stream->i_next_block_flags = 0;
p_stream->b_interpolation_failed = false;
@@ -807,8 +819,10 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
acc = va_arg( args, int );
if ( p_sys->i_length <= 0 || !b /* || ! STREAM_CAN_FASTSEEK */ )
{
- Ogg_PreparePostSeek( p_sys );
- return Oggseek_BlindSeektoPosition( p_demux, p_stream, f, b );
+ int ret = Oggseek_BlindSeektoPosition( p_demux, p_stream, f, b );
+ if( ret == VLC_SUCCESS )
+ Ogg_PreparePostSeek( p_sys );
+ return ret;
}
assert( p_sys->i_length > 0 );
@@ -816,9 +830,9 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
vlc_tick_t i_preroll = Ogg_GetDecoderPreroll( p_stream );
if( i_preroll > i64 )
i_preroll = i64;
- Ogg_PreparePostSeek( p_sys );
if ( Oggseek_SeektoAbsolutetime( p_demux, p_stream, VLC_TICK_0 + i64 - i_preroll ) >= 0 )
{
+ Ogg_PreparePostSeek( p_sys );
if( acc )
es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
VLC_TICK_0 + i64 );
@@ -1601,6 +1615,11 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
p_stream->i_serial_no = ogg_page_serialno( &p_ogg->current_page );
ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
+ if( ogg_page_granulepos( &p_ogg->current_page ) == 0 && !p_stream->b_oggds )
+ p_stream->page_type = OGGPAGE_HEADER;
+ else
+ p_stream->page_type = OGGPAGE_OTHER;
+
TAB_APPEND( p_ogg->i_streams, p_ogg->pp_stream, p_stream );
/* Extract the initial header from the first page and verify
@@ -2205,7 +2224,6 @@ static void Ogg_CreateES( demux_t *p_demux, bool stable_id )
p_stream->p_es = p_old_stream->p_es;
p_stream->b_finished = false;
- p_stream->b_reinit = false;
p_stream->b_initializing = false;
p_stream->i_pre_skip = 0;
es_format_Clean( &p_stream->fmt_old );
@@ -2280,7 +2298,6 @@ static int Ogg_BeginningOfStream( demux_t *p_demux )
p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
p_stream->i_pcr = VLC_TICK_INVALID;
- p_stream->b_reinit = false;
}
/* get total frame count for video stream; we will need this for seeking */
@@ -2352,6 +2369,7 @@ static void Ogg_LogicalStreamInit( logical_stream_t *p_stream )
es_format_Init( &p_stream->fmt_old, UNKNOWN_ES, 0 );
p_stream->i_pcr = VLC_TICK_INVALID;
p_stream->i_first_frame_index = 1;
+ p_stream->page_type = OGGPAGE_OTHER;
date_Set( &p_stream->dts, VLC_TICK_INVALID );
p_stream->b_initializing = true;
p_stream->b_contiguous = true; /* default */
@@ -2931,12 +2949,6 @@ static void Ogg_ReadOpusHeader( logical_stream_t *p_stream,
break;
}
}
- /* For Opus, trash the first 80 ms of decoded output as
- well, to avoid blowing out speakers if we get unlucky.
- Opus predicts content from prior frames, which can go
- badly if we seek right where the stream goes from very
- quiet to very loud. It will converge after a bit. */
- p_stream->i_pre_skip = __MAX( 80*48, p_stream->i_pre_skip );
}
static bool Ogg_ReadFlacStreamInfo( demux_t *p_demux, logical_stream_t *p_stream,
=====================================
modules/demux/ogg.h
=====================================
@@ -83,13 +83,18 @@ typedef struct logical_stream_s
/* Misc */
bool b_initializing;
bool b_finished;
- bool b_reinit;
bool b_oggds;
int i_granule_shift;
int i_next_block_flags;
/* Opus has a starting offset in the headers. */
int i_pre_skip;
+ enum
+ {
+ OGGPAGE_HEADER,
+ OGGPAGE_FIRST,
+ OGGPAGE_OTHER,
+ } page_type;
/* offset of first keyframe for theora; can be 0 or 1 depending on version number */
int8_t i_first_frame_index;
=====================================
modules/demux/oggseek.c
=====================================
@@ -309,6 +309,15 @@ clean:
ogg_stream_clear( &os );
}
+static void update_page_type( logical_stream_t *p_stream, int64_t i_granule )
+{
+ if( i_granule == 0 )
+ p_stream->page_type = OGGPAGE_HEADER;
+ else if( p_stream->page_type == OGGPAGE_HEADER )
+ p_stream->page_type = OGGPAGE_FIRST;
+ else
+ p_stream->page_type = OGGPAGE_OTHER;
+}
static int64_t find_first_page_granule( demux_t *p_demux,
int64_t i_pos1, int64_t i_pos2,
@@ -402,6 +411,7 @@ static int64_t find_first_page_granule( demux_t *p_demux,
if ( ogg_page_granulepos( &p_sys->current_page ) <= 0 )
{
+ update_page_type( p_stream, ogg_page_granulepos(( &p_sys->current_page )) );
/* A negative granulepos means that the packet continues on the
* next page => read the next page */
p_sys->i_input_position += i_result;
@@ -437,6 +447,8 @@ static bool OggSeekToPacket( demux_t *p_demux, logical_stream_t *p_stream,
p_sys->b_page_waiting = true;
int i=0;
+ update_page_type( p_stream, ogg_page_granulepos( &p_sys->current_page ) );
+
int64_t itarget_frame = Ogg_GetKeyframeGranule( p_stream, i_granulepos );
int64_t iframe = Ogg_GetKeyframeGranule( p_stream, ogg_page_granulepos( &p_sys->current_page ) );
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/fd231b8db7b1b7631cb79fd0b9a294cd858a7e98...262ab17e729ed5ea401a34a45487f2ab7bf65fdf
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/fd231b8db7b1b7631cb79fd0b9a294cd858a7e98...262ab17e729ed5ea401a34a45487f2ab7bf65fdf
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