[vlc-devel] commit: reconstruct Theora granpos (ogg.k.ogg.k )

git version control git at videolan.org
Thu Jul 30 14:27:05 CEST 2009


vlc | branch: 1.0-bugfix | ogg.k.ogg.k <ogg.k.ogg.k at googlemail.com> | Sat Jul 25 15:25:53 2009 +0100| [c3512fb9ee3a64ddca7054d5e265e9aa9a4c3e3e] | committer: Jean-Baptiste Kempf 

reconstruct Theora granpos

Signed-off-by: Laurent Aimar <fenrir at videolan.org>

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=c3512fb9ee3a64ddca7054d5e265e9aa9a4c3e3e
---

 modules/codec/theora.c |    5 +++++
 modules/demux/ogg.c    |    6 ++++++
 modules/mux/ogg.c      |   34 +++++++++++++++++-----------------
 3 files changed, 28 insertions(+), 17 deletions(-)

diff --git a/modules/codec/theora.c b/modules/codec/theora.c
index af17ae7..207a13f 100644
--- a/modules/codec/theora.c
+++ b/modules/codec/theora.c
@@ -819,6 +819,11 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pict )
     memcpy( p_block->p_buffer, oggpacket.packet, oggpacket.bytes );
     p_block->i_dts = p_block->i_pts = p_pict->date;
 
+    if( theora_packet_iskeyframe( &oggpacket ) )
+    {
+        p_block->i_flags |= BLOCK_FLAG_TYPE_I;
+    }
+
     return p_block;
 }
 
diff --git a/modules/demux/ogg.c b/modules/demux/ogg.c
index 2580c6a..f73e043 100644
--- a/modules/demux/ogg.c
+++ b/modules/demux/ogg.c
@@ -806,7 +806,13 @@ static void Ogg_DecodePacket( demux_t *p_demux,
         p_block->i_length = 0;
     }
     else if( p_stream->fmt.i_codec == VLC_FOURCC( 't','h','e','o' ) )
+    {
         p_block->i_dts = p_block->i_pts = i_pts;
+        if( (p_oggpacket->granulepos & ((1<<p_stream->i_granule_shift)-1)) == 0 )
+        {
+            p_block->i_flags |= BLOCK_FLAG_TYPE_I;
+        }
+    }
     else if( p_stream->fmt.i_codec == VLC_FOURCC( 'd','r','a','c' ) )
     {
         ogg_int64_t dts = p_oggpacket->granulepos >> 31;
diff --git a/modules/mux/ogg.c b/modules/mux/ogg.c
index fcdfb8a..bafc4d6 100644
--- a/modules/mux/ogg.c
+++ b/modules/mux/ogg.c
@@ -179,8 +179,10 @@ typedef struct
     int     i_packet_no;
     int     i_serial_no;
     int     i_keyframe_granule_shift; /* Theora only */
-    int     i_last_keyframe; /* dirac and eventually theora */
+    int     i_last_keyframe; /* dirac and theora */
+    int     i_num_frames; /* Theora only */
     uint64_t u_last_granulepos; /* Used for correct EOS page */
+    int64_t i_num_keyframes;
     ogg_stream_state os;
 
     oggds_header_t *p_oggds_header;
@@ -326,6 +328,9 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
     p_stream->i_fourcc    = p_input->p_fmt->i_codec;
     p_stream->i_serial_no = p_sys->i_next_serial_no++;
     p_stream->i_packet_no = 0;
+    p_stream->i_last_keyframe = 0;
+    p_stream->i_num_keyframes = 0;
+    p_stream->i_num_frames = 0;
 
     p_stream->p_oggds_header = 0;
 
@@ -654,17 +659,8 @@ static block_t *OggCreateHeader( sout_mux_t *p_mux )
             /* Get keyframe_granule_shift for theora granulepos calculation */
             if( p_stream->i_fourcc == VLC_FOURCC( 't', 'h', 'e', 'o' ) )
             {
-                int i_keyframe_frequency_force =
-                      1 << ((op.packet[40] << 6 >> 3) | (op.packet[41] >> 5));
-
-                /* granule_shift = i_log( frequency_force -1 ) */
-                p_stream->i_keyframe_granule_shift = 0;
-                i_keyframe_frequency_force--;
-                while( i_keyframe_frequency_force )
-                {
-                    p_stream->i_keyframe_granule_shift++;
-                    i_keyframe_frequency_force >>= 1;
-                }
+                p_stream->i_keyframe_granule_shift =
+                    ( (op.packet[40] & 0x03) << 3 ) | ( (op.packet[41] & 0xe0) >> 5 );
             }
         }
         else if( p_stream->i_fourcc == VLC_FOURCC( 'd', 'r', 'a', 'c' ) )
@@ -1002,11 +998,15 @@ static int MuxBlock( sout_mux_t *p_mux, sout_input_t *p_input )
     {
         if( p_stream->i_fourcc == VLC_FOURCC( 't', 'h', 'e', 'o' ) )
         {
-            /* FIXME, we assume only keyframes */
-            op.granulepos = ( ( p_data->i_dts - p_sys->i_start_dts ) *
-                p_input->p_fmt->video.i_frame_rate /
-                p_input->p_fmt->video.i_frame_rate_base /
-                INT64_C(1000000) ) << p_stream->i_keyframe_granule_shift;
+            p_stream->i_num_frames++;
+            if( p_data->i_flags & BLOCK_FLAG_TYPE_I )
+            {
+                p_stream->i_num_keyframes++;
+                p_stream->i_last_keyframe = p_stream->i_num_frames;
+            }
+
+            op.granulepos = (p_stream->i_last_keyframe << p_stream->i_keyframe_granule_shift )
+                          | (p_stream->i_num_frames-p_stream->i_last_keyframe);
         }
         else if( p_stream->i_fourcc == VLC_FOURCC( 'd', 'r', 'a', 'c' ) )
         {




More information about the vlc-devel mailing list