1 /*****************************************************************************
2 * essetup.h: es setup from stsd and extensions parsing
3 *****************************************************************************
4 * Copyright (C) 2001-2004, 2010, 2014 VLC authors and VideoLAN
6 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
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.
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.
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 *****************************************************************************/
30 #include <vlc_demux.h>
34 static void SetupESDS( demux_t *p_demux, mp4_track_t *p_track, const MP4_descriptor_decoder_config_t *p_decconfig )
36 /* First update information based on i_objectTypeIndication */
37 switch( p_decconfig->i_objectProfileIndication )
39 case( 0x20 ): /* MPEG4 VIDEO */
40 p_track->fmt.i_codec = VLC_CODEC_MP4V;
42 case( 0x21 ): /* H.264 */
43 p_track->fmt.i_codec = VLC_CODEC_H264;
46 p_track->fmt.i_codec = VLC_CODEC_MP4A;
47 if( p_decconfig->i_decoder_specific_info_len >= 2 &&
48 p_decconfig->p_decoder_specific_info[0] == 0xF8 &&
49 (p_decconfig->p_decoder_specific_info[1]&0xE0) == 0x80 )
51 p_track->fmt.i_codec = VLC_CODEC_ALS;
59 case( 0x65): /* MPEG2 video */
60 p_track->fmt.i_codec = VLC_CODEC_MPGV;
62 /* Theses are MPEG2-AAC */
63 case( 0x66): /* main profile */
64 case( 0x67): /* Low complexity profile */
65 case( 0x68): /* Scaleable Sampling rate profile */
66 p_track->fmt.i_codec = VLC_CODEC_MP4A;
68 /* True MPEG 2 audio */
70 p_track->fmt.i_codec = VLC_CODEC_MPGA;
72 case( 0x6a): /* MPEG1 video */
73 p_track->fmt.i_codec = VLC_CODEC_MPGV;
75 case( 0x6b): /* MPEG1 audio */
76 p_track->fmt.i_codec = VLC_CODEC_MPGA;
78 case( 0x6c ): /* jpeg */
79 p_track->fmt.i_codec = VLC_CODEC_JPEG;
81 case( 0x6d ): /* png */
82 p_track->fmt.i_codec = VLC_CODEC_PNG;
84 case( 0x6e ): /* jpeg2000 */
85 p_track->fmt.i_codec = VLC_FOURCC( 'M','J','2','C' );
87 case( 0xa3 ): /* vc1 */
88 p_track->fmt.i_codec = VLC_CODEC_VC1;
91 p_track->fmt.i_codec = VLC_CODEC_DIRAC;
94 p_track->fmt.i_codec = VLC_CODEC_A52;
97 p_track->fmt.i_codec = VLC_CODEC_EAC3;
99 case( 0xa9 ): /* dts */
100 case( 0xaa ): /* DTS-HD HRA */
101 case( 0xab ): /* DTS-HD Master Audio */
102 p_track->fmt.i_codec = VLC_CODEC_DTS;
105 p_track->fmt.i_codec = VLC_CODEC_VORBIS;
109 case( 0xe0 ): /* NeroDigital: dvd subs */
110 if( p_track->fmt.i_cat == SPU_ES )
112 p_track->fmt.i_codec = VLC_CODEC_SPU;
113 if( p_track->i_width > 0 )
114 p_track->fmt.subs.spu.i_original_frame_width = p_track->i_width;
115 if( p_track->i_height > 0 )
116 p_track->fmt.subs.spu.i_original_frame_height = p_track->i_height;
119 case( 0xe1 ): /* QCelp for 3gp */
120 if( p_track->fmt.i_cat == AUDIO_ES )
122 p_track->fmt.i_codec = VLC_CODEC_QCELP;
128 /* Unknown entry, but don't touch i_fourcc */
130 "unknown objectProfileIndication(0x%x) (Track[ID 0x%x])",
131 p_decconfig->i_objectProfileIndication,
132 p_track->i_track_ID );
136 p_track->fmt.i_extra = p_decconfig->i_decoder_specific_info_len;
137 if( p_track->fmt.i_extra > 0 )
139 p_track->fmt.p_extra = malloc( p_track->fmt.i_extra );
140 memcpy( p_track->fmt.p_extra, p_decconfig->p_decoder_specific_info,
141 p_track->fmt.i_extra );
143 if( p_track->fmt.i_codec == VLC_CODEC_SPU &&
144 p_track->fmt.i_extra >= 16 * 4 )
146 for( int i = 0; i < 16; i++ )
148 p_track->fmt.subs.spu.palette[1 + i] =
149 GetDWBE((char*)p_track->fmt.p_extra + i * 4);
151 p_track->fmt.subs.spu.palette[0] = 0xBeef;
155 int SetupVideoES( demux_t *p_demux, mp4_track_t *p_track, MP4_Box_t *p_sample )
157 MP4_Box_data_sample_vide_t *p_vide = p_sample->data.p_sample_vide;
159 p_track->fmt.video.i_width = p_vide->i_width;
160 p_track->fmt.video.i_height = p_vide->i_height;
161 p_track->fmt.video.i_bits_per_pixel = p_vide->i_depth;
163 /* fall on display size */
164 if( p_track->fmt.video.i_width <= 0 )
165 p_track->fmt.video.i_width = p_track->i_width;
166 if( p_track->fmt.video.i_height <= 0 )
167 p_track->fmt.video.i_height = p_track->i_height;
169 /* Find out apect ratio from display size */
170 if( p_track->i_width > 0 && p_track->i_height > 0 &&
171 /* Work-around buggy muxed files */
172 p_vide->i_width != p_track->i_width )
174 p_track->fmt.video.i_sar_num = p_track->i_width * p_track->fmt.video.i_height;
175 p_track->fmt.video.i_sar_den = p_track->i_height * p_track->fmt.video.i_width;
178 /* Support for cropping (eg. in H263 files) */
179 p_track->fmt.video.i_visible_width = p_track->fmt.video.i_width;
180 p_track->fmt.video.i_visible_height = p_track->fmt.video.i_height;
183 switch( (int)p_track->f_rotation ) {
185 p_track->fmt.video.orientation = ORIENT_ROTATED_90;
188 p_track->fmt.video.orientation = ORIENT_ROTATED_180;
191 p_track->fmt.video.orientation = ORIENT_ROTATED_270;
195 /* It's a little ugly but .. there are special cases */
196 switch( p_sample->i_type )
198 case( VLC_FOURCC( 's', '2', '6', '3' ) ):
199 p_track->fmt.i_codec = VLC_CODEC_H263;
201 case VLC_FOURCC('y','v','1','2'):
202 p_track->fmt.i_codec = VLC_CODEC_YV12;
204 case VLC_FOURCC('y','u','v','2'):
205 p_track->fmt.i_codec = VLC_FOURCC('Y','U','Y','2');
209 p_track->fmt.i_codec = p_sample->i_type;
214 /* Read extensions */
216 /* Set up A/R from extension atom */
217 const MP4_Box_t *p_pasp = MP4_BoxGet( p_sample, "pasp" );
218 if( p_pasp && BOXDATA(p_pasp) && BOXDATA(p_pasp)->i_horizontal_spacing > 0 &&
219 BOXDATA(p_pasp)->i_vertical_spacing > 0 )
221 p_track->fmt.video.i_sar_num = BOXDATA(p_pasp)->i_horizontal_spacing;
222 p_track->fmt.video.i_sar_den = BOXDATA(p_pasp)->i_vertical_spacing;
225 /* now see if esds is present and if so create a data packet
226 with decoder_specific_info */
227 MP4_Box_t *p_esds = MP4_BoxGet( p_sample, "esds" );
228 if ( p_esds && BOXDATA(p_esds) && BOXDATA(p_esds)->es_descriptor.p_decConfigDescr )
230 assert(p_sample->i_type == ATOM_mp4v);
231 SetupESDS( p_demux, p_track, BOXDATA(p_esds)->es_descriptor.p_decConfigDescr );
233 else switch( p_sample->i_type )
235 /* qt decoder, send the complete chunk */
236 case VLC_FOURCC ('h', 'd', 'v', '1'): // HDV 720p30
237 case VLC_FOURCC ('h', 'd', 'v', '2'): // HDV 1080i60
238 case VLC_FOURCC ('h', 'd', 'v', '3'): // HDV 1080i50
239 case VLC_FOURCC ('h', 'd', 'v', '5'): // HDV 720p25
240 case VLC_FOURCC ('m', 'x', '5', 'n'): // MPEG2 IMX NTSC 525/60 50mb/s produced by FCP
241 case VLC_FOURCC ('m', 'x', '5', 'p'): // MPEG2 IMX PAL 625/60 50mb/s produced by FCP
242 case VLC_FOURCC ('m', 'x', '4', 'n'): // MPEG2 IMX NTSC 525/60 40mb/s produced by FCP
243 case VLC_FOURCC ('m', 'x', '4', 'p'): // MPEG2 IMX PAL 625/60 40mb/s produced by FCP
244 case VLC_FOURCC ('m', 'x', '3', 'n'): // MPEG2 IMX NTSC 525/60 30mb/s produced by FCP
245 case VLC_FOURCC ('m', 'x', '3', 'p'): // MPEG2 IMX PAL 625/50 30mb/s produced by FCP
246 case VLC_FOURCC ('x', 'd', 'v', '2'): // XDCAM HD 1080i60
247 case VLC_FOURCC ('A', 'V', 'm', 'p'): // AVID IMX PAL
248 p_track->fmt.i_codec = VLC_CODEC_MPGV;
250 /* qt decoder, send the complete chunk */
253 case VLC_FOURCC( 'V', 'P', '3', '1' ):
254 case VLC_FOURCC( '3', 'I', 'V', '1' ):
255 case VLC_FOURCC( 'Z', 'y', 'G', 'o' ):
257 p_track->fmt.i_extra =
258 p_sample->data.p_sample_vide->i_qt_image_description;
259 if( p_track->fmt.i_extra > 0 )
261 p_track->fmt.p_extra = malloc( p_track->fmt.i_extra );
262 memcpy( p_track->fmt.p_extra,
263 p_sample->data.p_sample_vide->p_qt_image_description,
264 p_track->fmt.i_extra);
269 case VLC_FOURCC( 'v', 'c', '-', '1' ):
271 MP4_Box_t *p_dvc1 = MP4_BoxGet( p_sample, "dvc1" );
272 if( p_dvc1 && BOXDATA(p_dvc1) )
274 p_track->fmt.i_extra = BOXDATA(p_dvc1)->i_vc1;
275 if( p_track->fmt.i_extra > 0 )
277 p_track->fmt.p_extra = malloc( BOXDATA(p_dvc1)->i_vc1 );
278 memcpy( p_track->fmt.p_extra, BOXDATA(p_dvc1)->p_vc1,
279 p_track->fmt.i_extra );
284 msg_Err( p_demux, "missing dvc1" );
289 /* avc1: send avcC (h264 without annexe B, ie without start code)*/
290 case VLC_FOURCC( 'a', 'v', 'c', '1' ):
292 MP4_Box_t *p_avcC = MP4_BoxGet( p_sample, "avcC" );
294 if( p_avcC && BOXDATA(p_avcC) )
296 p_track->fmt.i_extra = BOXDATA(p_avcC)->i_avcC;
297 if( p_track->fmt.i_extra > 0 )
299 p_track->fmt.p_extra = malloc( BOXDATA(p_avcC)->i_avcC );
300 memcpy( p_track->fmt.p_extra, BOXDATA(p_avcC)->p_avcC,
301 p_track->fmt.i_extra );
306 msg_Err( p_demux, "missing avcC" );
310 case VLC_FOURCC( 'h', 'v', 'c', '1' ):
311 case VLC_FOURCC( 'h', 'e', 'v', '1' ):
313 MP4_Box_t *p_hvcC = MP4_BoxGet( p_sample, "hvcC" );
315 if( p_hvcC && BOXDATA(p_hvcC) )
317 p_track->fmt.i_extra = BOXDATA(p_hvcC)->i_hvcC;
318 if( p_track->fmt.i_extra > 0 )
320 p_track->fmt.p_extra = malloc( BOXDATA(p_hvcC)->i_hvcC );
321 memcpy( p_track->fmt.p_extra, BOXDATA(p_hvcC)->p_hvcC,
322 p_track->fmt.i_extra );
324 p_track->fmt.i_codec = VLC_CODEC_HEVC;
328 msg_Err( p_demux, "missing hvcC" );
335 MP4_Box_t *p_strf = MP4_BoxGet( p_sample, "strf", 0 );
336 if ( p_strf && BOXDATA(p_strf) )
338 p_track->fmt.i_codec = VLC_CODEC_WMV3;
339 p_track->fmt.video.i_width = BOXDATA(p_strf)->bmiHeader.biWidth;
340 p_track->fmt.video.i_visible_width = p_track->fmt.video.i_width;
341 p_track->fmt.video.i_height = BOXDATA(p_strf)->bmiHeader.biHeight;
342 p_track->fmt.video.i_visible_height =p_track->fmt.video.i_height;
343 p_track->fmt.video.i_bits_per_pixel = BOXDATA(p_strf)->bmiHeader.biBitCount;
344 p_track->fmt.i_extra = BOXDATA(p_strf)->i_extra;
345 if( p_track->fmt.i_extra > 0 )
347 p_track->fmt.p_extra = malloc( BOXDATA(p_strf)->i_extra );
348 memcpy( p_track->fmt.p_extra, BOXDATA(p_strf)->p_extra,
349 p_track->fmt.i_extra );
351 p_track->p_asf = MP4_BoxGet( p_sample, "ASF " );
357 msg_Dbg( p_demux, "Unrecognized FourCC %4.4s", (char *)&p_sample->i_type );
364 int SetupAudioES( demux_t *p_demux, mp4_track_t *p_track, MP4_Box_t *p_sample )
366 MP4_Box_data_sample_soun_t *p_soun = p_sample->data.p_sample_soun;
368 p_track->fmt.audio.i_channels = p_soun->i_channelcount;
369 p_track->fmt.audio.i_rate = p_soun->i_sampleratehi;
370 p_track->fmt.i_bitrate = p_soun->i_channelcount * p_soun->i_sampleratehi *
371 p_soun->i_samplesize;
372 p_track->fmt.audio.i_bitspersample = p_soun->i_samplesize;
374 p_track->fmt.i_original_fourcc = p_sample->i_type;
376 if( ( p_track->i_sample_size == 1 || p_track->i_sample_size == 2 ) )
378 if( p_soun->i_qt_version == 0 )
380 switch( p_sample->i_type )
382 case VLC_CODEC_ADPCM_IMA_QT:
383 p_soun->i_qt_version = 1;
384 p_soun->i_sample_per_packet = 64;
385 p_soun->i_bytes_per_packet = 34;
386 p_soun->i_bytes_per_frame = 34 * p_soun->i_channelcount;
387 p_soun->i_bytes_per_sample = 2;
389 case VLC_CODEC_MACE3:
390 p_soun->i_qt_version = 1;
391 p_soun->i_sample_per_packet = 6;
392 p_soun->i_bytes_per_packet = 2;
393 p_soun->i_bytes_per_frame = 2 * p_soun->i_channelcount;
394 p_soun->i_bytes_per_sample = 2;
396 case VLC_CODEC_MACE6:
397 p_soun->i_qt_version = 1;
398 p_soun->i_sample_per_packet = 12;
399 p_soun->i_bytes_per_packet = 2;
400 p_soun->i_bytes_per_frame = 2 * p_soun->i_channelcount;
401 p_soun->i_bytes_per_sample = 2;
404 case VLC_FOURCC( 'u', 'l', 'a', 'w' ):
405 p_soun->i_samplesize = 8;
406 p_track->i_sample_size = p_soun->i_channelcount;
408 case VLC_FOURCC( 'N', 'O', 'N', 'E' ):
409 case VLC_FOURCC( 'r', 'a', 'w', ' ' ):
410 case VLC_FOURCC( 't', 'w', 'o', 's' ):
411 case VLC_FOURCC( 's', 'o', 'w', 't' ):
412 /* What would be the fun if you could trust the .mov */
413 p_track->i_sample_size = ((p_soun->i_samplesize+7)/8) * p_soun->i_channelcount;
416 p_track->fmt.i_codec = p_sample->i_type;
421 else if( p_soun->i_qt_version == 1 && p_soun->i_sample_per_packet <= 0 )
423 p_soun->i_qt_version = 0;
426 else if( p_sample->data.p_sample_soun->i_qt_version == 1 )
428 switch( p_sample->i_type )
430 case( VLC_FOURCC( '.', 'm', 'p', '3' ) ):
431 case( VLC_FOURCC( 'm', 's', 0x00, 0x55 ) ):
433 if( p_track->i_sample_size > 1 )
434 p_soun->i_qt_version = 0;
439 case( VLC_FOURCC( 'm', 's', 0x20, 0x00 ) ):
440 p_soun->i_qt_version = 0;
447 if( p_track->i_sample_size != 0 && p_soun->i_qt_version == 1 &&
448 p_soun->i_sample_per_packet <= 0 )
450 msg_Err( p_demux, "Invalid sample per packet value for qt_version 1. Broken muxer!" );
451 p_soun->i_qt_version = 0;
455 /* Endianness atom */
456 const MP4_Box_t *p_enda = MP4_BoxGet( p_sample, "wave/enda" );
458 p_enda = MP4_BoxGet( p_sample, "enda" );
460 /* It's a little ugly but .. there are special cases */
461 switch( p_sample->i_type )
463 case( VLC_FOURCC( '.', 'm', 'p', '3' ) ):
464 case( VLC_FOURCC( 'm', 's', 0x00, 0x55 ) ):
466 p_track->fmt.i_codec = VLC_CODEC_MPGA;
471 const MP4_Box_t *p_dec3 = MP4_BoxGet( p_sample, "dec3", 0 );
473 p_track->fmt.i_codec = VLC_CODEC_EAC3;
474 if( p_dec3 && BOXDATA(p_dec3) )
476 p_track->fmt.audio.i_channels = 0;
477 p_track->fmt.i_bitrate = BOXDATA(p_dec3)->i_data_rate * 1000;
478 p_track->fmt.audio.i_bitspersample = 0;
484 MP4_Box_t *p_dac3 = MP4_BoxGet( p_sample, "dac3", 0 );
486 p_track->fmt.i_codec = VLC_CODEC_A52;
487 if( p_dac3 && BOXDATA(p_dac3) )
489 static const int pi_bitrate[] = {
496 p_track->fmt.audio.i_channels = 0;
497 p_track->fmt.i_bitrate = 0;
498 if( BOXDATA(p_dac3)->i_bitrate_code < sizeof(pi_bitrate)/sizeof(*pi_bitrate) )
499 p_track->fmt.i_bitrate = pi_bitrate[BOXDATA(p_dac3)->i_bitrate_code] * 1000;
500 p_track->fmt.audio.i_bitspersample = 0;
505 case( VLC_FOURCC( 'r', 'a', 'w', ' ' ) ):
506 case( VLC_FOURCC( 'N', 'O', 'N', 'E' ) ):
508 if( (p_soun->i_samplesize+7)/8 == 1 )
509 p_track->fmt.i_codec = VLC_CODEC_U8;
511 p_track->fmt.i_codec = VLC_FOURCC( 't', 'w', 'o', 's' );
513 /* Buggy files workaround */
514 if( (p_track->i_timescale != p_soun->i_sampleratehi) )
516 msg_Warn( p_demux, "i_timescale (%"PRId32") != i_sampleratehi "
517 "(%u), making both equal (report any problem).",
518 p_track->i_timescale, p_soun->i_sampleratehi );
520 if( p_soun->i_sampleratehi != 0 )
521 p_track->i_timescale = p_soun->i_sampleratehi;
523 p_soun->i_sampleratehi = p_track->i_timescale;
528 case VLC_FOURCC('i','n','2','4'):
529 p_track->fmt.i_codec = p_enda && BOXDATA(p_enda)->i_little_endian == 1 ?
530 VLC_FOURCC('4','2','n','i') : VLC_FOURCC('i','n','2','4');
532 case VLC_FOURCC('i','n','3','2'):
533 p_track->fmt.i_codec = p_enda && BOXDATA(p_enda)->i_little_endian == 1 ?
534 VLC_CODEC_S32L : VLC_CODEC_S32B;
536 case VLC_FOURCC('f','l','3','2'):
537 p_track->fmt.i_codec = p_enda && BOXDATA(p_enda)->i_little_endian == 1 ?
538 VLC_CODEC_F32L : VLC_CODEC_F32B;
540 case VLC_FOURCC('f','l','6','4'):
541 p_track->fmt.i_codec = p_enda && BOXDATA(p_enda)->i_little_endian == 1 ?
542 VLC_CODEC_F64L : VLC_CODEC_F64B;
545 case VLC_CODEC_DVD_LPCM:
547 if( p_soun->i_qt_version == 2 )
554 static const struct {
558 vlc_fourcc_t i_codec;
560 { 0x01, 0x03, 32, VLC_CODEC_F32L },
561 { 0x01, 0x03, 64, VLC_CODEC_F64L },
562 { 0x01|0x02, 0x03, 32, VLC_CODEC_F32B },
563 { 0x01|0x02, 0x03, 64, VLC_CODEC_F64B },
565 { 0x00, 0x05, 8, VLC_CODEC_U8 },
566 { 0x00| 0x04, 0x05, 8, VLC_CODEC_S8 },
568 { 0x00, 0x07, 16, VLC_CODEC_U16L },
569 { 0x00|0x02, 0x07, 16, VLC_CODEC_U16B },
570 { 0x00 |0x04, 0x07, 16, VLC_CODEC_S16L },
571 { 0x00|0x02|0x04, 0x07, 16, VLC_CODEC_S16B },
573 { 0x00, 0x07, 24, VLC_CODEC_U24L },
574 { 0x00|0x02, 0x07, 24, VLC_CODEC_U24B },
575 { 0x00 |0x04, 0x07, 24, VLC_CODEC_S24L },
576 { 0x00|0x02|0x04, 0x07, 24, VLC_CODEC_S24B },
578 { 0x00, 0x07, 32, VLC_CODEC_U32L },
579 { 0x00|0x02, 0x07, 32, VLC_CODEC_U32B },
580 { 0x00 |0x04, 0x07, 32, VLC_CODEC_S32L },
581 { 0x00|0x02|0x04, 0x07, 32, VLC_CODEC_S32B },
586 for( int i = 0; p_formats[i].i_codec; i++ )
588 if( p_formats[i].i_bits == p_soun->i_constbitsperchannel &&
589 (p_soun->i_formatflags & p_formats[i].i_mask) == p_formats[i].i_flags )
591 p_track->fmt.i_codec = p_formats[i].i_codec;
592 p_track->fmt.audio.i_bitspersample = p_soun->i_constbitsperchannel;
593 p_track->fmt.audio.i_blockalign =
594 p_soun->i_channelcount * p_soun->i_constbitsperchannel / 8;
595 p_track->i_sample_size = p_track->fmt.audio.i_blockalign;
597 p_soun->i_qt_version = 0;
605 p_track->fmt.i_codec = p_sample->i_type;
610 /* Process extensions */
612 /* Lookup for then channels extension */
613 const MP4_Box_t *p_chan = MP4_BoxGet( p_sample, "chan" );
616 if ( BOXDATA(p_chan)->layout.i_channels_layout_tag == MP4_CHAN_USE_CHANNELS_BITMAP )
618 uint32_t rgi_chans_sequence[AOUT_CHAN_MAX + 1];
619 uint16_t i_vlc_mapping = 0;
620 uint8_t i_channels = 0;
621 const uint32_t i_bitmap = BOXDATA(p_chan)->layout.i_channels_bitmap;
622 for (uint8_t i=0;i<MP4_CHAN_BITMAP_MAPPING_COUNT;i++)
624 if ( chan_bitmap_mapping[i].i_bitmap & i_bitmap )
627 if ( (chan_bitmap_mapping[i].i_vlc & i_vlc_mapping) ||
628 i_channels > AOUT_CHAN_MAX )
630 /* double mapping or unsupported number of channels */
632 msg_Warn( p_demux, "discarding chan mapping" );
635 i_vlc_mapping |= chan_bitmap_mapping[i].i_vlc;
636 rgi_chans_sequence[i_channels - 1] = chan_bitmap_mapping[i].i_vlc;
639 rgi_chans_sequence[i_channels] = 0;
640 p_track->b_chans_reorder = !!
641 aout_CheckChannelReorder( rgi_chans_sequence, NULL, i_vlc_mapping,
642 p_track->rgi_chans_reordering );
647 /* now see if esds is present and if so create a data packet
648 with decoder_specific_info */
649 MP4_Box_t *p_esds = MP4_BoxGet( p_sample, "esds" );
650 if ( !p_esds ) p_esds = MP4_BoxGet( p_sample, "wave/esds" );
651 if ( p_esds && BOXDATA(p_esds) && BOXDATA(p_esds)->es_descriptor.p_decConfigDescr )
653 assert(p_sample->i_type == ATOM_mp4a);
654 SetupESDS( p_demux, p_track, BOXDATA(p_esds)->es_descriptor.p_decConfigDescr );
656 else switch( p_sample->i_type )
658 case VLC_CODEC_AMR_NB:
659 p_track->fmt.audio.i_rate = 8000;
661 case VLC_CODEC_AMR_WB:
662 p_track->fmt.audio.i_rate = 16000;
664 case VLC_FOURCC( 'Q', 'D', 'M', 'C' ):
668 p_track->fmt.i_extra =
669 p_sample->data.p_sample_soun->i_qt_description;
670 if( p_track->fmt.i_extra > 0 )
672 p_track->fmt.p_extra = malloc( p_track->fmt.i_extra );
673 memcpy( p_track->fmt.p_extra,
674 p_sample->data.p_sample_soun->p_qt_description,
675 p_track->fmt.i_extra);
677 if( p_track->fmt.i_extra == 56 && p_sample->i_type == VLC_CODEC_ALAC )
679 p_track->fmt.audio.i_channels = *((uint8_t*)p_track->fmt.p_extra + 41);
680 p_track->fmt.audio.i_rate = GetDWBE((uint8_t*)p_track->fmt.p_extra + 52);
684 case VLC_CODEC_ADPCM_MS:
685 case VLC_CODEC_ADPCM_IMA_WAV:
686 case VLC_CODEC_QCELP:
688 p_track->fmt.audio.i_blockalign = p_sample->data.p_sample_soun->i_bytes_per_frame;
693 MP4_Box_t *p_WMA2 = MP4_BoxGet( p_sample, "wave/WMA2" );
694 if( p_WMA2 && BOXDATA(p_WMA2) )
696 p_track->fmt.audio.i_channels = BOXDATA(p_WMA2)->Format.nChannels;
697 p_track->fmt.audio.i_rate = BOXDATA(p_WMA2)->Format.nSamplesPerSec;
698 p_track->fmt.i_bitrate = BOXDATA(p_WMA2)->Format.nAvgBytesPerSec * 8;
699 p_track->fmt.audio.i_blockalign = BOXDATA(p_WMA2)->Format.nBlockAlign;
700 p_track->fmt.audio.i_bitspersample = BOXDATA(p_WMA2)->Format.wBitsPerSample;
701 p_track->fmt.i_extra = BOXDATA(p_WMA2)->i_extra;
702 if( p_track->fmt.i_extra > 0 )
704 p_track->fmt.p_extra = malloc( BOXDATA(p_WMA2)->i_extra );
705 memcpy( p_track->fmt.p_extra, BOXDATA(p_WMA2)->p_extra,
706 p_track->fmt.i_extra );
708 p_track->p_asf = MP4_BoxGet( p_sample, "wave/ASF " );
712 msg_Err( p_demux, "missing WMA2 %4.4s", (char*) &p_sample->p_father->i_type );
718 msg_Dbg( p_demux, "Unrecognized FourCC %4.4s", (char *)&p_sample->i_type );
726 int SetupSpuES( demux_t *p_demux, mp4_track_t *p_track, MP4_Box_t *p_sample )
728 MP4_Box_data_sample_text_t *p_text = p_sample->data.p_sample_text;
730 /* It's a little ugly but .. there are special cases */
731 switch( p_sample->i_type )
733 case( ATOM_c608 ): /* EIA608 closed captions */
734 //case( ATOM_c708 ): /* EIA708 closed captions */
735 p_track->fmt.i_codec = VLC_CODEC_EIA608_1;
736 p_track->fmt.i_cat = SPU_ES;
739 case( VLC_FOURCC( 't', 'e', 'x', 't' ) ):
740 case( VLC_FOURCC( 't', 'x', '3', 'g' ) ):
742 p_track->fmt.i_codec = VLC_CODEC_TX3G;
744 text_style_t *p_style = text_style_New();
747 if ( p_text->i_font_size ) /* !WARN: % in absolute storage */
748 p_style->i_font_size = p_text->i_font_size;
749 if ( p_text->i_font_color )
751 p_style->i_font_color = p_text->i_font_color >> 8;
752 p_style->i_font_alpha = p_text->i_font_color & 0xFF;
754 if ( p_text->i_background_color[3] >> 8 )
756 p_style->i_background_color = p_text->i_background_color[0] >> 8;
757 p_style->i_background_color |= p_text->i_background_color[1] >> 8;
758 p_style->i_background_color |= p_text->i_background_color[2] >> 8;
759 p_style->i_background_alpha = p_text->i_background_color[3] >> 8;
762 p_track->fmt.subs.p_style = p_style;
764 /* FIXME UTF-8 doesn't work here ? */
765 if( p_track->b_mac_encoding )
766 p_track->fmt.subs.psz_encoding = strdup( "MAC" );
768 p_track->fmt.subs.psz_encoding = strdup( "UTF-8" );
773 p_track->fmt.i_codec = p_sample->i_type;
777 /* now see if esds is present and if so create a data packet
778 with decoder_specific_info */
779 MP4_Box_t *p_esds = MP4_BoxGet( p_sample, "esds" );
780 if ( p_esds && BOXDATA(p_esds) && BOXDATA(p_esds)->es_descriptor.p_decConfigDescr )
782 SetupESDS( p_demux, p_track, BOXDATA(p_esds)->es_descriptor.p_decConfigDescr );