1 /*****************************************************************************
2 * input_ext-dec.c: services to the decoders
3 *****************************************************************************
4 * Copyright (C) 1998, 1999, 2000 VideoLAN
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
21 *****************************************************************************/
23 /*****************************************************************************
25 *****************************************************************************/
35 #include "stream_control.h"
36 #include "input_ext-dec.h"
39 /*****************************************************************************
40 * InitBitstream: initialize a bit_stream_t structure
41 *****************************************************************************/
42 void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo )
44 p_bit_stream->p_decoder_fifo = p_fifo;
45 p_bit_stream->pf_next_data_packet = NextDataPacket;
47 /* Get the first data packet. */
48 vlc_mutex_lock( &p_fifo->data_lock );
49 while ( DECODER_FIFO_ISEMPTY( *p_fifo ) )
53 vlc_mutex_unlock( &p_fifo->data_lock );
56 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
58 p_bit_stream->p_data = DECODER_FIFO_START( *p_fifo )->p_first;
59 p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
60 p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
61 p_bit_stream->fifo.buffer = 0;
62 p_bit_stream->fifo.i_available = 0;
63 vlc_mutex_unlock( &p_fifo->data_lock );
66 /*****************************************************************************
67 * NextDataPacket: go to the next data packet
68 *****************************************************************************/
69 void NextDataPacket( bit_stream_t * p_bit_stream )
71 WORD_TYPE buffer_left;
72 /* FIXME : not portable in a 64bit environment */
74 decoder_fifo_t * p_fifo = p_bit_stream->p_decoder_fifo;
76 /* Buffer used at the end of a decoder thread, to give it zero
77 * values if needed. */
78 static byte_t p_zero[64] = { 0, 0, 0, 0, 0, 0, 0,
85 0, 0, 0, 0, 0, 0, 0 };
87 /* Put the remaining bytes (not aligned on a word boundary) in a
88 * temporary buffer. */
89 i_bytes_left = p_bit_stream->p_end - p_bit_stream->p_byte;
90 buffer_left = *((WORD_TYPE *)p_bit_stream->p_end - 1);
92 /* We are looking for the next data packet that contains real data,
93 * and not just a PES header */
96 /* We were reading the last data packet of this PES packet... It's
97 * time to jump to the next PES packet */
98 if( p_bit_stream->p_data->p_next == NULL )
100 /* We are going to read/write the start and end indexes of the
101 * decoder fifo and to use the fifo's conditional variable,
102 * that's why we need to take the lock before. */
103 vlc_mutex_lock( &p_fifo->data_lock );
105 /* Is the input thread dying ? */
108 vlc_mutex_unlock( &p_fifo->data_lock );
109 p_bit_stream->p_byte = p_zero;
110 p_bit_stream->p_end = &p_zero[sizeof(p_zero) - 1];
114 /* We should increase the start index of the decoder fifo, but
115 * if we do this now, the input thread could overwrite the
116 * pointer to the current PES packet, and we weren't able to
117 * give it back to the netlist. That's why we free the PES
119 p_fifo->pf_delete_pes( p_fifo->p_packets_mgt,
120 DECODER_FIFO_START( *p_fifo ) );
121 DECODER_FIFO_INCSTART( *p_fifo );
123 while( DECODER_FIFO_ISEMPTY( *p_fifo ) )
125 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
128 vlc_mutex_unlock( &p_fifo->data_lock );
129 p_bit_stream->p_byte = p_zero;
130 p_bit_stream->p_end = &p_zero[sizeof(p_zero) - 1];
135 /* The next byte could be found in the next PES packet */
136 p_bit_stream->p_data = DECODER_FIFO_START( *p_fifo )->p_first;
138 /* We can release the fifo's data lock */
139 vlc_mutex_unlock( &p_fifo->data_lock );
143 /* Perhaps the next data packet of the current PES packet contains
144 * real data (ie its payload's size is greater than 0). */
145 p_bit_stream->p_data = p_bit_stream->p_data->p_next;
147 } while ( p_bit_stream->p_data->p_payload_start
148 == p_bit_stream->p_data->p_payload_end );
150 /* We've found a data packet which contains interesting data... */
151 p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
152 p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
154 /* Copy remaining bits of the previous packet */
155 *((WORD_TYPE *)p_bit_stream->p_byte - 1) = buffer_left;
156 p_bit_stream->p_byte -= i_bytes_left;