Commit c3512fb9 authored by ogg.k.ogg.k's avatar ogg.k.ogg.k Committed by Jean-Baptiste Kempf

reconstruct Theora granpos

Signed-off-by: default avatarLaurent Aimar <fenrir@videolan.org>
parent e366e700
...@@ -819,6 +819,11 @@ static block_t *Encode( encoder_t *p_enc, picture_t *p_pict ) ...@@ -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 ); memcpy( p_block->p_buffer, oggpacket.packet, oggpacket.bytes );
p_block->i_dts = p_block->i_pts = p_pict->date; 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; return p_block;
} }
......
...@@ -806,7 +806,13 @@ static void Ogg_DecodePacket( demux_t *p_demux, ...@@ -806,7 +806,13 @@ static void Ogg_DecodePacket( demux_t *p_demux,
p_block->i_length = 0; p_block->i_length = 0;
} }
else if( p_stream->fmt.i_codec == VLC_FOURCC( 't','h','e','o' ) ) else if( p_stream->fmt.i_codec == VLC_FOURCC( 't','h','e','o' ) )
{
p_block->i_dts = p_block->i_pts = i_pts; 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' ) ) else if( p_stream->fmt.i_codec == VLC_FOURCC( 'd','r','a','c' ) )
{ {
ogg_int64_t dts = p_oggpacket->granulepos >> 31; ogg_int64_t dts = p_oggpacket->granulepos >> 31;
......
...@@ -179,8 +179,10 @@ typedef struct ...@@ -179,8 +179,10 @@ typedef struct
int i_packet_no; int i_packet_no;
int i_serial_no; int i_serial_no;
int i_keyframe_granule_shift; /* Theora only */ 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 */ uint64_t u_last_granulepos; /* Used for correct EOS page */
int64_t i_num_keyframes;
ogg_stream_state os; ogg_stream_state os;
oggds_header_t *p_oggds_header; oggds_header_t *p_oggds_header;
...@@ -326,6 +328,9 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input ) ...@@ -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_fourcc = p_input->p_fmt->i_codec;
p_stream->i_serial_no = p_sys->i_next_serial_no++; p_stream->i_serial_no = p_sys->i_next_serial_no++;
p_stream->i_packet_no = 0; 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; p_stream->p_oggds_header = 0;
...@@ -654,17 +659,8 @@ static block_t *OggCreateHeader( sout_mux_t *p_mux ) ...@@ -654,17 +659,8 @@ static block_t *OggCreateHeader( sout_mux_t *p_mux )
/* Get keyframe_granule_shift for theora granulepos calculation */ /* Get keyframe_granule_shift for theora granulepos calculation */
if( p_stream->i_fourcc == VLC_FOURCC( 't', 'h', 'e', 'o' ) ) if( p_stream->i_fourcc == VLC_FOURCC( 't', 'h', 'e', 'o' ) )
{ {
int i_keyframe_frequency_force = p_stream->i_keyframe_granule_shift =
1 << ((op.packet[40] << 6 >> 3) | (op.packet[41] >> 5)); ( (op.packet[40] & 0x03) << 3 ) | ( (op.packet[41] & 0xe0) >> 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;
}
} }
} }
else if( p_stream->i_fourcc == VLC_FOURCC( 'd', 'r', 'a', 'c' ) ) 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 ) ...@@ -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' ) ) if( p_stream->i_fourcc == VLC_FOURCC( 't', 'h', 'e', 'o' ) )
{ {
/* FIXME, we assume only keyframes */ p_stream->i_num_frames++;
op.granulepos = ( ( p_data->i_dts - p_sys->i_start_dts ) * if( p_data->i_flags & BLOCK_FLAG_TYPE_I )
p_input->p_fmt->video.i_frame_rate / {
p_input->p_fmt->video.i_frame_rate_base / p_stream->i_num_keyframes++;
INT64_C(1000000) ) << p_stream->i_keyframe_granule_shift; 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' ) ) else if( p_stream->i_fourcc == VLC_FOURCC( 'd', 'r', 'a', 'c' ) )
{ {
......
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