1 /*****************************************************************************
2 * input_ext-dec.c: services to the decoders
3 *****************************************************************************
4 * Copyright (C) 1998, 1999, 2000 VideoLAN
5 * $Id: input_ext-dec.c,v 1.11 2001/03/21 13:42:34 sam Exp $
7 * Authors: Christophe Massiot <massiot@via.ecp.fr>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
36 #include "stream_control.h"
37 #include "input_ext-dec.h"
38 #include "input_ext-intf.h"
42 /*****************************************************************************
43 * InitBitstream: initialize a bit_stream_t structure
44 *****************************************************************************/
45 void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo )
47 p_bit_stream->p_decoder_fifo = p_fifo;
48 p_bit_stream->pf_next_data_packet = NextDataPacket;
49 p_bit_stream->pf_bitstream_callback = NULL;
50 p_bit_stream->p_callback_arg = NULL;
52 /* Get the first data packet. */
53 vlc_mutex_lock( &p_fifo->data_lock );
54 while ( DECODER_FIFO_ISEMPTY( *p_fifo ) )
58 vlc_mutex_unlock( &p_fifo->data_lock );
61 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
63 p_bit_stream->p_data = DECODER_FIFO_START( *p_fifo )->p_first;
64 p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
65 p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
66 p_bit_stream->fifo.buffer = 0;
67 p_bit_stream->fifo.i_available = 0;
68 vlc_mutex_unlock( &p_fifo->data_lock );
70 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
72 /* Get aligned on a word boundary.
73 * NB : we _will_ get aligned, because we have at most
74 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
75 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
76 AlignWord( p_bit_stream );
80 /*****************************************************************************
81 * NextDataPacket: go to the next data packet
82 *****************************************************************************/
83 void NextDataPacket( bit_stream_t * p_bit_stream )
85 decoder_fifo_t * p_fifo = p_bit_stream->p_decoder_fifo;
88 /* We are looking for the next data packet that contains real data,
89 * and not just a PES header */
92 /* We were reading the last data packet of this PES packet... It's
93 * time to jump to the next PES packet */
94 if( p_bit_stream->p_data->p_next == NULL )
96 /* We are going to read/write the start and end indexes of the
97 * decoder fifo and to use the fifo's conditional variable,
98 * that's why we need to take the lock before. */
99 vlc_mutex_lock( &p_fifo->data_lock );
101 /* Free the previous PES packet. */
102 p_fifo->pf_delete_pes( p_fifo->p_packets_mgt,
103 DECODER_FIFO_START( *p_fifo ) );
104 DECODER_FIFO_INCSTART( *p_fifo );
106 if( DECODER_FIFO_ISEMPTY( *p_fifo ) )
108 /* Wait for the input to tell us when we receive a packet. */
109 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
112 /* The next byte could be found in the next PES packet */
113 p_bit_stream->p_data = DECODER_FIFO_START( *p_fifo )->p_first;
115 vlc_mutex_unlock( &p_fifo->data_lock );
121 /* Perhaps the next data packet of the current PES packet contains
122 * real data (ie its payload's size is greater than 0). */
123 p_bit_stream->p_data = p_bit_stream->p_data->p_next;
127 } while ( p_bit_stream->p_data->p_payload_start
128 == p_bit_stream->p_data->p_payload_end );
130 /* We've found a data packet which contains interesting data... */
131 p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
132 p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
134 /* Call back the decoder. */
135 if( p_bit_stream->pf_bitstream_callback != NULL )
137 p_bit_stream->pf_bitstream_callback( p_bit_stream, b_new_pes );
141 /*****************************************************************************
142 * UnalignedShowBits : return i_bits bits from the bit stream, even when
143 * not aligned on a word boundary
144 *****************************************************************************/
145 u32 UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
147 /* We just fill in the bit buffer. */
148 while( p_bit_stream->fifo.i_available < i_bits )
150 if( p_bit_stream->p_byte < p_bit_stream->p_end )
152 p_bit_stream->fifo.buffer |= *(p_bit_stream->p_byte++)
153 << (8 * sizeof(WORD_TYPE) - 8
154 - p_bit_stream->fifo.i_available);
155 p_bit_stream->fifo.i_available += 8;
159 p_bit_stream->pf_next_data_packet( p_bit_stream );
161 if( (ptrdiff_t)p_bit_stream->p_byte & (sizeof(WORD_TYPE) - 1) )
163 /* We are not aligned anymore. */
164 if( ((ptrdiff_t)p_bit_stream->p_byte
165 & (sizeof(WORD_TYPE) - 1)) * 8
166 < p_bit_stream->fifo.i_available )
168 /* We are not aligned, and won't be. Copy the first word
169 * of the packet in a temporary buffer, and we'll see
172 p_bit_stream->i_showbits_buffer = 0;
174 for( i = 0; i < sizeof(WORD_TYPE) ; i++ )
176 if( p_bit_stream->p_byte >= p_bit_stream->p_end )
178 p_bit_stream->pf_next_data_packet( p_bit_stream );
180 ((byte_t *)&p_bit_stream->i_showbits_buffer)[i] =
181 * p_bit_stream->p_byte;
182 p_bit_stream->p_byte++;
185 /* This is kind of kludgy. */
186 p_bit_stream->p_data->p_payload_start += sizeof(WORD_TYPE);
187 p_bit_stream->p_byte =
188 (byte_t *)&p_bit_stream->i_showbits_buffer;
189 p_bit_stream->p_end =
190 (byte_t *)&p_bit_stream->i_showbits_buffer
192 p_bit_stream->showbits_data.p_next = p_bit_stream->p_data;
193 p_bit_stream->p_data = &p_bit_stream->showbits_data;
197 /* We are not aligned, but we can be. */
198 AlignWord( p_bit_stream );
202 return( ShowBits( p_bit_stream, i_bits ) );
205 return( p_bit_stream->fifo.buffer >> (8 * sizeof(WORD_TYPE) - i_bits) );
208 /*****************************************************************************
209 * UnalignedGetBits : returns i_bits bits from the bit stream and removes
210 * them from the buffer, even when the bit stream is not aligned on a word
212 *****************************************************************************/
213 u32 UnalignedGetBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
217 i_result = p_bit_stream->fifo.buffer
218 >> (8 * sizeof(WORD_TYPE) - i_bits);
219 i_bits = -p_bit_stream->fifo.i_available;
221 /* Gather missing bytes. */
224 if( p_bit_stream->p_byte < p_bit_stream->p_end )
226 i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
231 p_bit_stream->pf_next_data_packet( p_bit_stream );
232 i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
237 /* Gather missing bits. */
240 unsigned int i_tmp = 8 - i_bits;
242 if( p_bit_stream->p_byte < p_bit_stream->p_end )
244 i_result |= *p_bit_stream->p_byte >> i_tmp;
245 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
246 << ( sizeof(WORD_TYPE) * 8 - i_tmp );
247 p_bit_stream->fifo.i_available = i_tmp;
251 p_bit_stream->pf_next_data_packet( p_bit_stream );
252 i_result |= *p_bit_stream->p_byte >> i_tmp;
253 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
254 << ( sizeof(WORD_TYPE) * 8 - i_tmp );
255 p_bit_stream->fifo.i_available = i_tmp;
260 p_bit_stream->fifo.i_available = 0;
261 p_bit_stream->fifo.buffer = 0;
264 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
266 /* Get aligned on a word boundary. Otherwise it is safer
267 * to do it the next time.
268 * NB : we _will_ get aligned, because we have at most
269 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
270 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
271 AlignWord( p_bit_stream );
277 /*****************************************************************************
278 * UnalignedRemoveBits : removes i_bits (== -i_available) from the bit
279 * buffer, even when the bit stream is not aligned on a word boundary
280 *****************************************************************************/
281 void UnalignedRemoveBits( bit_stream_t * p_bit_stream )
283 /* First remove all unnecessary bytes. */
284 while( p_bit_stream->fifo.i_available <= -8 )
286 if( p_bit_stream->p_byte < p_bit_stream->p_end )
288 p_bit_stream->p_byte++;
289 p_bit_stream->fifo.i_available += 8;
293 p_bit_stream->pf_next_data_packet( p_bit_stream );
294 p_bit_stream->p_byte++;
295 p_bit_stream->fifo.i_available += 8;
299 /* Remove unnecessary bits. */
300 if( p_bit_stream->fifo.i_available < 0 )
302 if( p_bit_stream->p_byte < p_bit_stream->p_end )
304 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
305 << ( sizeof(WORD_TYPE) * 8 - 8
306 - p_bit_stream->fifo.i_available );
307 p_bit_stream->fifo.i_available += 8;
311 p_bit_stream->pf_next_data_packet( p_bit_stream );
312 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
313 << ( sizeof(WORD_TYPE) * 8 - 8
314 - p_bit_stream->fifo.i_available );
315 p_bit_stream->fifo.i_available += 8;
320 p_bit_stream->fifo.buffer = 0;
323 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
325 /* Get aligned on a word boundary. Otherwise it is safer
326 * to do it the next time.
327 * NB : we _will_ get aligned, because we have at most
328 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
329 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
330 AlignWord( p_bit_stream );