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.14 2001/04/28 03:36:25 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 *****************************************************************************/
29 #include <string.h> /* memcpy(), memset() */
30 #include <sys/types.h> /* off_t */
39 #include "stream_control.h"
40 #include "input_ext-dec.h"
41 #include "input_ext-intf.h"
45 /*****************************************************************************
46 * InitBitstream: initialize a bit_stream_t structure
47 *****************************************************************************/
48 void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo,
49 void (* pf_bitstream_callback)( struct bit_stream_s *,
51 void * p_callback_arg )
53 p_bit_stream->p_decoder_fifo = p_fifo;
54 p_bit_stream->pf_next_data_packet = NextDataPacket;
55 p_bit_stream->pf_bitstream_callback = pf_bitstream_callback;
56 p_bit_stream->p_callback_arg = p_callback_arg;
58 /* Get the first data packet. */
59 vlc_mutex_lock( &p_fifo->data_lock );
60 while ( DECODER_FIFO_ISEMPTY( *p_fifo ) )
64 vlc_mutex_unlock( &p_fifo->data_lock );
67 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
69 p_bit_stream->p_data = DECODER_FIFO_START( *p_fifo )->p_first;
70 p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
71 p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
72 p_bit_stream->fifo.buffer = 0;
73 p_bit_stream->fifo.i_available = 0;
74 vlc_mutex_unlock( &p_fifo->data_lock );
76 /* Call back the decoder. */
77 if( p_bit_stream->pf_bitstream_callback != NULL )
79 p_bit_stream->pf_bitstream_callback( p_bit_stream, 1 );
82 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
84 /* Get aligned on a word boundary.
85 * NB : we _will_ get aligned, because we have at most
86 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
87 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
88 AlignWord( p_bit_stream );
92 /*****************************************************************************
93 * NextDataPacket: go to the next data packet
94 *****************************************************************************/
95 void NextDataPacket( bit_stream_t * p_bit_stream )
97 decoder_fifo_t * p_fifo = p_bit_stream->p_decoder_fifo;
100 /* We are looking for the next data packet that contains real data,
101 * and not just a PES header */
104 /* We were reading the last data packet of this PES packet... It's
105 * time to jump to the next PES packet */
106 if( p_bit_stream->p_data->p_next == NULL )
108 /* We are going to read/write the start and end indexes of the
109 * decoder fifo and to use the fifo's conditional variable,
110 * that's why we need to take the lock before. */
111 vlc_mutex_lock( &p_fifo->data_lock );
113 /* Free the previous PES packet. */
114 p_fifo->pf_delete_pes( p_fifo->p_packets_mgt,
115 DECODER_FIFO_START( *p_fifo ) );
116 DECODER_FIFO_INCSTART( *p_fifo );
118 if( DECODER_FIFO_ISEMPTY( *p_fifo ) )
120 /* Wait for the input to tell us when we receive a packet. */
121 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
124 /* The next byte could be found in the next PES packet */
125 p_bit_stream->p_data = DECODER_FIFO_START( *p_fifo )->p_first;
127 vlc_mutex_unlock( &p_fifo->data_lock );
133 /* Perhaps the next data packet of the current PES packet contains
134 * real data (ie its payload's size is greater than 0). */
135 p_bit_stream->p_data = p_bit_stream->p_data->p_next;
139 } while ( p_bit_stream->p_data->p_payload_start
140 == p_bit_stream->p_data->p_payload_end );
142 /* We've found a data packet which contains interesting data... */
143 p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
144 p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
146 /* Call back the decoder. */
147 if( p_bit_stream->pf_bitstream_callback != NULL )
149 p_bit_stream->pf_bitstream_callback( p_bit_stream, b_new_pes );
153 /*****************************************************************************
154 * UnalignedShowBits : return i_bits bits from the bit stream, even when
155 * not aligned on a word boundary
156 *****************************************************************************/
157 u32 UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
159 /* We just fill in the bit buffer. */
160 while( p_bit_stream->fifo.i_available < i_bits )
162 if( p_bit_stream->p_byte < p_bit_stream->p_end )
164 p_bit_stream->fifo.buffer |= *(p_bit_stream->p_byte++)
165 << (8 * sizeof(WORD_TYPE) - 8
166 - p_bit_stream->fifo.i_available);
167 p_bit_stream->fifo.i_available += 8;
171 p_bit_stream->pf_next_data_packet( p_bit_stream );
173 if( (ptrdiff_t)p_bit_stream->p_byte & (sizeof(WORD_TYPE) - 1) )
175 /* We are not aligned anymore. */
176 if( ((ptrdiff_t)p_bit_stream->p_byte
177 & (sizeof(WORD_TYPE) - 1)) * 8
178 < p_bit_stream->fifo.i_available )
180 /* We are not aligned, and won't be. Copy the first word
181 * of the packet in a temporary buffer, and we'll see
184 p_bit_stream->i_showbits_buffer = 0;
186 for( i = 0; i < sizeof(WORD_TYPE) ; i++ )
188 if( p_bit_stream->p_byte >= p_bit_stream->p_end )
190 p_bit_stream->pf_next_data_packet( p_bit_stream );
192 ((byte_t *)&p_bit_stream->i_showbits_buffer)[i] =
193 * p_bit_stream->p_byte;
194 p_bit_stream->p_byte++;
197 /* This is kind of kludgy. */
198 p_bit_stream->p_data->p_payload_start += sizeof(WORD_TYPE);
199 p_bit_stream->p_byte =
200 (byte_t *)&p_bit_stream->i_showbits_buffer;
201 p_bit_stream->p_end =
202 (byte_t *)&p_bit_stream->i_showbits_buffer
204 p_bit_stream->showbits_data.p_next = p_bit_stream->p_data;
205 p_bit_stream->p_data = &p_bit_stream->showbits_data;
209 /* We are not aligned, but we can be. */
210 AlignWord( p_bit_stream );
214 return( ShowBits( p_bit_stream, i_bits ) );
217 return( p_bit_stream->fifo.buffer >> (8 * sizeof(WORD_TYPE) - i_bits) );
220 /*****************************************************************************
221 * UnalignedGetBits : returns i_bits bits from the bit stream and removes
222 * them from the buffer, even when the bit stream is not aligned on a word
224 *****************************************************************************/
225 u32 UnalignedGetBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
229 i_result = p_bit_stream->fifo.buffer
230 >> (8 * sizeof(WORD_TYPE) - i_bits);
231 i_bits = -p_bit_stream->fifo.i_available;
233 /* Gather missing bytes. */
236 if( p_bit_stream->p_byte < p_bit_stream->p_end )
238 i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
243 p_bit_stream->pf_next_data_packet( p_bit_stream );
244 i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
249 /* Gather missing bits. */
252 unsigned int i_tmp = 8 - i_bits;
254 if( p_bit_stream->p_byte < p_bit_stream->p_end )
256 i_result |= *p_bit_stream->p_byte >> i_tmp;
257 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
258 << ( sizeof(WORD_TYPE) * 8 - i_tmp );
259 p_bit_stream->fifo.i_available = i_tmp;
263 p_bit_stream->pf_next_data_packet( p_bit_stream );
264 i_result |= *p_bit_stream->p_byte >> i_tmp;
265 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
266 << ( sizeof(WORD_TYPE) * 8 - i_tmp );
267 p_bit_stream->fifo.i_available = i_tmp;
272 p_bit_stream->fifo.i_available = 0;
273 p_bit_stream->fifo.buffer = 0;
276 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
278 /* Get aligned on a word boundary. Otherwise it is safer
279 * to do it the next time.
280 * NB : we _will_ get aligned, because we have at most
281 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
282 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
283 AlignWord( p_bit_stream );
289 /*****************************************************************************
290 * UnalignedRemoveBits : removes i_bits (== -i_available) from the bit
291 * buffer, even when the bit stream is not aligned on a word boundary
292 *****************************************************************************/
293 void UnalignedRemoveBits( bit_stream_t * p_bit_stream )
295 /* First remove all unnecessary bytes. */
296 while( p_bit_stream->fifo.i_available <= -8 )
298 if( p_bit_stream->p_byte < p_bit_stream->p_end )
300 p_bit_stream->p_byte++;
301 p_bit_stream->fifo.i_available += 8;
305 p_bit_stream->pf_next_data_packet( p_bit_stream );
306 p_bit_stream->p_byte++;
307 p_bit_stream->fifo.i_available += 8;
311 /* Remove unnecessary bits. */
312 if( p_bit_stream->fifo.i_available < 0 )
314 if( p_bit_stream->p_byte < p_bit_stream->p_end )
316 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
317 << ( sizeof(WORD_TYPE) * 8 - 8
318 - p_bit_stream->fifo.i_available );
319 p_bit_stream->fifo.i_available += 8;
323 p_bit_stream->pf_next_data_packet( p_bit_stream );
324 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
325 << ( sizeof(WORD_TYPE) * 8 - 8
326 - p_bit_stream->fifo.i_available );
327 p_bit_stream->fifo.i_available += 8;
332 p_bit_stream->fifo.buffer = 0;
335 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
337 /* Get aligned on a word boundary. Otherwise it is safer
338 * to do it the next time.
339 * NB : we _will_ get aligned, because we have at most
340 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
341 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
342 AlignWord( p_bit_stream );