intf_DbgMsg("PES packet too short: trashed\n");
input_NetlistFreePES( p_input, p_pes );
p_pes = NULL;
- /* Stats XXX?? */
+ /* XXX: Stats */
return;
}
{
/* Trash the packet and set p_pes to NULL to be sure the next PES
packet will have its b_data_lost flag set */
- intf_DbgMsg("Corrupted PES packet received: trashed\n");
+ intf_DbgMsg("Corrupted PES packet (size doesn't match) : trashed\n");
input_NetlistFreePES( p_input, p_pes );
p_pes = NULL;
/* Stats XXX?? */
break;
default:
- /* The PES header contains at least 3 more bytes: parse them */
- p_pes->b_data_alignment = p_pes->p_pes_header[6] & 0x04;
- p_pes->b_has_pts = p_pes->p_pes_header[7] & 0x80;
- i_pes_header_size = p_pes->p_pes_header[8] + 9;
-
- /* Now parse the optional header extensions (in the limit of
- the 14 bytes */
- if( p_pes->b_has_pts )
+ switch( p_pes->p_pes_header[8] & 0xc0 )
{
- pcr_descriptor_t * p_pcr;
+ case 0x80: /* MPEG2: 10xx xxxx */
+ case 0x00: /* FIXME: This shouldn't be allowed !! */
+ /* The PES header contains at least 3 more bytes: parse them */
+ p_pes->b_data_alignment = p_pes->p_pes_header[6] & 0x04;
+ p_pes->b_has_pts = p_pes->p_pes_header[7] & 0x80;
+ i_pes_header_size = p_pes->p_pes_header[8] + 9;
+
+ /* Now parse the optional header extensions (in the limit of
+ the 14 bytes */
+ if( p_pes->b_has_pts )
+ {
+ pcr_descriptor_t * p_pcr;
- p_pcr = p_input->p_pcr;
+ p_pcr = p_input->p_pcr;
- p_pes->i_pts =
- ( ((mtime_t)(p_pes->p_pes_header[9] & 0x0E) << 29) |
- (((mtime_t)U16_AT(p_pes->p_pes_header + 10) << 14) - (1 << 14)) |
- ((mtime_t)U16_AT(p_pes->p_pes_header + 12) >> 1) ) * 300;
- p_pes->i_pts /= 27;
+ p_pes->i_pts =
+ ( ((mtime_t)(p_pes->p_pes_header[9] & 0x0E) << 29) |
+ (((mtime_t)U16_AT(p_pes->p_pes_header + 10) << 14) - (1 << 14)) |
+ ((mtime_t)U16_AT(p_pes->p_pes_header + 12) >> 1) ) * 300;
+ p_pes->i_pts /= 27;
- if( p_pcr->i_synchro_state )
- {
- switch( p_pcr->i_synchro_state )
+ if( p_pcr->i_synchro_state )
{
- case SYNCHRO_NOT_STARTED:
- p_pes->b_has_pts = 0;
- break;
-
- case SYNCHRO_START:
- p_pes->i_pts += p_pcr->delta_pcr;
- p_pcr->delta_absolute = mdate() - p_pes->i_pts + INPUT_PTS_DELAY;
- p_pes->i_pts += p_pcr->delta_absolute;
- p_pcr->i_synchro_state = 0;
- break;
-
- case SYNCHRO_REINIT: /* We skip a PES */
- p_pes->b_has_pts = 0;
- p_pcr->i_synchro_state = SYNCHRO_START;
- break;
+ switch( p_pcr->i_synchro_state )
+ {
+ case SYNCHRO_NOT_STARTED:
+ p_pes->b_has_pts = 0;
+ break;
+
+ case SYNCHRO_START:
+ p_pes->i_pts += p_pcr->delta_pcr;
+ p_pcr->delta_absolute = mdate() - p_pes->i_pts + INPUT_PTS_DELAY;
+ p_pes->i_pts += p_pcr->delta_absolute;
+ p_pcr->i_synchro_state = 0;
+ break;
+
+ case SYNCHRO_REINIT: /* We skip a PES */
+ p_pes->b_has_pts = 0;
+ p_pcr->i_synchro_state = SYNCHRO_START;
+ break;
+ }
+ }
+ else
+ {
+ p_pes->i_pts += p_pcr->delta_pcr + p_pcr->delta_absolute;
}
}
- else
- {
- p_pes->i_pts += p_pcr->delta_pcr + p_pcr->delta_absolute;
- }
+ break;
+
+ default: /* MPEG1 or some strange thing */
+ /* since this isn't supported yet, we certainly gonna crash */
+ intf_ErrMsg( "FIXME: unknown PES type %.2x\n",
+ p_pes->p_pes_header[8] );
+ i_pes_header_size = 6;
+ break;
+
}
break;
}
/* Now we've parsed the header, we just have to indicate in some
- specific TS packets where the PES payload begins (renumber
- i_payload_start), so that the decoders can find the beginning
- of their data right out of the box. */
+ * specific TS packets where the PES payload begins (renumber
+ * i_payload_start), so that the decoders can find the beginning
+ * of their data right out of the box. */
p_ts = p_pes->p_first_ts;
i_ts_payload_size = p_ts->i_payload_end - p_ts->i_payload_start;
while( i_pes_header_size > i_ts_payload_size )
i_pes_header_size -= i_ts_payload_size;
p_ts->i_payload_start = p_ts->i_payload_end;
/* Go to the next TS packet: here we won't have to test it is
- not NULL because we trash the PES packets when packet lost
- occurs */
+ * not NULL because we trash the PES packets when packet lost
+ * occurs */
p_ts = p_ts->p_next_ts;
i_ts_payload_size = p_ts->i_payload_end - p_ts->i_payload_start;
}
/* Now we can eventually put the PES packet in the decoder's
- PES fifo */
+ * PES fifo */
switch( p_es_descriptor->i_type )
{
case MPEG1_VIDEO_ES:
/* Try to find the beginning of the payload in the packet to initialise
- the do-while loop that follows -> Compute the i_data_offset variable:
- by default, the value is set so that we won't enter in the while loop.
- It will be set to a correct value if the data are not corrupted */
+ * the do-while loop that follows -> Compute the i_data_offset variable:
+ * by default, the value is set so that we won't enter in the while loop.
+ * It will be set to a correct value if the data are not corrupted */
i_data_offset = TS_PACKET_SIZE;
/* Has the reassembly of a section already begun in a previous packet ? */
else
{
/* The data that complete a previously began section are always at
- the beginning of the TS payload... */
+ * the beginning of the TS payload... */
i_data_offset = p_ts_packet->i_payload_start;
/* ...Unless there is a pointer field, that we have to bypass */
if( b_unit_start )
if( b_unit_start )
{
/* Get the offset at which the data for that section can be found
- The offset is stored in the pointer_field since we are
- interested in the first section of the TS packet. Note that
- the +1 is to bypass the pointer field */
+ * The offset is stored in the pointer_field since we are
+ * interested in the first section of the TS packet. Note that
+ * the +1 is to bypass the pointer field */
i_data_offset = p_ts_packet->i_payload_start +
p_ts_packet->buffer[p_ts_packet->i_payload_start] + 1;
//intf_DbgMsg( "New section beginning at offset %d in TS packet\n", i_data_offset );
i_data_length );
/* Interesting data are now after the ones we copied, since no gap is
- allowed between 2 sections in a TS packets */
+ * allowed between 2 sections in a TS packets */
i_data_offset += i_data_length;
/* Decode the packet if it is now complete */
#undef p_psi
}
+
void vpar_SynchroUpdateStructures( vpar_thread_t * p_vpar,
int i_coding_type, boolean_t b_kept )
{
- mtime_t i_delay;
+ double i_can_display;
mtime_t i_pts;
- pes_packet_t * p_pes = p_vpar->bit_stream.p_decoder_fifo->buffer[
+ pes_packet_t * p_pes = p_vpar->bit_stream.p_decoder_fifo->buffer[
p_vpar->bit_stream.p_decoder_fifo->i_start ];
/* try to guess the current DTS and PTS */
}
/* now we calculated all statistics, it's time to
- * decide what we have the time to display
- */
- i_delay = i_pts - p_vpar->synchro.i_last_kept_I_pts;
+ * decide what we have the time to display */
+ i_can_display = (float)(i_pts - p_vpar->synchro.i_last_kept_I_pts)
+ / p_vpar->synchro.i_delay;
- p_vpar->synchro.b_all_I
- = ( p_vpar->synchro.i_delay < i_delay );
+ p_vpar->synchro.b_all_I = 0;
+ p_vpar->synchro.b_all_B = 0;
+ p_vpar->synchro.b_all_P = 0;
+ p_vpar->synchro.displayable_p = 0;
+ p_vpar->synchro.displayable_b = 0;
- p_vpar->synchro.b_all_P
- = ( p_vpar->synchro.i_delay
- * (1 + p_vpar->synchro.i_P_seen) < i_delay );
-
- if( !p_vpar->synchro.b_all_P )
- {
- p_vpar->synchro.displayable_p
- //= -1.0 + (float)i_delay / (float)p_vpar->synchro.i_delay;
- = (-1.0 + (float)p_vpar->synchro.displayable_p + (float)i_delay / (float)p_vpar->synchro.i_delay) / 2.0;
- if( p_vpar->synchro.displayable_p < 0 )
- p_vpar->synchro.displayable_p = 0;
-
- p_vpar->synchro.b_all_B = 0;
- p_vpar->synchro.displayable_b = 0;
- }
- else
+ if( ( p_vpar->synchro.b_all_I = ( i_can_display > 1 ) ) )
{
- p_vpar->synchro.displayable_p = p_vpar->synchro.i_P_seen;
+ i_can_display -= 1;
- if( !(p_vpar->synchro.b_all_B
- = ( p_vpar->synchro.i_delay
- * (1 + p_vpar->synchro.i_B_seen
- + p_vpar->synchro.i_P_seen)) < i_delay) )
+ if( !( p_vpar->synchro.b_all_P
+ = ( i_can_display > p_vpar->synchro.i_P_seen ) ) )
{
- p_vpar->synchro.displayable_b
- //= -2.0 + i_delay / p_vpar->synchro.i_delay - p_vpar->synchro.b_all_P;
- = ( -2.0 + (float)p_vpar->synchro.displayable_b + (float)i_delay / (float)p_vpar->synchro.i_delay - (float)p_vpar->synchro.b_all_P) / 2.0;
+ p_vpar->synchro.displayable_p = i_can_display;
}
else
{
- p_vpar->synchro.displayable_b = p_vpar->synchro.i_B_seen;
+ i_can_display -= p_vpar->synchro.i_P_seen;
+
+ if( !( p_vpar->synchro.b_all_B
+ = ( i_can_display > p_vpar->synchro.i_B_seen ) ) )
+ {
+ p_vpar->synchro.displayable_b = i_can_display;
+ }
}
}
#if 1
if( p_vpar->synchro.b_all_I )
- intf_ErrMsg( "I: all " );
+ intf_ErrMsg( "I: 1/1 " );
if( p_vpar->synchro.b_all_P )
- intf_ErrMsg( "P: all " );
+ intf_ErrMsg( "P: %i/%i ", p_vpar->synchro.i_P_seen,
+ p_vpar->synchro.i_P_seen );
else if( p_vpar->synchro.displayable_p > 0 )
- intf_ErrMsg( "P: %f ", p_vpar->synchro.displayable_p );
+ intf_ErrMsg( "P: %.2f/%i ", p_vpar->synchro.displayable_p,
+ p_vpar->synchro.i_P_seen );
if( p_vpar->synchro.b_all_B )
- intf_ErrMsg( "B: all" );
+ intf_ErrMsg( "B: %i/%i", p_vpar->synchro.displayable_b,
+ p_vpar->synchro.displayable_b );
else if( p_vpar->synchro.displayable_b > 0 )
- intf_ErrMsg( "B: %f", p_vpar->synchro.displayable_b );
+ intf_ErrMsg( "B: %.2f/%i", p_vpar->synchro.displayable_b,
+ p_vpar->synchro.i_B_seen );
intf_ErrMsg( "\n" );
#endif
p_vpar->synchro.i_P_seen = 0;
case P_CODING_TYPE:
+ //return(1);
if( p_vpar->synchro.b_all_P )
{
//intf_ErrMsg( " p " );