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;
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;
/* 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 )
{
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 )
{