1 /*****************************************************************************
2 * input_ext-dec.c: services to the decoders
3 *****************************************************************************
4 * Copyright (C) 1998, 1999, 2000 VideoLAN
6 * Authors: Christophe Massiot <massiot@via.ecp.fr>
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"
37 #include "input_ext-intf.h"
41 /*****************************************************************************
42 * InitBitstream: initialize a bit_stream_t structure
43 *****************************************************************************/
44 void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo )
46 p_bit_stream->p_decoder_fifo = p_fifo;
47 p_bit_stream->pf_next_data_packet = NextDataPacket;
48 p_bit_stream->pf_bitstream_callback = NULL;
49 p_bit_stream->p_callback_arg = NULL;
51 /* Get the first data packet. */
52 vlc_mutex_lock( &p_fifo->data_lock );
53 while ( DECODER_FIFO_ISEMPTY( *p_fifo ) )
57 vlc_mutex_unlock( &p_fifo->data_lock );
60 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
62 p_bit_stream->p_data = DECODER_FIFO_START( *p_fifo )->p_first;
63 p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
64 p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
65 p_bit_stream->fifo.buffer = 0;
66 p_bit_stream->fifo.i_available = 0;
67 vlc_mutex_unlock( &p_fifo->data_lock );
69 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
71 /* Get aligned on a word boundary.
72 * NB : we _will_ get aligned, because we have at most
73 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
74 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
75 AlignWord( p_bit_stream );
79 /*****************************************************************************
80 * NextDataPacket: go to the next data packet
81 *****************************************************************************/
82 void NextDataPacket( bit_stream_t * p_bit_stream )
84 decoder_fifo_t * p_fifo = p_bit_stream->p_decoder_fifo;
87 /* We are looking for the next data packet that contains real data,
88 * and not just a PES header */
91 /* We were reading the last data packet of this PES packet... It's
92 * time to jump to the next PES packet */
93 if( p_bit_stream->p_data->p_next == NULL )
95 /* We are going to read/write the start and end indexes of the
96 * decoder fifo and to use the fifo's conditional variable,
97 * that's why we need to take the lock before. */
98 vlc_mutex_lock( &p_fifo->data_lock );
100 /* Free the previous PES packet. */
101 p_fifo->pf_delete_pes( p_fifo->p_packets_mgt,
102 DECODER_FIFO_START( *p_fifo ) );
103 DECODER_FIFO_INCSTART( *p_fifo );
105 if( DECODER_FIFO_ISEMPTY( *p_fifo ) )
107 /* Wait for the input to tell us when we receive a packet. */
108 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
111 /* The next byte could be found in the next PES packet */
112 p_bit_stream->p_data = DECODER_FIFO_START( *p_fifo )->p_first;
114 vlc_mutex_unlock( &p_fifo->data_lock );
120 /* Perhaps the next data packet of the current PES packet contains
121 * real data (ie its payload's size is greater than 0). */
122 p_bit_stream->p_data = p_bit_stream->p_data->p_next;
126 } while ( p_bit_stream->p_data->p_payload_start
127 == p_bit_stream->p_data->p_payload_end );
129 /* We've found a data packet which contains interesting data... */
130 p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
131 p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
133 /* Call back the decoder. */
134 if( p_bit_stream->pf_bitstream_callback != NULL )
136 p_bit_stream->pf_bitstream_callback( p_bit_stream, b_new_pes );
140 /*****************************************************************************
141 * UnalignedShowBits : return i_bits bits from the bit stream, even when
142 * not aligned on a word boundary
143 *****************************************************************************/
144 u32 UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
146 /* We just fill in the bit buffer. */
147 while( p_bit_stream->fifo.i_available < i_bits )
149 if( p_bit_stream->p_byte < p_bit_stream->p_end )
151 p_bit_stream->fifo.buffer |= *(p_bit_stream->p_byte++)
152 << (8 * sizeof(WORD_TYPE) - 8
153 - p_bit_stream->fifo.i_available);
154 p_bit_stream->fifo.i_available += 8;
158 p_bit_stream->pf_next_data_packet( p_bit_stream );
160 if( (ptrdiff_t)p_bit_stream->p_byte & (sizeof(WORD_TYPE) - 1) )
162 /* We are not aligned anymore. */
163 if( ((ptrdiff_t)p_bit_stream->p_byte
164 & (sizeof(WORD_TYPE) - 1)) * 8
165 < p_bit_stream->fifo.i_available )
167 /* We are not aligned, and won't be. Copy the first word
168 * of the packet in a temporary buffer, and we'll see
171 p_bit_stream->i_showbits_buffer = 0;
173 for( i = 0; i < sizeof(WORD_TYPE) ; i++ )
175 if( p_bit_stream->p_byte >= p_bit_stream->p_end )
177 p_bit_stream->pf_next_data_packet( p_bit_stream );
179 ((byte_t *)&p_bit_stream->i_showbits_buffer)[i] =
180 * p_bit_stream->p_byte;
181 p_bit_stream->p_byte++;
184 /* This is kind of kludgy. */
185 p_bit_stream->p_data->p_payload_start += sizeof(WORD_TYPE);
186 p_bit_stream->p_byte =
187 (byte_t *)&p_bit_stream->i_showbits_buffer;
188 p_bit_stream->p_end =
189 (byte_t *)&p_bit_stream->i_showbits_buffer
191 p_bit_stream->showbits_data.p_next = p_bit_stream->p_data;
192 p_bit_stream->p_data = &p_bit_stream->showbits_data;
196 /* We are not aligned, but we can be. */
197 AlignWord( p_bit_stream );
201 return( ShowBits( p_bit_stream, i_bits ) );
204 return( p_bit_stream->fifo.buffer >> (8 * sizeof(WORD_TYPE) - i_bits) );
207 /*****************************************************************************
208 * UnalignedGetBits : returns i_bits bits from the bit stream and removes
209 * them from the buffer, even when the bit stream is not aligned on a word
211 *****************************************************************************/
212 u32 UnalignedGetBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
216 i_result = p_bit_stream->fifo.buffer
217 >> (8 * sizeof(WORD_TYPE) - i_bits);
218 i_bits = -p_bit_stream->fifo.i_available;
220 /* Gather missing bytes. */
223 if( p_bit_stream->p_byte < p_bit_stream->p_end )
225 i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
230 p_bit_stream->pf_next_data_packet( p_bit_stream );
231 i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
236 /* Gather missing bits. */
239 unsigned int i_tmp = 8 - i_bits;
241 if( p_bit_stream->p_byte < p_bit_stream->p_end )
243 i_result |= *p_bit_stream->p_byte >> i_tmp;
244 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
245 << ( sizeof(WORD_TYPE) * 8 - i_tmp );
246 p_bit_stream->fifo.i_available = i_tmp;
250 p_bit_stream->pf_next_data_packet( p_bit_stream );
251 i_result |= *p_bit_stream->p_byte >> i_tmp;
252 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
253 << ( sizeof(WORD_TYPE) * 8 - i_tmp );
254 p_bit_stream->fifo.i_available = i_tmp;
259 p_bit_stream->fifo.i_available = 0;
260 p_bit_stream->fifo.buffer = 0;
263 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
265 /* Get aligned on a word boundary. Otherwise it is safer
266 * to do it the next time.
267 * NB : we _will_ get aligned, because we have at most
268 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
269 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
270 AlignWord( p_bit_stream );
276 /*****************************************************************************
277 * UnalignedRemoveBits : removes i_bits (== -i_available) from the bit
278 * buffer, even when the bit stream is not aligned on a word boundary
279 *****************************************************************************/
280 void UnalignedRemoveBits( bit_stream_t * p_bit_stream )
282 /* First remove all unnecessary bytes. */
283 while( p_bit_stream->fifo.i_available <= -8 )
285 if( p_bit_stream->p_byte < p_bit_stream->p_end )
287 p_bit_stream->p_byte++;
288 p_bit_stream->fifo.i_available += 8;
292 p_bit_stream->pf_next_data_packet( p_bit_stream );
293 p_bit_stream->p_byte++;
294 p_bit_stream->fifo.i_available += 8;
298 /* Remove unnecessary bits. */
299 if( p_bit_stream->fifo.i_available < 0 )
301 if( p_bit_stream->p_byte < p_bit_stream->p_end )
303 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
304 << ( sizeof(WORD_TYPE) * 8 - 8
305 - p_bit_stream->fifo.i_available );
306 p_bit_stream->fifo.i_available += 8;
310 p_bit_stream->pf_next_data_packet( p_bit_stream );
311 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
312 << ( sizeof(WORD_TYPE) * 8 - 8
313 - p_bit_stream->fifo.i_available );
314 p_bit_stream->fifo.i_available += 8;
319 p_bit_stream->fifo.buffer = 0;
322 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
324 /* Get aligned on a word boundary. Otherwise it is safer
325 * to do it the next time.
326 * NB : we _will_ get aligned, because we have at most
327 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
328 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
329 AlignWord( p_bit_stream );