1 /*****************************************************************************
2 * input_ext-dec.c: services to the decoders
3 *****************************************************************************
4 * Copyright (C) 1998-2001 VideoLAN
5 * $Id: input_ext-dec.c,v 1.23 2001/12/27 01:49:34 massiot 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 */
37 #include "stream_control.h"
38 #include "input_ext-dec.h"
39 #include "input_ext-intf.h"
40 #include "input_ext-plugins.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,
46 void (* pf_bitstream_callback)( struct bit_stream_s *,
48 void * p_callback_arg )
50 p_bit_stream->p_decoder_fifo = p_fifo;
51 p_bit_stream->pf_next_data_packet = NextDataPacket;
52 p_bit_stream->pf_bitstream_callback = pf_bitstream_callback;
53 p_bit_stream->p_callback_arg = p_callback_arg;
55 /* Get the first data packet. */
56 vlc_mutex_lock( &p_fifo->data_lock );
57 while ( p_fifo->p_first == NULL )
61 vlc_mutex_unlock( &p_fifo->data_lock );
64 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
66 p_bit_stream->p_data = p_fifo->p_first->p_first;
67 p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
68 p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
69 p_bit_stream->fifo.buffer = 0;
70 p_bit_stream->fifo.i_available = 0;
71 vlc_mutex_unlock( &p_fifo->data_lock );
73 /* Call back the decoder. */
74 if( p_bit_stream->pf_bitstream_callback != NULL )
76 p_bit_stream->pf_bitstream_callback( p_bit_stream, 1 );
79 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
81 /* Get aligned on a word boundary.
82 * NB : we _will_ get aligned, because we have at most
83 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
84 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
85 AlignWord( p_bit_stream );
89 /*****************************************************************************
90 * NextDataPacket: go to the next data packet
91 *****************************************************************************/
92 void NextDataPacket( bit_stream_t * p_bit_stream )
94 decoder_fifo_t * p_fifo = p_bit_stream->p_decoder_fifo;
97 /* We are looking for the next data packet that contains real data,
98 * and not just a PES header */
101 /* We were reading the last data packet of this PES packet... It's
102 * time to jump to the next PES packet */
103 if( p_bit_stream->p_data->p_next == NULL )
105 pes_packet_t * p_next;
107 vlc_mutex_lock( &p_fifo->data_lock );
109 /* Free the previous PES packet. */
110 p_next = p_fifo->p_first->p_next;
111 p_fifo->p_first->p_next = NULL;
112 p_fifo->pf_delete_pes( p_fifo->p_packets_mgt,
114 p_fifo->p_first = p_next;
117 if( p_fifo->p_first == NULL )
119 /* No PES in the FIFO. p_last is no longer valid. */
120 p_fifo->pp_last = &p_fifo->p_first;
122 /* Wait for the input to tell us when we receive a packet. */
123 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
126 /* The next byte could be found in the next PES packet */
127 p_bit_stream->p_data = p_fifo->p_first->p_first;
129 vlc_mutex_unlock( &p_fifo->data_lock );
135 /* Perhaps the next data packet of the current PES packet contains
136 * real data (ie its payload's size is greater than 0). */
137 p_bit_stream->p_data = p_bit_stream->p_data->p_next;
141 } while ( p_bit_stream->p_data->p_payload_start
142 == p_bit_stream->p_data->p_payload_end );
144 /* We've found a data packet which contains interesting data... */
145 p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
146 p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
148 /* Call back the decoder. */
149 if( p_bit_stream->pf_bitstream_callback != NULL )
151 p_bit_stream->pf_bitstream_callback( p_bit_stream, b_new_pes );
155 /*****************************************************************************
156 * UnalignedShowBits : places i_bits bits into the bit buffer, even when
157 * not aligned on a word boundary
158 *****************************************************************************/
159 u32 UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
161 /* We just fill in the bit buffer. */
162 while( p_bit_stream->fifo.i_available < i_bits )
164 if( p_bit_stream->p_byte < p_bit_stream->p_end )
166 p_bit_stream->fifo.buffer |= *(p_bit_stream->p_byte++)
167 << (8 * sizeof(WORD_TYPE) - 8
168 - p_bit_stream->fifo.i_available);
169 p_bit_stream->fifo.i_available += 8;
173 p_bit_stream->pf_next_data_packet( p_bit_stream );
175 if( (ptrdiff_t)p_bit_stream->p_byte & (sizeof(WORD_TYPE) - 1) )
177 /* We are not aligned anymore. */
178 if( ((ptrdiff_t)p_bit_stream->p_byte
179 & (sizeof(WORD_TYPE) - 1)) * 8
180 < p_bit_stream->fifo.i_available )
182 /* We are not aligned, and won't be. Copy the first word
183 * of the packet in a temporary buffer, and we'll see
187 /* sizeof(WORD_TYPE) - number of bytes to trash
188 * from the last payload */
191 p_bit_stream->i_showbits_buffer = 0;
193 for( j = i = 0 ; i < sizeof(WORD_TYPE) ; i++ )
195 if( p_bit_stream->p_byte >= p_bit_stream->p_end )
198 p_bit_stream->pf_next_data_packet( p_bit_stream );
200 ((byte_t *)&p_bit_stream->i_showbits_buffer)[i] =
201 * p_bit_stream->p_byte;
202 p_bit_stream->p_byte++;
205 /* This is kind of kludgy. */
206 p_bit_stream->p_data->p_payload_start +=
207 sizeof(WORD_TYPE) - j;
208 p_bit_stream->p_byte =
209 (byte_t *)&p_bit_stream->i_showbits_buffer;
210 p_bit_stream->p_end =
211 (byte_t *)&p_bit_stream->i_showbits_buffer
213 p_bit_stream->showbits_data.p_next = p_bit_stream->p_data;
214 p_bit_stream->p_data = &p_bit_stream->showbits_data;
218 /* We are not aligned, but we can be. */
219 AlignWord( p_bit_stream );
223 /* We have 32 bits ready for reading, it will be enough. */
228 /* It shouldn't loop :-)) */
229 return( ShowBits( p_bit_stream, i_bits ) );
232 /*****************************************************************************
233 * UnalignedGetBits : returns i_bits bits from the bit stream and removes
234 * them from the buffer, even when the bit stream is not aligned on a word
236 *****************************************************************************/
237 u32 UnalignedGetBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
241 i_result = p_bit_stream->fifo.buffer
242 >> (8 * sizeof(WORD_TYPE) - i_bits);
243 i_bits = -p_bit_stream->fifo.i_available;
245 /* Gather missing bytes. */
248 if( p_bit_stream->p_byte < p_bit_stream->p_end )
250 i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
255 p_bit_stream->pf_next_data_packet( p_bit_stream );
256 i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
261 /* Gather missing bits. */
264 unsigned int i_tmp = 8 - i_bits;
266 if( p_bit_stream->p_byte < p_bit_stream->p_end )
268 i_result |= *p_bit_stream->p_byte >> i_tmp;
269 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
270 << ( sizeof(WORD_TYPE) * 8 - i_tmp );
271 p_bit_stream->fifo.i_available = i_tmp;
275 p_bit_stream->pf_next_data_packet( p_bit_stream );
276 i_result |= *p_bit_stream->p_byte >> i_tmp;
277 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
278 << ( sizeof(WORD_TYPE) * 8 - i_tmp );
279 p_bit_stream->fifo.i_available = i_tmp;
284 p_bit_stream->fifo.i_available = 0;
285 p_bit_stream->fifo.buffer = 0;
288 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
290 /* Get aligned on a word boundary. Otherwise it is safer
291 * to do it the next time.
292 * NB : we _will_ get aligned, because we have at most
293 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
294 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
295 AlignWord( p_bit_stream );
301 /*****************************************************************************
302 * UnalignedRemoveBits : removes i_bits (== -i_available) from the bit
303 * buffer, even when the bit stream is not aligned on a word boundary
304 *****************************************************************************/
305 void UnalignedRemoveBits( bit_stream_t * p_bit_stream )
307 /* First remove all unnecessary bytes. */
308 while( p_bit_stream->fifo.i_available <= -8 )
310 if( p_bit_stream->p_byte < p_bit_stream->p_end )
312 p_bit_stream->p_byte++;
313 p_bit_stream->fifo.i_available += 8;
317 p_bit_stream->pf_next_data_packet( p_bit_stream );
318 p_bit_stream->p_byte++;
319 p_bit_stream->fifo.i_available += 8;
323 /* Remove unnecessary bits. */
324 if( p_bit_stream->fifo.i_available < 0 )
326 if( p_bit_stream->p_byte < p_bit_stream->p_end )
328 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
329 << ( sizeof(WORD_TYPE) * 8 - 8
330 - p_bit_stream->fifo.i_available );
331 p_bit_stream->fifo.i_available += 8;
335 p_bit_stream->pf_next_data_packet( p_bit_stream );
336 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
337 << ( sizeof(WORD_TYPE) * 8 - 8
338 - p_bit_stream->fifo.i_available );
339 p_bit_stream->fifo.i_available += 8;
344 p_bit_stream->fifo.buffer = 0;
347 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
349 /* Get aligned on a word boundary. Otherwise it is safer
350 * to do it the next time.
351 * NB : we _will_ get aligned, because we have at most
352 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
353 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
354 AlignWord( p_bit_stream );