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.36 2002/10/23 23:17:44 gbazin 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 * GetPES: return the first PES from the fifo
115 *****************************************************************************/
116 static inline pes_packet_t *_GetPES( decoder_fifo_t * p_fifo )
118 pes_packet_t * p_pes;
120 vlc_mutex_lock( &p_fifo->data_lock );
122 if( p_fifo->p_first == NULL )
124 /* No PES in the FIFO. p_last is no longer valid. */
125 p_fifo->pp_last = &p_fifo->p_first;
129 vlc_mutex_unlock( &p_fifo->data_lock );
133 /* Signal the input thread we're waiting. This is only
134 * needed in case of slave clock (ES plug-in) but it won't
136 vlc_cond_signal( &p_fifo->data_wait );
138 /* Wait for the input to tell us when we receive a packet. */
139 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
142 p_pes = p_fifo->p_first;
144 vlc_mutex_unlock( &p_fifo->data_lock );
149 pes_packet_t * GetPES( decoder_fifo_t * p_fifo )
151 return( _GetPES( p_fifo ) );
154 /*****************************************************************************
155 * NextPES: free the current PES and return the next one
156 *****************************************************************************/
157 static inline pes_packet_t * _NextPES( decoder_fifo_t * p_fifo )
159 pes_packet_t * p_next;
161 vlc_mutex_lock( &p_fifo->data_lock );
163 /* Free the previous PES packet. */
164 p_next = p_fifo->p_first->p_next;
165 p_fifo->p_first->p_next = NULL;
166 input_DeletePES( p_fifo->p_packets_mgt, p_fifo->p_first );
167 p_fifo->p_first = p_next;
170 vlc_mutex_unlock( &p_fifo->data_lock );
172 return _GetPES( p_fifo );
175 pes_packet_t * NextPES( decoder_fifo_t * p_fifo )
177 return( _NextPES( p_fifo ) );
180 /*****************************************************************************
181 * NextDataPacket: go to the data packet after *pp_data, return 1 if we
183 *****************************************************************************/
184 static inline vlc_bool_t _NextDataPacket( decoder_fifo_t * p_fifo,
185 data_packet_t ** pp_data )
187 vlc_bool_t b_new_pes;
189 /* We are looking for the next data packet that contains real data,
190 * and not just a PES header */
193 /* We were reading the last data packet of this PES packet... It's
194 * time to jump to the next PES packet */
195 if( (*pp_data)->p_next == NULL )
197 /* The next packet could be found in the next PES packet */
198 *pp_data = (_NextPES( p_fifo ))->p_first;
204 /* Perhaps the next data packet of the current PES packet contains
205 * real data (ie its payload's size is greater than 0). */
206 *pp_data = (*pp_data)->p_next;
210 } while ( (*pp_data)->p_payload_start == (*pp_data)->p_payload_end );
215 vlc_bool_t NextDataPacket( decoder_fifo_t * p_fifo, data_packet_t ** pp_data )
217 return( _NextDataPacket( p_fifo, pp_data ) );
220 /*****************************************************************************
221 * BitstreamNextDataPacket: go to the next data packet, and update bitstream
223 *****************************************************************************/
224 static inline void _BitstreamNextDataPacket( bit_stream_t * p_bit_stream )
226 decoder_fifo_t * p_fifo = p_bit_stream->p_decoder_fifo;
227 vlc_bool_t b_new_pes;
229 b_new_pes = _NextDataPacket( p_fifo, &p_bit_stream->p_data );
231 /* We've found a data packet which contains interesting data... */
232 p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
233 p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
235 /* Call back the decoder. */
236 if( p_bit_stream->pf_bitstream_callback != NULL )
238 p_bit_stream->pf_bitstream_callback( p_bit_stream, b_new_pes );
241 /* Discontinuity management. */
242 if( p_bit_stream->p_data->b_discard_payload )
244 p_bit_stream->i_pts = p_bit_stream->i_dts = 0;
247 /* Retrieve the PTS. */
248 if( b_new_pes && p_fifo->p_first->i_pts )
250 p_bit_stream->i_pts = p_fifo->p_first->i_pts;
251 p_bit_stream->i_dts = p_fifo->p_first->i_dts;
252 p_bit_stream->p_pts_validity = p_bit_stream->p_byte;
256 void BitstreamNextDataPacket( bit_stream_t * p_bit_stream )
258 _BitstreamNextDataPacket( p_bit_stream );
261 /*****************************************************************************
262 * UnalignedShowBits : places i_bits bits into the bit buffer, even when
263 * not aligned on a word boundary
264 *****************************************************************************/
265 u32 UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
267 /* We just fill in the bit buffer. */
268 while( p_bit_stream->fifo.i_available < i_bits )
270 if( p_bit_stream->p_byte < p_bit_stream->p_end )
272 p_bit_stream->fifo.buffer |= *(p_bit_stream->p_byte++)
273 << (8 * sizeof(WORD_TYPE) - 8
274 - p_bit_stream->fifo.i_available);
275 p_bit_stream->fifo.i_available += 8;
279 _BitstreamNextDataPacket( p_bit_stream );
281 if( (ptrdiff_t)p_bit_stream->p_byte & (sizeof(WORD_TYPE) - 1) )
283 /* We are not aligned anymore. */
284 if( ((ptrdiff_t)p_bit_stream->p_byte
285 & (sizeof(WORD_TYPE) - 1)) * 8
286 < p_bit_stream->fifo.i_available )
288 /* We are not aligned, and won't be. Copy the first word
289 * of the packet in a temporary buffer, and we'll see
293 /* sizeof(WORD_TYPE) - number of bytes to trash
294 * from the last payload */
297 p_bit_stream->i_showbits_buffer = 0;
299 for( j = i = 0 ; i < sizeof(WORD_TYPE) ; i++ )
301 if( p_bit_stream->p_byte >= p_bit_stream->p_end )
304 _BitstreamNextDataPacket( p_bit_stream );
306 ((byte_t *)&p_bit_stream->i_showbits_buffer)[i] =
307 * p_bit_stream->p_byte;
308 p_bit_stream->p_byte++;
311 /* This is kind of kludgy. */
312 p_bit_stream->p_data->p_payload_start +=
313 sizeof(WORD_TYPE) - j;
314 p_bit_stream->p_byte =
315 (byte_t *)&p_bit_stream->i_showbits_buffer;
316 p_bit_stream->p_end =
317 (byte_t *)&p_bit_stream->i_showbits_buffer
319 p_bit_stream->showbits_data.p_next = p_bit_stream->p_data;
320 p_bit_stream->p_data = &p_bit_stream->showbits_data;
324 /* We are not aligned, but we can be. */
325 AlignWord( p_bit_stream );
329 /* We have 32 bits ready for reading, it will be enough. */
334 /* It shouldn't loop :-)) */
335 return( ShowBits( p_bit_stream, i_bits ) );
338 /*****************************************************************************
339 * UnalignedGetBits : returns i_bits bits from the bit stream and removes
340 * them from the buffer, even when the bit stream is not aligned on a word
342 *****************************************************************************/
343 u32 UnalignedGetBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
347 i_result = p_bit_stream->fifo.buffer
348 >> (8 * sizeof(WORD_TYPE) - i_bits);
349 i_bits = -p_bit_stream->fifo.i_available;
351 /* Gather missing bytes. */
354 if( p_bit_stream->p_byte < p_bit_stream->p_end )
356 i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
361 _BitstreamNextDataPacket( p_bit_stream );
362 i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
367 /* Gather missing bits. */
370 unsigned int i_tmp = 8 - i_bits;
372 if( p_bit_stream->p_byte < p_bit_stream->p_end )
374 i_result |= *p_bit_stream->p_byte >> i_tmp;
375 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
376 << ( sizeof(WORD_TYPE) * 8 - i_tmp );
377 p_bit_stream->fifo.i_available = i_tmp;
381 _BitstreamNextDataPacket( p_bit_stream );
382 i_result |= *p_bit_stream->p_byte >> i_tmp;
383 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
384 << ( sizeof(WORD_TYPE) * 8 - i_tmp );
385 p_bit_stream->fifo.i_available = i_tmp;
390 p_bit_stream->fifo.i_available = 0;
391 p_bit_stream->fifo.buffer = 0;
394 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
396 /* Get aligned on a word boundary. Otherwise it is safer
397 * to do it the next time.
398 * NB : we _will_ get aligned, because we have at most
399 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
400 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
401 AlignWord( p_bit_stream );
407 /*****************************************************************************
408 * UnalignedRemoveBits : removes i_bits (== -i_available) from the bit
409 * buffer, even when the bit stream is not aligned on a word boundary
410 *****************************************************************************/
411 void UnalignedRemoveBits( bit_stream_t * p_bit_stream )
413 /* First remove all unnecessary bytes. */
414 while( p_bit_stream->fifo.i_available <= -8 )
416 if( p_bit_stream->p_byte < p_bit_stream->p_end )
418 p_bit_stream->p_byte++;
419 p_bit_stream->fifo.i_available += 8;
423 _BitstreamNextDataPacket( p_bit_stream );
424 p_bit_stream->p_byte++;
425 p_bit_stream->fifo.i_available += 8;
429 /* Remove unnecessary bits. */
430 if( p_bit_stream->fifo.i_available < 0 )
432 if( p_bit_stream->p_byte < p_bit_stream->p_end )
434 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
435 << ( sizeof(WORD_TYPE) * 8 - 8
436 - p_bit_stream->fifo.i_available );
437 p_bit_stream->fifo.i_available += 8;
441 _BitstreamNextDataPacket( p_bit_stream );
442 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
443 << ( sizeof(WORD_TYPE) * 8 - 8
444 - p_bit_stream->fifo.i_available );
445 p_bit_stream->fifo.i_available += 8;
450 p_bit_stream->fifo.buffer = 0;
453 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
455 /* Get aligned on a word boundary. Otherwise it is safer
456 * to do it the next time.
457 * NB : we _will_ get aligned, because we have at most
458 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
459 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
460 AlignWord( p_bit_stream );
464 /*****************************************************************************
465 * CurrentPTS: returns the current PTS and DTS
466 *****************************************************************************/
467 void CurrentPTS( bit_stream_t * p_bit_stream, mtime_t * pi_pts,
470 /* Check if the current PTS is already valid (ie. if the first byte
471 * of the packet has already been used in the decoder). */
472 ptrdiff_t p_diff = p_bit_stream->p_pts_validity - p_bit_stream->p_byte;
473 if( p_diff < 0 || p_diff > 4 /* We are far away so it is valid */
474 || (p_diff * 8) >= p_bit_stream->fifo.i_available
475 /* We have buffered less bytes than actually read */ )
477 *pi_pts = p_bit_stream->i_pts;
478 if( pi_dts != NULL ) *pi_dts = p_bit_stream->i_dts;
479 p_bit_stream->i_pts = 0;
480 p_bit_stream->i_dts = 0;
485 if( pi_dts != NULL) *pi_dts = 0;
489 /*****************************************************************************
490 * NextPTS: returns the PTS and DTS for the next starting byte
491 *****************************************************************************/
492 void NextPTS( bit_stream_t * p_bit_stream, mtime_t * pi_pts,
495 /* Check if the current PTS is already valid (ie. if the first byte
496 * of the packet has already been used in the decoder). */
497 ptrdiff_t p_diff = p_bit_stream->p_pts_validity - p_bit_stream->p_byte - 1;
498 if( p_diff < 0 || p_diff > 4 /* We are far away so it is valid */
499 || (p_diff * 8) >= p_bit_stream->fifo.i_available
500 /* We have buffered less bytes than actually read */ )
502 *pi_pts = p_bit_stream->i_pts;
503 if( pi_dts != NULL ) *pi_dts = p_bit_stream->i_dts;
504 p_bit_stream->i_pts = 0;
505 p_bit_stream->i_dts = 0;
510 if( pi_dts != NULL) *pi_dts = 0;
514 /****************************************************************************
515 * input_NextPES : extract a PES from the fifo. If pp_pes is NULL then this
516 * PES is deleted, else pp_pes will be set to this PES
517 ****************************************************************************/
518 int input_NextPES( decoder_fifo_t *p_fifo, pes_packet_t **pp_pes )
520 pes_packet_t *p_pes, *p_next;
522 vlc_mutex_lock( &p_fifo->data_lock );
524 /* if fifo is emty wait */
525 while( !p_fifo->p_first )
529 vlc_mutex_unlock( &p_fifo->data_lock );
536 vlc_cond_signal( &p_fifo->data_wait );
537 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
539 p_pes = p_fifo->p_first;
541 p_next = p_pes->p_next;
542 p_pes->p_next = NULL;
545 p_fifo->p_first = p_next;
548 if( !p_fifo->p_first )
550 /* No PES in the fifo */
551 /* pp_last no longer valid */
552 p_fifo->pp_last = &p_fifo->p_first;
554 vlc_mutex_unlock( &p_fifo->data_lock );
562 input_DeletePES( p_fifo->p_packets_mgt, p_pes );