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.43 2002/12/06 10:10:39 sam 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 /*****************************************************************************
37 * InitBitstream: initialize a bit_stream_t structure and returns VLC_SUCCESS
39 *****************************************************************************/
40 int 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 /* Get the first pes packet */
45 input_ExtractPES( p_fifo, &p_bit_stream->p_pes );
46 if( !p_bit_stream->p_pes )
49 p_bit_stream->p_decoder_fifo = p_fifo;
50 p_bit_stream->pf_bitstream_callback = pf_bitstream_callback;
51 p_bit_stream->p_callback_arg = p_callback_arg;
53 p_bit_stream->p_data = p_bit_stream->p_pes->p_first;
54 p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
55 p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
56 p_bit_stream->fifo.buffer = 0;
57 p_bit_stream->fifo.i_available = 0;
58 p_bit_stream->i_pts = p_bit_stream->p_pes->i_pts;
59 p_bit_stream->i_dts = p_bit_stream->p_pes->i_dts;
60 p_bit_stream->p_pts_validity = p_bit_stream->p_byte;
62 /* Call back the decoder. */
63 if( p_bit_stream->pf_bitstream_callback != NULL )
65 p_bit_stream->pf_bitstream_callback( p_bit_stream, 1 );
68 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
70 /* Get aligned on a word boundary.
71 * NB : we _will_ get aligned, because we have at most
72 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
73 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
74 AlignWord( p_bit_stream );
80 /*****************************************************************************
81 * CloseBitstream: free the bitstream structure.
82 *****************************************************************************/
83 void CloseBitstream( bit_stream_t * p_bit_stream )
85 if( p_bit_stream->p_pes )
86 input_DeletePES( p_bit_stream->p_decoder_fifo->p_packets_mgt,
87 p_bit_stream->p_pes );
90 /*****************************************************************************
91 * DecoderError : an error occured, use this function to empty the fifo
92 *****************************************************************************/
93 void DecoderError( decoder_fifo_t * p_fifo )
95 /* No need to take the lock, because input_ExtractPES already takes it
96 * and also check for p_fifo->b_die */
98 /* Wait until a `die' order is sent */
99 while( !p_fifo->b_die )
101 /* Trash all received PES packets */
102 input_ExtractPES( p_fifo, NULL );
106 /*****************************************************************************
107 * NextDataPacket: go to the data packet after *pp_data, return 1 if we
108 * changed PES. This function can fail in case of end of stream, you can
109 * check p_bit_stream->p_data or p_bit_stream->p_pes to know wether we did get
110 * the next data packet.
111 *****************************************************************************/
112 static inline vlc_bool_t _NextDataPacket( decoder_fifo_t * p_fifo,
113 bit_stream_t * p_bit_stream )
115 vlc_bool_t b_new_pes;
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 /* The next packet could be found in the next PES packet */
126 input_DeletePES( p_fifo->p_packets_mgt, p_bit_stream->p_pes );
127 input_ExtractPES( p_fifo, &p_bit_stream->p_pes );
128 if( !p_bit_stream->p_pes )
130 /* Couldn't get the next PES, might be an eos */
131 p_bit_stream->p_data = NULL;
134 p_bit_stream->p_data = p_bit_stream->p_pes->p_first;
139 /* Perhaps the next data packet of the current PES packet contains
140 * real data (ie its payload's size is greater than 0). */
141 p_bit_stream->p_data = p_bit_stream->p_data->p_next;
145 } while ( p_bit_stream->p_data->p_payload_start ==
146 p_bit_stream->p_data->p_payload_end );
151 vlc_bool_t NextDataPacket( decoder_fifo_t * p_fifo,
152 bit_stream_t * p_bit_stream )
154 return( _NextDataPacket( p_fifo, p_bit_stream ) );
157 /*****************************************************************************
158 * BitstreamNextDataPacket: go to the next data packet, and update bitstream
159 * context. This function can fail in case of eos!
160 *****************************************************************************/
161 static inline void _BitstreamNextDataPacket( bit_stream_t * p_bit_stream )
163 decoder_fifo_t * p_fifo = p_bit_stream->p_decoder_fifo;
164 vlc_bool_t b_new_pes;
166 b_new_pes = _NextDataPacket( p_fifo, p_bit_stream );
167 if( !p_bit_stream->p_pes ) return;
169 /* We've found a data packet which contains interesting data... */
170 p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
171 p_bit_stream->p_end = p_bit_stream->p_data->p_payload_end;
173 /* Call back the decoder. */
174 if( p_bit_stream->pf_bitstream_callback != NULL )
176 p_bit_stream->pf_bitstream_callback( p_bit_stream, b_new_pes );
179 /* Discontinuity management. */
180 if( p_bit_stream->p_data->b_discard_payload )
182 p_bit_stream->i_pts = p_bit_stream->i_dts = 0;
185 /* Retrieve the PTS. */
186 if( b_new_pes && p_bit_stream->p_pes->i_pts )
188 p_bit_stream->i_pts = p_bit_stream->p_pes->i_pts;
189 p_bit_stream->i_dts = p_bit_stream->p_pes->i_dts;
190 p_bit_stream->p_pts_validity = p_bit_stream->p_byte;
194 void BitstreamNextDataPacket( bit_stream_t * p_bit_stream )
196 _BitstreamNextDataPacket( p_bit_stream );
199 /*****************************************************************************
200 * UnalignedShowBits : places i_bits bits into the bit buffer, even when
201 * not aligned on a word boundary
202 *****************************************************************************/
203 u32 UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
205 /* We just fill in the bit buffer. */
206 while( (unsigned int)p_bit_stream->fifo.i_available < i_bits )
208 if( p_bit_stream->p_byte < p_bit_stream->p_end )
210 p_bit_stream->fifo.buffer |= *(p_bit_stream->p_byte++)
211 << (8 * sizeof(WORD_TYPE) - 8
212 - p_bit_stream->fifo.i_available);
213 p_bit_stream->fifo.i_available += 8;
217 _BitstreamNextDataPacket( p_bit_stream );
219 if( (ptrdiff_t)p_bit_stream->p_byte & (sizeof(WORD_TYPE) - 1) )
221 /* We are not aligned anymore. */
222 if( ((ptrdiff_t)p_bit_stream->p_byte
223 & (sizeof(WORD_TYPE) - 1)) * 8
224 < (unsigned int)p_bit_stream->fifo.i_available )
226 /* We are not aligned, and won't be. Copy the first word
227 * of the packet in a temporary buffer, and we'll see
231 /* sizeof(WORD_TYPE) - number of bytes to trash
232 * from the last payload */
235 p_bit_stream->i_showbits_buffer = 0;
237 for( j = i = 0 ; i < (int)sizeof(WORD_TYPE) ; i++ )
239 if( p_bit_stream->p_byte >= p_bit_stream->p_end )
242 _BitstreamNextDataPacket( p_bit_stream );
244 ((byte_t *)&p_bit_stream->i_showbits_buffer)[i] =
245 * p_bit_stream->p_byte;
246 p_bit_stream->p_byte++;
249 /* This is kind of kludgy. */
250 p_bit_stream->p_data->p_payload_start +=
251 sizeof(WORD_TYPE) - j;
252 p_bit_stream->p_byte =
253 (byte_t *)&p_bit_stream->i_showbits_buffer;
254 p_bit_stream->p_end =
255 (byte_t *)&p_bit_stream->i_showbits_buffer
257 p_bit_stream->showbits_data.p_next = p_bit_stream->p_data;
258 p_bit_stream->p_data = &p_bit_stream->showbits_data;
262 /* We are not aligned, but we can be. */
263 AlignWord( p_bit_stream );
267 /* We have 32 bits ready for reading, it will be enough. */
272 /* It shouldn't loop :-)) */
273 return( ShowBits( p_bit_stream, i_bits ) );
276 /*****************************************************************************
277 * UnalignedGetBits : returns i_bits bits from the bit stream and removes
278 * them from the buffer, even when the bit stream is not aligned on a word
280 *****************************************************************************/
281 u32 UnalignedGetBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
285 i_result = p_bit_stream->fifo.buffer
286 >> (8 * sizeof(WORD_TYPE) - i_bits);
287 i_bits = -p_bit_stream->fifo.i_available;
289 /* Gather missing bytes. */
292 if( p_bit_stream->p_byte < p_bit_stream->p_end )
294 i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
299 _BitstreamNextDataPacket( p_bit_stream );
300 i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
305 /* Gather missing bits. */
308 unsigned int i_tmp = 8 - i_bits;
310 if( p_bit_stream->p_byte < p_bit_stream->p_end )
312 i_result |= *p_bit_stream->p_byte >> i_tmp;
313 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
314 << ( sizeof(WORD_TYPE) * 8 - i_tmp );
315 p_bit_stream->fifo.i_available = i_tmp;
319 _BitstreamNextDataPacket( p_bit_stream );
320 i_result |= *p_bit_stream->p_byte >> i_tmp;
321 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
322 << ( sizeof(WORD_TYPE) * 8 - i_tmp );
323 p_bit_stream->fifo.i_available = i_tmp;
328 p_bit_stream->fifo.i_available = 0;
329 p_bit_stream->fifo.buffer = 0;
332 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
334 /* Get aligned on a word boundary. Otherwise it is safer
335 * to do it the next time.
336 * NB : we _will_ get aligned, because we have at most
337 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
338 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
339 AlignWord( p_bit_stream );
345 /*****************************************************************************
346 * UnalignedRemoveBits : removes i_bits (== -i_available) from the bit
347 * buffer, even when the bit stream is not aligned on a word boundary
348 *****************************************************************************/
349 void UnalignedRemoveBits( bit_stream_t * p_bit_stream )
351 /* First remove all unnecessary bytes. */
352 while( p_bit_stream->fifo.i_available <= -8 )
354 if( p_bit_stream->p_byte < p_bit_stream->p_end )
356 p_bit_stream->p_byte++;
357 p_bit_stream->fifo.i_available += 8;
361 _BitstreamNextDataPacket( p_bit_stream );
362 p_bit_stream->p_byte++;
363 p_bit_stream->fifo.i_available += 8;
367 /* Remove unnecessary bits. */
368 if( p_bit_stream->fifo.i_available < 0 )
370 if( p_bit_stream->p_byte < p_bit_stream->p_end )
372 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
373 << ( sizeof(WORD_TYPE) * 8 - 8
374 - p_bit_stream->fifo.i_available );
375 p_bit_stream->fifo.i_available += 8;
379 _BitstreamNextDataPacket( p_bit_stream );
380 p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
381 << ( sizeof(WORD_TYPE) * 8 - 8
382 - p_bit_stream->fifo.i_available );
383 p_bit_stream->fifo.i_available += 8;
388 p_bit_stream->fifo.buffer = 0;
391 if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
393 /* Get aligned on a word boundary. Otherwise it is safer
394 * to do it the next time.
395 * NB : we _will_ get aligned, because we have at most
396 * sizeof(WORD_TYPE) - 1 bytes to store, and at least
397 * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
398 AlignWord( p_bit_stream );
402 /*****************************************************************************
403 * CurrentPTS: returns the current PTS and DTS
404 *****************************************************************************/
405 void CurrentPTS( bit_stream_t * p_bit_stream, mtime_t * pi_pts,
408 /* Check if the current PTS is already valid (ie. if the first byte
409 * of the packet has already been used in the decoder). */
410 ptrdiff_t p_diff = p_bit_stream->p_pts_validity - p_bit_stream->p_byte;
411 if( p_diff < 0 || p_diff > 4 /* We are far away so it is valid */
412 || (p_diff * 8) >= p_bit_stream->fifo.i_available
413 /* We have buffered less bytes than actually read */ )
415 *pi_pts = p_bit_stream->i_pts;
416 if( pi_dts != NULL ) *pi_dts = p_bit_stream->i_dts;
417 p_bit_stream->i_pts = 0;
418 p_bit_stream->i_dts = 0;
423 if( pi_dts != NULL) *pi_dts = 0;
427 /*****************************************************************************
428 * NextPTS: returns the PTS and DTS for the next starting byte
429 *****************************************************************************/
430 void NextPTS( bit_stream_t * p_bit_stream, mtime_t * pi_pts,
433 /* Check if the current PTS is already valid (ie. if the first byte
434 * of the packet has already been used in the decoder). */
435 ptrdiff_t p_diff = p_bit_stream->p_pts_validity - p_bit_stream->p_byte - 1;
436 if( p_diff < 0 || p_diff > 4 /* We are far away so it is valid */
437 || (p_diff * 8) >= p_bit_stream->fifo.i_available
438 /* We have buffered less bytes than actually read */ )
440 *pi_pts = p_bit_stream->i_pts;
441 if( pi_dts != NULL ) *pi_dts = p_bit_stream->i_dts;
442 p_bit_stream->i_pts = 0;
443 p_bit_stream->i_dts = 0;
448 if( pi_dts != NULL) *pi_dts = 0;