[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