]> git.sesse.net Git - vlc/blob - modules/packetizer/mpeg4audio.c
* modules/packetizer/mpeg4audio.c: when packetizing adts streams, make sure we remove...
[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.11 2003/10/24 17:55:14 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, i_header_size;
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 9
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_header_size,
116                          unsigned int * pi_raw_blocks );
117
118 /*****************************************************************************
119  * Module descriptor
120  *****************************************************************************/
121 vlc_module_begin();
122     set_description( _("MPEG4 Audio packetizer") );
123     set_capability( "packetizer", 50 );
124     set_callbacks( OpenPacketizer, NULL );
125 vlc_module_end();
126
127 /*****************************************************************************
128  * OpenPacketizer: probe the packetizer and return score
129  *****************************************************************************/
130 static int OpenPacketizer( vlc_object_t *p_this )
131 {
132     decoder_t *p_dec = (decoder_t*)p_this;
133
134     if( p_dec->p_fifo->i_fourcc != VLC_FOURCC( 'm', 'p', '4', 'a' ) )
135     {
136         return VLC_EGENERIC;
137     }
138
139     /* Allocate the memory needed to store the decoder's structure */
140     if( ( p_dec->p_sys =
141           (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
142     {
143         msg_Err( p_dec, "out of memory" );
144         return VLC_EGENERIC;
145     }
146
147     p_dec->pf_init = InitPacketizer;
148     p_dec->pf_decode = RunFramePacketizer;
149     p_dec->pf_end = EndPacketizer;
150
151     return VLC_SUCCESS;
152 }
153
154 /*****************************************************************************
155  * InitPacketizer: Initalize the packetizer
156  *****************************************************************************/
157 static int InitPacketizer( decoder_t *p_dec )
158 {
159     decoder_sys_t *p_sys = p_dec->p_sys;
160     WAVEFORMATEX *p_wf;
161
162     p_sys->i_state = STATE_NOSYNC;
163
164     aout_DateSet( &p_sys->end_date, 0 );
165
166     p_sys->p_sout_input = NULL;
167     p_sys->p_sout_buffer = NULL;
168     p_sys->p_chain = NULL;
169
170     msg_Info( p_dec, "Running MPEG4 audio packetizer" );
171
172     p_wf = (WAVEFORMATEX*)p_dec->p_fifo->p_waveformatex;
173
174     if( p_wf && p_wf->cbSize > 0)
175     {
176         uint8_t *p_config = (uint8_t*)&p_wf[1];
177         int     i_index;
178
179         i_index = ( ( p_config[0] << 1 ) | ( p_config[1] >> 7 ) ) & 0x0f;
180         if( i_index != 0x0f )
181         {
182             p_sys->i_rate = i_sample_rates[i_index];
183             p_sys->i_frame_length = (( p_config[1] >> 2 ) & 0x01) ? 960 : 1024;
184         }
185         else
186         {
187             p_sys->i_rate = ( ( p_config[1] & 0x7f ) << 17 ) |
188                 ( p_config[2] << 9 ) | ( p_config[3] << 1 ) |
189                 ( p_config[4] >> 7 );
190             p_sys->i_frame_length = (( p_config[4] >> 2 ) & 0x01) ? 960 : 1024;
191         }
192
193         msg_Dbg( p_dec, "AAC %dHz %d samples/frame",
194                  p_sys->i_rate, p_sys->i_frame_length );
195
196         p_sys->i_channels = p_wf->nChannels;
197         p_sys->sout_format.i_extra_data = p_wf->cbSize;
198         p_sys->sout_format.p_extra_data = malloc( p_wf->cbSize );
199         memcpy( p_sys->sout_format.p_extra_data, &p_wf[1], p_wf->cbSize );
200     }
201     else
202     {
203         msg_Dbg( p_dec, "No decoder specific info, must be an ADTS stream" );
204
205         /* We will try to create a AAC Config from adts */
206         p_sys->sout_format.i_extra_data = 0;
207         p_sys->sout_format.p_extra_data = NULL;
208         p_dec->pf_decode = RunADTSPacketizer;
209     }
210
211     return VLC_SUCCESS;
212 }
213
214 /****************************************************************************
215  * RunFramePacketizer: the whole thing
216  ****************************************************************************
217  * This function must be fed with complete frames.
218  ****************************************************************************/
219 static int RunFramePacketizer( decoder_t *p_dec, block_t *p_block )
220 {
221     decoder_sys_t *p_sys = p_dec->p_sys;
222
223     if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
224     {
225         /* We've just started the stream, wait for the first PTS. */
226         block_Release( p_block );
227         return VLC_SUCCESS;
228     }
229
230     p_sys->pts = p_block->i_pts;
231     p_sys->i_frame_size = p_block->i_buffer;
232
233     if( GetSoutBuffer( p_dec, &p_sys->p_sout_buffer ) != VLC_SUCCESS )
234     {
235         return VLC_EGENERIC;
236     }
237
238     /* Copy the whole frame into the buffer */
239     p_dec->p_vlc->pf_memcpy( p_sys->p_sout_buffer->p_buffer,
240                              p_block->p_buffer, p_block->i_buffer );
241
242     sout_InputSendBuffer( p_sys->p_sout_input, p_sys->p_sout_buffer );
243     p_sys->p_sout_buffer = NULL;
244
245     block_Release( p_block );
246     return VLC_SUCCESS;
247 }
248
249 /****************************************************************************
250  * RunADTSPacketizer: the whole thing
251  ****************************************************************************/
252 static int RunADTSPacketizer( decoder_t *p_dec, block_t *p_block )
253 {
254     decoder_sys_t *p_sys = p_dec->p_sys;
255     uint8_t p_header[ADTS_HEADER_SIZE];
256
257     if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
258     {
259         /* We've just started the stream, wait for the first PTS. */
260         block_Release( p_block );
261         return VLC_SUCCESS;
262     }
263
264     if( p_block->b_discontinuity )
265     {
266         p_sys->i_state = STATE_SYNC;
267     }
268
269     if( p_sys->p_chain )
270     {
271         block_ChainAppend( &p_sys->p_chain, p_block );
272     }
273     else
274     {
275         block_ChainAppend( &p_sys->p_chain, p_block );
276         p_sys->bytestream = block_BytestreamInit( p_dec, p_sys->p_chain, 0 );
277     }
278
279     while( 1 )
280     {
281         switch( p_sys->i_state )
282         {
283
284         case STATE_NOSYNC:
285             while( block_PeekBytes( &p_sys->bytestream, p_header, 2 )
286                    == VLC_SUCCESS )
287             {
288                 /* Look for sync word - should be 0xfff + 2 layer bits */
289                 if( p_header[0] == 0xff && (p_header[1] & 0xf6) == 0xf0 )
290                 {
291                     p_sys->i_state = STATE_SYNC;
292                     break;
293                 }
294                 block_SkipByte( &p_sys->bytestream );
295             }
296             if( p_sys->i_state != STATE_SYNC )
297             {
298                 if( block_PeekByte( &p_sys->bytestream, p_header )
299                     == VLC_SUCCESS && p_header[0] == 0xff )
300                 {
301                     /* Start of a sync word, need more data */
302                     return VLC_SUCCESS;
303                 }
304
305                 block_ChainRelease( p_sys->p_chain );
306                 p_sys->p_chain = NULL;
307
308                 /* Need more data */
309                 return VLC_SUCCESS;
310             }
311
312         case STATE_SYNC:
313             /* New frame, set the Presentation Time Stamp */
314             p_sys->pts = p_sys->bytestream.p_block->i_pts;
315             if( p_sys->pts != 0 &&
316                 p_sys->pts != aout_DateGet( &p_sys->end_date ) )
317             {
318                 aout_DateSet( &p_sys->end_date, p_sys->pts );
319             }
320             p_sys->i_state = STATE_HEADER;
321             break;
322
323         case STATE_HEADER:
324             /* Get ADTS frame header (ADTS_HEADER_SIZE bytes) */
325             if( block_PeekBytes( &p_sys->bytestream, p_header,
326                                  ADTS_HEADER_SIZE ) != VLC_SUCCESS )
327             {
328                 /* Need more data */
329                 return VLC_SUCCESS;
330             }
331
332             /* Check if frame is valid and get frame info */
333             p_sys->i_frame_size = ADTSSyncInfo( p_dec, p_header,
334                                                 &p_sys->i_channels,
335                                                 &p_sys->i_rate,
336                                                 &p_sys->i_frame_length,
337                                                 &p_sys->i_header_size,
338                                                 &p_sys->i_raw_blocks );
339             if( p_sys->i_frame_size <= 0 )
340             {
341                 msg_Dbg( p_dec, "emulated sync word" );
342                 block_SkipByte( &p_sys->bytestream );
343                 p_sys->i_state = STATE_NOSYNC;
344                 break;
345             }
346
347             p_sys->i_state = STATE_DATA;
348
349         case STATE_DATA:
350             /* TODO: If p_block == NULL, flush the buffer without checking the
351              * next sync word */
352
353             /* Check if next expected frame contains the sync word */
354             if( block_PeekOffsetBytes( &p_sys->bytestream, p_sys->i_frame_size
355                                        + p_sys->i_header_size, p_header, 2 )
356                 != VLC_SUCCESS )
357             {
358                 /* Need more data */
359                 return VLC_SUCCESS;
360             }
361
362             if( p_header[0] != 0xff || (p_header[1] & 0xf6) != 0xf0 )
363             {
364                 msg_Dbg( p_dec, "emulated sync word "
365                          "(no sync on following frame)" );
366                 p_sys->i_state = STATE_NOSYNC;
367                 block_SkipByte( &p_sys->bytestream );
368                 break;
369             }
370
371             if( !p_sys->p_sout_buffer )
372             if( GetSoutBuffer( p_dec, &p_sys->p_sout_buffer ) != VLC_SUCCESS )
373             {
374                 return VLC_EGENERIC;
375             }
376
377             /* Skip the ADTS header */
378             if( p_sys->i_header_size )
379             {
380                 if( block_SkipBytes( &p_sys->bytestream,
381                                      p_sys->i_header_size ) != VLC_SUCCESS )
382                 {
383                     /* Need more data */
384                     return VLC_SUCCESS;
385                 }
386                 p_sys->i_header_size = 0;
387             }
388
389             /* Copy the whole frame into the buffer */
390             if( block_GetBytes( &p_sys->bytestream,
391                                 p_sys->p_sout_buffer->p_buffer,
392                                 p_sys->i_frame_size ) != VLC_SUCCESS )
393             {
394                 /* Need more data */
395                 return VLC_SUCCESS;
396             }
397
398             p_sys->p_chain = block_BytestreamFlush( &p_sys->bytestream );
399
400             sout_InputSendBuffer( p_sys->p_sout_input, p_sys->p_sout_buffer );
401
402             p_sys->i_state = STATE_NOSYNC;
403             p_sys->p_sout_buffer = NULL;
404
405             /* Make sure we don't reuse the same pts twice */
406             if( p_sys->pts == p_sys->bytestream.p_block->i_pts )
407                 p_sys->pts = p_sys->bytestream.p_block->i_pts = 0;
408         }
409     }
410
411     return VLC_SUCCESS;
412 }
413
414 /*****************************************************************************
415  * GetSoutBuffer:
416  *****************************************************************************/
417 static int GetSoutBuffer( decoder_t *p_dec, sout_buffer_t **pp_buffer )
418 {
419     decoder_sys_t *p_sys = p_dec->p_sys;
420
421     if( p_sys->p_sout_input != NULL &&
422         ( p_sys->sout_format.i_sample_rate != (int)p_sys->i_rate
423           || p_sys->sout_format.i_channels != (int)p_sys->i_channels ) )
424     {
425         /* Parameters changed - this should not happen. */
426     }
427
428     /* Creating the sout input if not created yet. */
429     if( p_sys->p_sout_input == NULL )
430     {
431         p_sys->sout_format.i_cat = AUDIO_ES;
432         p_sys->sout_format.i_fourcc = VLC_FOURCC( 'm', 'p', '4', 'a' );
433         p_sys->sout_format.i_sample_rate = p_sys->i_rate;
434         p_sys->sout_format.i_channels    = p_sys->i_channels;
435         p_sys->sout_format.i_block_align = 0;
436         p_sys->sout_format.i_bitrate     = 0;
437
438         aout_DateInit( &p_sys->end_date, p_sys->i_rate );
439         aout_DateSet( &p_sys->end_date, p_sys->pts );
440
441         p_sys->p_sout_input = sout_InputNew( p_dec, &p_sys->sout_format );
442         if( p_sys->p_sout_input == NULL )
443         {
444             msg_Err( p_dec, "cannot add a new stream" );
445             *pp_buffer = NULL;
446             return VLC_EGENERIC;
447         }
448         msg_Info( p_dec, "AAC channels: %d samplerate: %d",
449                   p_sys->i_channels, p_sys->i_rate );
450     }
451
452     *pp_buffer = sout_BufferNew( p_sys->p_sout_input->p_sout,
453                                  p_sys->i_frame_size );
454     if( *pp_buffer == NULL )
455     {
456         return VLC_EGENERIC;
457     }
458
459     (*pp_buffer)->i_pts =
460         (*pp_buffer)->i_dts = aout_DateGet( &p_sys->end_date );
461
462     (*pp_buffer)->i_length =
463         aout_DateIncrement( &p_sys->end_date, p_sys->i_frame_length )
464         - (*pp_buffer)->i_pts;
465
466     return VLC_SUCCESS;
467 }
468
469 /*****************************************************************************
470  * EndPacketizer: clean up the packetizer
471  *****************************************************************************/
472 static int EndPacketizer( decoder_t *p_dec )
473 {
474     if( p_dec->p_sys->p_sout_input != NULL )
475     {
476         if( p_dec->p_sys->p_sout_buffer )
477         {
478             sout_BufferDelete( p_dec->p_sys->p_sout_input->p_sout,
479                                p_dec->p_sys->p_sout_buffer );
480         }
481
482         sout_InputDelete( p_dec->p_sys->p_sout_input );
483     }
484
485     if( p_dec->p_sys->p_chain ) block_ChainRelease( p_dec->p_sys->p_chain );
486
487     free( p_dec->p_sys );
488
489     return VLC_SUCCESS;
490 }
491
492 /*****************************************************************************
493  * ADTSSyncInfo: parse MPEG 4 audio ADTS sync info
494  *****************************************************************************/
495 static int ADTSSyncInfo( decoder_t * p_dec, const byte_t * p_buf,
496                          unsigned int * pi_channels,
497                          unsigned int * pi_sample_rate,
498                          unsigned int * pi_frame_length,
499                          unsigned int * pi_header_size,
500                          unsigned int * pi_raw_blocks_in_frame )
501 {
502     decoder_sys_t *p_sys = p_dec->p_sys;
503     int i_id, i_profile, i_sample_rate_idx, i_frame_size;
504     vlc_bool_t b_crc;
505
506     /* Fixed header between frames */
507     i_id = ( (p_buf[1] >> 3) & 0x01 ) ? 2 : 4;
508     b_crc = !(p_buf[1] & 0x01);
509     i_profile = p_buf[2] >> 6;
510     i_sample_rate_idx = (p_buf[2] >> 2) & 0x0f;
511     *pi_sample_rate = i_sample_rates[i_sample_rate_idx];
512     *pi_channels = ((p_buf[2] & 0x01) << 2) | ((p_buf[3] >> 6) & 0x03);
513
514     /* Variable header */
515     i_frame_size = ((p_buf[3] & 0x03) << 11) | (p_buf[4] << 3) |
516                    ((p_buf[5] >> 5) & 0x7);
517     *pi_raw_blocks_in_frame = (p_buf[6] & 0x02) + 1;
518
519     if( !*pi_sample_rate || !*pi_channels || !i_frame_size )
520     {
521         return 0;
522     }
523
524     /* Fixme */
525     *pi_frame_length = 1024;
526
527     /* Build the decoder specific info header */
528     if( !p_dec->p_sys->sout_format.i_extra_data )
529     {
530         p_sys->sout_format.i_extra_data = 2;
531         p_sys->sout_format.p_extra_data = malloc( 2 );
532         p_sys->sout_format.p_extra_data[0] =
533             (i_profile + 1) << 3 | (i_sample_rate_idx >> 1);
534         p_sys->sout_format.p_extra_data[1] =
535             ((i_sample_rate_idx & 0x01) << 7) | (*pi_channels <<3);
536     }
537
538     /* ADTS header length */
539     *pi_header_size = b_crc ? 9 : 7;
540
541     return i_frame_size - *pi_header_size;
542 }