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 "../../packetizer/dts_header.h"
31 #include "../../packetizer/iso_color_tables.h"
33 #include <vlc_demux.h>
40 static void SetupGlobalExtensions( mp4_track_t
*p_track
, MP4_Box_t
*p_sample
)
42 if( !p_track
->fmt
.i_bitrate
)
44 const MP4_Box_t
*p_btrt
= MP4_BoxGet( p_sample
, "btrt" );
45 if( p_btrt
&& BOXDATA(p_btrt
) )
47 p_track
->fmt
.i_bitrate
= BOXDATA(p_btrt
)->i_avg_bitrate
;
52 static void SetupESDS( demux_t
*p_demux
, mp4_track_t
*p_track
, const MP4_descriptor_decoder_config_t
*p_decconfig
)
54 /* First update information based on i_objectTypeIndication */
55 /* See 14496-1 and http://mp4ra.org/#/object_types */
56 switch( p_decconfig
->i_objectProfileIndication
)
58 case( 0x20 ): /* MPEG4 VIDEO */
59 p_track
->fmt
.i_codec
= VLC_CODEC_MP4V
;
61 case( 0x21 ): /* H.264 */
62 p_track
->fmt
.i_codec
= VLC_CODEC_H264
;
66 p_track
->fmt
.i_codec
= VLC_CODEC_MP4A
;
67 if( p_decconfig
->i_decoder_specific_info_len
>= 2 &&
68 p_decconfig
->p_decoder_specific_info
[0] == 0xF8 &&
69 (p_decconfig
->p_decoder_specific_info
[1]&0xE0) == 0x80 )
71 p_track
->fmt
.i_codec
= VLC_CODEC_ALS
;
79 case( 0x65): /* MPEG2 video */
80 p_track
->fmt
.i_codec
= VLC_CODEC_MPGV
;
82 /* Theses are MPEG2-AAC */
83 case( 0x66): /* main profile */
84 case( 0x67): /* Low complexity profile */
85 case( 0x68): /* Scaleable Sampling rate profile */
86 p_track
->fmt
.i_codec
= VLC_CODEC_MP4A
;
88 /* True MPEG 2 audio */
90 p_track
->fmt
.i_codec
= VLC_CODEC_MPGA
;
92 case( 0x6a): /* MPEG1 video */
93 p_track
->fmt
.i_codec
= VLC_CODEC_MPGV
;
95 case( 0x6b): /* MPEG1 audio */
96 p_track
->fmt
.i_codec
= VLC_CODEC_MPGA
;
98 case( 0x6c ): /* jpeg */
99 p_track
->fmt
.i_codec
= VLC_CODEC_JPEG
;
101 case( 0x6d ): /* png */
102 p_track
->fmt
.i_codec
= VLC_CODEC_PNG
;
104 case( 0x6e ): /* jpeg2000 */
105 p_track
->fmt
.i_codec
= VLC_FOURCC( 'M','J','2','C' );
107 case( 0xa3 ): /* vc1 */
108 p_track
->fmt
.i_codec
= VLC_CODEC_VC1
;
111 p_track
->fmt
.i_codec
= VLC_CODEC_DIRAC
;
114 p_track
->fmt
.i_codec
= VLC_CODEC_A52
;
117 p_track
->fmt
.i_codec
= VLC_CODEC_EAC3
;
119 case( 0xaa ): /* DTS-HD HRA */
120 case( 0xab ): /* DTS-HD Master Audio */
121 p_track
->fmt
.i_profile
= PROFILE_DTS_HD
;
123 case( 0xa9 ): /* dts */
124 p_track
->fmt
.i_codec
= VLC_CODEC_DTS
;
127 p_track
->fmt
.i_codec
= VLC_CODEC_VORBIS
;
131 case( 0xe0 ): /* NeroDigital: dvd subs */
132 if( p_track
->fmt
.i_cat
== SPU_ES
)
134 p_track
->fmt
.i_codec
= VLC_CODEC_SPU
;
135 if( p_track
->i_width
> 0 )
136 p_track
->fmt
.subs
.spu
.i_original_frame_width
= p_track
->i_width
;
137 if( p_track
->i_height
> 0 )
138 p_track
->fmt
.subs
.spu
.i_original_frame_height
= p_track
->i_height
;
141 case( 0xe1 ): /* QCelp for 3gp */
142 if( p_track
->fmt
.i_cat
== AUDIO_ES
)
144 p_track
->fmt
.i_codec
= VLC_CODEC_QCELP
;
150 /* Unknown entry, but don't touch i_fourcc */
152 "unknown objectProfileIndication(0x%x) (Track[ID 0x%x])",
153 p_decconfig
->i_objectProfileIndication
,
154 p_track
->i_track_ID
);
158 p_track
->fmt
.i_original_fourcc
= 0; /* so we don't have MP4A as original fourcc */
159 p_track
->fmt
.i_bitrate
= p_decconfig
->i_avg_bitrate
;
161 p_track
->fmt
.i_extra
= p_decconfig
->i_decoder_specific_info_len
;
162 if( p_track
->fmt
.i_extra
> 0 )
164 p_track
->fmt
.p_extra
= malloc( p_track
->fmt
.i_extra
);
165 memcpy( p_track
->fmt
.p_extra
, p_decconfig
->p_decoder_specific_info
,
166 p_track
->fmt
.i_extra
);
168 if( p_track
->fmt
.i_codec
== VLC_CODEC_SPU
&&
169 p_track
->fmt
.i_extra
>= 16 * 4 )
171 for( int i
= 0; i
< 16; i
++ )
173 p_track
->fmt
.subs
.spu
.palette
[1 + i
] =
174 GetDWBE((char*)p_track
->fmt
.p_extra
+ i
* 4);
176 p_track
->fmt
.subs
.spu
.palette
[0] = SPU_PALETTE_DEFINED
;
180 static int SetupRTPReceptionHintTrack( demux_t
*p_demux
, mp4_track_t
*p_track
, MP4_Box_t
*p_sample
)
182 p_track
->fmt
.i_original_fourcc
= p_sample
->i_type
;
184 if( !p_track
->p_sdp
)
186 msg_Err(p_demux
, "Required 'sdp '-box not found");
189 MP4_Box_t
*p_sdp
= p_track
->p_sdp
;
191 char * pch
= strtok_r(BOXDATA(p_sdp
)->psz_text
, " =\n", &strtok_state
); /* media entry */
192 if( pch
&& pch
[0] != 'm' )
194 msg_Err(p_demux
, "No Media entry found in SDP:%s", pch
);
198 if( !( pch
= strtok_r(NULL
, " =\n", &strtok_state
) ) ) /* media type */
200 /* media type has already been checked */
201 msg_Dbg(p_demux
, "sdp: media type:%s", pch
);
202 if( !( pch
= strtok_r(NULL
, " =\n", &strtok_state
) ) ) /* port */
204 msg_Dbg(p_demux
, "sdp: port:%s", pch
);
205 if( !( pch
= strtok_r(NULL
, " =\n", &strtok_state
) ) ) /* protocol */
207 msg_Dbg(p_demux
, "sdp: protocol:%s", pch
);
209 if( !( pch
= strtok_r(NULL
, " =\n", &strtok_state
) ) ) /* fmt */
212 bool codec_set
= false;
213 /* process rtp types until we get an attribute field or end of sdp */
214 while( pch
&& pch
[0] != 'a' )
216 int rtp_payload
= atoi(pch
);
217 msg_Dbg(p_demux
, "sdp: payload type:%d", rtp_payload
);
221 /* Payload types 34 and under have a set type and can be identified here */
222 switch( rtp_payload
)
225 p_track
->fmt
.i_codec
= VLC_CODEC_GSM
;
232 pch
= strtok_r(NULL
, " =\n", &strtok_state
); /* attribute or additional payload type */
233 if( !pch
&& !codec_set
)
237 while( pch
&& pch
[0] == 'a' )
239 if( !( pch
= strtok_r(NULL
, " :=\n", &strtok_state
) ) ) /* attribute type */
241 msg_Dbg(p_demux
, "sdp: atrribute type:%s", pch
);
243 if( !strcmp(pch
, "rtpmap") )
245 if( !( pch
= strtok_r(NULL
, " :=\n", &strtok_state
) ) ) /* payload type */
247 msg_Dbg(p_demux
, "sdp: payload type:%s", pch
);
248 if( !(pch
= strtok_r(NULL
, " /:=\n", &strtok_state
) ) ) /* encoding name */
250 msg_Dbg(p_demux
, "sdp: encoding name:%s", pch
);
252 /* Simply adding codec recognition should work for most codecs */
253 /* Codecs using slices need their picture constructed from sample */
254 if( !strcmp(pch
, "H264") )
256 p_track
->fmt
.i_codec
= VLC_CODEC_H264
;
257 /* ******* sending AnnexB ! */
258 p_track
->fmt
.b_packetized
= false;
260 else if( !strcmp(pch
, "GSM") )
262 p_track
->fmt
.i_codec
= VLC_CODEC_GSM
;
264 else if( !strcmp(pch
, "Speex") )
266 p_track
->fmt
.i_codec
= VLC_CODEC_SPEEX
;
268 else if( !codec_set
)
270 msg_Err(p_demux
, "Support for codec contained in RTP \
271 Reception Hint Track RTP stream has not been added");
275 if( !( pch
= strtok_r(NULL
, " :=\n", &strtok_state
) ) ) /* clock rate */
277 int clock_rate
= atoi(pch
);
278 msg_Dbg(p_demux
, "sdp clock rate:%d", clock_rate
);
279 if( p_track
->fmt
.i_cat
== AUDIO_ES
)
280 p_track
->fmt
.audio
.i_rate
= clock_rate
;
282 pch
= strtok_r(NULL
, " =\n", &strtok_state
); /* next attribute */
285 const MP4_Box_t
*p_tims
= MP4_BoxGet(p_sample
, "tims");
286 if( p_tims
&& BOXDATA(p_tims
) && BOXDATA(p_tims
)->i_timescale
)
288 p_track
->i_timescale
= BOXDATA(p_tims
)->i_timescale
;
292 msg_Warn(p_demux
, "Missing mandatory box tims");
296 const MP4_Box_t
*p_tssy
= MP4_BoxGet(p_sample
, "tssy");
297 if( p_tssy
&& BOXDATA(p_tssy
) )
299 /* take the 2 last bits which indicate the synchronization mode */
300 p_track
->sync_mode
= (RTP_timstamp_synchronization_t
)
301 BOXDATA(p_tssy
)->i_reserved_timestamp_sync
& 0x03;
304 const MP4_Box_t
*p_tsro
= MP4_BoxGet(p_sample
, "tsro");
305 if( p_tsro
&& BOXDATA(p_tsro
) )
306 p_track
->i_tsro_offset
= BOXDATA(p_tsro
)->i_offset
;
308 msg_Dbg(p_demux
, "No tsro box present");
309 msg_Dbg(p_demux
, "setting tsro: %" PRId32
, p_track
->i_tsro_offset
);
315 int SetupVideoES( demux_t
*p_demux
, mp4_track_t
*p_track
, MP4_Box_t
*p_sample
)
317 MP4_Box_data_sample_vide_t
*p_vide
= p_sample
->data
.p_sample_vide
;
321 p_track
->fmt
.video
.i_width
= p_vide
->i_width
;
322 p_track
->fmt
.video
.i_height
= p_vide
->i_height
;
323 p_track
->fmt
.video
.i_bits_per_pixel
= p_vide
->i_depth
;
325 /* fall on display size */
326 if( p_track
->fmt
.video
.i_width
<= 0 )
327 p_track
->fmt
.video
.i_width
= p_track
->i_width
;
328 if( p_track
->fmt
.video
.i_height
<= 0 )
329 p_track
->fmt
.video
.i_height
= p_track
->i_height
;
331 /* Find out apect ratio from display size */
332 if( p_track
->i_width
> 0 && p_track
->i_height
> 0 &&
333 /* Work-around buggy muxed files */
334 p_vide
->i_width
!= p_track
->i_width
)
336 p_track
->fmt
.video
.i_sar_num
= p_track
->i_width
* p_track
->fmt
.video
.i_height
;
337 p_track
->fmt
.video
.i_sar_den
= p_track
->i_height
* p_track
->fmt
.video
.i_width
;
340 /* Support for cropping (eg. in H263 files) */
341 p_track
->fmt
.video
.i_visible_width
= p_track
->fmt
.video
.i_width
;
342 p_track
->fmt
.video
.i_visible_height
= p_track
->fmt
.video
.i_height
;
345 switch( (int)p_track
->f_rotation
) {
347 p_track
->fmt
.video
.orientation
= ORIENT_ROTATED_90
;
350 p_track
->fmt
.video
.orientation
= ORIENT_ROTATED_180
;
353 p_track
->fmt
.video
.orientation
= ORIENT_ROTATED_270
;
357 /* Set 360 video mode */
358 p_track
->fmt
.video
.projection_mode
= PROJECTION_MODE_RECTANGULAR
;
359 const MP4_Box_t
*p_uuid
= MP4_BoxGet( p_track
->p_track
, "uuid" );
360 for( ; p_uuid
; p_uuid
= p_uuid
->p_next
)
362 if( p_uuid
->i_type
== ATOM_uuid
363 && !CmpUUID( &p_uuid
->i_uuid
, &XML360BoxUUID
)
364 && p_uuid
->data
.p_360
)
366 p_track
->fmt
.video
.projection_mode
= p_uuid
->data
.p_360
->i_projection_mode
;
367 switch (p_uuid
->data
.p_360
->e_stereo_mode
)
369 case XML360_STEREOSCOPIC_TOP_BOTTOM
:
370 p_track
->fmt
.video
.multiview_mode
= MULTIVIEW_STEREO_TB
;
372 case XML360_STEREOSCOPIC_LEFT_RIGHT
:
373 p_track
->fmt
.video
.multiview_mode
= MULTIVIEW_STEREO_SBS
;
376 p_track
->fmt
.video
.multiview_mode
= MULTIVIEW_2D
;
382 const MP4_Box_t
*p_st3d
= MP4_BoxGet( p_sample
, "st3d" );
383 if (p_st3d
&& BOXDATA(p_st3d
))
385 switch( BOXDATA(p_st3d
)->i_stereo_mode
)
387 case ST3D_MONOSCOPIC
:
388 p_track
->fmt
.video
.multiview_mode
= MULTIVIEW_2D
;
390 case ST3D_STEREOSCOPIC_TOP_BOTTOM
:
391 p_track
->fmt
.video
.multiview_mode
= MULTIVIEW_STEREO_TB
;
393 case ST3D_STEREOSCOPIC_LEFT_RIGHT
:
394 p_track
->fmt
.video
.multiview_mode
= MULTIVIEW_STEREO_SBS
;
397 msg_Warn( p_demux
, "Unknown stereo mode %d", BOXDATA(p_st3d
)->i_stereo_mode
);
403 for( p_uuid
= MP4_BoxGet( p_sample
, "uuid" ); p_uuid
;
404 p_uuid
= p_uuid
->p_next
)
406 if( p_uuid
->i_type
== ATOM_uuid
&&
407 !CmpUUID( &p_uuid
->i_uuid
, &PS3DDSBoxUUID
) &&
408 p_uuid
->data
.p_binary
&&
409 p_uuid
->data
.p_binary
->i_blob
== 4 &&
410 !memcmp( p_uuid
->data
.p_binary
->p_blob
, "\x82\x81\x10\x02", 4 ) )
412 p_track
->fmt
.video
.multiview_mode
= MULTIVIEW_STEREO_FRAME
;
418 const MP4_Box_t
*p_prhd
= MP4_BoxGet( p_sample
, "sv3d/proj/prhd" );
419 if (p_prhd
&& BOXDATA(p_prhd
))
421 p_track
->fmt
.video
.pose
.yaw
= BOXDATA(p_prhd
)->f_pose_yaw_degrees
;
422 p_track
->fmt
.video
.pose
.pitch
= BOXDATA(p_prhd
)->f_pose_pitch_degrees
;
423 p_track
->fmt
.video
.pose
.roll
= BOXDATA(p_prhd
)->f_pose_roll_degrees
;
426 const MP4_Box_t
*p_equi
= MP4_BoxGet( p_sample
, "sv3d/proj/equi" );
427 const MP4_Box_t
*p_cbmp
= MP4_BoxGet( p_sample
, "sv3d/proj/cbmp" );
428 if (p_equi
&& BOXDATA(p_equi
))
429 p_track
->fmt
.video
.projection_mode
= PROJECTION_MODE_EQUIRECTANGULAR
;
430 else if (p_cbmp
&& BOXDATA(p_cbmp
))
431 p_track
->fmt
.video
.projection_mode
= PROJECTION_MODE_CUBEMAP_LAYOUT_STANDARD
;
433 /* It's a little ugly but .. there are special cases */
434 switch( p_sample
->i_type
)
436 case( VLC_FOURCC( 's', '2', '6', '3' ) ):
437 p_track
->fmt
.i_codec
= VLC_CODEC_H263
;
439 case VLC_FOURCC('y','v','1','2'):
440 p_track
->fmt
.i_codec
= VLC_CODEC_YV12
;
442 case VLC_FOURCC('y','u','v','2'):
443 p_track
->fmt
.i_codec
= VLC_CODEC_YUYV
;
445 case VLC_FOURCC('r','a','w',' '):
446 switch( p_vide
->i_depth
) {
448 p_track
->fmt
.i_codec
= VLC_CODEC_RGB15
;
451 p_track
->fmt
.i_codec
= VLC_CODEC_RGB24
;
454 p_track
->fmt
.i_codec
= VLC_CODEC_ARGB
;
457 p_track
->fmt
.i_codec
= VLC_CODEC_GREY
;
460 msg_Dbg( p_demux
, "Unrecognized raw video format (depth = %d)",
462 p_track
->fmt
.i_codec
= p_sample
->i_type
;
466 case( VLC_FOURCC( 'r', 'r', 't', 'p' ) ): /* RTP Reception Hint Track */
468 if( !SetupRTPReceptionHintTrack( p_demux
, p_track
, p_sample
) )
469 p_track
->fmt
.i_codec
= p_sample
->i_type
;
473 p_track
->fmt
.i_codec
= p_sample
->i_type
;
478 /* Read extensions */
480 /* Set up A/R from extension atom */
481 const MP4_Box_t
*p_pasp
= MP4_BoxGet( p_sample
, "pasp" );
482 if( p_pasp
&& BOXDATA(p_pasp
) && BOXDATA(p_pasp
)->i_horizontal_spacing
> 0 &&
483 BOXDATA(p_pasp
)->i_vertical_spacing
> 0 )
485 p_track
->fmt
.video
.i_sar_num
= BOXDATA(p_pasp
)->i_horizontal_spacing
;
486 p_track
->fmt
.video
.i_sar_den
= BOXDATA(p_pasp
)->i_vertical_spacing
;
489 const MP4_Box_t
*p_fiel
= MP4_BoxGet( p_sample
, "fiel" );
490 if( p_fiel
&& BOXDATA(p_fiel
) )
492 p_track
->i_block_flags
= BOXDATA(p_fiel
)->i_flags
;
495 const MP4_Box_t
*p_colr
= MP4_BoxGet( p_sample
, "colr" );
496 if ( p_colr
!= NULL
)
498 if ( BOXDATA(p_colr
)->i_type
== VLC_FOURCC( 'n', 'c', 'l', 'c' ) ||
499 BOXDATA(p_colr
)->i_type
== VLC_FOURCC( 'n', 'c', 'l', 'x' ) )
501 p_track
->fmt
.video
.primaries
=
502 iso_23001_8_cp_to_vlc_primaries( BOXDATA( p_colr
)->nclc
.i_primary_idx
);
503 p_track
->fmt
.video
.transfer
=
504 iso_23001_8_tc_to_vlc_xfer( BOXDATA( p_colr
)->nclc
.i_transfer_function_idx
);
505 p_track
->fmt
.video
.space
=
506 iso_23001_8_mc_to_vlc_coeffs( BOXDATA( p_colr
)->nclc
.i_matrix_idx
);
507 if ( BOXDATA(p_colr
)->i_type
== VLC_FOURCC( 'n', 'c', 'l', 'x' ) &&
508 (BOXDATA(p_colr
)->nclc
.i_full_range
>> 7) != 0 )
509 p_track
->fmt
.video
.color_range
= COLOR_RANGE_FULL
;
511 p_track
->fmt
.video
.color_range
= COLOR_RANGE_LIMITED
;
515 SetupGlobalExtensions( p_track
, p_sample
);
517 /* now see if esds is present and if so create a data packet
518 with decoder_specific_info */
519 MP4_Box_t
*p_esds
= MP4_BoxGet( p_sample
, "esds" );
520 if ( p_esds
&& BOXDATA(p_esds
) && BOXDATA(p_esds
)->es_descriptor
.p_decConfigDescr
)
522 assert(p_sample
->i_type
== ATOM_mp4v
);
523 SetupESDS( p_demux
, p_track
, BOXDATA(p_esds
)->es_descriptor
.p_decConfigDescr
);
525 else switch( p_sample
->i_type
)
527 /* qt decoder, send the complete chunk */
528 case VLC_FOURCC ('h', 'd', 'v', '1'): // HDV 720p30
529 case VLC_FOURCC ('h', 'd', 'v', '2'): // HDV 1080i60
530 case VLC_FOURCC ('h', 'd', 'v', '3'): // HDV 1080i50
531 case VLC_FOURCC ('h', 'd', 'v', '5'): // HDV 720p25
532 case VLC_FOURCC ('m', 'x', '5', 'n'): // MPEG2 IMX NTSC 525/60 50mb/s produced by FCP
533 case VLC_FOURCC ('m', 'x', '5', 'p'): // MPEG2 IMX PAL 625/60 50mb/s produced by FCP
534 case VLC_FOURCC ('m', 'x', '4', 'n'): // MPEG2 IMX NTSC 525/60 40mb/s produced by FCP
535 case VLC_FOURCC ('m', 'x', '4', 'p'): // MPEG2 IMX PAL 625/60 40mb/s produced by FCP
536 case VLC_FOURCC ('m', 'x', '3', 'n'): // MPEG2 IMX NTSC 525/60 30mb/s produced by FCP
537 case VLC_FOURCC ('m', 'x', '3', 'p'): // MPEG2 IMX PAL 625/50 30mb/s produced by FCP
538 case VLC_FOURCC ('x', 'd', 'v', '2'): // XDCAM HD 1080i60
539 case VLC_FOURCC ('A', 'V', 'm', 'p'): // AVID IMX PAL
540 p_track
->fmt
.i_codec
= VLC_CODEC_MPGV
;
542 /* qt decoder, send the complete chunk */
545 case VLC_FOURCC( 'V', 'P', '3', '1' ):
546 case VLC_FOURCC( '3', 'I', 'V', '1' ):
547 case VLC_FOURCC( 'Z', 'y', 'G', 'o' ):
549 p_track
->fmt
.i_extra
=
550 p_sample
->data
.p_sample_vide
->i_qt_image_description
;
551 if( p_track
->fmt
.i_extra
> 0 )
553 p_track
->fmt
.p_extra
= malloc( p_track
->fmt
.i_extra
);
554 memcpy( p_track
->fmt
.p_extra
,
555 p_sample
->data
.p_sample_vide
->p_qt_image_description
,
556 p_track
->fmt
.i_extra
);
561 case VLC_FOURCC( 'A', 'V', 'j', '2' ):
562 p_track
->fmt
.i_codec
= VLC_CODEC_JPEG2000
;
563 /* final decoded resolution stored in ARES w, h, nbfields to group
564 * but since avcodec can't tell... */
567 case VLC_FOURCC('j', 'p', 'e', 'g'):
568 p_track
->fmt
.i_codec
= VLC_CODEC_MJPG
;
573 MP4_Box_t
*p_binary
= MP4_BoxGet( p_sample
, "glbl" );
574 if( p_binary
&& BOXDATA(p_binary
) && BOXDATA(p_binary
)->i_blob
)
576 p_track
->fmt
.p_extra
= malloc( BOXDATA(p_binary
)->i_blob
);
577 if( p_track
->fmt
.p_extra
)
579 p_track
->fmt
.i_extra
= BOXDATA(p_binary
)->i_blob
;
580 memcpy( p_track
->fmt
.p_extra
, BOXDATA(p_binary
)->p_blob
,
581 p_track
->fmt
.i_extra
);
587 case VLC_FOURCC( 'v', 'c', '-', '1' ):
589 MP4_Box_t
*p_dvc1
= MP4_BoxGet( p_sample
, "dvc1" );
590 if( p_dvc1
&& BOXDATA(p_dvc1
) )
592 p_track
->fmt
.i_extra
= BOXDATA(p_dvc1
)->i_vc1
;
593 if( p_track
->fmt
.i_extra
> 0 )
595 p_track
->fmt
.p_extra
= malloc( BOXDATA(p_dvc1
)->i_vc1
);
596 memcpy( p_track
->fmt
.p_extra
, BOXDATA(p_dvc1
)->p_vc1
,
597 p_track
->fmt
.i_extra
);
602 msg_Err( p_demux
, "missing dvc1" );
609 static_assert(ATOM_av01
== VLC_CODEC_AV1
, "VLC_CODEC_AV1 != ATOM_av01");
610 MP4_Box_t
*p_av1C
= MP4_BoxGet( p_sample
, "av1C" );
611 if( p_av1C
&& BOXDATA(p_av1C
) )
613 p_track
->fmt
.i_profile
= BOXDATA(p_av1C
)->i_profile
;
614 p_track
->fmt
.i_level
= BOXDATA(p_av1C
)->i_level
;
615 if( BOXDATA(p_av1C
)->i_av1C
)
617 p_track
->fmt
.p_extra
= malloc( BOXDATA(p_av1C
)->i_av1C
);
618 if( p_track
->fmt
.p_extra
)
620 memcpy( p_track
->fmt
.p_extra
, BOXDATA(p_av1C
)->p_av1C
,
621 BOXDATA(p_av1C
)->i_av1C
);
622 p_track
->fmt
.i_extra
= BOXDATA(p_av1C
)->i_av1C
;
629 /* avc1: send avcC (h264 without annexe B, ie without start code)*/
630 case VLC_FOURCC( 'a', 'v', 'c', '3' ):
631 case VLC_FOURCC( 'a', 'v', 'c', '1' ):
632 case VLC_FOURCC( 'd', 'v', 'a', '1' ): /* DolbyVision */
633 case VLC_FOURCC( 'd', 'v', 'a', 'v' ): /* DolbyVision */
635 MP4_Box_t
*p_avcC
= MP4_BoxGet( p_sample
, "avcC" );
637 if( p_avcC
&& BOXDATA(p_avcC
) )
639 p_track
->fmt
.i_profile
= BOXDATA(p_avcC
)->i_profile
;
640 p_track
->fmt
.i_level
= BOXDATA(p_avcC
)->i_level
;
641 p_track
->fmt
.i_extra
= BOXDATA(p_avcC
)->i_avcC
;
642 if( p_track
->fmt
.i_extra
> 0 )
644 p_track
->fmt
.p_extra
= malloc( BOXDATA(p_avcC
)->i_avcC
);
645 memcpy( p_track
->fmt
.p_extra
, BOXDATA(p_avcC
)->p_avcC
,
646 p_track
->fmt
.i_extra
);
651 msg_Err( p_demux
, "missing avcC" );
655 case VLC_FOURCC( 'h', 'v', 'c', '1' ):
656 case VLC_FOURCC( 'h', 'e', 'v', '1' ):
657 case VLC_FOURCC( 'd', 'v', 'h', 'e' ): /* DolbyVision */
658 case VLC_FOURCC( 'd', 'v', 'h', '1' ): /* DolbyVision */
660 MP4_Box_t
*p_hvcC
= MP4_BoxGet( p_sample
, "hvcC" );
662 /* Handle DV fourcc collision at demux level */
663 if( p_sample
->i_type
== VLC_FOURCC( 'd', 'v', 'h', '1' ) )
664 p_track
->fmt
.i_codec
= VLC_FOURCC( 'd', 'v', 'h', 'e' );
666 if( p_hvcC
&& p_hvcC
->data
.p_binary
&& p_hvcC
->data
.p_binary
->i_blob
)
668 p_track
->fmt
.p_extra
= malloc( p_hvcC
->data
.p_binary
->i_blob
);
669 if( p_track
->fmt
.p_extra
)
671 p_track
->fmt
.i_extra
= p_hvcC
->data
.p_binary
->i_blob
;
672 memcpy( p_track
->fmt
.p_extra
, p_hvcC
->data
.p_binary
->p_blob
,
673 p_hvcC
->data
.p_binary
->i_blob
);
678 msg_Err( p_demux
, "missing hvcC" );
687 const MP4_Box_t
*p_vpcC
= MP4_BoxGet( p_sample
, "vpcC" );
688 if( p_vpcC
&& BOXDATA(p_vpcC
) )
690 const MP4_Box_data_vpcC_t
*p_data
= BOXDATA(p_vpcC
);
691 if( p_sample
->i_type
== ATOM_vp10
)
692 p_track
->fmt
.i_codec
= VLC_CODEC_VP10
;
693 else if( p_sample
->i_type
== ATOM_vp09
)
694 p_track
->fmt
.i_codec
= VLC_CODEC_VP9
;
696 p_track
->fmt
.i_codec
= VLC_CODEC_VP8
;
697 p_track
->fmt
.i_profile
= p_data
->i_profile
;
698 p_track
->fmt
.i_level
= p_data
->i_level
;
700 if( p_data
->i_version
== 0 ) /* old deprecated */
702 const uint8_t colorspacesmapping
[] =
707 COLOR_SPACE_SMPTE_170
,
708 COLOR_SPACE_SMPTE_240
,
713 if( p_data
->i_color_primaries
< ARRAY_SIZE(colorspacesmapping
) )
714 p_track
->fmt
.video
.space
= colorspacesmapping
[p_data
->i_color_primaries
];
716 if( p_data
->i_xfer_function
== 0 )
717 p_track
->fmt
.video
.transfer
= TRANSFER_FUNC_BT709
;
718 else if ( p_data
->i_xfer_function
== 1 )
719 p_track
->fmt
.video
.transfer
= TRANSFER_FUNC_SMPTE_ST2084
;
723 p_track
->fmt
.video
.primaries
=
724 iso_23001_8_cp_to_vlc_primaries( p_data
->i_color_primaries
);
725 p_track
->fmt
.video
.transfer
=
726 iso_23001_8_tc_to_vlc_xfer( p_data
->i_xfer_function
);
727 p_track
->fmt
.video
.space
=
728 iso_23001_8_mc_to_vlc_coeffs( p_data
->i_matrix_coeffs
);
731 p_track
->fmt
.video
.color_range
= p_data
->i_fullrange
? COLOR_RANGE_FULL
: COLOR_RANGE_LIMITED
;
732 p_track
->fmt
.video
.i_bits_per_pixel
= p_data
->i_bit_depth
;
734 if( p_data
->i_codec_init_datasize
)
736 p_track
->fmt
.p_extra
= malloc( p_data
->i_codec_init_datasize
);
737 if( p_track
->fmt
.p_extra
)
739 p_track
->fmt
.i_extra
= p_data
->i_codec_init_datasize
;
740 memcpy( p_track
->fmt
.p_extra
, p_data
->p_codec_init_data
,
741 p_data
->i_codec_init_datasize
);
745 const MP4_Box_t
*p_SmDm
= MP4_BoxGet( p_sample
, "SmDm" );
747 p_SmDm
= MP4_BoxGet( p_sample
, "mdcv" );
748 if( p_SmDm
&& BOXDATA(p_SmDm
) )
750 memcpy( p_track
->fmt
.video
.mastering
.primaries
,
751 BOXDATA(p_SmDm
)->primaries
, sizeof(uint16_t) * 6 );
752 memcpy( p_track
->fmt
.video
.mastering
.white_point
,
753 BOXDATA(p_SmDm
)->white_point
, sizeof(uint16_t) * 2 );
754 p_track
->fmt
.video
.mastering
.max_luminance
= BOXDATA(p_SmDm
)->i_luminanceMax
;
755 p_track
->fmt
.video
.mastering
.min_luminance
= BOXDATA(p_SmDm
)->i_luminanceMin
;
758 const MP4_Box_t
*p_CoLL
= MP4_BoxGet( p_sample
, "CoLL" );
760 p_CoLL
= MP4_BoxGet( p_sample
, "clli" );
761 if( p_CoLL
&& BOXDATA(p_CoLL
) )
763 p_track
->fmt
.video
.lighting
.MaxCLL
= BOXDATA(p_CoLL
)->i_maxCLL
;
764 p_track
->fmt
.video
.lighting
.MaxFALL
= BOXDATA(p_CoLL
)->i_maxFALL
;
771 p_track
->p_asf
= MP4_BoxGet( p_sample
, "ASF " );
774 case VLC_FOURCC('W','V','C','1'):
776 MP4_Box_t
*p_strf
= MP4_BoxGet( p_sample
, "strf", 0 );
777 if ( p_strf
&& BOXDATA(p_strf
) )
779 p_track
->fmt
.video
.i_width
= BOXDATA(p_strf
)->bmiHeader
.biWidth
;
780 p_track
->fmt
.video
.i_visible_width
= p_track
->fmt
.video
.i_width
;
781 p_track
->fmt
.video
.i_height
= BOXDATA(p_strf
)->bmiHeader
.biHeight
;
782 p_track
->fmt
.video
.i_visible_height
=p_track
->fmt
.video
.i_height
;
783 p_track
->fmt
.video
.i_bits_per_pixel
= BOXDATA(p_strf
)->bmiHeader
.biBitCount
;
784 p_track
->fmt
.i_extra
= BOXDATA(p_strf
)->i_extra
;
785 if( p_track
->fmt
.i_extra
> 0 )
787 p_track
->fmt
.p_extra
= malloc( BOXDATA(p_strf
)->i_extra
);
788 memcpy( p_track
->fmt
.p_extra
, BOXDATA(p_strf
)->p_extra
,
789 p_track
->fmt
.i_extra
);
795 case VLC_FOURCC( 'a', 'i', '5', 'p' ):
796 case VLC_FOURCC( 'a', 'i', '5', 'q' ):
797 case VLC_FOURCC( 'a', 'i', '5', '2' ):
798 case VLC_FOURCC( 'a', 'i', '5', '3' ):
799 case VLC_FOURCC( 'a', 'i', '5', '5' ):
800 case VLC_FOURCC( 'a', 'i', '5', '6' ):
801 case VLC_FOURCC( 'a', 'i', '1', 'p' ):
802 case VLC_FOURCC( 'a', 'i', '1', 'q' ):
803 case VLC_FOURCC( 'a', 'i', '1', '2' ):
804 case VLC_FOURCC( 'a', 'i', '1', '3' ):
805 case VLC_FOURCC( 'a', 'i', '1', '5' ):
806 case VLC_FOURCC( 'a', 'i', '1', '6' ):
808 if( !p_track
->fmt
.i_extra
&& p_track
->fmt
.video
.i_width
< UINT16_MAX
&&
809 p_fiel
&& BOXDATA(p_fiel
) )
811 p_track
->fmt
.p_extra
=
812 AVCi_create_AnnexB( p_track
->fmt
.video
.i_width
,
813 !!BOXDATA(p_fiel
)->i_flags
, &p_track
->fmt
.i_extra
);
819 msg_Dbg( p_demux
, "Unrecognized FourCC %4.4s", (char *)&p_sample
->i_type
);
826 static bool SetupAudioFromWaveFormatEx( es_format_t
*p_fmt
, const MP4_Box_t
*p_WMA2
)
828 if( p_WMA2
&& BOXDATA(p_WMA2
) )
830 wf_tag_to_fourcc(BOXDATA(p_WMA2
)->Format
.wFormatTag
, &p_fmt
->i_codec
, NULL
);
831 p_fmt
->audio
.i_channels
= BOXDATA(p_WMA2
)->Format
.nChannels
;
832 p_fmt
->audio
.i_rate
= BOXDATA(p_WMA2
)->Format
.nSamplesPerSec
;
833 p_fmt
->i_bitrate
= BOXDATA(p_WMA2
)->Format
.nAvgBytesPerSec
* 8;
834 p_fmt
->audio
.i_blockalign
= BOXDATA(p_WMA2
)->Format
.nBlockAlign
;
835 p_fmt
->audio
.i_bitspersample
= BOXDATA(p_WMA2
)->Format
.wBitsPerSample
;
836 p_fmt
->i_extra
= BOXDATA(p_WMA2
)->i_extra
;
837 if( p_fmt
->i_extra
> 0 )
839 p_fmt
->p_extra
= malloc( BOXDATA(p_WMA2
)->i_extra
);
840 memcpy( p_fmt
->p_extra
, BOXDATA(p_WMA2
)->p_extra
, p_fmt
->i_extra
);
847 int SetupAudioES( demux_t
*p_demux
, mp4_track_t
*p_track
, MP4_Box_t
*p_sample
)
849 MP4_Box_data_sample_soun_t
*p_soun
= p_sample
->data
.p_sample_soun
;
853 p_track
->fmt
.audio
.i_channels
= p_soun
->i_channelcount
;
854 p_track
->fmt
.audio
.i_rate
= p_soun
->i_sampleratehi
;
855 if( p_soun
->i_qt_version
== 0 ) /* otherwise defaults to meaningless 16 */
857 p_track
->fmt
.audio
.i_bitspersample
= p_soun
->i_samplesize
;
858 p_track
->fmt
.i_bitrate
= p_soun
->i_channelcount
* p_soun
->i_sampleratehi
*
859 p_soun
->i_samplesize
;
862 p_track
->fmt
.i_original_fourcc
= p_sample
->i_type
;
864 if( ( p_track
->i_sample_size
== 1 || p_track
->i_sample_size
== 2 ) )
866 if( p_soun
->i_qt_version
== 0 )
868 switch( p_sample
->i_type
)
870 case VLC_CODEC_ADPCM_IMA_QT
:
871 p_soun
->i_qt_version
= 1;
872 p_soun
->i_sample_per_packet
= 64;
873 p_soun
->i_bytes_per_packet
= 34;
874 p_soun
->i_bytes_per_frame
= 34 * p_soun
->i_channelcount
;
875 p_soun
->i_bytes_per_sample
= 2;
877 case VLC_CODEC_MACE3
:
878 p_soun
->i_qt_version
= 1;
879 p_soun
->i_sample_per_packet
= 6;
880 p_soun
->i_bytes_per_packet
= 2;
881 p_soun
->i_bytes_per_frame
= 2 * p_soun
->i_channelcount
;
882 p_soun
->i_bytes_per_sample
= 2;
884 case VLC_CODEC_MACE6
:
885 p_soun
->i_qt_version
= 1;
886 p_soun
->i_sample_per_packet
= 12;
887 p_soun
->i_bytes_per_packet
= 2;
888 p_soun
->i_bytes_per_frame
= 2 * p_soun
->i_channelcount
;
889 p_soun
->i_bytes_per_sample
= 2;
892 p_track
->fmt
.i_codec
= p_sample
->i_type
;
897 else if( p_soun
->i_qt_version
== 1 && p_soun
->i_sample_per_packet
<= 0 )
899 p_soun
->i_qt_version
= 0;
902 else if( p_sample
->data
.p_sample_soun
->i_qt_version
== 1 )
904 switch( p_sample
->i_type
)
906 case( VLC_FOURCC( '.', 'm', 'p', '3' ) ):
907 case( VLC_FOURCC( 'm', 's', 0x00, 0x55 ) ):
909 if( p_track
->i_sample_size
> 1 )
910 p_soun
->i_qt_version
= 0;
915 case( VLC_FOURCC( 'm', 's', 0x20, 0x00 ) ):
916 p_soun
->i_qt_version
= 0;
922 if ( p_sample
->data
.p_sample_soun
->i_compressionid
== 0xFFFE /* -2 */)
924 /* redefined sample tables for vbr audio */
926 else if ( p_track
->i_sample_size
!= 0 && p_soun
->i_sample_per_packet
== 0 )
928 msg_Err( p_demux
, "Invalid sample per packet value for qt_version 1. Broken muxer! %u %u",
929 p_track
->i_sample_size
, p_soun
->i_sample_per_packet
);
930 p_soun
->i_qt_version
= 0;
934 /* Endianness atom */
935 const MP4_Box_t
*p_enda
= MP4_BoxGet( p_sample
, "wave/enda" );
937 p_enda
= MP4_BoxGet( p_sample
, "enda" );
939 /* It's a little ugly but .. there are special cases */
940 switch( p_sample
->i_type
)
942 case( VLC_FOURCC( 'r', 'r', 't', 'p' ) ): /* RTP Reception Hint Track */
944 if( !SetupRTPReceptionHintTrack( p_demux
, p_track
, p_sample
) )
948 case ATOM_agsm
: /* Apple gsm 33 bytes != MS GSM (agsm fourcc, 65 bytes) */
949 p_track
->fmt
.i_codec
= VLC_CODEC_GSM
;
951 case( VLC_FOURCC( '.', 'm', 'p', '3' ) ):
952 case( VLC_FOURCC( 'm', 's', 0x00, 0x55 ) ):
954 p_track
->fmt
.i_codec
= VLC_CODEC_MPGA
;
959 const MP4_Box_t
*p_vCtH
= MP4_BoxGet( p_sample
, "wave/vCtH" ); /* kCookieTypeVorbisHeader */
960 const MP4_Box_t
*p_vCtd
= MP4_BoxGet( p_sample
, "wave/vCt#" ); /* kCookieTypeVorbisComments */
961 const MP4_Box_t
*p_vCtC
= MP4_BoxGet( p_sample
, "wave/vCtC" ); /* kCookieTypeVorbisCodebooks */
962 if( p_vCtH
&& p_vCtH
->data
.p_binary
&&
963 p_vCtd
&& p_vCtd
->data
.p_binary
&&
964 p_vCtC
&& p_vCtC
->data
.p_binary
)
966 unsigned headers_sizes
[3] = {
967 p_vCtH
->data
.p_binary
->i_blob
,
968 p_vCtd
->data
.p_binary
->i_blob
,
969 p_vCtC
->data
.p_binary
->i_blob
972 const void * headers
[3] = {
973 p_vCtH
->data
.p_binary
->p_blob
,
974 p_vCtd
->data
.p_binary
->p_blob
,
975 p_vCtC
->data
.p_binary
->p_blob
978 if( xiph_PackHeaders( &p_track
->fmt
.i_extra
, &p_track
->fmt
.p_extra
,
979 headers_sizes
, headers
, 3 ) == VLC_SUCCESS
)
981 p_track
->fmt
.i_codec
= VLC_CODEC_VORBIS
;
982 p_track
->fmt
.b_packetized
= false;
989 const MP4_Box_t
*p_fCtS
= MP4_BoxGet( p_sample
, "wave/fCtS" ); /* kCookieTypeFLACStreaminfo */
990 if( p_fCtS
&& p_fCtS
->data
.p_binary
)
992 size_t i_extra
= 8 + p_fCtS
->data
.p_binary
->i_blob
;
993 uint8_t *p_extra
= malloc(i_extra
);
996 p_track
->fmt
.i_extra
= i_extra
;
997 p_track
->fmt
.p_extra
= p_extra
;
998 memcpy( p_extra
, "fLaC", 4 );
999 SetDWBE( &p_extra
[4], p_fCtS
->data
.p_binary
->i_blob
); /* want the lowest 24bits */
1000 p_extra
[4] = 0x80; /* 0x80 Last metablock | 0x00 StreamInfo */
1001 memcpy( &p_extra
[8], p_fCtS
->data
.p_binary
->p_blob
, p_fCtS
->data
.p_binary
->i_blob
);
1003 p_track
->fmt
.i_codec
= VLC_CODEC_FLAC
;
1004 p_track
->fmt
.b_packetized
= false;
1011 const MP4_Box_t
*p_dfLa
= MP4_BoxGet( p_sample
, "dfLa", 0 );
1012 if( p_dfLa
&& p_dfLa
->data
.p_binary
->i_blob
> 4 &&
1013 GetDWBE(p_dfLa
->data
.p_binary
->p_blob
) == 0 ) /* fullbox header, avoids creating dedicated parser */
1015 size_t i_extra
= p_dfLa
->data
.p_binary
->i_blob
;
1016 uint8_t *p_extra
= malloc(i_extra
);
1017 if( likely( p_extra
) )
1019 p_track
->fmt
.i_extra
= i_extra
;
1020 p_track
->fmt
.p_extra
= p_extra
;
1021 memcpy( p_extra
, p_dfLa
->data
.p_binary
->p_blob
, p_dfLa
->data
.p_binary
->i_blob
);
1022 memcpy( p_extra
, "fLaC", 4 );
1023 p_track
->fmt
.i_codec
= VLC_CODEC_FLAC
;
1030 p_track
->fmt
.i_codec
= VLC_CODEC_EAC3
;
1031 /* TS 102.366. F6 The values of the ChannelCount and SampleSize fields
1032 * within the EC3SampleEntry Box shall be ignored. */
1033 p_track
->fmt
.audio
.i_channels
= 0;
1034 p_track
->fmt
.audio
.i_bitspersample
= 0;
1036 const MP4_Box_t
*p_dec3
= MP4_BoxGet( p_sample
, "dec3", 0 );
1037 if( p_dec3
&& BOXDATA(p_dec3
) )
1039 p_track
->fmt
.i_bitrate
= BOXDATA(p_dec3
)->i_data_rate
* 1000;
1046 p_track
->fmt
.i_codec
= VLC_CODEC_A52
;
1047 /* TS 102.366. F3 The values of the ChannelCount and SampleSize fields
1048 * within the AC3SampleEntry Box shall be ignored */
1049 p_track
->fmt
.audio
.i_channels
= 0;
1050 p_track
->fmt
.audio
.i_bitspersample
= 0;
1052 MP4_Box_t
*p_dac3
= MP4_BoxGet( p_sample
, "dac3", 0 );
1053 if( p_dac3
&& BOXDATA(p_dac3
) )
1055 static const int pi_bitrate
[] = {
1062 p_track
->fmt
.i_bitrate
= 0;
1063 if( BOXDATA(p_dac3
)->i_bitrate_code
< sizeof(pi_bitrate
)/sizeof(*pi_bitrate
) )
1064 p_track
->fmt
.i_bitrate
= pi_bitrate
[BOXDATA(p_dac3
)->i_bitrate_code
] * 1000;
1069 case ATOM_dtse
: /* DTS‐HD Lossless formats */
1070 case ATOM_dtsh
: /* DTS‐HD audio formats */
1071 case ATOM_dtsl
: /* DTS‐HD Lossless formats */
1073 p_track
->fmt
.i_codec
= VLC_CODEC_DTS
;
1074 p_track
->fmt
.i_profile
= PROFILE_DTS_HD
;
1078 case VLC_FOURCC( 't', 'w', 'o', 's' ):
1079 case VLC_FOURCC( 's', 'o', 'w', 't' ):
1080 p_track
->fmt
.i_codec
= p_sample
->i_type
;
1081 p_track
->fmt
.audio
.i_bitspersample
= 16;
1085 case( VLC_FOURCC( 'r', 'a', 'w', ' ' ) ):
1086 case( VLC_FOURCC( 'N', 'O', 'N', 'E' ) ):
1088 if( (p_soun
->i_samplesize
+7)/8 == 1 )
1090 p_track
->fmt
.i_codec
= VLC_CODEC_U8
;
1091 p_track
->fmt
.audio
.i_bitspersample
= 8;
1095 p_track
->fmt
.i_codec
= VLC_FOURCC( 't', 'w', 'o', 's' );
1096 p_track
->fmt
.audio
.i_bitspersample
= 16;
1098 p_track
->fmt
.i_original_fourcc
= p_track
->fmt
.i_codec
;
1100 /* Buggy files workaround */
1101 if( (p_track
->i_timescale
!= p_soun
->i_sampleratehi
) )
1103 msg_Warn( p_demux
, "i_timescale (%"PRId32
") != i_sampleratehi "
1104 "(%u), making both equal (report any problem).",
1105 p_track
->i_timescale
, p_soun
->i_sampleratehi
);
1107 if( p_soun
->i_sampleratehi
!= 0 )
1108 p_track
->i_timescale
= p_soun
->i_sampleratehi
;
1110 p_soun
->i_sampleratehi
= p_track
->i_timescale
;
1116 p_track
->fmt
.i_original_fourcc
=
1117 p_track
->fmt
.i_codec
= p_enda
&& BOXDATA(p_enda
)->i_little_endian
== 1 ?
1118 VLC_CODEC_S24L
: VLC_CODEC_S24B
;
1121 p_track
->fmt
.i_original_fourcc
=
1122 p_track
->fmt
.i_codec
= p_enda
&& BOXDATA(p_enda
)->i_little_endian
== 1 ?
1123 VLC_CODEC_S32L
: VLC_CODEC_S32B
;
1126 p_track
->fmt
.i_original_fourcc
=
1127 p_track
->fmt
.i_codec
= p_enda
&& BOXDATA(p_enda
)->i_little_endian
== 1 ?
1128 VLC_CODEC_F32L
: VLC_CODEC_F32B
;
1131 p_track
->fmt
.i_original_fourcc
=
1132 p_track
->fmt
.i_codec
= p_enda
&& BOXDATA(p_enda
)->i_little_endian
== 1 ?
1133 VLC_CODEC_F64L
: VLC_CODEC_F64B
;
1136 case VLC_CODEC_DVD_LPCM
:
1138 if( p_soun
->i_qt_version
== 2 )
1145 static const struct {
1149 vlc_fourcc_t i_codec
;
1151 { 0x01, 0x03, 32, VLC_CODEC_F32L
},
1152 { 0x01, 0x03, 64, VLC_CODEC_F64L
},
1153 { 0x01|0x02, 0x03, 32, VLC_CODEC_F32B
},
1154 { 0x01|0x02, 0x03, 64, VLC_CODEC_F64B
},
1156 { 0x00, 0x05, 8, VLC_CODEC_U8
},
1157 { 0x00| 0x04, 0x05, 8, VLC_CODEC_S8
},
1159 { 0x00, 0x07, 16, VLC_CODEC_U16L
},
1160 { 0x00|0x02, 0x07, 16, VLC_CODEC_U16B
},
1161 { 0x00 |0x04, 0x07, 16, VLC_CODEC_S16L
},
1162 { 0x00|0x02|0x04, 0x07, 16, VLC_CODEC_S16B
},
1164 { 0x00, 0x07, 24, VLC_CODEC_U24L
},
1165 { 0x00|0x02, 0x07, 24, VLC_CODEC_U24B
},
1166 { 0x00 |0x04, 0x07, 24, VLC_CODEC_S24L
},
1167 { 0x00|0x02|0x04, 0x07, 24, VLC_CODEC_S24B
},
1169 { 0x00, 0x07, 32, VLC_CODEC_U32L
},
1170 { 0x00|0x02, 0x07, 32, VLC_CODEC_U32B
},
1171 { 0x00 |0x04, 0x07, 32, VLC_CODEC_S32L
},
1172 { 0x00|0x02|0x04, 0x07, 32, VLC_CODEC_S32B
},
1177 for( int i
= 0; p_formats
[i
].i_codec
; i
++ )
1179 if( p_formats
[i
].i_bits
== p_soun
->i_constbitsperchannel
&&
1180 (p_soun
->i_formatflags
& p_formats
[i
].i_mask
) == p_formats
[i
].i_flags
)
1182 p_track
->fmt
.i_codec
= p_formats
[i
].i_codec
;
1183 p_track
->fmt
.audio
.i_bitspersample
= p_soun
->i_constbitsperchannel
;
1184 p_track
->fmt
.audio
.i_blockalign
=
1185 p_soun
->i_channelcount
* p_soun
->i_constbitsperchannel
/ 8;
1186 p_track
->i_sample_size
= p_track
->fmt
.audio
.i_blockalign
;
1188 p_soun
->i_qt_version
= 0;
1196 p_track
->fmt
.i_codec
= p_sample
->i_type
;
1201 /* Process extensions */
1203 /* Lookup for then channels extension */
1204 const MP4_Box_t
*p_chan
= MP4_BoxGet( p_sample
, "chan" );
1207 uint16_t i_vlc_mapping
= 0;
1208 uint8_t i_channels
= 0;
1209 const uint32_t *p_rg_chans_order
= NULL
;
1211 if ( CoreAudio_Layout_to_vlc( &BOXDATA(p_chan
)->layout
,
1212 &i_vlc_mapping
, &i_channels
,
1213 &p_rg_chans_order
) != VLC_SUCCESS
)
1215 msg_Warn( p_demux
, "discarding chan mapping" );
1217 else if( i_vlc_mapping
)
1219 const unsigned i_bps
= aout_BitsPerSample( p_track
->fmt
.i_codec
);
1220 /* Uncompressed audio */
1221 if( i_bps
&& aout_CheckChannelReorder( p_rg_chans_order
, NULL
,
1223 p_track
->rgi_chans_reordering
) )
1224 p_track
->b_chans_reorder
= true;
1226 /* we can only set bitmap for VLC mapping or [re]mapped pcm audio
1227 * as vlc can't enumerate channels for compressed content */
1228 if( i_bps
|| p_track
->rgi_chans_reordering
== NULL
)
1230 p_track
->fmt
.audio
.i_channels
= vlc_popcount(i_vlc_mapping
);
1231 p_track
->fmt
.audio
.i_physical_channels
= i_vlc_mapping
;
1236 SetupGlobalExtensions( p_track
, p_sample
);
1238 /* now see if esds is present and if so create a data packet
1239 with decoder_specific_info */
1240 MP4_Box_t
*p_esds
= MP4_BoxGet( p_sample
, "esds" );
1241 if ( !p_esds
) p_esds
= MP4_BoxGet( p_sample
, "wave/esds" );
1242 if ( p_esds
&& BOXDATA(p_esds
) && BOXDATA(p_esds
)->es_descriptor
.p_decConfigDescr
)
1244 assert(p_sample
->i_type
== ATOM_mp4a
);
1245 SetupESDS( p_demux
, p_track
, BOXDATA(p_esds
)->es_descriptor
.p_decConfigDescr
);
1247 else switch( p_sample
->i_type
)
1249 case VLC_CODEC_AMR_NB
:
1250 p_track
->fmt
.audio
.i_rate
= 8000;
1252 case VLC_CODEC_AMR_WB
:
1253 p_track
->fmt
.audio
.i_rate
= 16000;
1255 case VLC_CODEC_QDMC
:
1256 case VLC_CODEC_QDM2
:
1257 case VLC_CODEC_ALAC
:
1259 p_track
->fmt
.i_extra
=
1260 p_sample
->data
.p_sample_soun
->i_qt_description
;
1261 if( p_track
->fmt
.i_extra
> 0 )
1263 p_track
->fmt
.p_extra
= malloc( p_track
->fmt
.i_extra
);
1264 memcpy( p_track
->fmt
.p_extra
,
1265 p_sample
->data
.p_sample_soun
->p_qt_description
,
1266 p_track
->fmt
.i_extra
);
1268 if( p_track
->fmt
.i_extra
== 56 && p_sample
->i_type
== VLC_CODEC_ALAC
)
1270 p_track
->fmt
.audio
.i_channels
= *((uint8_t*)p_track
->fmt
.p_extra
+ 41);
1271 p_track
->fmt
.audio
.i_rate
= GetDWBE((uint8_t*)p_track
->fmt
.p_extra
+ 52);
1275 case VLC_CODEC_ADPCM_MS
:
1276 case VLC_CODEC_ADPCM_IMA_WAV
:
1277 case VLC_CODEC_QCELP
:
1279 p_track
->fmt
.audio
.i_blockalign
= p_sample
->data
.p_sample_soun
->i_bytes_per_frame
;
1284 if( SetupAudioFromWaveFormatEx( &p_track
->fmt
,
1285 MP4_BoxGet( p_sample
, "wave/WMA2" ) ) )
1287 p_track
->p_asf
= MP4_BoxGet( p_sample
, "wave/ASF " );
1291 msg_Err( p_demux
, "missing WMA2 %4.4s", (char*) &p_sample
->p_father
->i_type
);
1295 case ATOM_wma
: /* isml wmapro */
1297 if( !SetupAudioFromWaveFormatEx( &p_track
->fmt
, MP4_BoxGet( p_sample
, "wfex" ) ) )
1298 msg_Err( p_demux
, "missing wfex for wma" );
1303 if(p_track
->fmt
.i_codec
== 0)
1304 msg_Dbg( p_demux
, "Unrecognized FourCC %4.4s", (char *)&p_sample
->i_type
);
1309 const MP4_Box_t
*p_SA3D
= MP4_BoxGet(p_sample
, "SA3D");
1310 if (p_SA3D
&& BOXDATA(p_SA3D
))
1311 p_track
->fmt
.audio
.channel_type
= AUDIO_CHANNEL_TYPE_AMBISONICS
;
1314 if ( p_soun
->i_qt_version
== 0 && p_track
->fmt
.i_codec
== VLC_CODEC_QCELP
)
1316 /* Shouldn't be v0, as it is a compressed codec !*/
1317 p_soun
->i_qt_version
= 1;
1318 p_soun
->i_compressionid
= 0xFFFE;
1324 int SetupSpuES( demux_t
*p_demux
, mp4_track_t
*p_track
, MP4_Box_t
*p_sample
)
1326 /* It's a little ugly but .. there are special cases */
1327 switch( p_sample
->i_type
)
1329 case VLC_FOURCC('s','t','p','p'):
1330 p_track
->fmt
.i_codec
= VLC_CODEC_TTML
;
1333 p_track
->fmt
.i_codec
= VLC_CODEC_WEBVTT
;
1335 case ATOM_c608
: /* EIA608 closed captions */
1336 p_track
->fmt
.i_codec
= VLC_CODEC_CEA608
;
1337 p_track
->fmt
.subs
.cc
.i_reorder_depth
= -1;
1339 case ATOM_c708
: /* EIA708 closed captions */
1340 p_track
->fmt
.i_codec
= VLC_CODEC_CEA708
;
1341 p_track
->fmt
.subs
.cc
.i_reorder_depth
= -1;
1344 case( VLC_FOURCC( 't', 'e', 'x', 't' ) ):
1345 case( VLC_FOURCC( 't', 'x', '3', 'g' ) ):
1347 const MP4_Box_data_sample_text_t
*p_text
= p_sample
->data
.p_sample_text
;
1351 if( p_sample
->i_type
== VLC_FOURCC( 't', 'e', 'x', 't' ) )
1352 p_track
->fmt
.i_codec
= VLC_CODEC_QTXT
;
1354 p_track
->fmt
.i_codec
= VLC_CODEC_TX3G
;
1356 if( GetDWBE(p_text
->p_data
) & 0xC0000000 )
1358 p_track
->fmt
.i_priority
= ES_PRIORITY_SELECTABLE_MIN
+ 1;
1359 p_track
->b_forced_spu
= true;
1362 p_track
->fmt
.p_extra
= malloc( p_text
->i_data
);
1363 if( p_track
->fmt
.p_extra
)
1365 memcpy( p_track
->fmt
.p_extra
, p_text
->p_data
, p_text
->i_data
);
1366 p_track
->fmt
.i_extra
= p_text
->i_data
;
1369 /* FIXME UTF-8 doesn't work here ? */
1370 if( p_track
->b_mac_encoding
)
1371 p_track
->fmt
.subs
.psz_encoding
= strdup( "MAC" );
1373 p_track
->fmt
.subs
.psz_encoding
= strdup( "UTF-8" );
1378 p_track
->fmt
.i_codec
= p_sample
->i_type
;
1382 SetupGlobalExtensions( p_track
, p_sample
);
1384 /* now see if esds is present and if so create a data packet
1385 with decoder_specific_info */
1386 MP4_Box_t
*p_esds
= MP4_BoxGet( p_sample
, "esds" );
1387 if ( p_esds
&& BOXDATA(p_esds
) && BOXDATA(p_esds
)->es_descriptor
.p_decConfigDescr
)
1389 SetupESDS( p_demux
, p_track
, BOXDATA(p_esds
)->es_descriptor
.p_decConfigDescr
);