Commit 1b4c719d authored by Francois Cartegnie's avatar Francois Cartegnie

demux: ogg: handle opus seeking (fix #9334)

parent 26651679
...@@ -570,9 +570,27 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) ...@@ -570,9 +570,27 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
} }
Ogg_ResetStreamHelper( p_sys ); Ogg_ResetStreamHelper( p_sys );
int64_t i_block = p_sys->pp_seekpoints[i_seekpoint]->i_time_offset * p_sys->i_bitrate / INT64_C(8000000);
if( stream_Seek( p_demux->s, i_block ) ) if ( p_sys->i_bitrate == 0 )
return VLC_EGENERIC; {
/* we won't be able to find block by time
* we'll need to bisect search from here
* or use skeleton index if any (FIXME)
*/
if ( p_sys->pp_stream[0]->fmt.i_codec == VLC_CODEC_OPUS )
{
/* Granule = Freq * T + pre-skip */
oggseek_find_frame ( p_demux, p_sys->pp_stream[0],
( p_sys->pp_seekpoints[i_seekpoint]->i_time_offset * 0.048 + p_sys->pp_stream[0]->i_pre_skip ) );
}
else return VLC_EGENERIC;
}
else
{
int64_t i_block = p_sys->pp_seekpoints[i_seekpoint]->i_time_offset * p_sys->i_bitrate / INT64_C(8000000);
if( stream_Seek( p_demux->s, i_block ) )
return VLC_EGENERIC;
}
p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT; p_demux->info.i_update |= INPUT_UPDATE_SEEKPOINT;
p_demux->info.i_seekpoint = i_seekpoint; p_demux->info.i_seekpoint = i_seekpoint;
return VLC_SUCCESS; return VLC_SUCCESS;
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
#include "ogg.h" #include "ogg.h"
#include "oggseek.h" #include "oggseek.h"
//#define OGG_SEEK_DEBUG 1
/************************************************************ /************************************************************
* index entries * index entries
*************************************************************/ *************************************************************/
...@@ -214,10 +214,6 @@ static int64_t get_data( demux_t *p_demux, int64_t i_bytes_to_read ) ...@@ -214,10 +214,6 @@ static int64_t get_data( demux_t *p_demux, int64_t i_bytes_to_read )
return i_result; return i_result;
} }
/* Find the first first ogg page for p_stream between offsets i_pos1 and i_pos2, /* Find the first first ogg page for p_stream between offsets i_pos1 and i_pos2,
return file offset in bytes; -1 is returned on failure */ return file offset in bytes; -1 is returned on failure */
...@@ -357,11 +353,6 @@ static int64_t find_first_page( demux_t *p_demux, int64_t i_pos1, int64_t i_pos2 ...@@ -357,11 +353,6 @@ static int64_t find_first_page( demux_t *p_demux, int64_t i_pos1, int64_t i_pos2
/* Find the last frame for p_stream, /* Find the last frame for p_stream,
-1 is returned on failure */ -1 is returned on failure */
...@@ -553,14 +544,20 @@ static int64_t ogg_seek( demux_t *p_demux, logical_stream_t *p_stream, int64_t i ...@@ -553,14 +544,20 @@ static int64_t ogg_seek( demux_t *p_demux, logical_stream_t *p_stream, int64_t i
} }
break; break;
} }
#ifdef OGG_SEEK_DEBUG
if ( p_stream->fmt.i_codec == VLC_CODEC_THEORA ) msg_Dbg( p_demux, "Bisecting startpos=%ld endpos=%ld kframe=%ld iframe=%ld",
i_start_pos, i_end_pos, i_kframe, i_frame);
#endif
if ( p_stream->fmt.i_codec == VLC_CODEC_THEORA || p_stream->fmt.i_codec == VLC_CODEC_OPUS )
{ {
i_pagepos = find_first_page( p_demux, i_start_pos, i_end_pos, p_stream, i_pagepos = find_first_page( p_demux, i_start_pos, i_end_pos, p_stream,
&i_kframe, &i_frame ); &i_kframe, &i_frame );
} }
else return -1; else return -1;
#ifdef OGG_SEEK_DEBUG
msg_Dbg( p_demux, "Page Found startpos=%ld endpos=%ld kframe=%ld iframe=%ld pagepos=%ld",
i_start_pos, i_end_pos, i_kframe, i_frame, i_pagepos);
#endif
if ( i_pagepos != -1 && i_kframe != -1 ) if ( i_pagepos != -1 && i_kframe != -1 )
{ {
/* found a page */ /* found a page */
...@@ -588,7 +585,6 @@ static int64_t ogg_seek( demux_t *p_demux, logical_stream_t *p_stream, int64_t i ...@@ -588,7 +585,6 @@ static int64_t ogg_seek( demux_t *p_demux, logical_stream_t *p_stream, int64_t i
} }
else i_start_pos = i_pagepos; else i_start_pos = i_pagepos;
} }
else else
{ {
...@@ -635,7 +631,6 @@ static demux_index_entry_t *get_bounds_for ( logical_stream_t *p_stream, int64_t ...@@ -635,7 +631,6 @@ static demux_index_entry_t *get_bounds_for ( logical_stream_t *p_stream, int64_t
while ( idx != NULL ) while ( idx != NULL )
{ {
if ( idx-> i_pagepos < 0 ) if ( idx-> i_pagepos < 0 )
{ {
/* kframe was found to be invalid */ /* kframe was found to be invalid */
...@@ -643,7 +638,7 @@ static demux_index_entry_t *get_bounds_for ( logical_stream_t *p_stream, int64_t ...@@ -643,7 +638,7 @@ static demux_index_entry_t *get_bounds_for ( logical_stream_t *p_stream, int64_t
continue; continue;
} }
if ( p_stream->fmt.i_codec == VLC_CODEC_THEORA ) if ( p_stream->fmt.i_codec == VLC_CODEC_THEORA || p_stream->fmt.i_codec == VLC_CODEC_OPUS )
{ {
i_gpos = idx->i_value; i_gpos = idx->i_value;
i_kframe = i_gpos >> p_stream->i_granule_shift; i_kframe = i_gpos >> p_stream->i_granule_shift;
...@@ -787,19 +782,31 @@ int oggseek_find_frame ( demux_t *p_demux, logical_stream_t *p_stream, int64_t i ...@@ -787,19 +782,31 @@ int oggseek_find_frame ( demux_t *p_demux, logical_stream_t *p_stream, int64_t i
if ( fidx == NULL ) if ( fidx == NULL )
{ {
/* no exact match found; search the domain for highest keyframe <= i_cframe */ /* no exact match found; search the domain for highest keyframe <= i_cframe */
#ifdef OGG_SEEK_DEBUG
msg_Dbg( p_demux, "Not found in index, searching");
#endif
i_granulepos = ogg_seek ( p_demux, p_stream, i_cframe, i_pos_lower, i_pos_upper, i_granulepos = ogg_seek ( p_demux, p_stream, i_cframe, i_pos_lower, i_pos_upper,
&i_pagepos, true ); &i_pagepos, true );
if ( i_granulepos == -1 ) if ( i_granulepos == -1 )
{ {
#ifdef OGG_SEEK_DEBUG
msg_Err( p_demux, "Unable to find the requested frame");
#endif
return VLC_EGENERIC; return VLC_EGENERIC;
} }
} }
else { else {
i_granulepos = fidx->i_value; i_granulepos = fidx->i_value;
} }
if ( p_stream->fmt.i_codec == VLC_CODEC_OPUS )
{
#ifdef OGG_SEEK_DEBUG
msg_Dbg( p_demux, "OPUS seeks to granulepos %ld (%ld frames)", i_granulepos, i_tframe - i_cframe );
#endif
oggseek_theora_index_entry_add( p_stream, i_granulepos, p_sys->i_input_position );
}
else
if ( p_stream->fmt.i_codec == VLC_CODEC_THEORA ) if ( p_stream->fmt.i_codec == VLC_CODEC_THEORA )
{ {
i_kframe = i_granulepos >> p_stream->i_granule_shift; i_kframe = i_granulepos >> p_stream->i_granule_shift;
......
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