Commit c0f850f8 authored by François Cartegnie's avatar François Cartegnie 🤞

demux: ogg: use mtime

parent 4b206fc0
......@@ -535,7 +535,7 @@ static int Demux( demux_t * p_demux )
if ( p_stream->prepcr.pp_blocks )
{
int64_t pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream, ogg_page_granulepos( &p_sys->current_page ), false );
mtime_t pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream, ogg_page_granulepos( &p_sys->current_page ), false );
p_stream->i_previous_pcr = pagestamp;
#ifdef HAVE_LIBVORBIS
int i_prev_blocksize = 0;
......@@ -587,24 +587,27 @@ static int Demux( demux_t * p_demux )
case VLC_CODEC_SPEEX:
case VLC_CODEC_OPUS:
case VLC_CODEC_VORBIS:
pagestamp -= CLOCK_FREQ * p_block->i_nb_samples / p_stream->f_rate;
if ( pagestamp < 0 )
if( pagestamp != VLC_TS_INVALID )
{
pagestamp -= CLOCK_FREQ * p_block->i_nb_samples / p_stream->f_rate;
p_block->i_pts = p_sys->i_nzpcr_offset + pagestamp;
}
else
{
p_block->i_pts = VLC_TS_INVALID;
if( p_sys->i_nzpcr_offset == 0 ) /* not on chained streams */
p_block->i_flags |= BLOCK_FLAG_PREROLL;
}
else
p_block->i_pts = VLC_TS_0 + p_sys->i_nzpcr_offset + pagestamp;
b_fixed = true;
break;
default:
if ( p_stream->fmt.i_cat == VIDEO_ES )
{
pagestamp = pagestamp - ( CLOCK_FREQ / p_stream->f_rate );
if( pagestamp < 0 )
pagestamp = 0;
p_block->i_pts = VLC_TS_0 + p_sys->i_nzpcr_offset + pagestamp;
if( pagestamp != VLC_TS_INVALID )
{
pagestamp = pagestamp - ( CLOCK_FREQ / p_stream->f_rate );
p_block->i_pts = p_sys->i_nzpcr_offset + pagestamp;
}
b_fixed = true;
}
}
......@@ -613,8 +616,7 @@ static int Demux( demux_t * p_demux )
if ( b_fixed )
{
pagestamp = p_stream->i_previous_pcr; /* as set above */
if ( pagestamp < 0 ) pagestamp = 0;
p_stream->i_pcr = VLC_TS_0 + pagestamp;
p_stream->i_pcr = pagestamp;
p_stream->i_pcr += p_sys->i_nzpcr_offset;
p_stream->i_previous_granulepos = ogg_page_granulepos( &p_sys->current_page );
}
......@@ -626,11 +628,11 @@ static int Demux( demux_t * p_demux )
}
int64_t i_pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream,
ogg_page_granulepos( &p_sys->current_page ), false );
if ( i_pagestamp > -1 )
mtime_t i_pagestamp = Oggseek_GranuleToAbsTimestamp( p_stream,
ogg_page_granulepos( &p_sys->current_page ), false );
if ( i_pagestamp != VLC_TS_INVALID )
{
p_stream->i_pcr = VLC_TS_0 + i_pagestamp;
p_stream->i_pcr = i_pagestamp;
p_stream->i_pcr += p_sys->i_nzpcr_offset;
}
......@@ -809,7 +811,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
return VLC_EGENERIC;
}
vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, VLC_TS_0 + i64, b ) )
{
Ogg_ResetStreamsHelper( p_sys );
if( acc )
......@@ -883,7 +885,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
assert( p_sys->i_length > 0 );
i64 = CLOCK_FREQ * p_sys->i_length * f;
Ogg_ResetStreamsHelper( p_sys );
if ( Oggseek_SeektoAbsolutetime( p_demux, p_stream, i64 ) >= 0 )
if ( Oggseek_SeektoAbsolutetime( p_demux, p_stream, VLC_TS_0 + i64 ) >= 0 )
{
if( acc )
es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
......@@ -954,7 +956,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
}
vlc_stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &b );
if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, i64, b ) )
if ( Oggseek_BlindSeektoAbsoluteTime( p_demux, p_stream, VLC_TS_0 + i64, b ) )
{
Ogg_ResetStreamsHelper( p_sys );
es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
......@@ -1044,7 +1046,7 @@ static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
p_stream->fmt.i_codec == VLC_CODEC_OGGSPOTS ||
(p_stream->b_oggds && p_stream->fmt.i_cat == VIDEO_ES) )
{
p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
p_stream->i_pcr = Oggseek_GranuleToAbsTimestamp( p_stream,
p_oggpacket->granulepos, true );
p_stream->i_pcr += p_ogg->i_nzpcr_offset;
}
......@@ -1082,7 +1084,7 @@ static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
{
if( p_stream->i_previous_granulepos > 0 )
{
p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream, ++p_stream->i_previous_granulepos, false );
p_stream->i_pcr = Oggseek_GranuleToAbsTimestamp( p_stream, ++p_stream->i_previous_granulepos, false );
p_stream->i_pcr += p_ogg->i_nzpcr_offset;
}
/* First frame in ogm can be -1 (0 0 -1 2 3 -1 5 ...) */
......@@ -1121,7 +1123,7 @@ static void Ogg_UpdatePCR( demux_t *p_demux, logical_stream_t *p_stream,
i_duration = p_stream->special.speex.i_framesize *
p_stream->special.speex.i_framesperpacket;
p_oggpacket->granulepos = p_stream->i_previous_granulepos + i_duration;
p_stream->i_pcr = VLC_TS_0 + Oggseek_GranuleToAbsTimestamp( p_stream,
p_stream->i_pcr = Oggseek_GranuleToAbsTimestamp( p_stream,
p_stream->i_previous_granulepos, false );
p_stream->i_pcr += p_ogg->i_nzpcr_offset;
}
......@@ -1204,7 +1206,7 @@ static void Ogg_SendOrQueueBlocks( demux_t *p_demux, logical_stream_t *p_stream,
tosend->i_dts, tosend->i_pts, p_stream->i_pcr, p_ogg->i_pcr ); )
es_out_Send( p_demux->out, p_stream->p_es, tosend );
if ( p_ogg->i_pcr < VLC_TS_0 && i_firstpts != VLC_TS_INVALID )
if ( p_ogg->i_pcr == VLC_TS_INVALID && i_firstpts != VLC_TS_INVALID )
{
p_ogg->i_pcr = i_firstpts;
if( likely( !p_ogg->b_slave ) )
......@@ -1453,10 +1455,8 @@ static void Ogg_DecodePacket( demux_t *p_demux,
if( p_stream->fmt.i_codec == VLC_CODEC_DIRAC )
{
ogg_int64_t nzdts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, false );
ogg_int64_t nzpts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, true );
p_block->i_dts = ( nzdts != VLC_TS_INVALID ) ? VLC_TS_0 + nzdts : nzdts;
p_block->i_pts = ( nzpts != VLC_TS_INVALID ) ? VLC_TS_0 + nzpts : nzpts;
p_block->i_dts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, false );
p_block->i_pts = Oggseek_GranuleToAbsTimestamp( p_stream, p_oggpacket->granulepos, true );
/* granulepos for dirac is possibly broken, this value should be ignored */
if( 0 >= p_oggpacket->granulepos )
{
......@@ -3322,12 +3322,15 @@ static void Ogg_ApplySkeleton( logical_stream_t *p_stream )
}
/* Return true if there's a skeleton exact match */
bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, int64_t i_time,
bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, mtime_t i_time,
int64_t *pi_lower, int64_t *pi_upper )
{
if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index )
if ( !p_stream || !p_stream->p_skel || !p_stream->p_skel->p_index ||
i_time == VLC_TS_INVALID )
return false;
i_time -= VLC_TS_0;
/* Validate range */
if ( i_time < p_stream->p_skel->i_indexfirstnum
* p_stream->p_skel->i_indexstampden ||
......
......@@ -242,5 +242,5 @@ typedef struct
unsigned const char * Read7BitsVariableLE( unsigned const char *,
unsigned const char *,
uint64_t * );
bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, int64_t i_time,
bool Ogg_GetBoundsUsingSkeletonIndex( logical_stream_t *p_stream, mtime_t i_time,
int64_t *pi_lower, int64_t *pi_upper );
......@@ -96,7 +96,7 @@ static demux_index_entry_t *index_entry_new( void )
/* We insert into index, sorting by pagepos (as a page can match multiple
time stamps) */
const demux_index_entry_t *OggSeek_IndexAdd ( logical_stream_t *p_stream,
int64_t i_timestamp,
mtime_t i_timestamp,
int64_t i_pagepos )
{
demux_index_entry_t *idx;
......@@ -106,7 +106,7 @@ const demux_index_entry_t *OggSeek_IndexAdd ( logical_stream_t *p_stream,
idx = p_stream->idx;
if ( i_timestamp < 1 || i_pagepos < 1 ) return NULL;
if ( i_timestamp == VLC_TS_INVALID || i_pagepos < 1 ) return NULL;
if ( idx == NULL )
{
......@@ -151,7 +151,7 @@ const demux_index_entry_t *OggSeek_IndexAdd ( logical_stream_t *p_stream,
return idx;
}
static bool OggSeekIndexFind ( logical_stream_t *p_stream, int64_t i_timestamp,
static bool OggSeekIndexFind ( logical_stream_t *p_stream, mtime_t i_timestamp,
int64_t *pi_pos_lower, int64_t *pi_pos_upper )
{
demux_index_entry_t *idx = p_stream->idx;
......@@ -290,15 +290,16 @@ void Oggseek_ProbeEnd( demux_t *p_demux )
continue;
i_length = Oggseek_GranuleToAbsTimestamp( p_sys->pp_stream[i], i_granule, false );
p_sys->i_length = __MAX( p_sys->i_length, i_length / 1000000 );
if( i_length > VLC_TS_INVALID )
p_sys->i_length = __MAX( p_sys->i_length, (i_length - VLC_TS_0) / 1000000 );
break;
}
}
if ( i_length > 0 ) break;
if ( i_length > VLC_TS_INVALID ) break;
}
/* We found at least a page with valid granule */
if ( i_length > 0 ) break;
if ( i_length > VLC_TS_INVALID ) break;
/* Otherwise increase read size, starting earlier */
if ( i_backoffset <= ( UINT_MAX >> 1 ) )
......@@ -674,12 +675,12 @@ restart:
}
/* Dont use b_presentation with frames granules ! */
int64_t Oggseek_GranuleToAbsTimestamp( logical_stream_t *p_stream,
mtime_t Oggseek_GranuleToAbsTimestamp( logical_stream_t *p_stream,
int64_t i_granule, bool b_presentation )
{
int64_t i_timestamp = -1;
mtime_t i_timestamp = VLC_TS_INVALID;
if ( i_granule < 1 - !!p_stream->b_oggds )
return -1;
return VLC_TS_INVALID;
if ( p_stream->b_oggds )
{
......@@ -746,12 +747,12 @@ int64_t Oggseek_GranuleToAbsTimestamp( logical_stream_t *p_stream,
}
}
return i_timestamp;
return i_timestamp != VLC_TS_INVALID ? i_timestamp + VLC_TS_0 : VLC_TS_INVALID;
}
/* returns pos */
static int64_t OggBisectSearchByTime( demux_t *p_demux, logical_stream_t *p_stream,
int64_t i_targettime, int64_t i_pos_lower, int64_t i_pos_upper)
mtime_t i_targettime, int64_t i_pos_lower, int64_t i_pos_upper)
{
int64_t i_start_pos;
int64_t i_end_pos;
......@@ -760,11 +761,11 @@ static int64_t OggBisectSearchByTime( demux_t *p_demux, logical_stream_t *p_stre
struct
{
int64_t i_pos;
int64_t i_timestamp;
mtime_t i_timestamp;
int64_t i_granule;
} bestlower = { p_stream->i_data_start, -1, -1 },
current = { -1, -1, -1 },
lowestupper = { -1, -1, -1 };
} bestlower = { p_stream->i_data_start, VLC_TS_INVALID, -1 },
current = { -1, VLC_TS_INVALID, -1 },
lowestupper = { -1, VLC_TS_INVALID, -1 };
demux_sys_t *p_sys = p_demux->p_sys;
......@@ -805,15 +806,11 @@ static int64_t OggBisectSearchByTime( demux_t *p_demux, logical_stream_t *p_stre
current.i_timestamp = Oggseek_GranuleToAbsTimestamp( p_stream,
current.i_granule, false );
if ( current.i_timestamp == -1 && current.i_granule > 0 )
if ( current.i_timestamp == VLC_TS_INVALID && current.i_granule > 0 )
{
msg_Err( p_demux, "Unmatched granule. New codec ?" );
return -1;
}
else if ( current.i_timestamp < -1 ) /* due to preskip with some codecs */
{
current.i_timestamp = 0;
}
if ( current.i_pos != -1 && current.i_granule != -1 )
{
......@@ -828,7 +825,8 @@ static int64_t OggBisectSearchByTime( demux_t *p_demux, logical_stream_t *p_stre
}
else if ( current.i_timestamp > i_targettime )
{
if ( lowestupper.i_timestamp == -1 || current.i_timestamp < lowestupper.i_timestamp )
if ( lowestupper.i_timestamp == VLC_TS_INVALID ||
current.i_timestamp < lowestupper.i_timestamp )
lowestupper = current;
/* check lower half of segment */
i_start_pos -= i_segsize;
......@@ -895,7 +893,7 @@ static int64_t OggBisectSearchByTime( demux_t *p_demux, logical_stream_t *p_stre
*************************************************************************/
int Oggseek_BlindSeektoAbsoluteTime( demux_t *p_demux, logical_stream_t *p_stream,
int64_t i_time, bool b_fastseek )
mtime_t i_time, bool b_fastseek )
{
demux_sys_t *p_sys = p_demux->p_sys;
int64_t i_lowerpos = -1;
......@@ -918,7 +916,7 @@ int Oggseek_BlindSeektoAbsoluteTime( demux_t *p_demux, logical_stream_t *p_strea
{
/* But only if there's no keyframe/preload requirements */
/* FIXME: add function to get preload time by codec, ex: opus */
i_lowerpos = i_time * p_sys->i_bitrate / INT64_C(8000000);
i_lowerpos = VLC_TS_0 + (i_time - VLC_TS_0) * p_sys->i_bitrate / INT64_C(8000000);
b_found = true;
}
......@@ -991,7 +989,7 @@ int Oggseek_BlindSeektoPosition( demux_t *p_demux, logical_stream_t *p_stream,
}
int Oggseek_SeektoAbsolutetime( demux_t *p_demux, logical_stream_t *p_stream,
int64_t i_time )
mtime_t i_time )
{
demux_sys_t *p_sys = p_demux->p_sys;
......
......@@ -42,7 +42,7 @@ struct oggseek_index_entry
demux_index_entry_t *p_prev;
/* value is highest granulepos for theora, sync frame for dirac */
int64_t i_value;
mtime_t i_value;
int64_t i_pagepos;
/* not used for theora because the granulepos tells us this */
......@@ -52,12 +52,12 @@ struct oggseek_index_entry
int64_t Ogg_GetKeyframeGranule ( logical_stream_t *p_stream, int64_t i_granule );
bool Ogg_IsKeyFrame ( logical_stream_t *, ogg_packet * );
int64_t Oggseek_GranuleToAbsTimestamp ( logical_stream_t *p_stream, int64_t i_granule,
bool b_presentation );
int Oggseek_BlindSeektoAbsoluteTime ( demux_t *, logical_stream_t *, int64_t, bool );
mtime_t Oggseek_GranuleToAbsTimestamp ( logical_stream_t *p_stream, int64_t i_granule,
bool b_presentation );
int Oggseek_BlindSeektoAbsoluteTime ( demux_t *, logical_stream_t *, mtime_t, bool );
int Oggseek_BlindSeektoPosition ( demux_t *, logical_stream_t *, double f, bool );
int Oggseek_SeektoAbsolutetime ( demux_t *, logical_stream_t *, int64_t i_granulepos );
const demux_index_entry_t *OggSeek_IndexAdd ( logical_stream_t *, int64_t, int64_t );
int Oggseek_SeektoAbsolutetime ( demux_t *, logical_stream_t *, mtime_t );
const demux_index_entry_t *OggSeek_IndexAdd ( logical_stream_t *, mtime_t, int64_t );
void Oggseek_ProbeEnd( demux_t * );
void oggseek_index_entries_free ( demux_index_entry_t * );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment