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.27 2001/12/31 03:26:27 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 *****************************************************************************/
27 #include <string.h> /* memcpy(), memset() */
28 #include <sys/types.h> /* off_t */
30 #include <videolan/vlc.h>
32 #include "stream_control.h"
33 #include "input_ext-dec.h"
34 #include "input_ext-intf.h"
35 #include "input_ext-plugins.h"
37 /*****************************************************************************
38 * InitBitstream: initialize a bit_stream_t structure
39 *****************************************************************************/
40 void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo,
41 void (* pf_bitstream_callback)( struct bit_stream_s *,
43 void * p_callback_arg )
45 p_bit_stream->p_decoder_fifo = p_fifo;
46 p_bit_stream->pf_next_data_packet = NextDataPacket;
47 p_bit_stream->pf_bitstream_callback = pf_bitstream_callback;
48 p_bit_stream->p_callback_arg = p_callback_arg;
50 /* Get the first data packet. */
51 vlc_mutex_lock( &p_fifo->data_lock );
52 while ( p_fifo->p_first == NULL )
56 vlc_mutex_unlock( &p_fifo->data_lock );
59 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
61 p_bit_stream->p_data = p_fifo->p_first->p_first;
62 p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
63 p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
64 p_bit_stream->fifo.buffer = 0;
65 p_bit_stream->fifo.i_available = 0;
66 vlc_mutex_unlock( &p_fifo->data_lock );
68 /* Call back the decoder. */
69 if( p_bit_stream->pf_bitstream_callback != NULL )
71 p_bit_stream->pf_bitstream_callback( p_bit_stream, 1 );
74 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
76 /* Get aligned on a word boundary.
77 * NB : we _will_ get aligned, because we have at most
78 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
79 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
80 AlignWord( p_bit_stream );
84 /*****************************************************************************
85 * DecoderError : an error occured, use this function to empty the fifo
86 *****************************************************************************/
87 void DecoderError( decoder_fifo_t * p_fifo )
89 /* We take the lock, because we are going to read/write the start/end
90 * indexes of the decoder fifo */
91 vlc_mutex_lock (&p_fifo->data_lock);
93 /* Wait until a `die' order is sent */
94 while (!p_fifo->b_die)
96 /* Trash all received PES packets */
97 p_fifo->pf_delete_pes( p_fifo->p_packets_mgt, p_fifo->p_first );
98 p_fifo->p_first = NULL;
99 p_fifo->pp_last = &p_fifo->p_first;
101 /* Waiting for the input thread to put new PES packets in the fifo */
102 vlc_cond_wait (&p_fifo->data_wait, &p_fifo->data_lock);
105 /* We can release the lock before leaving */
106 vlc_mutex_unlock (&p_fifo->data_lock);
109 /*****************************************************************************
110 * NextDataPacket: go to the next data packet
111 *****************************************************************************/
112 void NextDataPacket( bit_stream_t * p_bit_stream )
114 decoder_fifo_t * p_fifo = p_bit_stream->p_decoder_fifo;
117 /* We are looking for the next data packet that contains real data,
118 * and not just a PES header */
121 /* We were reading the last data packet of this PES packet... It's
122 * time to jump to the next PES packet */
123 if( p_bit_stream->p_data->p_next == NULL )
125 pes_packet_t * p_next;
127 vlc_mutex_lock( &p_fifo->data_lock );
129 /* Free the previous PES packet. */
130 p_next = p_fifo->p_first->p_next;
131 p_fifo->p_first->p_next = NULL;
132 p_fifo->pf_delete_pes( p_fifo->p_packets_mgt,
134 p_fifo->p_first = p_next;
137 if( p_fifo->p_first == NULL )
139 /* No PES in the FIFO. p_last is no longer valid. */
140 p_fifo->pp_last = &p_fifo->p_first;
142 /* Wait for the input to tell us when we receive a packet. */
143 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
146 /* The next byte could be found in the next PES packet */
147 p_bit_stream->p_data = p_fifo->p_first->p_first;
149 vlc_mutex_unlock( &p_fifo->data_lock );
155 /* Perhaps the next data packet of the current PES packet contains
156 * real data (ie its payload's size is greater than 0). */
157 p_bit_stream->p_data = p_bit_stream->p_data->p_next;
161 } while ( p_bit_stream->p_data->p_payload_start
162 == p_bit_stream->p_data->p_payload_end );
164 /* We've found a data packet which contains interesting data... */
165 p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
166 p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
168 /* Call back the decoder. */
169 if( p_bit_stream->pf_bitstream_callback != NULL )
171 p_bit_stream->pf_bitstream_callback( p_bit_stream, b_new_pes );
175 /*****************************************************************************
176 * UnalignedShowBits : places i_bits bits into the bit buffer, even when
177 * not aligned on a word boundary
178 *****************************************************************************/
179 u32 UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
181 /* We just fill in the bit buffer. */
182 while( p_bit_stream->fifo.i_available < i_bits )
184 if( p_bit_stream->p_byte < p_bit_stream->p_end )
186 p_bit_stream->fifo.buffer |= *(p_bit_stream->p_byte++)
187 << (8 * sizeof(WORD_TYPE) - 8
188 - p_bit_stream->fifo.i_available);
189 p_bit_stream->fifo.i_available += 8;
193 p_bit_stream->pf_next_data_packet( p_bit_stream );
195 if( (ptrdiff_t)p_bit_stream->p_byte & (sizeof(WORD_TYPE) - 1) )
197 /* We are not aligned anymore. */
198 if( ((ptrdiff_t)p_bit_stream->p_byte
199 & (sizeof(WORD_TYPE) - 1)) * 8
200 < p_bit_stream->fifo.i_available )
202 /* We are not aligned, and won't be. Copy the first word
203 * of the packet in a temporary buffer, and we'll see
207 /* sizeof(WORD_TYPE) - number of bytes to trash
208 * from the last payload */
211 p_bit_stream->i_showbits_buffer = 0;
213 for( j = i = 0 ; i < sizeof(WORD_TYPE) ; i++ )
215 if( p_bit_stream->p_byte >= p_bit_stream->p_end )
218 p_bit_stream->pf_next_data_packet( p_bit_stream );
220 ((byte_t *)&p_bit_stream->i_showbits_buffer)[i] =
221 * p_bit_stream->p_byte;
222 p_bit_stream->p_byte++;
225 /* This is kind of kludgy. */
226 p_bit_stream->p_data->p_payload_start +=
227 sizeof(WORD_TYPE) - j;
228 p_bit_stream->p_byte =
229 (byte_t *)&p_bit_stream->i_showbits_buffer;
230 p_bit_stream->p_end =
231 (byte_t *)&p_bit_stream->i_showbits_buffer
233 p_bit_stream->showbits_data.p_next = p_bit_stream->p_data;
234 p_bit_stream->p_data = &p_bit_stream->showbits_data;
238 /* We are not aligned, but we can be. */
239 AlignWord( p_bit_stream );
243 /* We have 32 bits ready for reading, it will be enough. */
248 /* It shouldn't loop :-)) */
249 return( ShowBits( p_bit_stream, i_bits ) );
252 /*****************************************************************************
253 * UnalignedGetBits : returns i_bits bits from the bit stream and removes
254 * them from the buffer, even when the bit stream is not aligned on a word
256 *****************************************************************************/
257 u32 UnalignedGetBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
261 i_result = p_bit_stream->fifo.buffer
262 >> (8 * sizeof(WORD_TYPE) - i_bits);
263 i_bits = -p_bit_stream->fifo.i_available;
265 /* Gather missing bytes. */
268 if( p_bit_stream->p_byte < p_bit_stream->p_end )
270 i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
275 p_bit_stream->pf_next_data_packet( p_bit_stream );
276 i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
281 /* Gather missing bits. */
284 unsigned int i_tmp = 8 - i_bits;
286 if( p_bit_stream->p_byte < p_bit_stream->p_end )
288 i_result |= *p_bit_stream->p_byte >> i_tmp;
289 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
290 << ( sizeof(WORD_TYPE) * 8 - i_tmp );
291 p_bit_stream->fifo.i_available = i_tmp;
295 p_bit_stream->pf_next_data_packet( p_bit_stream );
296 i_result |= *p_bit_stream->p_byte >> i_tmp;
297 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
298 << ( sizeof(WORD_TYPE) * 8 - i_tmp );
299 p_bit_stream->fifo.i_available = i_tmp;
304 p_bit_stream->fifo.i_available = 0;
305 p_bit_stream->fifo.buffer = 0;
308 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
310 /* Get aligned on a word boundary. Otherwise it is safer
311 * to do it the next time.
312 * NB : we _will_ get aligned, because we have at most
313 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
314 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
315 AlignWord( p_bit_stream );
321 /*****************************************************************************
322 * UnalignedRemoveBits : removes i_bits (== -i_available) from the bit
323 * buffer, even when the bit stream is not aligned on a word boundary
324 *****************************************************************************/
325 void UnalignedRemoveBits( bit_stream_t * p_bit_stream )
327 /* First remove all unnecessary bytes. */
328 while( p_bit_stream->fifo.i_available <= -8 )
330 if( p_bit_stream->p_byte < p_bit_stream->p_end )
332 p_bit_stream->p_byte++;
333 p_bit_stream->fifo.i_available += 8;
337 p_bit_stream->pf_next_data_packet( p_bit_stream );
338 p_bit_stream->p_byte++;
339 p_bit_stream->fifo.i_available += 8;
343 /* Remove unnecessary bits. */
344 if( p_bit_stream->fifo.i_available < 0 )
346 if( p_bit_stream->p_byte < p_bit_stream->p_end )
348 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
349 << ( sizeof(WORD_TYPE) * 8 - 8
350 - p_bit_stream->fifo.i_available );
351 p_bit_stream->fifo.i_available += 8;
355 p_bit_stream->pf_next_data_packet( p_bit_stream );
356 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
357 << ( sizeof(WORD_TYPE) * 8 - 8
358 - p_bit_stream->fifo.i_available );
359 p_bit_stream->fifo.i_available += 8;
364 p_bit_stream->fifo.buffer = 0;
367 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
369 /* Get aligned on a word boundary. Otherwise it is safer
370 * to do it the next time.
371 * NB : we _will_ get aligned, because we have at most
372 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
373 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
374 AlignWord( p_bit_stream );