]> git.sesse.net Git - vlc/blob - modules/demux/mp4/essetup.c
demux: mp4: never match an empty fragment on seek
[vlc] / modules / demux / mp4 / essetup.c
1 /*****************************************************************************
2  * essetup.h: es setup from stsd and extensions parsing
3  *****************************************************************************
4  * Copyright (C) 2001-2004, 2010, 2014 VLC authors and VideoLAN
5  *
6  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program; if not, write to the Free Software Foundation,
20  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21  *****************************************************************************/
22
23 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 #endif
26
27 #include "mp4.h"
28
29 #include <vlc_demux.h>
30 #include <vlc_aout.h>
31 #include <assert.h>
32
33 static void SetupESDS( demux_t *p_demux, mp4_track_t *p_track, const MP4_descriptor_decoder_config_t *p_decconfig )
34 {
35     /* First update information based on i_objectTypeIndication */
36     switch( p_decconfig->i_objectProfileIndication )
37     {
38     case( 0x20 ): /* MPEG4 VIDEO */
39         p_track->fmt.i_codec = VLC_CODEC_MP4V;
40         break;
41     case( 0x21 ): /* H.264 */
42         p_track->fmt.i_codec = VLC_CODEC_H264;
43         break;
44     case( 0x40):
45         p_track->fmt.i_codec = VLC_CODEC_MP4A;
46         if( p_decconfig->i_decoder_specific_info_len >= 2 &&
47                 p_decconfig->p_decoder_specific_info[0]       == 0xF8 &&
48                 (p_decconfig->p_decoder_specific_info[1]&0xE0) == 0x80 )
49         {
50             p_track->fmt.i_codec = VLC_CODEC_ALS;
51         }
52         break;
53     case( 0x60):
54     case( 0x61):
55     case( 0x62):
56     case( 0x63):
57     case( 0x64):
58     case( 0x65): /* MPEG2 video */
59         p_track->fmt.i_codec = VLC_CODEC_MPGV;
60         break;
61         /* Theses are MPEG2-AAC */
62     case( 0x66): /* main profile */
63     case( 0x67): /* Low complexity profile */
64     case( 0x68): /* Scaleable Sampling rate profile */
65         p_track->fmt.i_codec = VLC_CODEC_MP4A;
66         break;
67         /* True MPEG 2 audio */
68     case( 0x69):
69         p_track->fmt.i_codec = VLC_CODEC_MPGA;
70         break;
71     case( 0x6a): /* MPEG1 video */
72         p_track->fmt.i_codec = VLC_CODEC_MPGV;
73         break;
74     case( 0x6b): /* MPEG1 audio */
75         p_track->fmt.i_codec = VLC_CODEC_MPGA;
76         break;
77     case( 0x6c ): /* jpeg */
78         p_track->fmt.i_codec = VLC_CODEC_JPEG;
79         break;
80     case( 0x6d ): /* png */
81         p_track->fmt.i_codec = VLC_CODEC_PNG;
82         break;
83     case( 0x6e ): /* jpeg2000 */
84         p_track->fmt.i_codec = VLC_FOURCC( 'M','J','2','C' );
85         break;
86     case( 0xa3 ): /* vc1 */
87         p_track->fmt.i_codec = VLC_CODEC_VC1;
88         break;
89     case( 0xa4 ):
90         p_track->fmt.i_codec = VLC_CODEC_DIRAC;
91         break;
92     case( 0xa5 ):
93         p_track->fmt.i_codec = VLC_CODEC_A52;
94         break;
95     case( 0xa6 ):
96         p_track->fmt.i_codec = VLC_CODEC_EAC3;
97         break;
98     case( 0xa9 ): /* dts */
99     case( 0xaa ): /* DTS-HD HRA */
100     case( 0xab ): /* DTS-HD Master Audio */
101         p_track->fmt.i_codec = VLC_CODEC_DTS;
102         break;
103     case( 0xDD ):
104         p_track->fmt.i_codec = VLC_CODEC_VORBIS;
105         break;
106
107         /* Private ID */
108     case( 0xe0 ): /* NeroDigital: dvd subs */
109         if( p_track->fmt.i_cat == SPU_ES )
110         {
111             p_track->fmt.i_codec = VLC_CODEC_SPU;
112             if( p_track->i_width > 0 )
113                 p_track->fmt.subs.spu.i_original_frame_width = p_track->i_width;
114             if( p_track->i_height > 0 )
115                 p_track->fmt.subs.spu.i_original_frame_height = p_track->i_height;
116             break;
117         }
118     case( 0xe1 ): /* QCelp for 3gp */
119         if( p_track->fmt.i_cat == AUDIO_ES )
120         {
121             p_track->fmt.i_codec = VLC_CODEC_QCELP;
122         }
123         break;
124
125         /* Fallback */
126     default:
127         /* Unknown entry, but don't touch i_fourcc */
128         msg_Warn( p_demux,
129                   "unknown objectProfileIndication(0x%x) (Track[ID 0x%x])",
130                   p_decconfig->i_objectProfileIndication,
131                   p_track->i_track_ID );
132         break;
133     }
134
135     p_track->fmt.i_extra = p_decconfig->i_decoder_specific_info_len;
136     if( p_track->fmt.i_extra > 0 )
137     {
138         p_track->fmt.p_extra = malloc( p_track->fmt.i_extra );
139         memcpy( p_track->fmt.p_extra, p_decconfig->p_decoder_specific_info,
140                 p_track->fmt.i_extra );
141     }
142     if( p_track->fmt.i_codec == VLC_CODEC_SPU &&
143             p_track->fmt.i_extra >= 16 * 4 )
144     {
145         for( int i = 0; i < 16; i++ )
146         {
147             p_track->fmt.subs.spu.palette[1 + i] =
148                     GetDWBE((char*)p_track->fmt.p_extra + i * 4);
149         }
150         p_track->fmt.subs.spu.palette[0] = 0xBeef;
151     }
152 }
153
154 int SetupVideoES( demux_t *p_demux, mp4_track_t *p_track, MP4_Box_t *p_sample )
155 {
156     MP4_Box_data_sample_vide_t *p_vide = p_sample->data.p_sample_vide;
157
158     p_track->fmt.video.i_width = p_vide->i_width;
159     p_track->fmt.video.i_height = p_vide->i_height;
160     p_track->fmt.video.i_bits_per_pixel = p_vide->i_depth;
161
162     /* fall on display size */
163     if( p_track->fmt.video.i_width <= 0 )
164         p_track->fmt.video.i_width = p_track->i_width;
165     if( p_track->fmt.video.i_height <= 0 )
166         p_track->fmt.video.i_height = p_track->i_height;
167
168     /* Find out apect ratio from display size */
169     if( p_track->i_width > 0 && p_track->i_height > 0 &&
170         /* Work-around buggy muxed files */
171         p_vide->i_width != p_track->i_width )
172     {
173         p_track->fmt.video.i_sar_num = p_track->i_width  * p_track->fmt.video.i_height;
174         p_track->fmt.video.i_sar_den = p_track->i_height * p_track->fmt.video.i_width;
175     }
176
177     /* Support for cropping (eg. in H263 files) */
178     p_track->fmt.video.i_visible_width = p_track->fmt.video.i_width;
179     p_track->fmt.video.i_visible_height = p_track->fmt.video.i_height;
180
181     /* Rotation */
182     switch( (int)p_track->f_rotation ) {
183         case 90:
184             p_track->fmt.video.orientation = ORIENT_ROTATED_90;
185             break;
186         case 180:
187             p_track->fmt.video.orientation = ORIENT_ROTATED_180;
188             break;
189         case 270:
190             p_track->fmt.video.orientation = ORIENT_ROTATED_270;
191             break;
192     }
193
194     /* It's a little ugly but .. there are special cases */
195     switch( p_sample->i_type )
196     {
197         case( VLC_FOURCC( 's', '2', '6', '3' ) ):
198             p_track->fmt.i_codec = VLC_CODEC_H263;
199             break;
200         case VLC_FOURCC('y','v','1','2'):
201             p_track->fmt.i_codec = VLC_CODEC_YV12;
202             break;
203         case VLC_FOURCC('y','u','v','2'):
204             p_track->fmt.i_codec = VLC_FOURCC('Y','U','Y','2');
205             break;
206
207         default:
208             p_track->fmt.i_codec = p_sample->i_type;
209             break;
210     }
211
212
213     /* Read extensions */
214
215     /* Set up A/R from extension atom */
216     const MP4_Box_t *p_pasp = MP4_BoxGet( p_sample, "pasp" );
217     if( p_pasp && BOXDATA(p_pasp) && BOXDATA(p_pasp)->i_horizontal_spacing > 0 &&
218                   BOXDATA(p_pasp)->i_vertical_spacing > 0 )
219     {
220         p_track->fmt.video.i_sar_num = BOXDATA(p_pasp)->i_horizontal_spacing;
221         p_track->fmt.video.i_sar_den = BOXDATA(p_pasp)->i_vertical_spacing;
222     }
223
224     /* now see if esds is present and if so create a data packet
225         with decoder_specific_info  */
226     MP4_Box_t *p_esds = MP4_BoxGet( p_sample, "esds" );
227     if ( p_esds && BOXDATA(p_esds) && BOXDATA(p_esds)->es_descriptor.p_decConfigDescr )
228     {
229         assert(p_sample->i_type == ATOM_mp4v);
230         SetupESDS( p_demux, p_track, BOXDATA(p_esds)->es_descriptor.p_decConfigDescr );
231     }
232     else switch( p_sample->i_type )
233     {
234         /* qt decoder, send the complete chunk */
235         case VLC_FOURCC ('h', 'd', 'v', '1'): // HDV 720p30
236         case VLC_FOURCC ('h', 'd', 'v', '2'): // HDV 1080i60
237         case VLC_FOURCC ('h', 'd', 'v', '3'): // HDV 1080i50
238         case VLC_FOURCC ('h', 'd', 'v', '5'): // HDV 720p25
239         case VLC_FOURCC ('m', 'x', '5', 'n'): // MPEG2 IMX NTSC 525/60 50mb/s produced by FCP
240         case VLC_FOURCC ('m', 'x', '5', 'p'): // MPEG2 IMX PAL 625/60 50mb/s produced by FCP
241         case VLC_FOURCC ('m', 'x', '4', 'n'): // MPEG2 IMX NTSC 525/60 40mb/s produced by FCP
242         case VLC_FOURCC ('m', 'x', '4', 'p'): // MPEG2 IMX PAL 625/60 40mb/s produced by FCP
243         case VLC_FOURCC ('m', 'x', '3', 'n'): // MPEG2 IMX NTSC 525/60 30mb/s produced by FCP
244         case VLC_FOURCC ('m', 'x', '3', 'p'): // MPEG2 IMX PAL 625/50 30mb/s produced by FCP
245         case VLC_FOURCC ('x', 'd', 'v', '2'): // XDCAM HD 1080i60
246         case VLC_FOURCC ('A', 'V', 'm', 'p'): // AVID IMX PAL
247             p_track->fmt.i_codec = VLC_CODEC_MPGV;
248             break;
249         /* qt decoder, send the complete chunk */
250         case VLC_CODEC_SVQ1:
251         case VLC_CODEC_SVQ3:
252         case VLC_FOURCC( 'V', 'P', '3', '1' ):
253         case VLC_FOURCC( '3', 'I', 'V', '1' ):
254         case VLC_FOURCC( 'Z', 'y', 'G', 'o' ):
255         {
256             p_track->fmt.i_extra =
257                 p_sample->data.p_sample_vide->i_qt_image_description;
258             if( p_track->fmt.i_extra > 0 )
259             {
260                 p_track->fmt.p_extra = malloc( p_track->fmt.i_extra );
261                 memcpy( p_track->fmt.p_extra,
262                         p_sample->data.p_sample_vide->p_qt_image_description,
263                         p_track->fmt.i_extra);
264             }
265             break;
266         }
267
268         case VLC_FOURCC( 'v', 'c', '-', '1' ):
269         {
270             MP4_Box_t *p_dvc1 = MP4_BoxGet( p_sample, "dvc1" );
271             if( p_dvc1 && BOXDATA(p_dvc1) )
272             {
273                 p_track->fmt.i_extra = BOXDATA(p_dvc1)->i_vc1;
274                 if( p_track->fmt.i_extra > 0 )
275                 {
276                     p_track->fmt.p_extra = malloc( BOXDATA(p_dvc1)->i_vc1 );
277                     memcpy( p_track->fmt.p_extra, BOXDATA(p_dvc1)->p_vc1,
278                             p_track->fmt.i_extra );
279                 }
280             }
281             else
282             {
283                 msg_Err( p_demux, "missing dvc1" );
284             }
285             break;
286         }
287
288         /* avc1: send avcC (h264 without annexe B, ie without start code)*/
289         case VLC_FOURCC( 'a', 'v', 'c', '1' ):
290         {
291             MP4_Box_t *p_avcC = MP4_BoxGet( p_sample, "avcC" );
292
293             if( p_avcC && BOXDATA(p_avcC) )
294             {
295                 p_track->fmt.i_extra = BOXDATA(p_avcC)->i_avcC;
296                 if( p_track->fmt.i_extra > 0 )
297                 {
298                     p_track->fmt.p_extra = malloc( BOXDATA(p_avcC)->i_avcC );
299                     memcpy( p_track->fmt.p_extra, BOXDATA(p_avcC)->p_avcC,
300                             p_track->fmt.i_extra );
301                 }
302             }
303             else
304             {
305                 msg_Err( p_demux, "missing avcC" );
306             }
307             break;
308         }
309         case VLC_FOURCC( 'h', 'v', 'c', '1' ):
310         case VLC_FOURCC( 'h', 'e', 'v', '1' ):
311         {
312             MP4_Box_t *p_hvcC = MP4_BoxGet( p_sample, "hvcC" );
313
314             if( p_hvcC && BOXDATA(p_hvcC) )
315             {
316                 p_track->fmt.i_extra = BOXDATA(p_hvcC)->i_hvcC;
317                 if( p_track->fmt.i_extra > 0 )
318                 {
319                     p_track->fmt.p_extra = malloc( BOXDATA(p_hvcC)->i_hvcC );
320                     memcpy( p_track->fmt.p_extra, BOXDATA(p_hvcC)->p_hvcC,
321                             p_track->fmt.i_extra );
322                 }
323                 p_track->fmt.i_codec = VLC_CODEC_HEVC;
324             }
325             else
326             {
327                 msg_Err( p_demux, "missing hvcC" );
328             }
329             break;
330         }
331
332         case ATOM_WMV3:
333         {
334             MP4_Box_t *p_strf = MP4_BoxGet(  p_sample, "strf", 0 );
335             if ( p_strf && BOXDATA(p_strf) )
336             {
337                 p_track->fmt.i_codec = VLC_CODEC_WMV3;
338                 p_track->fmt.video.i_width = BOXDATA(p_strf)->bmiHeader.biWidth;
339                 p_track->fmt.video.i_visible_width = p_track->fmt.video.i_width;
340                 p_track->fmt.video.i_height = BOXDATA(p_strf)->bmiHeader.biHeight;
341                 p_track->fmt.video.i_visible_height =p_track->fmt.video.i_height;
342                 p_track->fmt.video.i_bits_per_pixel = BOXDATA(p_strf)->bmiHeader.biBitCount;
343                 p_track->fmt.i_extra = BOXDATA(p_strf)->i_extra;
344                 if( p_track->fmt.i_extra > 0 )
345                 {
346                     p_track->fmt.p_extra = malloc( BOXDATA(p_strf)->i_extra );
347                     memcpy( p_track->fmt.p_extra, BOXDATA(p_strf)->p_extra,
348                             p_track->fmt.i_extra );
349                 }
350                 p_track->p_asf = MP4_BoxGet( p_sample, "ASF " );
351             }
352             break;
353         }
354
355         default:
356             msg_Dbg( p_demux, "Unrecognized FourCC %4.4s", (char *)&p_sample->i_type );
357             break;
358     }
359
360     return 1;
361 }
362
363 int SetupAudioES( demux_t *p_demux, mp4_track_t *p_track, MP4_Box_t *p_sample )
364 {
365     MP4_Box_data_sample_soun_t *p_soun = p_sample->data.p_sample_soun;
366
367     p_track->fmt.audio.i_channels = p_soun->i_channelcount;
368     p_track->fmt.audio.i_rate = p_soun->i_sampleratehi;
369     p_track->fmt.i_bitrate = p_soun->i_channelcount * p_soun->i_sampleratehi *
370                              p_soun->i_samplesize;
371     p_track->fmt.audio.i_bitspersample = p_soun->i_samplesize;
372
373     p_track->fmt.i_original_fourcc = p_sample->i_type;
374
375     if( ( p_track->i_sample_size == 1 || p_track->i_sample_size == 2 ) )
376     {
377         if( p_soun->i_qt_version == 0 )
378         {
379             switch( p_sample->i_type )
380             {
381             case VLC_CODEC_ADPCM_IMA_QT:
382                 p_soun->i_qt_version = 1;
383                 p_soun->i_sample_per_packet = 64;
384                 p_soun->i_bytes_per_packet  = 34;
385                 p_soun->i_bytes_per_frame   = 34 * p_soun->i_channelcount;
386                 p_soun->i_bytes_per_sample  = 2;
387                 break;
388             case VLC_CODEC_MACE3:
389                 p_soun->i_qt_version = 1;
390                 p_soun->i_sample_per_packet = 6;
391                 p_soun->i_bytes_per_packet  = 2;
392                 p_soun->i_bytes_per_frame   = 2 * p_soun->i_channelcount;
393                 p_soun->i_bytes_per_sample  = 2;
394                 break;
395             case VLC_CODEC_MACE6:
396                 p_soun->i_qt_version = 1;
397                 p_soun->i_sample_per_packet = 12;
398                 p_soun->i_bytes_per_packet  = 2;
399                 p_soun->i_bytes_per_frame   = 2 * p_soun->i_channelcount;
400                 p_soun->i_bytes_per_sample  = 2;
401                 break;
402             case VLC_CODEC_ALAW:
403             case VLC_FOURCC( 'u', 'l', 'a', 'w' ):
404                 p_soun->i_samplesize = 8;
405                 p_track->i_sample_size = p_soun->i_channelcount;
406                 break;
407             case VLC_FOURCC( 'N', 'O', 'N', 'E' ):
408             case VLC_FOURCC( 'r', 'a', 'w', ' ' ):
409             case VLC_FOURCC( 't', 'w', 'o', 's' ):
410             case VLC_FOURCC( 's', 'o', 'w', 't' ):
411                 /* What would be the fun if you could trust the .mov */
412                 p_track->i_sample_size = ((p_soun->i_samplesize+7)/8) * p_soun->i_channelcount;
413                 break;
414             default:
415                 p_track->fmt.i_codec = p_sample->i_type;
416                 break;
417             }
418
419         }
420         else if( p_soun->i_qt_version == 1 && p_soun->i_sample_per_packet <= 0 )
421         {
422             p_soun->i_qt_version = 0;
423         }
424     }
425     else if( p_sample->data.p_sample_soun->i_qt_version == 1 )
426     {
427         switch( p_sample->i_type )
428         {
429         case( VLC_FOURCC( '.', 'm', 'p', '3' ) ):
430         case( VLC_FOURCC( 'm', 's', 0x00, 0x55 ) ):
431         {
432             if( p_track->i_sample_size > 1 )
433                 p_soun->i_qt_version = 0;
434             break;
435         }
436         case( ATOM_ac3 ):
437         case( ATOM_eac3 ):
438         case( VLC_FOURCC( 'm', 's', 0x20, 0x00 ) ):
439             p_soun->i_qt_version = 0;
440             break;
441         default:
442             break;
443         }
444     }
445
446     if( p_track->i_sample_size != 0 && p_soun->i_qt_version == 1 &&
447         p_soun->i_sample_per_packet <= 0 )
448     {
449         msg_Err( p_demux, "Invalid sample per packet value for qt_version 1. Broken muxer!" );
450         p_soun->i_qt_version = 0;
451     }
452
453
454     /* Endianness atom */
455     const MP4_Box_t *p_enda = MP4_BoxGet( p_sample, "wave/enda" );
456     if( !p_enda )
457         p_enda = MP4_BoxGet( p_sample, "enda" );
458
459     /* It's a little ugly but .. there are special cases */
460     switch( p_sample->i_type )
461     {
462         case( VLC_FOURCC( '.', 'm', 'p', '3' ) ):
463         case( VLC_FOURCC( 'm', 's', 0x00, 0x55 ) ):
464         {
465             p_track->fmt.i_codec = VLC_CODEC_MPGA;
466             break;
467         }
468         case( ATOM_eac3 ):
469         {
470             const MP4_Box_t *p_dec3 = MP4_BoxGet(  p_sample, "dec3", 0 );
471
472             p_track->fmt.i_codec = VLC_CODEC_EAC3;
473             if( p_dec3 && BOXDATA(p_dec3) )
474             {
475                 p_track->fmt.audio.i_channels = 0;
476                 p_track->fmt.i_bitrate = BOXDATA(p_dec3)->i_data_rate * 1000;
477                 p_track->fmt.audio.i_bitspersample = 0;
478             }
479             break;
480         }
481         case( ATOM_ac3 ):
482         {
483             MP4_Box_t *p_dac3 = MP4_BoxGet(  p_sample, "dac3", 0 );
484
485             p_track->fmt.i_codec = VLC_CODEC_A52;
486             if( p_dac3 && BOXDATA(p_dac3) )
487             {
488                 static const int pi_bitrate[] = {
489                      32,  40,  48,  56,
490                      64,  80,  96, 112,
491                     128, 160, 192, 224,
492                     256, 320, 384, 448,
493                     512, 576, 640,
494                 };
495                 p_track->fmt.audio.i_channels = 0;
496                 p_track->fmt.i_bitrate = 0;
497                 if( BOXDATA(p_dac3)->i_bitrate_code < sizeof(pi_bitrate)/sizeof(*pi_bitrate) )
498                     p_track->fmt.i_bitrate = pi_bitrate[BOXDATA(p_dac3)->i_bitrate_code] * 1000;
499                 p_track->fmt.audio.i_bitspersample = 0;
500             }
501             break;
502         }
503
504         case( VLC_FOURCC( 'r', 'a', 'w', ' ' ) ):
505         case( VLC_FOURCC( 'N', 'O', 'N', 'E' ) ):
506         {
507             if( (p_soun->i_samplesize+7)/8 == 1 )
508                 p_track->fmt.i_codec = VLC_CODEC_U8;
509             else
510                 p_track->fmt.i_codec = VLC_FOURCC( 't', 'w', 'o', 's' );
511
512             /* Buggy files workaround */
513             if( (p_track->i_timescale != p_soun->i_sampleratehi) )
514             {
515                 msg_Warn( p_demux, "i_timescale (%"PRId32") != i_sampleratehi "
516                           "(%u), making both equal (report any problem).",
517                           p_track->i_timescale, p_soun->i_sampleratehi );
518
519                 if( p_soun->i_sampleratehi != 0 )
520                     p_track->i_timescale = p_soun->i_sampleratehi;
521                 else
522                     p_soun->i_sampleratehi = p_track->i_timescale;
523             }
524             break;
525         }
526
527         case ATOM_in24:
528             p_track->fmt.i_codec = p_enda && BOXDATA(p_enda)->i_little_endian == 1 ?
529                                     VLC_FOURCC('4','2','n','i') : VLC_FOURCC('i','n','2','4');
530             break;
531         case ATOM_in32:
532             p_track->fmt.i_codec = p_enda && BOXDATA(p_enda)->i_little_endian == 1 ?
533                                     VLC_CODEC_S32L : VLC_CODEC_S32B;
534             break;
535         case ATOM_fl32:
536             p_track->fmt.i_codec = p_enda && BOXDATA(p_enda)->i_little_endian == 1 ?
537                                     VLC_CODEC_F32L : VLC_CODEC_F32B;
538             break;
539         case ATOM_fl64:
540             p_track->fmt.i_codec = p_enda && BOXDATA(p_enda)->i_little_endian == 1 ?
541                                     VLC_CODEC_F64L : VLC_CODEC_F64B;
542             break;
543
544         case VLC_CODEC_DVD_LPCM:
545         {
546             if( p_soun->i_qt_version == 2 )
547             {
548                 /* Flags:
549                  *  0x01: IsFloat
550                  *  0x02: IsBigEndian
551                  *  0x04: IsSigned
552                  */
553                 static const struct {
554                     unsigned     i_flags;
555                     unsigned     i_mask;
556                     unsigned     i_bits;
557                     vlc_fourcc_t i_codec;
558                 } p_formats[] = {
559                     { 0x01,           0x03, 32, VLC_CODEC_F32L },
560                     { 0x01,           0x03, 64, VLC_CODEC_F64L },
561                     { 0x01|0x02,      0x03, 32, VLC_CODEC_F32B },
562                     { 0x01|0x02,      0x03, 64, VLC_CODEC_F64B },
563
564                     { 0x00,           0x05,  8, VLC_CODEC_U8 },
565                     { 0x00|     0x04, 0x05,  8, VLC_CODEC_S8 },
566
567                     { 0x00,           0x07, 16, VLC_CODEC_U16L },
568                     { 0x00|0x02,      0x07, 16, VLC_CODEC_U16B },
569                     { 0x00     |0x04, 0x07, 16, VLC_CODEC_S16L },
570                     { 0x00|0x02|0x04, 0x07, 16, VLC_CODEC_S16B },
571
572                     { 0x00,           0x07, 24, VLC_CODEC_U24L },
573                     { 0x00|0x02,      0x07, 24, VLC_CODEC_U24B },
574                     { 0x00     |0x04, 0x07, 24, VLC_CODEC_S24L },
575                     { 0x00|0x02|0x04, 0x07, 24, VLC_CODEC_S24B },
576
577                     { 0x00,           0x07, 32, VLC_CODEC_U32L },
578                     { 0x00|0x02,      0x07, 32, VLC_CODEC_U32B },
579                     { 0x00     |0x04, 0x07, 32, VLC_CODEC_S32L },
580                     { 0x00|0x02|0x04, 0x07, 32, VLC_CODEC_S32B },
581
582                     {0, 0, 0, 0}
583                 };
584
585                 for( int i = 0; p_formats[i].i_codec; i++ )
586                 {
587                     if( p_formats[i].i_bits == p_soun->i_constbitsperchannel &&
588                         (p_soun->i_formatflags & p_formats[i].i_mask) == p_formats[i].i_flags )
589                     {
590                         p_track->fmt.i_codec = p_formats[i].i_codec;
591                         p_track->fmt.audio.i_bitspersample = p_soun->i_constbitsperchannel;
592                         p_track->fmt.audio.i_blockalign =
593                                 p_soun->i_channelcount * p_soun->i_constbitsperchannel / 8;
594                         p_track->i_sample_size = p_track->fmt.audio.i_blockalign;
595
596                         p_soun->i_qt_version = 0;
597                         break;
598                     }
599                 }
600             }
601             break;
602         }
603         default:
604             p_track->fmt.i_codec = p_sample->i_type;
605             break;
606     }
607
608
609     /* Process extensions */
610
611     /* Lookup for then channels extension */
612     const MP4_Box_t *p_chan = MP4_BoxGet( p_sample, "chan" );
613     if ( p_chan )
614     {
615         if ( BOXDATA(p_chan)->layout.i_channels_layout_tag == MP4_CHAN_USE_CHANNELS_BITMAP )
616         {
617             uint32_t rgi_chans_sequence[AOUT_CHAN_MAX + 1];
618             uint16_t i_vlc_mapping = 0;
619             uint8_t i_channels = 0;
620             const uint32_t i_bitmap = BOXDATA(p_chan)->layout.i_channels_bitmap;
621             for (uint8_t i=0;i<MP4_CHAN_BITMAP_MAPPING_COUNT;i++)
622             {
623                 if ( chan_bitmap_mapping[i].i_bitmap & i_bitmap )
624                 {
625                     i_channels++;
626                     if ( (chan_bitmap_mapping[i].i_vlc & i_vlc_mapping) ||
627                          i_channels > AOUT_CHAN_MAX )
628                     {
629                         /* double mapping or unsupported number of channels */
630                         i_vlc_mapping = 0;
631                         msg_Warn( p_demux, "discarding chan mapping" );
632                         break;
633                     }
634                     i_vlc_mapping |= chan_bitmap_mapping[i].i_vlc;
635                     rgi_chans_sequence[i_channels - 1] = chan_bitmap_mapping[i].i_vlc;
636                 }
637             }
638             rgi_chans_sequence[i_channels] = 0;
639             p_track->b_chans_reorder = !!
640                     aout_CheckChannelReorder( rgi_chans_sequence, NULL, i_vlc_mapping,
641                                               p_track->rgi_chans_reordering );
642         }
643
644     }
645
646     /* now see if esds is present and if so create a data packet
647         with decoder_specific_info  */
648     MP4_Box_t *p_esds = MP4_BoxGet( p_sample, "esds" );
649     if ( !p_esds ) p_esds = MP4_BoxGet( p_sample, "wave/esds" );
650     if ( p_esds && BOXDATA(p_esds) && BOXDATA(p_esds)->es_descriptor.p_decConfigDescr )
651     {
652         assert(p_sample->i_type == ATOM_mp4a);
653         SetupESDS( p_demux, p_track, BOXDATA(p_esds)->es_descriptor.p_decConfigDescr );
654     }
655     else switch( p_sample->i_type )
656     {
657         case VLC_CODEC_AMR_NB:
658             p_track->fmt.audio.i_rate = 8000;
659             break;
660         case VLC_CODEC_AMR_WB:
661             p_track->fmt.audio.i_rate = 16000;
662             break;
663         case VLC_FOURCC( 'Q', 'D', 'M', 'C' ):
664         case VLC_CODEC_QDM2:
665         case VLC_CODEC_ALAC:
666         {
667             p_track->fmt.i_extra =
668                 p_sample->data.p_sample_soun->i_qt_description;
669             if( p_track->fmt.i_extra > 0 )
670             {
671                 p_track->fmt.p_extra = malloc( p_track->fmt.i_extra );
672                 memcpy( p_track->fmt.p_extra,
673                         p_sample->data.p_sample_soun->p_qt_description,
674                         p_track->fmt.i_extra);
675             }
676             if( p_track->fmt.i_extra == 56 && p_sample->i_type == VLC_CODEC_ALAC )
677             {
678                 p_track->fmt.audio.i_channels = *((uint8_t*)p_track->fmt.p_extra + 41);
679                 p_track->fmt.audio.i_rate = GetDWBE((uint8_t*)p_track->fmt.p_extra + 52);
680             }
681             break;
682         }
683         case VLC_CODEC_ADPCM_MS:
684         case VLC_CODEC_ADPCM_IMA_WAV:
685         case VLC_CODEC_QCELP:
686         {
687             p_track->fmt.audio.i_blockalign = p_sample->data.p_sample_soun->i_bytes_per_frame;
688             break;
689         }
690         case ATOM_WMA2:
691         {
692             MP4_Box_t *p_WMA2 = MP4_BoxGet( p_sample, "wave/WMA2" );
693             if( p_WMA2 && BOXDATA(p_WMA2) )
694             {
695                 p_track->fmt.audio.i_channels = BOXDATA(p_WMA2)->Format.nChannels;
696                 p_track->fmt.audio.i_rate = BOXDATA(p_WMA2)->Format.nSamplesPerSec;
697                 p_track->fmt.i_bitrate = BOXDATA(p_WMA2)->Format.nAvgBytesPerSec * 8;
698                 p_track->fmt.audio.i_blockalign = BOXDATA(p_WMA2)->Format.nBlockAlign;
699                 p_track->fmt.audio.i_bitspersample = BOXDATA(p_WMA2)->Format.wBitsPerSample;
700                 p_track->fmt.i_extra = BOXDATA(p_WMA2)->i_extra;
701                 if( p_track->fmt.i_extra > 0 )
702                 {
703                     p_track->fmt.p_extra = malloc( BOXDATA(p_WMA2)->i_extra );
704                     memcpy( p_track->fmt.p_extra, BOXDATA(p_WMA2)->p_extra,
705                             p_track->fmt.i_extra );
706                 }
707                 p_track->p_asf = MP4_BoxGet( p_sample, "wave/ASF " );
708             }
709             else
710             {
711                 msg_Err( p_demux, "missing WMA2 %4.4s", (char*) &p_sample->p_father->i_type );
712             }
713             break;
714         }
715
716         default:
717             msg_Dbg( p_demux, "Unrecognized FourCC %4.4s", (char *)&p_sample->i_type );
718             break;
719     }
720
721     return 1;
722 }
723
724
725 int SetupSpuES( demux_t *p_demux, mp4_track_t *p_track, MP4_Box_t *p_sample )
726 {
727     MP4_Box_data_sample_text_t *p_text = p_sample->data.p_sample_text;
728
729     /* It's a little ugly but .. there are special cases */
730     switch( p_sample->i_type )
731     {
732         case( ATOM_c608 ): /* EIA608 closed captions */
733         //case( ATOM_c708 ): /* EIA708 closed captions */
734             p_track->fmt.i_codec = VLC_CODEC_EIA608_1;
735             p_track->fmt.i_cat = SPU_ES;
736             break;
737
738         case( VLC_FOURCC( 't', 'e', 'x', 't' ) ):
739         case( VLC_FOURCC( 't', 'x', '3', 'g' ) ):
740         {
741             p_track->fmt.i_codec = VLC_CODEC_TX3G;
742
743             text_style_t *p_style = text_style_New();
744             if ( p_style )
745             {
746                 if ( p_text->i_font_size ) /* !WARN: % in absolute storage */
747                     p_style->i_font_size = p_text->i_font_size;
748                 if ( p_text->i_font_color )
749                 {
750                     p_style->i_font_color = p_text->i_font_color >> 8;
751                     p_style->i_font_alpha = p_text->i_font_color & 0xFF;
752                 }
753                 if ( p_text->i_background_color[3] >> 8 )
754                 {
755                     p_style->i_background_color = p_text->i_background_color[0] >> 8;
756                     p_style->i_background_color |= p_text->i_background_color[1] >> 8;
757                     p_style->i_background_color |= p_text->i_background_color[2] >> 8;
758                     p_style->i_background_alpha = p_text->i_background_color[3] >> 8;
759                 }
760             }
761             p_track->fmt.subs.p_style = p_style;
762
763             /* FIXME UTF-8 doesn't work here ? */
764             if( p_track->b_mac_encoding )
765                 p_track->fmt.subs.psz_encoding = strdup( "MAC" );
766             else
767                 p_track->fmt.subs.psz_encoding = strdup( "UTF-8" );
768             break;
769         }
770
771         default:
772             p_track->fmt.i_codec = p_sample->i_type;
773             break;
774     }
775
776     /* now see if esds is present and if so create a data packet
777         with decoder_specific_info  */
778     MP4_Box_t *p_esds = MP4_BoxGet( p_sample, "esds" );
779     if ( p_esds && BOXDATA(p_esds) && BOXDATA(p_esds)->es_descriptor.p_decConfigDescr )
780     {
781         SetupESDS( p_demux, p_track, BOXDATA(p_esds)->es_descriptor.p_decConfigDescr );
782     }
783
784     return 1;
785 }