]> git.sesse.net Git - vlc/blob - modules/packetizer/mpeg4audio.c
* include/vlc_block_helper.h: fixed an idiotically stupid bug in block_PeekOffsetBytes().
[vlc] / modules / packetizer / mpeg4audio.c
1 /*****************************************************************************
2  * mpeg4audio.c: parse and packetize an MPEG 4 audio stream
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id: mpeg4audio.c,v 1.10 2003/10/23 20:51:20 gbazin Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *          Gildas Bazin <gbazin@netcourrier.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include <stdlib.h>                                      /* malloc(), free() */
29 #include <string.h>                                              /* strdup() */
30
31 #include <vlc/vlc.h>
32 #include <vlc/aout.h>
33 #include <vlc/decoder.h>
34 #include <vlc/input.h>
35 #include <vlc/sout.h>
36 #include "codecs.h"
37
38 #include "vlc_block_helper.h"
39
40 /* AAC Config in ES:
41  *
42  * AudioObjectType          5 bits
43  * samplingFrequencyIndex   4 bits
44  * if (samplingFrequencyIndex == 0xF)
45  *  samplingFrequency   24 bits
46  * channelConfiguration     4 bits
47  * GA_SpecificConfig
48  *  FrameLengthFlag         1 bit 1024 or 960
49  *  DependsOnCoreCoder      1 bit (always 0)
50  *  ExtensionFlag           1 bit (always 0)
51  */
52
53 /*****************************************************************************
54  * decoder_sys_t : decoder descriptor
55  *****************************************************************************/
56 struct decoder_sys_t
57 {
58     /*
59      * Input properties
60      */
61     int        i_state;
62
63     block_t *p_chain;
64     block_bytestream_t bytestream;
65
66     /*
67      * Packetizer output properties
68      */
69     sout_packetizer_input_t *p_sout_input;
70     sout_format_t           sout_format;
71     sout_buffer_t *         p_sout_buffer;            /* current sout buffer */
72
73     /*
74      * Common properties
75      */
76     audio_date_t          end_date;
77     mtime_t pts;
78
79     int i_frame_size, i_raw_blocks;
80     unsigned int i_channels;
81     unsigned int i_rate, i_frame_length;
82 };
83
84 enum {
85
86     STATE_NOSYNC,
87     STATE_SYNC,
88     STATE_HEADER,
89     STATE_NEXT_SYNC,
90     STATE_DATA
91 };
92
93 static int i_sample_rates[] = 
94 {
95     96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 
96     16000, 12000, 11025, 8000,  7350,  0,     0,     0
97 };
98
99 #define ADTS_HEADER_SIZE 6
100
101 /****************************************************************************
102  * Local prototypes
103  ****************************************************************************/
104 static int OpenPacketizer( vlc_object_t * );
105 static int InitPacketizer( decoder_t * );
106 static int RunFramePacketizer ( decoder_t *, block_t * );
107 static int RunADTSPacketizer ( decoder_t *, block_t * );
108 static int EndPacketizer ( decoder_t * );
109 static int GetSoutBuffer( decoder_t *, sout_buffer_t ** );
110
111 static int ADTSSyncInfo( decoder_t *, const byte_t * p_buf,
112                          unsigned int * pi_channels,
113                          unsigned int * pi_sample_rate,
114                          unsigned int * pi_frame_length,
115                          unsigned int * pi_raw_blocks );
116
117 /*****************************************************************************
118  * Module descriptor
119  *****************************************************************************/
120 vlc_module_begin();
121     set_description( _("MPEG4 Audio packetizer") );
122     set_capability( "packetizer", 50 );
123     set_callbacks( OpenPacketizer, NULL );
124 vlc_module_end();
125
126 /*****************************************************************************
127  * OpenPacketizer: probe the packetizer and return score
128  *****************************************************************************/
129 static int OpenPacketizer( vlc_object_t *p_this )
130 {
131     decoder_t *p_dec = (decoder_t*)p_this;
132
133     if( p_dec->p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', '4', 'a' ) )
134     {
135         return VLC_EGENERIC;
136     }
137
138     /* Allocate the memory needed to store the decoder's structure */
139     if( ( p_dec->p_sys =
140           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
141     {
142         msg_Err( p_dec, "out of memory" );
143         return VLC_EGENERIC;
144     }
145
146     p_dec->pf_init = InitPacketizer;
147     p_dec->pf_decode = RunFramePacketizer;
148     p_dec->pf_end = EndPacketizer;
149
150     return VLC_SUCCESS;
151 }
152
153 /*****************************************************************************
154  * InitPacketizer: Initalize the packetizer
155  *****************************************************************************/
156 static int InitPacketizer( decoder_t *p_dec )
157 {
158     decoder_sys_t *p_sys = p_dec->p_sys;
159     WAVEFORMATEX *p_wf;
160
161     p_sys->i_state = STATE_NOSYNC;
162
163     aout_DateSet( &p_sys->end_date, 0 );
164
165     p_sys->p_sout_input = NULL;
166     p_sys->p_sout_buffer = NULL;
167     p_sys->p_chain = NULL;
168
169     msg_Info( p_dec, "Running MPEG4 audio packetizer" );
170
171     p_wf = (WAVEFORMATEX*)p_dec->p_fifo->p_waveformatex;
172
173     if( p_wf && p_wf->cbSize > 0)
174     {
175         uint8_t *p_config = (uint8_t*)&p_wf[1];
176         int     i_index;
177
178         i_index = ( ( p_config[0] << 1 ) | ( p_config[1] >> 7 ) ) & 0x0f;
179         if( i_index != 0x0f )
180         {
181             p_sys->i_rate = i_sample_rates[i_index];
182             p_sys->i_frame_length = (( p_config[1] >> 2 ) & 0x01) ? 960 : 1024;
183         }
184         else
185         {
186             p_sys->i_rate = ( ( p_config[1] & 0x7f ) << 17 ) |
187                 ( p_config[2] << 9 ) | ( p_config[3] << 1 ) |
188                 ( p_config[4] >> 7 );
189             p_sys->i_frame_length = (( p_config[4] >> 2 ) & 0x01) ? 960 : 1024;
190         }
191
192         msg_Dbg( p_dec, "AAC %dHz %d samples/frame",
193                  p_sys->i_rate, p_sys->i_frame_length );
194
195         p_sys->i_channels = p_wf->nChannels;
196         p_sys->sout_format.i_extra_data = p_wf->cbSize;
197         p_sys->sout_format.p_extra_data = malloc( p_wf->cbSize );
198         memcpy( p_sys->sout_format.p_extra_data, &p_wf[1], p_wf->cbSize );
199     }
200     else
201     {
202         msg_Dbg( p_dec, "No decoder specific info, must be an ADTS stream" );
203
204         /* We will try to create a AAC Config from adts */
205         p_sys->sout_format.i_extra_data = 0;
206         p_sys->sout_format.p_extra_data = NULL;
207         p_dec->pf_decode = RunADTSPacketizer;
208     }
209
210     return VLC_SUCCESS;
211 }
212
213 /****************************************************************************
214  * RunFramePacketizer: the whole thing
215  ****************************************************************************
216  * This function must be fed with complete frames.
217  ****************************************************************************/
218 static int RunFramePacketizer( decoder_t *p_dec, block_t *p_block )
219 {
220     decoder_sys_t *p_sys = p_dec->p_sys;
221
222     if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
223     {
224         /* We've just started the stream, wait for the first PTS. */
225         block_Release( p_block );
226         return VLC_SUCCESS;
227     }
228
229     p_sys->pts = p_block->i_pts;
230     p_sys->i_frame_size = p_block->i_buffer;
231
232     if( GetSoutBuffer( p_dec, &p_sys->p_sout_buffer ) != VLC_SUCCESS )
233     {
234         return VLC_EGENERIC;
235     }
236
237     /* Copy the whole frame into the buffer */
238     p_dec->p_vlc->pf_memcpy( p_sys->p_sout_buffer->p_buffer,
239                              p_block->p_buffer, p_block->i_buffer );
240
241     sout_InputSendBuffer( p_sys->p_sout_input, p_sys->p_sout_buffer );
242     p_sys->p_sout_buffer = NULL;
243
244     block_Release( p_block );
245     return VLC_SUCCESS;
246 }
247
248 /****************************************************************************
249  * RunADTSPacketizer: the whole thing
250  ****************************************************************************/
251 static int RunADTSPacketizer( decoder_t *p_dec, block_t *p_block )
252 {
253     decoder_sys_t *p_sys = p_dec->p_sys;
254     uint8_t p_header[ADTS_HEADER_SIZE];
255
256     if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
257     {
258         /* We've just started the stream, wait for the first PTS. */
259         block_Release( p_block );
260         return VLC_SUCCESS;
261     }
262
263     if( p_block->b_discontinuity )
264     {
265         p_sys->i_state = STATE_SYNC;
266     }
267
268     if( p_sys->p_chain )
269     {
270         block_ChainAppend( &p_sys->p_chain, p_block );
271     }
272     else
273     {
274         block_ChainAppend( &p_sys->p_chain, p_block );
275         p_sys->bytestream = block_BytestreamInit( p_dec, p_sys->p_chain, 0 );
276     }
277
278     while( 1 )
279     {
280         switch( p_sys->i_state )
281         {
282
283         case STATE_NOSYNC:
284             while( block_PeekBytes( &p_sys->bytestream, p_header, 2 )
285                    == VLC_SUCCESS )
286             {
287                 /* Look for sync word - should be 0xfff + 2 layer bits */
288                 if( p_header[0] == 0xff && (p_header[1] & 0xf6) == 0xf0 )
289                 {
290                     p_sys->i_state = STATE_SYNC;
291                     break;
292                 }
293                 block_SkipByte( &p_sys->bytestream );
294             }
295             if( p_sys->i_state != STATE_SYNC )
296             {
297                 if( block_PeekByte( &p_sys->bytestream, p_header )
298                     == VLC_SUCCESS && p_header[0] == 0xff )
299                 {
300                     /* Start of a sync word, need more data */
301                     return VLC_SUCCESS;
302                 }
303
304                 block_ChainRelease( p_sys->p_chain );
305                 p_sys->p_chain = NULL;
306
307                 /* Need more data */
308                 return VLC_SUCCESS;
309             }
310
311         case STATE_SYNC:
312             /* New frame, set the Presentation Time Stamp */
313             p_sys->pts = p_sys->bytestream.p_block->i_pts;
314             if( p_sys->pts != 0 &&
315                 p_sys->pts != aout_DateGet( &p_sys->end_date ) )
316             {
317                 aout_DateSet( &p_sys->end_date, p_sys->pts );
318             }
319             p_sys->i_state = STATE_HEADER;
320             break;
321
322         case STATE_HEADER:
323             /* Get ADTS frame header (ADTS_HEADER_SIZE bytes) */
324             if( block_PeekBytes( &p_sys->bytestream, p_header,
325                                  ADTS_HEADER_SIZE ) != VLC_SUCCESS )
326             {
327                 /* Need more data */
328                 return VLC_SUCCESS;
329             }
330
331             /* Check if frame is valid and get frame info */
332             p_sys->i_frame_size = ADTSSyncInfo( p_dec, p_header,
333                                                 &p_sys->i_channels,
334                                                 &p_sys->i_rate,
335                                                 &p_sys->i_frame_length,
336                                                 &p_sys->i_raw_blocks );
337             if( !p_sys->i_frame_size )
338             {
339                 msg_Dbg( p_dec, "emulated sync word" );
340                 block_SkipByte( &p_sys->bytestream );
341                 p_sys->i_state = STATE_NOSYNC;
342                 break;
343             }
344
345             p_sys->i_state = STATE_DATA;
346
347         case STATE_DATA:
348             /* TODO: If p_block == NULL, flush the buffer without checking the
349              * next sync word */
350
351             /* Check if next expected frame contains the sync word */
352             if( block_PeekOffsetBytes( &p_sys->bytestream,
353                                        p_sys->i_frame_size, p_header, 2 )
354                 != VLC_SUCCESS )
355             {
356                 /* Need more data */
357                 return VLC_SUCCESS;
358             }
359
360             if( p_header[0] != 0xff || (p_header[1] & 0xf6) != 0xf0 )
361             {
362                 msg_Dbg( p_dec, "emulated sync word "
363                          "(no sync on following frame)" );
364                 p_sys->i_state = STATE_NOSYNC;
365                 block_SkipByte( &p_sys->bytestream );
366                 break;
367             }
368
369             if( !p_sys->p_sout_buffer )
370             if( GetSoutBuffer( p_dec, &p_sys->p_sout_buffer ) != VLC_SUCCESS )
371             {
372                 return VLC_EGENERIC;
373             }
374
375             /* Copy the whole frame into the buffer */
376             if( block_GetBytes( &p_sys->bytestream,
377                                 p_sys->p_sout_buffer->p_buffer,
378                                 p_sys->i_frame_size ) != VLC_SUCCESS )
379             {
380                 /* Need more data */
381                 return VLC_SUCCESS;
382             }
383
384             p_sys->p_chain = block_BytestreamFlush( &p_sys->bytestream );
385
386             sout_InputSendBuffer( p_sys->p_sout_input, p_sys->p_sout_buffer );
387
388             p_sys->i_state = STATE_NOSYNC;
389             p_sys->p_sout_buffer = NULL;
390
391             /* Make sure we don't reuse the same pts twice */
392             if( p_sys->pts == p_sys->bytestream.p_block->i_pts )
393                 p_sys->pts = p_sys->bytestream.p_block->i_pts = 0;
394         }
395     }
396
397     return VLC_SUCCESS;
398 }
399
400 /*****************************************************************************
401  * GetSoutBuffer:
402  *****************************************************************************/
403 static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer )
404 {
405     decoder_sys_t *p_sys = p_dec->p_sys;
406
407     if( p_sys->p_sout_input != NULL &&
408         ( p_sys->sout_format.i_sample_rate != (int)p_sys->i_rate
409           || p_sys->sout_format.i_channels != (int)p_sys->i_channels ) )
410     {
411         /* Parameters changed - this should not happen. */
412     }
413
414     /* Creating the sout input if not created yet. */
415     if( p_sys->p_sout_input == NULL )
416     {
417         p_sys->sout_format.i_cat = AUDIO_ES;
418         p_sys->sout_format.i_fourcc = VLC_FOURCC( 'm', 'p', '4', 'a' );
419         p_sys->sout_format.i_sample_rate = p_sys->i_rate;
420         p_sys->sout_format.i_channels    = p_sys->i_channels;
421         p_sys->sout_format.i_block_align = 0;
422         p_sys->sout_format.i_bitrate     = 0;
423
424         aout_DateInit( &p_sys->end_date, p_sys->i_rate );
425         aout_DateSet( &p_sys->end_date, p_sys->pts );
426
427         p_sys->p_sout_input = sout_InputNew( p_dec, &p_sys->sout_format );
428         if( p_sys->p_sout_input == NULL )
429         {
430             msg_Err( p_dec, "cannot add a new stream" );
431             *pp_buffer = NULL;
432             return VLC_EGENERIC;
433         }
434         msg_Info( p_dec, "AAC channels: %d samplerate: %d",
435                   p_sys->i_channels, p_sys->i_rate );
436     }
437
438     *pp_buffer = sout_BufferNew( p_sys->p_sout_input->p_sout,
439                                  p_sys->i_frame_size );
440     if( *pp_buffer == NULL )
441     {
442         return VLC_EGENERIC;
443     }
444
445     (*pp_buffer)->i_pts =
446         (*pp_buffer)->i_dts = aout_DateGet( &p_sys->end_date );
447
448     (*pp_buffer)->i_length =
449         aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length )
450         - (*pp_buffer)->i_pts;
451
452     return VLC_SUCCESS;
453 }
454
455 /*****************************************************************************
456  * EndPacketizer: clean up the packetizer
457  *****************************************************************************/
458 static int EndPacketizer( decoder_t *p_dec )
459 {
460     if( p_dec->p_sys->p_sout_input != NULL )
461     {
462         if( p_dec->p_sys->p_sout_buffer )
463         {
464             sout_BufferDelete( p_dec->p_sys->p_sout_input->p_sout,
465                                p_dec->p_sys->p_sout_buffer );
466         }
467
468         sout_InputDelete( p_dec->p_sys->p_sout_input );
469     }
470
471     if( p_dec->p_sys->p_chain ) block_ChainRelease( p_dec->p_sys->p_chain );
472
473     free( p_dec->p_sys );
474
475     return VLC_SUCCESS;
476 }
477
478 /*****************************************************************************
479  * ADTSSyncInfo: parse MPEG 4 audio ADTS sync info
480  *****************************************************************************/
481 static int ADTSSyncInfo( decoder_t * p_dec, const byte_t * p_buf,
482                          unsigned int * pi_channels,
483                          unsigned int * pi_sample_rate,
484                          unsigned int * pi_frame_length,
485                          unsigned int * pi_raw_blocks_in_frame )
486 {
487     decoder_sys_t *p_sys = p_dec->p_sys;
488     int i_id, i_profile, i_sample_rate_idx, i_frame_size;
489
490     /* Fixed header between frames */
491     i_id = ( (p_buf[1] >> 3) & 0x01 ) ? 2 : 4;
492     i_profile = p_buf[2] >> 6;
493     i_sample_rate_idx = (p_buf[2] >> 2) & 0x0f;
494     *pi_sample_rate = i_sample_rates[i_sample_rate_idx];
495     *pi_channels = ((p_buf[2] & 0x01) << 2) | ((p_buf[3] >> 6) & 0x03);
496
497     /* Variable header */
498     i_frame_size = ((p_buf[3] & 0x03) << 11) | (p_buf[4] << 3) |
499                    ((p_buf[5] >> 5) & 0x7);
500     *pi_raw_blocks_in_frame = (p_buf[6] & 0x02) + 1;
501
502     if( !*pi_sample_rate || !*pi_channels || !i_frame_size )
503     {
504         return 0;
505     }
506
507     /* Fixme */
508     *pi_frame_length = 1024;
509
510     /* Build the decoder specific info header */
511     if( !p_dec->p_sys->sout_format.i_extra_data )
512     {
513         p_sys->sout_format.i_extra_data = 2;
514         p_sys->sout_format.p_extra_data = malloc( 2 );
515         p_sys->sout_format.p_extra_data[0] =
516             (i_profile + 1) << 3 | (i_sample_rate_idx > 1);
517         p_sys->sout_format.p_extra_data[1] =
518             ((i_sample_rate_idx & 0x01) << 7) | (*pi_channels <<3);
519     }
520
521     return i_frame_size;
522 }