[vlc-commits] demux: ogg: handle opus seeking (fix #9334)
Francois Cartegnie
git at videolan.org
Sat Sep 7 22:16:08 CEST 2013
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Sat Sep 7 22:08:47 2013 +0200| [1b4c719d06c758c0f9e19166b7a42a99cc6717f3] | committer: Francois Cartegnie
demux: ogg: handle opus seeking (fix #9334)
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=1b4c719d06c758c0f9e19166b7a42a99cc6717f3
---
modules/demux/ogg.c | 24 +++++++++++++++++++++---
modules/demux/oggseek.c | 43 +++++++++++++++++++++++++------------------
2 files changed, 46 insertions(+), 21 deletions(-)
diff --git a/modules/demux/ogg.c b/modules/demux/ogg.c
index c07394f..57edb99 100644
--- a/modules/demux/ogg.c
+++ b/modules/demux/ogg.c
@@ -570,9 +570,27 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
}
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 ) )
- return VLC_EGENERIC;
+
+ if ( p_sys->i_bitrate == 0 )
+ {
+ /* 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_seekpoint = i_seekpoint;
return VLC_SUCCESS;
diff --git a/modules/demux/oggseek.c b/modules/demux/oggseek.c
index 3c65e5f..a059fa0 100644
--- a/modules/demux/oggseek.c
+++ b/modules/demux/oggseek.c
@@ -38,7 +38,7 @@
#include "ogg.h"
#include "oggseek.h"
-
+//#define OGG_SEEK_DEBUG 1
/************************************************************
* index entries
*************************************************************/
@@ -214,10 +214,6 @@ static int64_t get_data( demux_t *p_demux, int64_t i_bytes_to_read )
return i_result;
}
-
-
-
-
/* 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 */
@@ -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,
-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
}
break;
}
-
- if ( p_stream->fmt.i_codec == VLC_CODEC_THEORA )
+#ifdef OGG_SEEK_DEBUG
+ 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_kframe, &i_frame );
}
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 )
{
/* found a page */
@@ -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
{
@@ -635,7 +631,6 @@ static demux_index_entry_t *get_bounds_for ( logical_stream_t *p_stream, int64_t
while ( idx != NULL )
{
-
if ( idx-> i_pagepos < 0 )
{
/* 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
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_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
if ( fidx == NULL )
{
/* 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_pagepos, true );
if ( i_granulepos == -1 )
{
+#ifdef OGG_SEEK_DEBUG
+ msg_Err( p_demux, "Unable to find the requested frame");
+#endif
return VLC_EGENERIC;
}
-
}
else {
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 )
{
i_kframe = i_granulepos >> p_stream->i_granule_shift;
More information about the vlc-commits
mailing list