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.45 2003/03/04 13:21:19 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() */
31 #include "stream_control.h"
32 #include "input_ext-dec.h"
33 #include "input_ext-intf.h"
34 #include "input_ext-plugins.h"
36 /****************************************************************************
38 *****************************************************************************
39 * Extract a PES from the fifo. If pp_pes is NULL then the PES is just
40 * deleted, otherwise *pp_pes will point to this PES.
41 ****************************************************************************/
42 void input_ExtractPES( decoder_fifo_t *p_fifo, pes_packet_t **pp_pes )
46 vlc_mutex_lock( &p_fifo->data_lock );
48 if( p_fifo->p_first == NULL )
52 vlc_mutex_unlock( &p_fifo->data_lock );
53 if( pp_pes ) *pp_pes = NULL;
57 /* Signal the input thread we're waiting. This is only
58 * needed in case of slave clock (ES plug-in) but it won't
60 vlc_cond_signal( &p_fifo->data_wait );
62 /* Wait for the input to tell us when we received a packet. */
63 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
66 p_pes = p_fifo->p_first;
67 p_fifo->p_first = p_pes->p_next;
71 if( !p_fifo->p_first )
73 /* No PES in the FIFO. p_last is no longer valid. */
74 p_fifo->pp_last = &p_fifo->p_first;
77 vlc_mutex_unlock( &p_fifo->data_lock );
82 input_DeletePES( p_fifo->p_packets_mgt, p_pes );
85 /*****************************************************************************
86 * InitBitstream: initialize a bit_stream_t structure and returns VLC_SUCCESS
88 *****************************************************************************/
89 int InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo,
90 void (* pf_bitstream_callback)( bit_stream_t *, vlc_bool_t ),
91 void * p_callback_arg )
93 /* Get the first pes packet */
94 input_ExtractPES( p_fifo, &p_bit_stream->p_pes );
95 if( !p_bit_stream->p_pes )
98 p_bit_stream->p_decoder_fifo = p_fifo;
99 p_bit_stream->pf_bitstream_callback = pf_bitstream_callback;
100 p_bit_stream->p_callback_arg = p_callback_arg;
102 p_bit_stream->p_data = p_bit_stream->p_pes->p_first;
103 p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
104 p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
105 p_bit_stream->fifo.buffer = 0;
106 p_bit_stream->fifo.i_available = 0;
107 p_bit_stream->i_pts = p_bit_stream->p_pes->i_pts;
108 p_bit_stream->i_dts = p_bit_stream->p_pes->i_dts;
109 p_bit_stream->p_pts_validity = p_bit_stream->p_byte;
111 /* Call back the decoder. */
112 if( p_bit_stream->pf_bitstream_callback != NULL )
114 p_bit_stream->pf_bitstream_callback( p_bit_stream, 1 );
117 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
119 /* Get aligned on a word boundary.
120 * NB : we _will_ get aligned, because we have at most
121 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
122 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
123 AlignWord( p_bit_stream );
129 /*****************************************************************************
130 * CloseBitstream: free the bitstream structure.
131 *****************************************************************************/
132 void CloseBitstream( bit_stream_t * p_bit_stream )
134 if( p_bit_stream->p_pes )
135 input_DeletePES( p_bit_stream->p_decoder_fifo->p_packets_mgt,
136 p_bit_stream->p_pes );
139 /*****************************************************************************
140 * DecoderError : an error occured, use this function to empty the fifo
141 *****************************************************************************/
142 void DecoderError( decoder_fifo_t * p_fifo )
144 /* No need to take the lock, because input_ExtractPES already takes it
145 * and also check for p_fifo->b_die */
147 /* Wait until a `die' order is sent */
148 while( !p_fifo->b_die )
150 /* Trash all received PES packets */
151 input_ExtractPES( p_fifo, NULL );
155 /*****************************************************************************
156 * NextDataPacket: go to the data packet after *pp_data, return 1 if we
157 * changed PES. This function can fail in case of end of stream, you can
158 * check p_bit_stream->p_data or p_bit_stream->p_pes to know wether we did get
159 * the next data packet.
160 *****************************************************************************/
161 static inline vlc_bool_t _NextDataPacket( decoder_fifo_t * p_fifo,
162 bit_stream_t * p_bit_stream )
164 vlc_bool_t b_new_pes;
166 /* We are looking for the next data packet that contains real data,
167 * and not just a PES header */
170 /* Sanity check. Yes, this can happen if the caller doesn't check
171 * for p_fifo->b_die beforehand. */
172 if( p_bit_stream->p_pes == NULL ) return 0;
174 /* We were reading the last data packet of this PES packet... It's
175 * time to jump to the next PES packet */
176 if( p_bit_stream->p_data->p_next == NULL )
178 /* The next packet could be found in the next PES packet */
179 input_DeletePES( p_fifo->p_packets_mgt, p_bit_stream->p_pes );
180 input_ExtractPES( p_fifo, &p_bit_stream->p_pes );
181 if( !p_bit_stream->p_pes )
183 /* Couldn't get the next PES, might be an eos */
184 p_bit_stream->p_data = NULL;
187 p_bit_stream->p_data = p_bit_stream->p_pes->p_first;
192 /* Perhaps the next data packet of the current PES packet contains
193 * real data (ie its payload's size is greater than 0). */
194 p_bit_stream->p_data = p_bit_stream->p_data->p_next;
198 } while ( p_bit_stream->p_data->p_payload_start ==
199 p_bit_stream->p_data->p_payload_end );
204 vlc_bool_t NextDataPacket( decoder_fifo_t * p_fifo,
205 bit_stream_t * p_bit_stream )
207 return( _NextDataPacket( p_fifo, p_bit_stream ) );
210 /*****************************************************************************
211 * BitstreamNextDataPacket: go to the next data packet, and update bitstream
212 * context. This function can fail in case of eos!
213 *****************************************************************************/
214 static inline void _BitstreamNextDataPacket( bit_stream_t * p_bit_stream )
216 decoder_fifo_t * p_fifo = p_bit_stream->p_decoder_fifo;
217 vlc_bool_t b_new_pes;
219 b_new_pes = _NextDataPacket( p_fifo, p_bit_stream );
220 if( !p_bit_stream->p_pes ) return;
222 /* We've found a data packet which contains interesting data... */
223 p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
224 p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
226 /* Call back the decoder. */
227 if( p_bit_stream->pf_bitstream_callback != NULL )
229 p_bit_stream->pf_bitstream_callback( p_bit_stream, b_new_pes );
232 /* Discontinuity management. */
233 if( p_bit_stream->p_data->b_discard_payload )
235 p_bit_stream->i_pts = p_bit_stream->i_dts = 0;
238 /* Retrieve the PTS. */
239 if( b_new_pes && p_bit_stream->p_pes->i_pts )
241 p_bit_stream->i_pts = p_bit_stream->p_pes->i_pts;
242 p_bit_stream->i_dts = p_bit_stream->p_pes->i_dts;
243 p_bit_stream->p_pts_validity = p_bit_stream->p_byte;
247 void BitstreamNextDataPacket( bit_stream_t * p_bit_stream )
249 _BitstreamNextDataPacket( p_bit_stream );
252 /*****************************************************************************
253 * UnalignedShowBits : places i_bits bits into the bit buffer, even when
254 * not aligned on a word boundary
255 *****************************************************************************/
256 u32 UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
258 /* We just fill in the bit buffer. */
259 while( (unsigned int)p_bit_stream->fifo.i_available < i_bits )
261 if( p_bit_stream->p_byte < p_bit_stream->p_end )
263 p_bit_stream->fifo.buffer |= *(p_bit_stream->p_byte++)
264 << (8 * sizeof(WORD_TYPE) - 8
265 - p_bit_stream->fifo.i_available);
266 p_bit_stream->fifo.i_available += 8;
270 _BitstreamNextDataPacket( p_bit_stream );
271 if( p_bit_stream->p_decoder_fifo->b_die ) return 0;
273 if( (ptrdiff_t)p_bit_stream->p_byte & (sizeof(WORD_TYPE) - 1) )
275 /* We are not aligned anymore. */
276 if( ((ptrdiff_t)p_bit_stream->p_byte
277 & (sizeof(WORD_TYPE) - 1)) * 8
278 < (unsigned int)p_bit_stream->fifo.i_available )
280 /* We are not aligned, and won't be. Copy the first word
281 * of the packet in a temporary buffer, and we'll see
285 /* sizeof(WORD_TYPE) - number of bytes to trash
286 * from the last payload */
289 p_bit_stream->i_showbits_buffer = 0;
291 for( j = i = 0 ; i < (int)sizeof(WORD_TYPE) ; i++ )
293 if( p_bit_stream->p_byte >= p_bit_stream->p_end )
296 _BitstreamNextDataPacket( p_bit_stream );
297 if( p_bit_stream->p_decoder_fifo->b_die ) return 0;
299 ((byte_t *)&p_bit_stream->i_showbits_buffer)[i] =
300 * p_bit_stream->p_byte;
301 p_bit_stream->p_byte++;
304 /* This is kind of kludgy. */
305 p_bit_stream->p_data->p_payload_start +=
306 sizeof(WORD_TYPE) - j;
307 p_bit_stream->p_byte =
308 (byte_t *)&p_bit_stream->i_showbits_buffer;
309 p_bit_stream->p_end =
310 (byte_t *)&p_bit_stream->i_showbits_buffer
312 p_bit_stream->showbits_data.p_next = p_bit_stream->p_data;
313 p_bit_stream->p_data = &p_bit_stream->showbits_data;
317 /* We are not aligned, but we can be. */
318 AlignWord( p_bit_stream );
322 /* We have 32 bits ready for reading, it will be enough. */
327 /* It shouldn't loop :-)) */
328 return( ShowBits( p_bit_stream, i_bits ) );
331 /*****************************************************************************
332 * UnalignedGetBits : returns i_bits bits from the bit stream and removes
333 * them from the buffer, even when the bit stream is not aligned on a word
335 *****************************************************************************/
336 u32 UnalignedGetBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
340 i_result = p_bit_stream->fifo.buffer
341 >> (8 * sizeof(WORD_TYPE) - i_bits);
342 i_bits = -p_bit_stream->fifo.i_available;
344 /* Gather missing bytes. */
347 if( p_bit_stream->p_byte < p_bit_stream->p_end )
349 i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
354 _BitstreamNextDataPacket( p_bit_stream );
355 if( p_bit_stream->p_decoder_fifo->b_die ) return 0;
356 i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
361 /* Gather missing bits. */
364 unsigned int i_tmp = 8 - i_bits;
366 if( p_bit_stream->p_byte < p_bit_stream->p_end )
368 i_result |= *p_bit_stream->p_byte >> i_tmp;
369 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
370 << ( sizeof(WORD_TYPE) * 8 - i_tmp );
371 p_bit_stream->fifo.i_available = i_tmp;
375 _BitstreamNextDataPacket( p_bit_stream );
376 if( p_bit_stream->p_decoder_fifo->b_die ) return 0;
377 i_result |= *p_bit_stream->p_byte >> i_tmp;
378 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
379 << ( sizeof(WORD_TYPE) * 8 - i_tmp );
380 p_bit_stream->fifo.i_available = i_tmp;
385 p_bit_stream->fifo.i_available = 0;
386 p_bit_stream->fifo.buffer = 0;
389 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
391 /* Get aligned on a word boundary. Otherwise it is safer
392 * to do it the next time.
393 * NB : we _will_ get aligned, because we have at most
394 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
395 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
396 AlignWord( p_bit_stream );
402 /*****************************************************************************
403 * UnalignedRemoveBits : removes i_bits (== -i_available) from the bit
404 * buffer, even when the bit stream is not aligned on a word boundary
405 *****************************************************************************/
406 void UnalignedRemoveBits( bit_stream_t * p_bit_stream )
408 /* First remove all unnecessary bytes. */
409 while( p_bit_stream->fifo.i_available <= -8 )
411 if( p_bit_stream->p_byte < p_bit_stream->p_end )
413 p_bit_stream->p_byte++;
414 p_bit_stream->fifo.i_available += 8;
418 _BitstreamNextDataPacket( p_bit_stream );
419 if( p_bit_stream->p_decoder_fifo->b_die ) return;
420 p_bit_stream->p_byte++;
421 p_bit_stream->fifo.i_available += 8;
425 /* Remove unnecessary bits. */
426 if( p_bit_stream->fifo.i_available < 0 )
428 if( p_bit_stream->p_byte < p_bit_stream->p_end )
430 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
431 << ( sizeof(WORD_TYPE) * 8 - 8
432 - p_bit_stream->fifo.i_available );
433 p_bit_stream->fifo.i_available += 8;
437 _BitstreamNextDataPacket( p_bit_stream );
438 if( p_bit_stream->p_decoder_fifo->b_die ) return;
439 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
440 << ( sizeof(WORD_TYPE) * 8 - 8
441 - p_bit_stream->fifo.i_available );
442 p_bit_stream->fifo.i_available += 8;
447 p_bit_stream->fifo.buffer = 0;
450 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
452 /* Get aligned on a word boundary. Otherwise it is safer
453 * to do it the next time.
454 * NB : we _will_ get aligned, because we have at most
455 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
456 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
457 AlignWord( p_bit_stream );
461 /*****************************************************************************
462 * CurrentPTS: returns the current PTS and DTS
463 *****************************************************************************/
464 void CurrentPTS( bit_stream_t * p_bit_stream, mtime_t * pi_pts,
467 /* Check if the current PTS is already valid (ie. if the first byte
468 * of the packet has already been used in the decoder). */
469 ptrdiff_t p_diff = p_bit_stream->p_pts_validity - p_bit_stream->p_byte;
470 if( p_diff < 0 || p_diff > 4 /* We are far away so it is valid */
471 || (p_diff * 8) >= p_bit_stream->fifo.i_available
472 /* We have buffered less bytes than actually read */ )
474 *pi_pts = p_bit_stream->i_pts;
475 if( pi_dts != NULL ) *pi_dts = p_bit_stream->i_dts;
476 p_bit_stream->i_pts = 0;
477 p_bit_stream->i_dts = 0;
482 if( pi_dts != NULL) *pi_dts = 0;
486 /*****************************************************************************
487 * NextPTS: returns the PTS and DTS for the next starting byte
488 *****************************************************************************/
489 void NextPTS( bit_stream_t * p_bit_stream, mtime_t * pi_pts,
492 /* Check if the current PTS is already valid (ie. if the first byte
493 * of the packet has already been used in the decoder). */
494 ptrdiff_t p_diff = p_bit_stream->p_pts_validity - p_bit_stream->p_byte - 1;
495 if( p_diff < 0 || p_diff > 4 /* We are far away so it is valid */
496 || (p_diff * 8) >= p_bit_stream->fifo.i_available
497 /* We have buffered less bytes than actually read */ )
499 *pi_pts = p_bit_stream->i_pts;
500 if( pi_dts != NULL ) *pi_dts = p_bit_stream->i_dts;
501 p_bit_stream->i_pts = 0;
502 p_bit_stream->i_dts = 0;
507 if( pi_dts != NULL) *pi_dts = 0;