]> git.sesse.net Git - vlc/blob - src/input/input_ext-dec.c
* ALL: New ogg demux and vorbis codec modules for preliminary support of
[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.36 2002/10/23 23:17:44 gbazin 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 #include <sys/types.h>                                              /* off_t */
29
30 #include <vlc/vlc.h>
31
32 #include "stream_control.h"
33 #include "input_ext-dec.h"
34 #include "input_ext-intf.h"
35 #include "input_ext-plugins.h"
36
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 )
43 {
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;
47
48     /* Get the first data packet. */
49     vlc_mutex_lock( &p_fifo->data_lock );
50     while ( p_fifo->p_first == NULL )
51     {
52         if ( p_fifo->b_die )
53         {
54             vlc_mutex_unlock( &p_fifo->data_lock );
55             return;
56         }
57         vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
58     }
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 );
68
69     /* Call back the decoder. */
70     if( p_bit_stream->pf_bitstream_callback != NULL )
71     {
72         p_bit_stream->pf_bitstream_callback( p_bit_stream, 1 );
73     }
74
75     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
76     {
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 );
82     }
83 }
84
85 /*****************************************************************************
86  * DecoderError : an error occured, use this function to empty the fifo
87  *****************************************************************************/
88 void DecoderError( decoder_fifo_t * p_fifo )
89 {
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);
93
94     /* Wait until a `die' order is sent */
95     while (!p_fifo->b_die)
96     {
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;
101
102         /* If the input is waiting for us, tell him to stop */
103         vlc_cond_signal( &p_fifo->data_wait );
104
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);
107     }
108
109     /* We can release the lock before leaving */
110     vlc_mutex_unlock (&p_fifo->data_lock);
111 }
112
113 /*****************************************************************************
114  * GetPES: return the first PES from the fifo
115  *****************************************************************************/
116 static inline pes_packet_t *_GetPES( decoder_fifo_t * p_fifo )
117 {
118     pes_packet_t * p_pes;
119
120     vlc_mutex_lock( &p_fifo->data_lock );
121
122     if( p_fifo->p_first == NULL )
123     {
124         /* No PES in the FIFO. p_last is no longer valid. */
125         p_fifo->pp_last = &p_fifo->p_first;
126
127         if( p_fifo->b_die )
128         {
129             vlc_mutex_unlock( &p_fifo->data_lock );
130             return NULL;
131         }
132
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
135          * harm. */
136         vlc_cond_signal( &p_fifo->data_wait );
137
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 );
140     }
141
142     p_pes = p_fifo->p_first;
143
144     vlc_mutex_unlock( &p_fifo->data_lock );
145
146     return p_pes;
147 }
148
149 pes_packet_t * GetPES( decoder_fifo_t * p_fifo )
150 {
151     return( _GetPES( p_fifo ) );
152 }
153
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 )
158 {
159     pes_packet_t * p_next;
160
161     vlc_mutex_lock( &p_fifo->data_lock );
162
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;
168     p_fifo->i_depth--;
169
170     vlc_mutex_unlock( &p_fifo->data_lock );
171
172     return _GetPES( p_fifo );
173 }
174
175 pes_packet_t * NextPES( decoder_fifo_t * p_fifo )
176 {
177     return( _NextPES( p_fifo ) );
178 }
179
180 /*****************************************************************************
181  * NextDataPacket: go to the data packet after *pp_data, return 1 if we
182  * changed PES
183  *****************************************************************************/
184 static inline vlc_bool_t _NextDataPacket( decoder_fifo_t * p_fifo,
185                                           data_packet_t ** pp_data )
186 {
187     vlc_bool_t b_new_pes;
188
189     /* We are looking for the next data packet that contains real data,
190      * and not just a PES header */
191     do
192     {
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 )
196         {
197             /* The next packet could be found in the next PES packet */
198             *pp_data = (_NextPES( p_fifo ))->p_first;
199
200             b_new_pes = 1;
201         }
202         else
203         {
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;
207
208             b_new_pes = 0;
209         }
210     } while ( (*pp_data)->p_payload_start == (*pp_data)->p_payload_end );
211
212     return( b_new_pes );
213 }
214
215 vlc_bool_t NextDataPacket( decoder_fifo_t * p_fifo, data_packet_t ** pp_data )
216 {
217     return( _NextDataPacket( p_fifo, pp_data ) );
218 }
219
220 /*****************************************************************************
221  * BitstreamNextDataPacket: go to the next data packet, and update bitstream
222  * context
223  *****************************************************************************/
224 static inline void _BitstreamNextDataPacket( bit_stream_t * p_bit_stream )
225 {
226     decoder_fifo_t *    p_fifo = p_bit_stream->p_decoder_fifo;
227     vlc_bool_t          b_new_pes;
228
229     b_new_pes = _NextDataPacket( p_fifo, &p_bit_stream->p_data );
230
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;
234
235     /* Call back the decoder. */
236     if( p_bit_stream->pf_bitstream_callback != NULL )
237     {
238         p_bit_stream->pf_bitstream_callback( p_bit_stream, b_new_pes );
239     }
240
241     /* Discontinuity management. */
242     if( p_bit_stream->p_data->b_discard_payload )
243     {
244         p_bit_stream->i_pts = p_bit_stream->i_dts = 0;
245     }
246
247     /* Retrieve the PTS. */
248     if( b_new_pes && p_fifo->p_first->i_pts )
249     {
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;
253     }
254 }
255
256 void BitstreamNextDataPacket( bit_stream_t * p_bit_stream )
257 {
258     _BitstreamNextDataPacket( p_bit_stream );
259 }
260
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 )
266 {
267     /* We just fill in the bit buffer. */
268     while( p_bit_stream->fifo.i_available < i_bits )
269     {
270         if( p_bit_stream->p_byte < p_bit_stream->p_end )
271         {
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;
276         }
277         else
278         {
279             _BitstreamNextDataPacket( p_bit_stream );
280
281             if( (ptrdiff_t)p_bit_stream->p_byte & (sizeof(WORD_TYPE) - 1) )
282             {
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 )
287                 {
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
290                      * later. */
291                     int     i;
292
293                     /* sizeof(WORD_TYPE) - number of bytes to trash
294                      * from the last payload */
295                     int     j;
296
297                     p_bit_stream->i_showbits_buffer = 0;
298
299                     for( j = i = 0 ; i < sizeof(WORD_TYPE) ; i++ )
300                     {
301                         if( p_bit_stream->p_byte >= p_bit_stream->p_end )
302                         {
303                             j = i;
304                             _BitstreamNextDataPacket( p_bit_stream );
305                         }
306                         ((byte_t *)&p_bit_stream->i_showbits_buffer)[i] =
307                             * p_bit_stream->p_byte;
308                         p_bit_stream->p_byte++;
309                     }
310
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
318                             + sizeof(WORD_TYPE);
319                     p_bit_stream->showbits_data.p_next = p_bit_stream->p_data;
320                     p_bit_stream->p_data = &p_bit_stream->showbits_data;
321                 }
322                 else
323                 {
324                     /* We are not aligned, but we can be. */
325                     AlignWord( p_bit_stream );
326                 }
327             }
328
329             /* We have 32 bits ready for reading, it will be enough. */
330             break;
331         }
332     }
333
334     /* It shouldn't loop :-)) */
335     return( ShowBits( p_bit_stream, i_bits ) );
336 }
337
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
341  * boundary
342  *****************************************************************************/
343 u32 UnalignedGetBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
344 {
345     u32         i_result;
346
347     i_result = p_bit_stream->fifo.buffer
348                     >> (8 * sizeof(WORD_TYPE) - i_bits);
349     i_bits = -p_bit_stream->fifo.i_available;
350
351     /* Gather missing bytes. */
352     while( i_bits >= 8 )
353     {
354         if( p_bit_stream->p_byte < p_bit_stream->p_end )
355         {
356             i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
357             i_bits -= 8;
358         }
359         else
360         {
361             _BitstreamNextDataPacket( p_bit_stream );
362             i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
363             i_bits -= 8;
364         }
365     }
366
367     /* Gather missing bits. */
368     if( i_bits > 0 )
369     {
370         unsigned int    i_tmp = 8 - i_bits;
371
372         if( p_bit_stream->p_byte < p_bit_stream->p_end )
373         {
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;
378         }
379         else
380         {
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;
386         }
387     }
388     else
389     {
390         p_bit_stream->fifo.i_available = 0;
391         p_bit_stream->fifo.buffer = 0;
392     }
393
394     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
395     {
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 );
402     }
403
404     return( i_result );
405 }
406
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 )
412 {
413     /* First remove all unnecessary bytes. */
414     while( p_bit_stream->fifo.i_available <= -8 )
415     {
416         if( p_bit_stream->p_byte < p_bit_stream->p_end )
417         {
418             p_bit_stream->p_byte++;
419             p_bit_stream->fifo.i_available += 8;
420         }
421         else
422         {
423             _BitstreamNextDataPacket( p_bit_stream );
424             p_bit_stream->p_byte++;
425             p_bit_stream->fifo.i_available += 8;
426         }
427     }
428
429     /* Remove unnecessary bits. */
430     if( p_bit_stream->fifo.i_available < 0 )
431     {
432         if( p_bit_stream->p_byte < p_bit_stream->p_end )
433         {
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;
438         }
439         else
440         {
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;
446         }
447     }
448     else
449     {
450         p_bit_stream->fifo.buffer = 0;
451     }
452
453     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
454     {
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 );
461     }
462 }
463
464 /*****************************************************************************
465  * CurrentPTS: returns the current PTS and DTS
466  *****************************************************************************/
467 void CurrentPTS( bit_stream_t * p_bit_stream, mtime_t * pi_pts,
468                  mtime_t * pi_dts )
469 {
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 */ )
476     {
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;
481     }
482     else
483     {
484         *pi_pts = 0;
485         if( pi_dts != NULL) *pi_dts = 0;
486     }
487 }
488
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,
493               mtime_t * pi_dts )
494 {
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 */ )
501     {
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;
506     }
507     else
508     {
509         *pi_pts = 0;
510         if( pi_dts != NULL) *pi_dts = 0;
511     }
512 }
513
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 )
519 {
520     pes_packet_t *p_pes, *p_next;
521
522     vlc_mutex_lock( &p_fifo->data_lock );
523
524     /* if fifo is emty wait */
525     while( !p_fifo->p_first )
526     {
527         if( p_fifo->b_die )
528         {
529             vlc_mutex_unlock( &p_fifo->data_lock );
530             if( pp_pes )
531             {
532                 *pp_pes = NULL;
533             }
534             return( -1 );
535         }
536         vlc_cond_signal( &p_fifo->data_wait );
537         vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
538     }
539     p_pes = p_fifo->p_first;
540
541     p_next = p_pes->p_next;
542     p_pes->p_next = NULL;
543
544
545     p_fifo->p_first = p_next;
546     p_fifo->i_depth--;
547
548     if( !p_fifo->p_first )
549     {
550         /* No PES in the fifo */
551         /* pp_last no longer valid */
552         p_fifo->pp_last = &p_fifo->p_first;
553     }
554     vlc_mutex_unlock( &p_fifo->data_lock );
555
556     if( pp_pes )
557     {
558         *pp_pes = p_pes;
559     }
560     else
561     {
562         input_DeletePES( p_fifo->p_packets_mgt, p_pes );
563     }
564     return( 0 );
565 }
566