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.34 2002/08/26 23:00:23 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 */
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)( bit_stream_t *, vlc_bool_t ),
42 void * p_callback_arg )
44 p_bit_stream->p_decoder_fifo = p_fifo;
45 p_bit_stream->pf_bitstream_callback = pf_bitstream_callback;
46 p_bit_stream->p_callback_arg = p_callback_arg;
48 /* Get the first data packet. */
49 vlc_mutex_lock( &p_fifo->data_lock );
50 while ( p_fifo->p_first == NULL )
54 vlc_mutex_unlock( &p_fifo->data_lock );
57 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
59 p_bit_stream->p_data = p_fifo->p_first->p_first;
60 p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
61 p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
62 p_bit_stream->fifo.buffer = 0;
63 p_bit_stream->fifo.i_available = 0;
64 p_bit_stream->i_pts = p_fifo->p_first->i_pts;
65 p_bit_stream->i_dts = p_fifo->p_first->i_dts;
66 p_bit_stream->p_pts_validity = p_bit_stream->p_byte;
67 vlc_mutex_unlock( &p_fifo->data_lock );
69 /* Call back the decoder. */
70 if( p_bit_stream->pf_bitstream_callback != NULL )
72 p_bit_stream->pf_bitstream_callback( p_bit_stream, 1 );
75 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
77 /* Get aligned on a word boundary.
78 * NB : we _will_ get aligned, because we have at most
79 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
80 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
81 AlignWord( p_bit_stream );
85 /*****************************************************************************
86 * DecoderError : an error occured, use this function to empty the fifo
87 *****************************************************************************/
88 void DecoderError( decoder_fifo_t * p_fifo )
90 /* We take the lock, because we are going to read/write the start/end
91 * indexes of the decoder fifo */
92 vlc_mutex_lock (&p_fifo->data_lock);
94 /* Wait until a `die' order is sent */
95 while (!p_fifo->b_die)
97 /* Trash all received PES packets */
98 input_DeletePES( p_fifo->p_packets_mgt, p_fifo->p_first );
99 p_fifo->p_first = NULL;
100 p_fifo->pp_last = &p_fifo->p_first;
102 /* If the input is waiting for us, tell him to stop */
103 vlc_cond_signal( &p_fifo->data_wait );
105 /* Waiting for the input thread to put new PES packets in the fifo */
106 vlc_cond_wait (&p_fifo->data_wait, &p_fifo->data_lock);
109 /* We can release the lock before leaving */
110 vlc_mutex_unlock (&p_fifo->data_lock);
113 /*****************************************************************************
114 * NextDataPacket: go to the data packet after *pp_data, return 1 if we
116 *****************************************************************************/
117 static inline vlc_bool_t _NextDataPacket( decoder_fifo_t * p_fifo,
118 data_packet_t ** pp_data )
120 vlc_bool_t b_new_pes;
122 /* We are looking for the next data packet that contains real data,
123 * and not just a PES header */
126 /* We were reading the last data packet of this PES packet... It's
127 * time to jump to the next PES packet */
128 if( (*pp_data)->p_next == NULL )
130 pes_packet_t * p_next;
132 vlc_mutex_lock( &p_fifo->data_lock );
134 /* Free the previous PES packet. */
135 p_next = p_fifo->p_first->p_next;
136 p_fifo->p_first->p_next = NULL;
137 input_DeletePES( p_fifo->p_packets_mgt, p_fifo->p_first );
138 p_fifo->p_first = p_next;
141 if( p_fifo->p_first == NULL )
143 /* No PES in the FIFO. p_last is no longer valid. */
144 p_fifo->pp_last = &p_fifo->p_first;
146 /* Signal the input thread we're waiting. This is only
147 * needed in case of slave clock (ES plug-in) but it won't
149 vlc_cond_signal( &p_fifo->data_wait );
151 /* Wait for the input to tell us when we receive a packet. */
152 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
155 /* The next packet could be found in the next PES packet */
156 *pp_data = p_fifo->p_first->p_first;
158 vlc_mutex_unlock( &p_fifo->data_lock );
164 /* Perhaps the next data packet of the current PES packet contains
165 * real data (ie its payload's size is greater than 0). */
166 *pp_data = (*pp_data)->p_next;
170 } while ( (*pp_data)->p_payload_start == (*pp_data)->p_payload_end );
175 vlc_bool_t NextDataPacket( decoder_fifo_t * p_fifo, data_packet_t ** pp_data )
177 return( _NextDataPacket( p_fifo, pp_data ) );
180 /*****************************************************************************
181 * BitstreamNextDataPacket: go to the next data packet, and update bitstream
183 *****************************************************************************/
184 static inline void _BitstreamNextDataPacket( bit_stream_t * p_bit_stream )
186 decoder_fifo_t * p_fifo = p_bit_stream->p_decoder_fifo;
187 vlc_bool_t b_new_pes;
189 b_new_pes = _NextDataPacket( p_fifo, &p_bit_stream->p_data );
191 /* We've found a data packet which contains interesting data... */
192 p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
193 p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
195 /* Call back the decoder. */
196 if( p_bit_stream->pf_bitstream_callback != NULL )
198 p_bit_stream->pf_bitstream_callback( p_bit_stream, b_new_pes );
201 /* Discontinuity management. */
202 if( p_bit_stream->p_data->b_discard_payload )
204 p_bit_stream->i_pts = p_bit_stream->i_dts = 0;
207 /* Retrieve the PTS. */
208 if( b_new_pes && p_fifo->p_first->i_pts )
210 p_bit_stream->i_pts = p_fifo->p_first->i_pts;
211 p_bit_stream->i_dts = p_fifo->p_first->i_dts;
212 p_bit_stream->p_pts_validity = p_bit_stream->p_byte;
216 void BitstreamNextDataPacket( bit_stream_t * p_bit_stream )
218 _BitstreamNextDataPacket( p_bit_stream );
221 /*****************************************************************************
222 * UnalignedShowBits : places i_bits bits into the bit buffer, even when
223 * not aligned on a word boundary
224 *****************************************************************************/
225 u32 UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
227 /* We just fill in the bit buffer. */
228 while( p_bit_stream->fifo.i_available < i_bits )
230 if( p_bit_stream->p_byte < p_bit_stream->p_end )
232 p_bit_stream->fifo.buffer |= *(p_bit_stream->p_byte++)
233 << (8 * sizeof(WORD_TYPE) - 8
234 - p_bit_stream->fifo.i_available);
235 p_bit_stream->fifo.i_available += 8;
239 _BitstreamNextDataPacket( p_bit_stream );
241 if( (ptrdiff_t)p_bit_stream->p_byte & (sizeof(WORD_TYPE) - 1) )
243 /* We are not aligned anymore. */
244 if( ((ptrdiff_t)p_bit_stream->p_byte
245 & (sizeof(WORD_TYPE) - 1)) * 8
246 < p_bit_stream->fifo.i_available )
248 /* We are not aligned, and won't be. Copy the first word
249 * of the packet in a temporary buffer, and we'll see
253 /* sizeof(WORD_TYPE) - number of bytes to trash
254 * from the last payload */
257 p_bit_stream->i_showbits_buffer = 0;
259 for( j = i = 0 ; i < sizeof(WORD_TYPE) ; i++ )
261 if( p_bit_stream->p_byte >= p_bit_stream->p_end )
264 _BitstreamNextDataPacket( p_bit_stream );
266 ((byte_t *)&p_bit_stream->i_showbits_buffer)[i] =
267 * p_bit_stream->p_byte;
268 p_bit_stream->p_byte++;
271 /* This is kind of kludgy. */
272 p_bit_stream->p_data->p_payload_start +=
273 sizeof(WORD_TYPE) - j;
274 p_bit_stream->p_byte =
275 (byte_t *)&p_bit_stream->i_showbits_buffer;
276 p_bit_stream->p_end =
277 (byte_t *)&p_bit_stream->i_showbits_buffer
279 p_bit_stream->showbits_data.p_next = p_bit_stream->p_data;
280 p_bit_stream->p_data = &p_bit_stream->showbits_data;
284 /* We are not aligned, but we can be. */
285 AlignWord( p_bit_stream );
289 /* We have 32 bits ready for reading, it will be enough. */
294 /* It shouldn't loop :-)) */
295 return( ShowBits( p_bit_stream, i_bits ) );
298 /*****************************************************************************
299 * UnalignedGetBits : returns i_bits bits from the bit stream and removes
300 * them from the buffer, even when the bit stream is not aligned on a word
302 *****************************************************************************/
303 u32 UnalignedGetBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
307 i_result = p_bit_stream->fifo.buffer
308 >> (8 * sizeof(WORD_TYPE) - i_bits);
309 i_bits = -p_bit_stream->fifo.i_available;
311 /* Gather missing bytes. */
314 if( p_bit_stream->p_byte < p_bit_stream->p_end )
316 i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
321 _BitstreamNextDataPacket( p_bit_stream );
322 i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
327 /* Gather missing bits. */
330 unsigned int i_tmp = 8 - i_bits;
332 if( p_bit_stream->p_byte < p_bit_stream->p_end )
334 i_result |= *p_bit_stream->p_byte >> i_tmp;
335 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
336 << ( sizeof(WORD_TYPE) * 8 - i_tmp );
337 p_bit_stream->fifo.i_available = i_tmp;
341 _BitstreamNextDataPacket( p_bit_stream );
342 i_result |= *p_bit_stream->p_byte >> i_tmp;
343 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
344 << ( sizeof(WORD_TYPE) * 8 - i_tmp );
345 p_bit_stream->fifo.i_available = i_tmp;
350 p_bit_stream->fifo.i_available = 0;
351 p_bit_stream->fifo.buffer = 0;
354 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
356 /* Get aligned on a word boundary. Otherwise it is safer
357 * to do it the next time.
358 * NB : we _will_ get aligned, because we have at most
359 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
360 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
361 AlignWord( p_bit_stream );
367 /*****************************************************************************
368 * UnalignedRemoveBits : removes i_bits (== -i_available) from the bit
369 * buffer, even when the bit stream is not aligned on a word boundary
370 *****************************************************************************/
371 void UnalignedRemoveBits( bit_stream_t * p_bit_stream )
373 /* First remove all unnecessary bytes. */
374 while( p_bit_stream->fifo.i_available <= -8 )
376 if( p_bit_stream->p_byte < p_bit_stream->p_end )
378 p_bit_stream->p_byte++;
379 p_bit_stream->fifo.i_available += 8;
383 _BitstreamNextDataPacket( p_bit_stream );
384 p_bit_stream->p_byte++;
385 p_bit_stream->fifo.i_available += 8;
389 /* Remove unnecessary bits. */
390 if( p_bit_stream->fifo.i_available < 0 )
392 if( p_bit_stream->p_byte < p_bit_stream->p_end )
394 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
395 << ( sizeof(WORD_TYPE) * 8 - 8
396 - p_bit_stream->fifo.i_available );
397 p_bit_stream->fifo.i_available += 8;
401 _BitstreamNextDataPacket( p_bit_stream );
402 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
403 << ( sizeof(WORD_TYPE) * 8 - 8
404 - p_bit_stream->fifo.i_available );
405 p_bit_stream->fifo.i_available += 8;
410 p_bit_stream->fifo.buffer = 0;
413 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
415 /* Get aligned on a word boundary. Otherwise it is safer
416 * to do it the next time.
417 * NB : we _will_ get aligned, because we have at most
418 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
419 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
420 AlignWord( p_bit_stream );
424 /*****************************************************************************
425 * CurrentPTS: returns the current PTS and DTS
426 *****************************************************************************/
427 void CurrentPTS( bit_stream_t * p_bit_stream, mtime_t * pi_pts,
430 /* Check if the current PTS is already valid (ie. if the first byte
431 * of the packet has already been used in the decoder). */
432 ptrdiff_t p_diff = p_bit_stream->p_pts_validity - p_bit_stream->p_byte;
433 if( p_diff < 0 || p_diff > 4 /* We are far away so it is valid */
434 || (p_diff * 8) >= p_bit_stream->fifo.i_available
435 /* We have buffered less bytes than actually read */ )
437 *pi_pts = p_bit_stream->i_pts;
438 if( pi_dts != NULL ) *pi_dts = p_bit_stream->i_dts;
439 p_bit_stream->i_pts = 0;
440 p_bit_stream->i_dts = 0;
445 if( pi_dts != NULL) *pi_dts = 0;
449 /*****************************************************************************
450 * NextPTS: returns the PTS and DTS for the next starting byte
451 *****************************************************************************/
452 void NextPTS( bit_stream_t * p_bit_stream, mtime_t * pi_pts,
455 /* Check if the current PTS is already valid (ie. if the first byte
456 * of the packet has already been used in the decoder). */
457 ptrdiff_t p_diff = p_bit_stream->p_pts_validity - p_bit_stream->p_byte - 1;
458 if( p_diff < 0 || p_diff > 4 /* We are far away so it is valid */
459 || (p_diff * 8) >= p_bit_stream->fifo.i_available
460 /* We have buffered less bytes than actually read */ )
462 *pi_pts = p_bit_stream->i_pts;
463 if( pi_dts != NULL ) *pi_dts = p_bit_stream->i_dts;
464 p_bit_stream->i_pts = 0;
465 p_bit_stream->i_dts = 0;
470 if( pi_dts != NULL) *pi_dts = 0;