- 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 = 9 + p_pes->p_pes_header[8];
-
- /* 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;
- pthread_mutex_lock( &p_pcr->lock );
- if( p_pcr->delta_clock == 0 )
- {
- p_pes->b_has_pts = 0;
- }
- else
- {
- 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) );
- p_pes->i_pts *= 300;
- p_pes->i_pts /= 27;
- p_pes->i_pts += p_pcr->delta_clock;
- if( p_pcr->c_pts == 0 )
- {
- p_pcr->delta_decode = mdate() - p_pes->i_pts + 500000;
- }
- p_pes->i_pts += p_pcr->delta_decode;
- p_pcr->c_pts += 1;
- }
- pthread_mutex_unlock( &p_pcr->lock );
- }
- 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. */
- 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 )
- {
- /* These packets are entirely filled by the PES header. */
- 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 */
- p_ts = p_ts->p_next_ts;
- i_ts_payload_size = p_ts->i_payload_end - p_ts->i_payload_start;
- }
- /* This last packet is partly header, partly payload. */
- p_ts->i_payload_start += i_pes_header_size;
-
- /* Now we can eventually put the PES packet in the decoder's
- PES fifo */
- switch( p_es_descriptor->i_type )
- {
- case MPEG1_VIDEO_ES:
- case MPEG2_VIDEO_ES:
- p_fifo = &(((vdec_thread_t*)(p_es_descriptor->p_dec))->fifo);
- break;
- case MPEG1_AUDIO_ES:
- case MPEG2_AUDIO_ES:
- p_fifo = &(((adec_thread_t*)(p_es_descriptor->p_dec))->fifo);
- break;
- default:
- /* This should never happen. */
- intf_DbgMsg("Unknown stream type (%d, %d): PES trashed\n",
- p_es_descriptor->i_id, p_es_descriptor->i_type);
- p_fifo = NULL;
- break;
- }
-
- if( p_fifo != NULL )
- {
- pthread_mutex_lock( &p_fifo->data_lock );
- if( DECODER_FIFO_ISFULL( *p_fifo ) )
- {
- /* The FIFO is full !!! This should not happen. */
-#ifdef STATS
- p_input->c_ts_packets_trashed += p_pes->i_ts_packets;
- p_es_descriptor->c_invalid_packets += p_pes->i_ts_packets;
-#endif
- input_NetlistFreePES( p_input, p_pes );
- intf_DbgMsg("PES trashed - fifo full ! (%d, %d)\n",
- p_es_descriptor->i_id, p_es_descriptor->i_type);
- }
- else
- {
-// intf_DbgMsg("Putting %p into fifo %p/%d\n",
-// p_pes, p_fifo, p_fifo->i_end);
- p_fifo->buffer[p_fifo->i_end] = p_pes;
- DECODER_FIFO_INCEND( *p_fifo );
-
- /* Warn the decoder that it's got work to do. */
- pthread_cond_signal( &p_fifo->data_wait );
- }
- pthread_mutex_unlock( &p_fifo->data_lock );
- }
- else
- {
- intf_DbgMsg("No fifo to receive PES %p: trash\n", p_pes);
-#ifdef STATS
- p_input->c_ts_packets_trashed += p_pes->i_ts_packets;
- p_es_descriptor->c_invalid_packets += p_pes->i_ts_packets;
-#endif
- input_NetlistFreePES( p_input, p_pes );
- }
- }
- }
-
-
- /* If we are at the beginning of a new PES packet, we must fetch a new
- PES buffer to begin with the reassembly of this PES packet. This is
- also here that we can synchronise with the stream if we we lost
- packets or if the decoder has just started */
- if( b_unit_start )
- {
- p_last_pes = p_pes;
-
- /* Get a new one PES from the PES netlist. */
- if( (p_pes = input_NetlistGetPES( p_input )) == (NULL) )
- {
- /* PES netlist is empty ! */
- p_input->b_error = 1;
- }
- else
- {
-// intf_DbgMsg("New PES packet %p (first TS: %p)\n", p_pes, p_ts_packet);
-
- /* Init the PES fields so that the first TS packet could be correctly
- added to the PES packet (see below) */