+ /* 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 )
+ p_sys->i_interpolated_pts +=
+ ( (i_time_ref + i_time_increment -
+ p_sys->i_last_time - p_sys->i_last_timeincr) *
+ I64C(1000000) / 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;
+ }
+