- /* The PES packet is valid. Check its type to test if it may
- carry additional informations in a header extension */
- p_pes->i_stream_id = p_pes->p_pes_header[3];
-
- switch( p_pes->i_stream_id )
- {
- case 0xBE: /* Padding */
- case 0xBC: /* Program stream map */
- case 0xBF: /* Private stream 2 */
- case 0xB0: /* ECM */
- case 0xB1: /* EMM */
- case 0xFF: /* Program stream directory */
- case 0xF2: /* DSMCC stream */
- case 0xF8: /* ITU-T H.222.1 type E stream */
- /* The payload begins immediatly after the 6 bytes header, so
- we have finished with the parsing */
- i_pes_header_size = 6;
- 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 )
- {
- pcr_descriptor_t * 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;
-
- if( p_pcr->i_synchro_state )
- {
- 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;
- }
- }
- 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:
-#ifdef OLD_DECODER
- p_fifo = &(((vdec_thread_t*)(p_es_descriptor->p_dec))->fifo);
-#else
- p_fifo = &(((vpar_thread_t*)(p_es_descriptor->p_dec))->fifo);
-#endif
- break;
-
- case MPEG1_AUDIO_ES:
- case MPEG2_AUDIO_ES:
- p_fifo = &(((adec_thread_t*)(p_es_descriptor->p_dec))->fifo);
- break;
-
- case AC3_AUDIO_ES:
-#if 0
- /* we skip 4 bytes at the beginning of the AC3 payload */
- p_ts->i_payload_start += 4;
-#endif
- p_fifo = &(((ac3dec_thread_t *)(p_es_descriptor->p_dec))->fifo);
- break;
-
- case DVD_SPU_ES:
- /* we skip 4 bytes at the beginning of the subpicture payload */
- p_ts->i_payload_start += 4;
- p_fifo = &(((spudec_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 )
- {
- vlc_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_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. */
- vlc_cond_signal( &p_fifo->data_wait );
- }
- vlc_mutex_unlock( &p_fifo->data_lock );
- }
- else
- {
- intf_DbgMsg("No fifo to receive PES %p: trash\n", p_pes);
-#ifdef STATS
- p_input->c_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 );
- }