]> git.sesse.net Git - vlc/blob - src/input/input_ext-dec.c
* src/libvlc.h: disabled the encoders config options (encoders are not used anymore...
[vlc] / src / input / input_ext-dec.c
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 $
6  *
7  * Authors: Christophe Massiot <massiot@via.ecp.fr>
8  *
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.
13  * 
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.
18  *
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  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <string.h>                                    /* memcpy(), memset() */
28
29 #include <vlc/vlc.h>
30
31 #include "stream_control.h"
32 #include "input_ext-dec.h"
33 #include "input_ext-intf.h"
34 #include "input_ext-plugins.h"
35
36 /****************************************************************************
37  * input_ExtractPES
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 )
43 {
44     pes_packet_t *p_pes;
45
46     vlc_mutex_lock( &p_fifo->data_lock );
47
48     if( p_fifo->p_first == NULL )
49     {
50         if( p_fifo->b_die )
51         {
52             vlc_mutex_unlock( &p_fifo->data_lock );
53             if( pp_pes ) *pp_pes = NULL;
54             return;
55         }
56
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
59          * harm. */
60         vlc_cond_signal( &p_fifo->data_wait );
61
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 );
64     }
65
66     p_pes = p_fifo->p_first;
67     p_fifo->p_first = p_pes->p_next;
68     p_pes->p_next = NULL;
69     p_fifo->i_depth--;
70
71     if( !p_fifo->p_first )
72     {
73         /* No PES in the FIFO. p_last is no longer valid. */
74         p_fifo->pp_last = &p_fifo->p_first;
75     }
76
77     vlc_mutex_unlock( &p_fifo->data_lock );
78
79     if( pp_pes )
80         *pp_pes = p_pes;
81     else
82         input_DeletePES( p_fifo->p_packets_mgt, p_pes );
83 }
84
85 /*****************************************************************************
86  * InitBitstream: initialize a bit_stream_t structure and returns VLC_SUCCESS
87  *                on 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 )
92 {
93     /* Get the first pes packet */
94     input_ExtractPES( p_fifo, &p_bit_stream->p_pes );
95     if( !p_bit_stream->p_pes )
96         return VLC_EGENERIC;
97
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;
101
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;
110
111     /* Call back the decoder. */
112     if( p_bit_stream->pf_bitstream_callback != NULL )
113     {
114         p_bit_stream->pf_bitstream_callback( p_bit_stream, 1 );
115     }
116
117     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
118     {
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 );
124     }
125
126     return VLC_SUCCESS;
127 }
128
129 /*****************************************************************************
130  * CloseBitstream: free the bitstream structure.
131  *****************************************************************************/
132 void CloseBitstream( bit_stream_t * p_bit_stream )
133 {
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 );
137 }
138
139 /*****************************************************************************
140  * DecoderError : an error occured, use this function to empty the fifo
141  *****************************************************************************/
142 void DecoderError( decoder_fifo_t * p_fifo )
143 {
144     /* No need to take the lock, because input_ExtractPES already takes it
145      * and also check for p_fifo->b_die */
146
147     /* Wait until a `die' order is sent */
148     while( !p_fifo->b_die )
149     {
150         /* Trash all received PES packets */
151         input_ExtractPES( p_fifo, NULL );
152     }
153 }
154
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 )
163 {
164     vlc_bool_t b_new_pes;
165
166     /* We are looking for the next data packet that contains real data,
167      * and not just a PES header */
168     do
169     {
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;
173
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 )
177         {
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 )
182             {
183                 /* Couldn't get the next PES, might be an eos */
184                 p_bit_stream->p_data = NULL;
185                 return 0;
186             }
187             p_bit_stream->p_data = p_bit_stream->p_pes->p_first;
188             b_new_pes = 1;
189         }
190         else
191         {
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;
195
196             b_new_pes = 0;
197         }
198     } while ( p_bit_stream->p_data->p_payload_start ==
199               p_bit_stream->p_data->p_payload_end );
200
201     return( b_new_pes );
202 }
203
204 vlc_bool_t NextDataPacket( decoder_fifo_t * p_fifo,
205                            bit_stream_t * p_bit_stream )
206 {
207     return( _NextDataPacket( p_fifo, p_bit_stream ) );
208 }
209
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 )
215 {
216     decoder_fifo_t *    p_fifo = p_bit_stream->p_decoder_fifo;
217     vlc_bool_t          b_new_pes;
218
219     b_new_pes = _NextDataPacket( p_fifo, p_bit_stream );
220     if( !p_bit_stream->p_pes ) return;
221
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;
225
226     /* Call back the decoder. */
227     if( p_bit_stream->pf_bitstream_callback != NULL )
228     {
229         p_bit_stream->pf_bitstream_callback( p_bit_stream, b_new_pes );
230     }
231
232     /* Discontinuity management. */
233     if( p_bit_stream->p_data->b_discard_payload )
234     {
235         p_bit_stream->i_pts = p_bit_stream->i_dts = 0;
236     }
237
238     /* Retrieve the PTS. */
239     if( b_new_pes && p_bit_stream->p_pes->i_pts )
240     {
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;
244     }
245 }
246
247 void BitstreamNextDataPacket( bit_stream_t * p_bit_stream )
248 {
249     _BitstreamNextDataPacket( p_bit_stream );
250 }
251
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 )
257 {
258     /* We just fill in the bit buffer. */
259     while( (unsigned int)p_bit_stream->fifo.i_available < i_bits )
260     {
261         if( p_bit_stream->p_byte < p_bit_stream->p_end )
262         {
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;
267         }
268         else
269         {
270             _BitstreamNextDataPacket( p_bit_stream );
271             if( p_bit_stream->p_decoder_fifo->b_die ) return 0;
272
273             if( (ptrdiff_t)p_bit_stream->p_byte & (sizeof(WORD_TYPE) - 1) )
274             {
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 )
279                 {
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
282                      * later. */
283                     int     i;
284
285                     /* sizeof(WORD_TYPE) - number of bytes to trash
286                      * from the last payload */
287                     int     j;
288
289                     p_bit_stream->i_showbits_buffer = 0;
290
291                     for( j = i = 0 ; i < (int)sizeof(WORD_TYPE) ; i++ )
292                     {
293                         if( p_bit_stream->p_byte >= p_bit_stream->p_end )
294                         {
295                             j = i;
296                             _BitstreamNextDataPacket( p_bit_stream );
297                             if( p_bit_stream->p_decoder_fifo->b_die ) return 0;
298                         }
299                         ((byte_t *)&p_bit_stream->i_showbits_buffer)[i] =
300                             * p_bit_stream->p_byte;
301                         p_bit_stream->p_byte++;
302                     }
303
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
311                             + sizeof(WORD_TYPE);
312                     p_bit_stream->showbits_data.p_next = p_bit_stream->p_data;
313                     p_bit_stream->p_data = &p_bit_stream->showbits_data;
314                 }
315                 else
316                 {
317                     /* We are not aligned, but we can be. */
318                     AlignWord( p_bit_stream );
319                 }
320             }
321
322             /* We have 32 bits ready for reading, it will be enough. */
323             break;
324         }
325     }
326
327     /* It shouldn't loop :-)) */
328     return( ShowBits( p_bit_stream, i_bits ) );
329 }
330
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
334  * boundary
335  *****************************************************************************/
336 u32 UnalignedGetBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
337 {
338     u32         i_result;
339
340     i_result = p_bit_stream->fifo.buffer
341                     >> (8 * sizeof(WORD_TYPE) - i_bits);
342     i_bits = -p_bit_stream->fifo.i_available;
343
344     /* Gather missing bytes. */
345     while( i_bits >= 8 )
346     {
347         if( p_bit_stream->p_byte < p_bit_stream->p_end )
348         {
349             i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
350             i_bits -= 8;
351         }
352         else
353         {
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);
357             i_bits -= 8;
358         }
359     }
360
361     /* Gather missing bits. */
362     if( i_bits > 0 )
363     {
364         unsigned int    i_tmp = 8 - i_bits;
365
366         if( p_bit_stream->p_byte < p_bit_stream->p_end )
367         {
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;
372         }
373         else
374         {
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;
381         }
382     }
383     else
384     {
385         p_bit_stream->fifo.i_available = 0;
386         p_bit_stream->fifo.buffer = 0;
387     }
388
389     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
390     {
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 );
397     }
398
399     return( i_result );
400 }
401
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 )
407 {
408     /* First remove all unnecessary bytes. */
409     while( p_bit_stream->fifo.i_available <= -8 )
410     {
411         if( p_bit_stream->p_byte < p_bit_stream->p_end )
412         {
413             p_bit_stream->p_byte++;
414             p_bit_stream->fifo.i_available += 8;
415         }
416         else
417         {
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;
422         }
423     }
424
425     /* Remove unnecessary bits. */
426     if( p_bit_stream->fifo.i_available < 0 )
427     {
428         if( p_bit_stream->p_byte < p_bit_stream->p_end )
429         {
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;
434         }
435         else
436         {
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;
443         }
444     }
445     else
446     {
447         p_bit_stream->fifo.buffer = 0;
448     }
449
450     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
451     {
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 );
458     }
459 }
460
461 /*****************************************************************************
462  * CurrentPTS: returns the current PTS and DTS
463  *****************************************************************************/
464 void CurrentPTS( bit_stream_t * p_bit_stream, mtime_t * pi_pts,
465                  mtime_t * pi_dts )
466 {
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 */ )
473     {
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;
478     }
479     else
480     {
481         *pi_pts = 0;
482         if( pi_dts != NULL) *pi_dts = 0;
483     }
484 }
485
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,
490               mtime_t * pi_dts )
491 {
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 */ )
498     {
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;
503     }
504     else
505     {
506         *pi_pts = 0;
507         if( pi_dts != NULL) *pi_dts = 0;
508     }
509 }