]> git.sesse.net Git - vlc/blob - src/input/input_ext-dec.c
* Removed dead code.
[vlc] / src / input / input_ext-dec.c
1 /*****************************************************************************
2  * input_ext-dec.c: services to the decoders
3  *****************************************************************************
4  * Copyright (C) 1998, 1999, 2000 VideoLAN
5  *
6  * Authors: 
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  * 
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
21  *****************************************************************************/
22
23 /*****************************************************************************
24  * Preamble
25  *****************************************************************************/
26 #include "defs.h"
27
28 #include "config.h"
29 #include "common.h"
30 #include "threads.h"
31 #include "mtime.h"
32
33 #include "intf_msg.h"
34
35 #include "stream_control.h"
36 #include "input_ext-dec.h"
37 #include "input_ext-intf.h"
38
39 #include "input.h"
40
41 /*****************************************************************************
42  * InitBitstream: initialize a bit_stream_t structure
43  *****************************************************************************/
44 void InitBitstream( bit_stream_t * p_bit_stream, decoder_fifo_t * p_fifo )
45 {
46     p_bit_stream->p_decoder_fifo = p_fifo;
47     p_bit_stream->pf_next_data_packet = NextDataPacket;
48     p_bit_stream->pf_bitstream_callback = NULL;
49     p_bit_stream->p_callback_arg = NULL;
50
51     /* Get the first data packet. */
52     vlc_mutex_lock( &p_fifo->data_lock );
53     while ( DECODER_FIFO_ISEMPTY( *p_fifo ) )
54     {
55         if ( p_fifo->b_die )
56         {
57             vlc_mutex_unlock( &p_fifo->data_lock );
58             return;
59         }
60         vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
61     }
62     p_bit_stream->p_data = DECODER_FIFO_START( *p_fifo )->p_first;
63     p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
64     p_bit_stream->p_end  = p_bit_stream->p_data->p_payload_end;
65     p_bit_stream->fifo.buffer = 0;
66     p_bit_stream->fifo.i_available = 0;
67     vlc_mutex_unlock( &p_fifo->data_lock );
68 }
69
70 /*****************************************************************************
71  * NextDataPacket: go to the next data packet
72  *****************************************************************************/
73 void NextDataPacket( bit_stream_t * p_bit_stream )
74 {
75     decoder_fifo_t *    p_fifo = p_bit_stream->p_decoder_fifo;
76     boolean_t           b_new_pes;
77
78     /* We are looking for the next data packet that contains real data,
79      * and not just a PES header */
80     do
81     {
82         /* We were reading the last data packet of this PES packet... It's
83          * time to jump to the next PES packet */
84         if( p_bit_stream->p_data->p_next == NULL )
85         {
86             /* We are going to read/write the start and end indexes of the
87              * decoder fifo and to use the fifo's conditional variable,
88              * that's why we need to take the lock before. */
89             vlc_mutex_lock( &p_fifo->data_lock );
90
91             /* Free the previous PES packet. */
92             p_fifo->pf_delete_pes( p_fifo->p_packets_mgt,
93                                    DECODER_FIFO_START( *p_fifo ) );
94             DECODER_FIFO_INCSTART( *p_fifo );
95
96             if( DECODER_FIFO_ISEMPTY( *p_fifo ) )
97             {
98                 /* Wait for the input to tell us when we receive a packet. */
99                 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
100             }
101
102             /* The next byte could be found in the next PES packet */
103             p_bit_stream->p_data = DECODER_FIFO_START( *p_fifo )->p_first;
104
105             vlc_mutex_unlock( &p_fifo->data_lock );
106
107             b_new_pes = 1;
108         }
109         else
110         {
111             /* Perhaps the next data packet of the current PES packet contains
112              * real data (ie its payload's size is greater than 0). */
113             p_bit_stream->p_data = p_bit_stream->p_data->p_next;
114
115             b_new_pes = 0;
116         }
117     } while ( p_bit_stream->p_data->p_payload_start
118                == p_bit_stream->p_data->p_payload_end );
119
120     /* We've found a data packet which contains interesting data... */
121     p_bit_stream->p_byte = p_bit_stream->p_data->p_payload_start;
122     p_bit_stream->p_end  = p_bit_stream->p_data->p_payload_end;
123
124     /* Call back the decoder. */
125     if( p_bit_stream->pf_bitstream_callback != NULL )
126     {
127         p_bit_stream->pf_bitstream_callback( p_bit_stream, b_new_pes );
128     }
129 }
130
131 /*****************************************************************************
132  * UnalignedShowBits : return i_bits bits from the bit stream, even when
133  * not aligned on a word boundary
134  *****************************************************************************/
135 u32 UnalignedShowBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
136 {
137     /* We just fill in the bit buffer. */
138     while( p_bit_stream->fifo.i_available < i_bits )
139     {
140         if( p_bit_stream->p_byte < p_bit_stream->p_end )
141         {
142             p_bit_stream->fifo.buffer |= *(p_bit_stream->p_byte++)
143                                             << (8 * sizeof(WORD_TYPE) - 8
144                                             - p_bit_stream->fifo.i_available);
145             p_bit_stream->fifo.i_available += 8;
146         }
147         else
148         {
149             p_bit_stream->pf_next_data_packet( p_bit_stream );
150             p_bit_stream->fifo.buffer |= *(p_bit_stream->p_byte++)
151                                             << (8 * sizeof(WORD_TYPE) - 8
152                                             - p_bit_stream->fifo.i_available);
153             p_bit_stream->fifo.i_available += 8;
154         }
155     }
156     return( p_bit_stream->fifo.buffer >> (8 * sizeof(WORD_TYPE) - i_bits) );
157 }
158
159 /*****************************************************************************
160  * UnalignedGetBits : returns i_bits bits from the bit stream and removes
161  * them from the buffer, even when the bit stream is not aligned on a word
162  * boundary
163  *****************************************************************************/
164 u32 UnalignedGetBits( bit_stream_t * p_bit_stream, unsigned int i_bits )
165 {
166     u32         i_result;
167
168     i_result = p_bit_stream->fifo.buffer
169                     >> (8 * sizeof(WORD_TYPE) - i_bits);
170     i_bits = -p_bit_stream->fifo.i_available;
171
172     /* Gather missing bytes. */
173     while( i_bits >= 8 )
174     {
175         if( p_bit_stream->p_byte < p_bit_stream->p_end )
176         {
177             i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
178             i_bits -= 8;
179         }
180         else
181         {
182             p_bit_stream->pf_next_data_packet( p_bit_stream );
183             i_result |= *(p_bit_stream->p_byte++) << (i_bits - 8);
184             i_bits -= 8;
185         }
186     }
187
188     /* Gather missing bits. */
189     if( i_bits > 0 )
190     {
191         unsigned int    i_tmp = 8 - i_bits;
192
193         if( p_bit_stream->p_byte < p_bit_stream->p_end )
194         {
195             i_result |= *p_bit_stream->p_byte >> i_tmp;
196             p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
197                  << ( sizeof(WORD_TYPE) * 8 - i_tmp );
198             p_bit_stream->fifo.i_available = i_tmp;
199         }
200         else
201         {
202             p_bit_stream->pf_next_data_packet( p_bit_stream );
203             i_result |= *p_bit_stream->p_byte >> i_tmp;
204             p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
205                  << ( sizeof(WORD_TYPE) * 8 - i_tmp );
206             p_bit_stream->fifo.i_available = i_tmp;
207         }
208     }
209     else
210     {
211         p_bit_stream->fifo.i_available = 0;
212         p_bit_stream->fifo.buffer = 0;
213     }
214
215     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
216     {
217         /* Get aligned on a word boundary. Otherwise it is safer
218          * to do it the next time.
219          * NB : we _will_ get aligned, because we have at most 
220          * sizeof(WORD_TYPE) - 1 bytes to store, and at least
221          * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
222         AlignWord( p_bit_stream );
223     }
224
225     return( i_result );
226 }
227
228 /*****************************************************************************
229  * UnalignedRemoveBits : removes i_bits (== -i_available) from the bit
230  * buffer, even when the bit stream is not aligned on a word boundary
231  *****************************************************************************/
232 void UnalignedRemoveBits( bit_stream_t * p_bit_stream )
233 {
234     /* First remove all unnecessary bytes. */
235     while( p_bit_stream->fifo.i_available <= -8 )
236     {
237         if( p_bit_stream->p_byte < p_bit_stream->p_end )
238         {
239             p_bit_stream->p_byte++;
240             p_bit_stream->fifo.i_available += 8;
241         }
242         else
243         {
244             p_bit_stream->pf_next_data_packet( p_bit_stream );
245             p_bit_stream->p_byte++;
246             p_bit_stream->fifo.i_available += 8;
247         }
248     }
249
250     /* Remove unnecessary bits. */
251     if( p_bit_stream->fifo.i_available < 0 )
252     {
253         if( p_bit_stream->p_byte < p_bit_stream->p_end )
254         {
255             p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
256                  << ( sizeof(WORD_TYPE) * 8 - 8
257                          - p_bit_stream->fifo.i_available );
258             p_bit_stream->fifo.i_available += 8;
259         }
260         else
261         {
262             p_bit_stream->pf_next_data_packet( p_bit_stream );
263             p_bit_stream->fifo.buffer = *(p_bit_stream->p_byte++)
264                  << ( sizeof(WORD_TYPE) * 8 - 8
265                          - p_bit_stream->fifo.i_available );
266             p_bit_stream->fifo.i_available += 8;
267         }
268     }
269     else
270     {
271         p_bit_stream->fifo.buffer = 0;
272     }
273
274     if( p_bit_stream->p_byte <= p_bit_stream->p_end - sizeof(WORD_TYPE) )
275     {
276         /* Get aligned on a word boundary. Otherwise it is safer
277          * to do it the next time.
278          * NB : we _will_ get aligned, because we have at most 
279          * sizeof(WORD_TYPE) - 1 bytes to store, and at least
280          * sizeof(WORD_TYPE) - 1 empty bytes in the bit buffer. */
281         AlignWord( p_bit_stream );
282     }
283 }
284