- if( p_start[3] >= 0x20 && p_start[3] <= 0x2f )
- {
- /* Start of the VOL */
- p_vol = p_start;
- }
- else if( p_start[3] == 0xb3 )
- {
- /* GOP header */
- }
- else if( p_start[3] == 0xb6 )
- {
- /* Parse the VOP */
- bs_t s;
- int i_modulo_time_base = 0;
- int i_time_increment_bits;
- int64_t i_time_increment, i_time_ref;
-
- /* FIXME: we don't actually check we received enough data to read
- * the VOP time increment. */
- bs_init( &s, &p_start[4],
- p_sys->i_buffer - (p_start - p_sys->p_buffer) - 4 );
-
- switch( bs_read( &s, 2 ) )
- {
- case 0:
- p_sys->i_flags = BLOCK_FLAG_TYPE_I;
- break;
- case 1:
- p_sys->i_flags = BLOCK_FLAG_TYPE_P;
- break;
- case 2:
- p_sys->i_flags = BLOCK_FLAG_TYPE_B;
- p_sys->b_frame = VLC_TRUE;
- break;
- case 3: /* gni ? */
- p_sys->i_flags = BLOCK_FLAG_TYPE_PB;
- break;
- }
-
- while( bs_read( &s, 1 ) ) i_modulo_time_base++;
- if( !bs_read1( &s ) ) continue; /* Marker */
-
- /* VOP time increment */
- i_time_increment_bits = vlc_log2(p_dec->p_sys->i_fps_num - 1) + 1;
- if( i_time_increment_bits < 1 ) i_time_increment_bits = 1;
- i_time_increment = bs_read( &s, i_time_increment_bits );
-
- /* Interpolate PTS/DTS */
- if( !(p_sys->i_flags & BLOCK_FLAG_TYPE_B) )
- {
- p_sys->i_last_time_ref = p_sys->i_time_ref;
- p_sys->i_time_ref +=
- (i_modulo_time_base * p_dec->p_sys->i_fps_num);
- i_time_ref = p_sys->i_time_ref;
- }
- else
- {
- i_time_ref = p_sys->i_last_time_ref +
- (i_modulo_time_base * p_dec->p_sys->i_fps_num);
- }
-
- if( p_dec->p_sys->i_fps_num < 5 && /* Work-around buggy streams */
- p_dec->fmt_in.video.i_frame_rate > 0 &&
- p_dec->fmt_in.video.i_frame_rate_base > 0 )
- {
- p_sys->i_interpolated_pts += I64C(1000000) *
- p_dec->fmt_in.video.i_frame_rate_base *
- p_block->i_rate / INPUT_RATE_DEFAULT /
- p_dec->fmt_in.video.i_frame_rate;
- }
- else if( p_dec->p_sys->i_fps_num )
- p_sys->i_interpolated_pts +=
- ( I64C(1000000) * (i_time_ref + i_time_increment -
- p_sys->i_last_time - p_sys->i_last_timeincr) *
- p_block->i_rate / INPUT_RATE_DEFAULT /
- p_dec->p_sys->i_fps_num );
-
- p_sys->i_last_time = i_time_ref;
- p_sys->i_last_timeincr = i_time_increment;
-
- /* Correct interpolated dts when we receive a new pts/dts */
- if( p_block->i_pts > 0 )
- p_sys->i_interpolated_pts = p_block->i_pts;
- if( p_block->i_dts > 0 )
- p_sys->i_interpolated_dts = p_block->i_dts;
-
- if( (p_sys->i_flags & BLOCK_FLAG_TYPE_B) || !p_sys->b_frame )
- {
- /* Trivial case (DTS == PTS) */
-
- p_sys->i_interpolated_dts = p_sys->i_interpolated_pts;
-
- if( p_block->i_pts > 0 )
- p_sys->i_interpolated_dts = p_block->i_pts;
- if( p_block->i_dts > 0 )
- p_sys->i_interpolated_dts = p_block->i_dts;
-
- p_sys->i_interpolated_pts = p_sys->i_interpolated_dts;
- }
- else
- {
- if( p_sys->i_last_ref_pts > 0 )
- p_sys->i_interpolated_dts = p_sys->i_last_ref_pts;
-
- p_sys->i_last_ref_pts = p_sys->i_interpolated_pts;
- }
-
- p_sys->b_vop = VLC_TRUE;
-
- /* Don't re-use the same PTS/DTS twice */
- p_block->i_pts = p_block->i_dts = 0;
- }