[vlc-devel] commit: reconstruct Theora granpos (ogg.k.ogg.k )
git version control
git at videolan.org
Wed Jul 29 00:20:39 CEST 2009
vlc | branch: master | ogg.k.ogg.k <ogg.k.ogg.k at googlemail.com> | Sat Jul 25 15:25:53 2009 +0100| [d7ba3f3f8499e95a4a7011f54dc59208852e834c] | committer: Laurent Aimar
reconstruct Theora granpos
Signed-off-by: Laurent Aimar <fenrir at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=d7ba3f3f8499e95a4a7011f54dc59208852e834c
---
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 4faf908..83c4a54 100644
--- a/modules/codec/theora.c
+++ b/modules/codec/theora.c
@@ -818,6 +818,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 5e50b7a..6387e12 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_CODEC_THEORA )
+ {
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_CODEC_DIRAC )
{
ogg_int64_t dts = p_oggpacket->granulepos >> 31;
diff --git a/modules/mux/ogg.c b/modules/mux/ogg.c
index 3736371..abe139b 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_CODEC_THEORA )
{
- 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_CODEC_DIRAC )
@@ -1002,11 +998,15 @@ static int MuxBlock( sout_mux_t *p_mux, sout_input_t *p_input )
{
if( p_stream->i_fourcc == VLC_CODEC_THEORA )
{
- /* 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_CODEC_DIRAC )
{
More information about the vlc-devel
mailing list