1 /*****************************************************************************
2 * libmp4mux.c: mp4/mov muxer
3 *****************************************************************************
4 * Copyright (C) 2001, 2002, 2003, 2006, 20115 VLC authors and VideoLAN
6 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7 * Gildas Bazin <gbazin at videolan dot org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
27 #include "libmp4mux.h"
28 #include "../demux/mp4/libmp4.h" /* flags */
29 #include "../packetizer/hevc_nal.h"
30 #include "../packetizer/h264_nal.h" /* h264_AnnexB_get_spspps */
31 #include "../packetizer/hxxx_nal.h"
34 #include <vlc_iso_lang.h>
39 bool mp4mux_trackinfo_Init(mp4mux_trackinfo_t
*p_stream
, unsigned i_id
,
42 memset(p_stream
, 0, sizeof(*p_stream
));
43 p_stream
->i_track_id
= i_id
;
45 p_stream
->i_timescale
= i_timescale
;
46 p_stream
->i_entry_count
= 0;
47 p_stream
->i_entry_max
= 1000;
49 p_stream
->entry
= calloc(p_stream
->i_entry_max
, sizeof(mp4mux_entry_t
));
53 es_format_Init(&p_stream
->fmt
, UNKNOWN_ES
, 0);
58 void mp4mux_trackinfo_Clear(mp4mux_trackinfo_t
*p_stream
)
60 es_format_Clean(&p_stream
->fmt
);
61 if (p_stream
->a52_frame
)
62 block_Release(p_stream
->a52_frame
);
63 free(p_stream
->entry
);
64 free(p_stream
->p_edits
);
68 bo_t
*box_new(const char *fcc
)
70 bo_t
*box
= malloc(sizeof(*box
));
74 if(!bo_init(box
, 1024))
81 bo_add_fourcc(box
, fcc
);
86 bo_t
*box_full_new(const char *fcc
, uint8_t v
, uint32_t f
)
88 bo_t
*box
= box_new(fcc
);
98 void box_fix(bo_t
*box
, uint32_t i_size
)
100 bo_set_32be(box
, 0, i_size
);
103 void box_gather (bo_t
*box
, bo_t
*box2
)
105 if(box2
&& box2
->b
&& box
&& box
->b
)
107 box_fix(box2
, box2
->b
->i_buffer
);
108 size_t i_offset
= box
->b
->i_buffer
;
109 box
->b
= block_Realloc(box
->b
, 0, box
->b
->i_buffer
+ box2
->b
->i_buffer
);
111 memcpy(&box
->b
->p_buffer
[i_offset
], box2
->b
->p_buffer
, box2
->b
->i_buffer
);
116 static inline void bo_add_mp4_tag_descr(bo_t
*box
, uint8_t tag
, uint32_t size
)
119 for (int i
= 3; i
>0; i
--)
120 bo_add_8(box
, (size
>>(7*i
)) | 0x80);
121 bo_add_8(box
, size
& 0x7F);
124 static int64_t get_timestamp(void)
126 int64_t i_timestamp
= time(NULL
);
128 i_timestamp
+= 2082844800; // MOV/MP4 start date is 1/1/1904
129 // 208284480 is (((1970 - 1904) * 365) + 17) * 24 * 60 * 60
134 /****************************************************************************/
136 static void matrix_apply_rotation(es_format_t
*fmt
, uint32_t mvhd_matrix
[9])
138 enum video_orientation_t orientation
= ORIENT_NORMAL
;
139 if (fmt
->i_cat
== VIDEO_ES
)
140 orientation
= fmt
->video
.orientation
;
144 mvhd_matrix[1] = ((uint32_t)(a)) << 16; \
145 mvhd_matrix[0] = ((uint32_t)(b)) << 16; \
148 switch (orientation
) {
149 case ORIENT_ROTATED_90
: ATAN( 1, 0); break;
150 case ORIENT_ROTATED_180
: ATAN( 0, -1); break;
151 case ORIENT_ROTATED_270
: ATAN(-1, 0); break;
152 default: ATAN( 0, 1); break;
155 mvhd_matrix
[3] = mvhd_matrix
[0] ? 0 : 0x10000;
156 mvhd_matrix
[4] = mvhd_matrix
[1] ? 0 : 0x10000;
159 static void AddEdit(bo_t
*elst
,
160 int64_t i_movie_scaled_duration
,
161 int64_t i_media_scaled_time
,
166 bo_add_64be(elst
, i_movie_scaled_duration
);
167 bo_add_64be(elst
, i_media_scaled_time
);
171 bo_add_32be(elst
, i_movie_scaled_duration
);
172 bo_add_32be(elst
, i_media_scaled_time
);
174 bo_add_16be(elst
, 1);
175 bo_add_16be(elst
, 0);
178 static bo_t
*GetEDTS( mp4mux_trackinfo_t
*p_track
, uint32_t i_movietimescale
, bool b_64_ext
)
180 if(p_track
->i_edits_count
== 0)
183 bo_t
*edts
= box_new("edts");
184 bo_t
*elst
= box_full_new("elst", b_64_ext
? 1 : 0, 0);
192 uint32_t i_total_edits
= p_track
->i_edits_count
;
193 for(unsigned i
=0; i
<p_track
->i_edits_count
; i
++)
195 /* !WARN! media time must start sample time 0, we need a -1 edit for start offsets */
196 if(p_track
->p_edits
[i
].i_start_offset
)
200 bo_add_32be(elst
, i_total_edits
);
202 for(unsigned i
=0; i
<p_track
->i_edits_count
; i
++)
204 if(p_track
->p_edits
[i
].i_start_offset
)
207 p_track
->p_edits
[i
].i_start_offset
* i_movietimescale
/ CLOCK_FREQ
,
212 /* !WARN AGAIN! Uses different Timescales ! */
214 p_track
->p_edits
[i
].i_duration
* i_movietimescale
/ CLOCK_FREQ
,
215 p_track
->p_edits
[i
].i_start_time
* p_track
->i_timescale
/ CLOCK_FREQ
,
219 box_gather(edts
, elst
);
223 static bo_t
*GetESDS(mp4mux_trackinfo_t
*p_track
)
228 int i_decoder_specific_info_size
= (p_track
->fmt
.i_extra
> 0) ? 5 + p_track
->fmt
.i_extra
: 0;
230 esds
= box_full_new("esds", 0, 0);
234 /* Compute Max bitrate */
235 int64_t i_bitrate_avg
= 0;
236 int64_t i_bitrate_max
= 0;
237 /* Compute avg/max bitrate */
238 for (unsigned i
= 0; i
< p_track
->i_entry_count
; i
++) {
239 i_bitrate_avg
+= p_track
->entry
[i
].i_size
;
240 if (p_track
->entry
[i
].i_length
> 0) {
241 int64_t i_bitrate
= INT64_C(8000000) * p_track
->entry
[i
].i_size
/ p_track
->entry
[i
].i_length
;
242 if (i_bitrate
> i_bitrate_max
)
243 i_bitrate_max
= i_bitrate
;
247 if (p_track
->i_read_duration
> 0)
248 i_bitrate_avg
= INT64_C(8000000) * i_bitrate_avg
/ p_track
->i_read_duration
;
251 if (i_bitrate_max
<= 1)
252 i_bitrate_max
= 0x7fffffff;
255 bo_add_mp4_tag_descr(esds
, 0x03, 3 + 5 + 13 + i_decoder_specific_info_size
+ 5 + 1);
256 bo_add_16be(esds
, p_track
->i_track_id
);
257 bo_add_8 (esds
, 0x1f); // flags=0|streamPriority=0x1f
259 /* DecoderConfigDescr */
260 bo_add_mp4_tag_descr(esds
, 0x04, 13 + i_decoder_specific_info_size
);
262 int i_object_type_indication
;
263 switch(p_track
->fmt
.i_codec
)
266 i_object_type_indication
= 0x20;
269 if(p_track
->fmt
.i_original_fourcc
== VLC_CODEC_MP1V
)
271 i_object_type_indication
= 0x6b;
275 /* MPEG-I=0x6b, MPEG-II = 0x60 -> 0x65 */
276 i_object_type_indication
= 0x65;
279 /* MPEG-I=0x6b, MPEG-II = 0x60 -> 0x65 */
280 i_object_type_indication
= 0x6b;
283 /* FIXME for mpeg2-aac == 0x66->0x68 */
284 i_object_type_indication
= 0x40;
287 i_object_type_indication
=
288 p_track
->fmt
.audio
.i_rate
< 32000 ? 0x69 : 0x6b;
291 i_object_type_indication
= 0xa9;
294 i_object_type_indication
= 0xFE; /* No profile specified */
298 uint8_t i_stream_type
;
299 switch(p_track
->fmt
.i_cat
)
302 i_stream_type
= 0x04;
305 i_stream_type
= 0x05;
308 i_stream_type
= 0x0D;
311 i_stream_type
= 0x20; /* Private */
315 bo_add_8 (esds
, i_object_type_indication
);
316 bo_add_8 (esds
, (i_stream_type
<< 2) | 1);
317 bo_add_24be(esds
, 1024 * 1024); // bufferSizeDB
318 bo_add_32be(esds
, i_bitrate_max
); // maxBitrate
319 bo_add_32be(esds
, i_bitrate_avg
); // avgBitrate
321 if (p_track
->fmt
.i_extra
> 0) {
322 /* DecoderSpecificInfo */
323 bo_add_mp4_tag_descr(esds
, 0x05, p_track
->fmt
.i_extra
);
325 for (int i
= 0; i
< p_track
->fmt
.i_extra
; i
++)
326 bo_add_8(esds
, ((uint8_t*)p_track
->fmt
.p_extra
)[i
]);
329 /* SL_Descr mandatory */
330 bo_add_mp4_tag_descr(esds
, 0x06, 1);
331 bo_add_8 (esds
, 0x02); // sl_predefined
336 static bo_t
*GetWaveTag(mp4mux_trackinfo_t
*p_track
)
341 wave
= box_new("wave");
344 box
= box_new("frma");
347 bo_add_fourcc(box
, "mp4a");
348 box_gather(wave
, box
);
351 box
= box_new("mp4a");
355 box_gather(wave
, box
);
358 box
= GetESDS(p_track
);
359 box_gather(wave
, box
);
361 box
= box_new("srcq");
364 bo_add_32be(box
, 0x40);
365 box_gather(wave
, box
);
369 bo_add_32be(wave
, 8); /* new empty box */
370 bo_add_32be(wave
, 0); /* box label */
375 static bo_t
*GetDec3Tag(es_format_t
*p_fmt
, block_t
*a52_frame
)
381 bs_write_init(&s
, a52_frame
->p_buffer
, sizeof(a52_frame
->i_buffer
));
382 bs_skip(&s
, 16); // syncword
384 uint8_t fscod
, bsid
, bsmod
, acmod
, lfeon
, strmtyp
;
388 strmtyp
= bs_read(&s
, 2);
390 if (strmtyp
& 0x1) // dependent or reserved stream
393 if (bs_read(&s
, 3) != 0x0) // substreamid: we don't support more than 1 stream
397 bs_skip(&s
, 11); // frmsizecod
398 fscod
= bs_read(&s
, 2);
400 bs_skip(&s
, 2); // fscod2
403 numblkscod
= bs_read(&s
, 2);
406 acmod
= bs_read(&s
, 3);
407 lfeon
= bs_read1(&s
);
409 bsid
= bs_read(&s
, 5);
411 bs_skip(&s
, 5); // dialnorm
412 if (bs_read1(&s
)) // compre
413 bs_skip(&s
, 5); // compr
416 bs_skip(&s
, 5); // dialnorm2
417 if (bs_read1(&s
)) // compr2e
418 bs_skip(&s
, 8); // compr2
421 if (strmtyp
== 0x1) // dependent stream XXX: unsupported
422 if (bs_read1(&s
)) // chanmape
423 bs_skip(&s
, 16); // chanmap
425 /* we have to skip mixing info to read bsmod */
426 if (bs_read1(&s
)) { // mixmdate
427 if (acmod
> 0x2) // 2+ channels
428 bs_skip(&s
, 2); // dmixmod
429 if ((acmod
& 0x1) && (acmod
> 0x2)) // 3 front channels
430 bs_skip(&s
, 3 + 3); // ltrtcmixlev + lorocmixlev
431 if (acmod
& 0x4) // surround channel
432 bs_skip(&s
, 3 + 3); // ltrsurmixlev + lorosurmixlev
435 bs_skip(&s
, 5); // lfemixlevcod
436 if (strmtyp
== 0) { // independent stream
437 if (bs_read1(&s
)) // pgmscle
438 bs_skip(&s
, 6); // pgmscl
439 if (acmod
== 0x0) // dual mono
440 if (bs_read1(&s
)) // pgmscl2e
441 bs_skip(&s
, 6); // pgmscl2
442 if (bs_read1(&s
)) // extpgmscle
443 bs_skip(&s
, 6); // extpgmscl
444 uint8_t mixdef
= bs_read(&s
, 2);
447 else if (mixdef
== 0x2)
449 else if (mixdef
== 0x3) {
450 uint8_t mixdeflen
= bs_read(&s
, 5);
451 bs_skip(&s
, 8 * (mixdeflen
+ 2));
453 if (acmod
< 0x2) { // mono or dual mono
454 if (bs_read1(&s
)) // paninfoe
455 bs_skip(&s
, 14); // paninfo
456 if (acmod
== 0) // dual mono
457 if (bs_read1(&s
)) // paninfo2e
458 bs_skip(&s
, 14); // paninfo2
460 if (bs_read1(&s
)) { // frmmixcfginfoe
461 static const int blocks
[4] = { 1, 2, 3, 6 };
462 int number_of_blocks
= blocks
[numblkscod
];
463 if (number_of_blocks
== 1)
464 bs_skip(&s
, 5); // blkmixcfginfo[0]
465 else for (int i
= 0; i
< number_of_blocks
; i
++)
466 if (bs_read1(&s
)) // blkmixcfginfoe
467 bs_skip(&s
, 5); // blkmixcfginfo[i]
472 if (bs_read1(&s
)) // infomdate
473 bsmod
= bs_read(&s
, 3);
475 uint8_t mp4_eac3_header
[5] = {0};
476 bs_init(&s
, mp4_eac3_header
, sizeof(mp4_eac3_header
));
478 int data_rate
= p_fmt
->i_bitrate
/ 1000;
479 bs_write(&s
, 13, data_rate
);
480 bs_write(&s
, 3, 0); // num_ind_sub - 1
481 bs_write(&s
, 2, fscod
);
482 bs_write(&s
, 5, bsid
);
483 bs_write(&s
, 5, bsmod
);
484 bs_write(&s
, 3, acmod
);
485 bs_write(&s
, 1, lfeon
);
486 bs_write(&s
, 3, 0); // reserved
487 bs_write(&s
, 4, 0); // num_dep_sub
488 bs_write(&s
, 1, 0); // reserved
490 bo_t
*dec3
= box_new("dec3");
492 bo_add_mem(dec3
, sizeof(mp4_eac3_header
), mp4_eac3_header
);
497 static bo_t
*GetDac3Tag(block_t
*a52_frame
)
502 bo_t
*dac3
= box_new("dac3");
507 bs_init(&s
, a52_frame
->p_buffer
, sizeof(a52_frame
->i_buffer
));
509 uint8_t fscod
, bsid
, bsmod
, acmod
, lfeon
, frmsizecod
;
511 bs_skip(&s
, 16 + 16); // syncword + crc
513 fscod
= bs_read(&s
, 2);
514 frmsizecod
= bs_read(&s
, 6);
515 bsid
= bs_read(&s
, 5);
516 bsmod
= bs_read(&s
, 3);
517 acmod
= bs_read(&s
, 3);
519 bs_skip(&s
, 2); // dsurmod
521 if ((acmod
& 1) && acmod
!= 1)
522 bs_skip(&s
, 2); // cmixlev
524 bs_skip(&s
, 2); // surmixlev
527 lfeon
= bs_read1(&s
);
529 uint8_t mp4_a52_header
[3];
530 bs_init(&s
, mp4_a52_header
, sizeof(mp4_a52_header
));
532 bs_write(&s
, 2, fscod
);
533 bs_write(&s
, 5, bsid
);
534 bs_write(&s
, 3, bsmod
);
535 bs_write(&s
, 3, acmod
);
536 bs_write(&s
, 1, lfeon
);
537 bs_write(&s
, 5, frmsizecod
>> 1); // bit_rate_code
538 bs_write(&s
, 5, 0); // reserved
540 bo_add_mem(dac3
, sizeof(mp4_a52_header
), mp4_a52_header
);
545 static bo_t
*GetDamrTag(es_format_t
*p_fmt
)
547 bo_t
*damr
= box_new("damr");
551 bo_add_fourcc(damr
, "REFC");
554 if (p_fmt
->i_codec
== VLC_CODEC_AMR_NB
)
555 bo_add_16be(damr
, 0x81ff); /* Mode set (all modes for AMR_NB) */
557 bo_add_16be(damr
, 0x83ff); /* Mode set (all modes for AMR_WB) */
558 bo_add_16be(damr
, 0x1); /* Mode change period (no restriction) */
563 static bo_t
*GetD263Tag(void)
565 bo_t
*d263
= box_new("d263");
569 bo_add_fourcc(d263
, "VLC ");
570 bo_add_16be(d263
, 0xa);
576 static void hevcParseVPS(uint8_t * p_buffer
, size_t i_buffer
, uint8_t *general
,
577 uint8_t * numTemporalLayer
, bool * temporalIdNested
)
583 bs_init(&bs
, p_buffer
, i_buffer
);
584 unsigned i_bitflow
= 0;
585 bs
.p_fwpriv
= &i_bitflow
;
586 bs
.pf_forward
= hxxx_bsfw_ep3b_to_rbsp
; /* Does the emulated 3bytes conversion to rbsp */
588 /* first two bytes are the NAL header, 3rd and 4th are:
589 vps_video_parameter_set_id(4)
590 vps_reserved_3_2bis(2)
591 vps_max_layers_minus1(6)
592 vps_max_sub_layers_minus1(3)
593 vps_temporal_id_nesting_flags
595 bs_skip( &bs
, 16 + 4 + 2 + 6 );
596 *numTemporalLayer
= bs_read( &bs
, 3 ) + 1;
597 *temporalIdNested
= bs_read1( &bs
);
599 /* 5th & 6th are reserved 0xffff */
601 /* copy the first 12 bytes of profile tier */
602 for(unsigned i
=0; i
<12; i
++)
603 general
[i
] = bs_read( &bs
, 8 );
606 static inline void hevc_skip_profile_tiers_level( bs_t
* bs
, int32_t max_sub_layer_minus1
)
608 uint8_t sub_layer_profile_present_flag
[8];
609 uint8_t sub_layer_level_present_flag
[8];
611 /* skipping useless fields of the VPS see https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-H.265-201304-I!!PDF-E&type=item */
612 bs_skip( bs
, 2 + 1 + 5 + 32 + 1 + 1 + 1 + 1 + 44 + 8 );
614 for( int32_t i
= 0; i
< max_sub_layer_minus1
; i
++ )
616 sub_layer_profile_present_flag
[i
] = bs_read1( bs
);
617 sub_layer_level_present_flag
[i
] = bs_read1( bs
);
620 if(max_sub_layer_minus1
> 0)
621 bs_skip( bs
, (8 - max_sub_layer_minus1
) * 2 );
623 for( int32_t i
= 0; i
< max_sub_layer_minus1
; i
++ )
625 if( sub_layer_profile_present_flag
[i
] )
626 bs_skip( bs
, 2 + 1 + 5 + 32 + 1 + 1 + 1 + 1 + 44 );
627 if( sub_layer_level_present_flag
[i
] )
632 static void hevcParseSPS(uint8_t * p_buffer
, size_t i_buffer
, uint8_t * chroma_idc
,
633 uint8_t *bit_depth_luma_minus8
, uint8_t *bit_depth_chroma_minus8
)
639 bs_init(&bs
, p_buffer
+ 2, i_buffer
- 2);
640 unsigned i_bitflow
= 0;
641 bs
.p_fwpriv
= &i_bitflow
;
642 bs
.pf_forward
= hxxx_bsfw_ep3b_to_rbsp
; /* Does the emulated 3bytes conversion to rbsp */
646 uint32_t sps_max_sublayer_minus1
= bs_read(&bs
, 3);
648 /* skip nesting flag */
651 hevc_skip_profile_tiers_level(&bs
, sps_max_sublayer_minus1
);
654 (void) bs_read_ue( &bs
);
656 *chroma_idc
= bs_read_ue(&bs
);
657 if (*chroma_idc
== 3)
660 /* skip width and heigh */
661 (void) bs_read_ue( &bs
);
662 (void) bs_read_ue( &bs
);
664 uint32_t conformance_window_flag
= bs_read1(&bs
);
665 if (conformance_window_flag
) {
667 (void) bs_read_ue(&bs
);
668 (void) bs_read_ue(&bs
);
669 (void) bs_read_ue(&bs
);
670 (void) bs_read_ue(&bs
);
672 *bit_depth_luma_minus8
= bs_read_ue(&bs
);
673 *bit_depth_chroma_minus8
= bs_read_ue(&bs
);
676 static bo_t
*GetHvcCTag(es_format_t
*p_fmt
, bool b_completeness
)
678 /* Generate hvcC box matching iso/iec 14496-15 3rd edition */
679 bo_t
*hvcC
= box_new("hvcC");
680 if(!hvcC
|| !p_fmt
->i_extra
)
688 struct nal rg_vps
[HEVC_VPS_ID_MAX
+ 1], rg_sps
[HEVC_SPS_ID_MAX
+ 1],
689 rg_pps
[HEVC_PPS_ID_MAX
+ 1], *p_sei
= NULL
, *p_nal
= NULL
;
690 uint8_t i_vps
= 0, i_sps
= 0, i_pps
= 0, i_num_arrays
= 0;
693 uint8_t * p_buffer
= p_fmt
->p_extra
;
694 size_t i_buffer
= p_fmt
->i_extra
;
696 /* Extradata is already an HEVCDecoderConfigurationRecord */
697 if(hevc_ishvcC(p_buffer
, i_buffer
))
699 (void) bo_add_mem(hvcC
, i_buffer
, p_buffer
);
703 uint8_t general_configuration
[12] = {0};
704 uint8_t i_numTemporalLayer
= 0;
705 uint8_t i_chroma_idc
= 1;
706 uint8_t i_bit_depth_luma_minus8
= 0;
707 uint8_t i_bit_depth_chroma_minus8
= 0;
708 bool b_temporalIdNested
= false;
710 uint32_t cmp
= 0xFFFFFFFF;
712 /* look for start code 0X0000001 */
714 cmp
= (cmp
<< 8) | *p_buffer
;
715 if((cmp
^ UINT32_C(0x100)) <= UINT32_C(0xFF))
721 p_nal
->i_buffer
= p_buffer
- p_nal
->p_buffer
- ((i_buffer
)?3:0);
723 switch (hevc_getNALType(p_buffer
)) {
726 if(i_vps
> HEVC_VPS_ID_MAX
)
728 p_nal
= &rg_vps
[i_vps
++];
729 p_nal
->p_buffer
= p_buffer
;
730 /* Only keep the general profile from the first VPS
731 * if there are several (this shouldn't happen so soon) */
733 hevcParseVPS(p_buffer
, i_buffer
, general_configuration
,
734 &i_numTemporalLayer
, &b_temporalIdNested
);
740 if(i_sps
> HEVC_SPS_ID_MAX
)
742 p_nal
= &rg_sps
[i_sps
++];
743 p_nal
->p_buffer
= p_buffer
;
744 if (i_sps
== 1 && i_buffer
> 15) {
745 /* Get Chroma_idc and bitdepths */
746 hevcParseSPS(p_buffer
, i_buffer
, &i_chroma_idc
,
747 &i_bit_depth_luma_minus8
, &i_bit_depth_chroma_minus8
);
754 if(i_pps
> HEVC_PPS_ID_MAX
)
756 p_nal
= &rg_pps
[i_pps
++];
757 p_nal
->p_buffer
= p_buffer
;
763 case HEVC_NAL_PREF_SEI
:
764 case HEVC_NAL_SUFF_SEI
: {
765 struct nal
* p_tmp
= realloc(p_sei
, sizeof(struct nal
) * (i_sei
+ 1));
769 p_nal
= &p_sei
[i_sei
++];
770 p_nal
->p_buffer
= p_buffer
;
780 bo_add_8(hvcC
, 0x01);
781 bo_add_mem(hvcC
, 12, general_configuration
);
782 /* Don't set min spatial segmentation */
783 bo_add_16be(hvcC
, 0xF000);
784 /* Don't set parallelism type since segmentation isn't set */
785 bo_add_8(hvcC
, 0xFC);
786 bo_add_8(hvcC
, (0xFC | (i_chroma_idc
& 0x03)));
787 bo_add_8(hvcC
, (0xF8 | (i_bit_depth_luma_minus8
& 0x07)));
788 bo_add_8(hvcC
, (0xF8 | (i_bit_depth_chroma_minus8
& 0x07)));
790 /* Don't set framerate */
791 bo_add_16be(hvcC
, 0x0000);
792 /* Force NAL size of 4 bytes that replace the startcode */
793 bo_add_8(hvcC
, (((i_numTemporalLayer
& 0x07) << 3) |
794 (b_temporalIdNested
<< 2) | 0x03));
795 bo_add_8(hvcC
, i_num_arrays
);
800 bo_add_8(hvcC
, HEVC_NAL_VPS
| (b_completeness
? 0x80 : 0));
801 bo_add_16be(hvcC
, i_vps
);
802 for (uint8_t i
= 0; i
< i_vps
; i
++) {
804 bo_add_16be(hvcC
, p_nal
->i_buffer
);
805 bo_add_mem(hvcC
, p_nal
->i_buffer
, p_nal
->p_buffer
);
811 bo_add_8(hvcC
, HEVC_NAL_SPS
| (b_completeness
? 0x80 : 0));
812 bo_add_16be(hvcC
, i_sps
);
813 for (uint8_t i
= 0; i
< i_sps
; i
++) {
815 bo_add_16be(hvcC
, p_nal
->i_buffer
);
816 bo_add_mem(hvcC
, p_nal
->i_buffer
, p_nal
->p_buffer
);
822 bo_add_8(hvcC
, HEVC_NAL_PPS
| (b_completeness
? 0x80 : 0));
823 bo_add_16be(hvcC
, i_pps
);
824 for (uint8_t i
= 0; i
< i_pps
; i
++) {
826 bo_add_16be(hvcC
, p_nal
->i_buffer
);
827 bo_add_mem(hvcC
, p_nal
->i_buffer
, p_nal
->p_buffer
);
833 bo_add_8(hvcC
, HEVC_NAL_PREF_SEI
| (b_completeness
? 0x80 : 0));
834 bo_add_16be(hvcC
, i_sei
);
835 for (size_t i
= 0; i
< i_sei
; i
++) {
837 bo_add_16be(hvcC
, p_nal
->i_buffer
);
838 bo_add_mem(hvcC
, p_nal
->i_buffer
, p_nal
->p_buffer
);
845 static bo_t
*GetWaveFormatExTag(es_format_t
*p_fmt
, const char *tag
)
847 bo_t
*box
= box_new(tag
);
852 fourcc_to_wf_tag(p_fmt
->i_codec
, &wFormatTag
);
853 bo_add_16le(box
, wFormatTag
); //wFormatTag
854 bo_add_16le(box
, p_fmt
->audio
.i_channels
); //nChannels
855 bo_add_32le(box
, p_fmt
->audio
.i_rate
); //nSamplesPerSec
856 bo_add_32le(box
, p_fmt
->i_bitrate
/ 8); //nAvgBytesPerSec
857 bo_add_16le(box
, p_fmt
->audio
.i_blockalign
); //nBlockAlign
858 bo_add_16le(box
, p_fmt
->audio
.i_bitspersample
); //wBitsPerSample
859 bo_add_16le(box
, p_fmt
->i_extra
); //cbSize
861 bo_add_mem(box
, p_fmt
->i_extra
, p_fmt
->p_extra
);
866 static bo_t
*GetxxxxTag(es_format_t
*p_fmt
, const char *tag
)
868 bo_t
*box
= box_new(tag
);
871 bo_add_mem(box
, p_fmt
->i_extra
, p_fmt
->p_extra
);
875 static bo_t
*GetAvcCTag(es_format_t
*p_fmt
)
877 bo_t
*avcC
= box_new("avcC");/* FIXME use better value */
880 const uint8_t *p_sps
, *p_pps
, *p_ext
;
881 size_t i_sps_size
, i_pps_size
, i_ext_size
;
883 if(! h264_AnnexB_get_spspps(p_fmt
->p_extra
, p_fmt
->i_extra
,
886 &p_ext
, &i_ext_size
) )
888 p_sps
= p_pps
= p_ext
= NULL
;
889 i_sps_size
= i_pps_size
= i_ext_size
= 0;
892 bo_add_8(avcC
, 1); /* configuration version */
893 bo_add_8(avcC
, i_sps_size
> 3 ? p_sps
[1] : PROFILE_H264_MAIN
);
894 bo_add_8(avcC
, i_sps_size
> 3 ? p_sps
[2] : 64);
895 bo_add_8(avcC
, i_sps_size
> 3 ? p_sps
[3] : 30); /* level, 5.1 */
896 bo_add_8(avcC
, 0xff); /* 0b11111100 | lengthsize = 0x11 */
898 bo_add_8(avcC
, 0xe0 | (i_sps_size
> 0 ? 1 : 0)); /* 0b11100000 | sps_count */
899 if (i_sps_size
> 0) {
900 bo_add_16be(avcC
, i_sps_size
);
901 bo_add_mem(avcC
, i_sps_size
, p_sps
);
904 bo_add_8(avcC
, (i_pps_size
> 0 ? 1 : 0)); /* pps_count */
905 if (i_pps_size
> 0) {
906 bo_add_16be(avcC
, i_pps_size
);
907 bo_add_mem(avcC
, i_pps_size
, p_pps
);
910 if( i_sps_size
> 3 &&
911 (p_sps
[1] == PROFILE_H264_HIGH
||
912 p_sps
[1] == PROFILE_H264_HIGH_10
||
913 p_sps
[1] == PROFILE_H264_HIGH_422
||
914 p_sps
[1] == PROFILE_H264_HIGH_444
||
915 p_sps
[1] == PROFILE_H264_HIGH_444_PREDICTIVE
) )
917 h264_sequence_parameter_set_t
*p_spsdata
= h264_decode_sps( p_sps
, i_sps_size
, true );
921 if( h264_get_chroma_luma( p_spsdata
, &data
[0], &data
[1], &data
[2]) )
923 bo_add_8(avcC
, 0xFC | data
[0]);
924 bo_add_8(avcC
, 0xF8 | (data
[1] - 8));
925 bo_add_8(avcC
, 0xF8 | (data
[2] - 8));
926 bo_add_8(avcC
, (i_ext_size
> 0 ? 1 : 0));
927 if (i_ext_size
> 0) {
928 bo_add_16be(avcC
, i_ext_size
);
929 bo_add_mem(avcC
, i_ext_size
, p_ext
);
932 h264_release_sps( p_spsdata
);
939 /* TODO: No idea about these values */
940 static bo_t
*GetSVQ3Tag(es_format_t
*p_fmt
)
942 bo_t
*smi
= box_new("SMI ");
946 if (p_fmt
->i_extra
> 0x4e) {
947 uint8_t *p_end
= &((uint8_t*)p_fmt
->p_extra
)[p_fmt
->i_extra
];
948 uint8_t *p
= &((uint8_t*)p_fmt
->p_extra
)[0x46];
950 while (p
+ 8 < p_end
) {
951 int i_size
= GetDWBE(p
);
952 if (i_size
<= 1) /* FIXME handle 1 as long size */
954 if (!strncmp((const char *)&p
[4], "SMI ", 4)) {
955 bo_add_mem(smi
, p_end
- p
- 8, &p
[8]);
962 /* Create a dummy one in fallback */
963 bo_add_fourcc(smi
, "SEQH");
964 bo_add_32be(smi
, 0x5);
965 bo_add_32be(smi
, 0xe2c0211d);
971 static bo_t
*GetUdtaTag(mp4mux_trackinfo_t
**pp_tracks
, unsigned int i_tracks
)
973 bo_t
*udta
= box_new("udta");
978 for (unsigned int i
= 0; i
< i_tracks
; i
++) {
979 mp4mux_trackinfo_t
*p_stream
= pp_tracks
[i
];
980 vlc_fourcc_t codec
= p_stream
->fmt
.i_codec
;
982 if (codec
== VLC_CODEC_MP4V
|| codec
== VLC_CODEC_MP4A
) {
983 bo_t
*box
= box_new("\251req");
987 bo_add_16be(box
, sizeof("QuickTime 6.0 or greater") - 1);
989 bo_add_mem(box
, sizeof("QuickTime 6.0 or greater") - 1,
990 (uint8_t *)"QuickTime 6.0 or greater");
991 box_gather(udta
, box
);
998 bo_t
*box
= box_new("\251enc");
1002 bo_add_16be(box
, sizeof(PACKAGE_STRING
" stream output") - 1);
1003 bo_add_16be(box
, 0);
1004 bo_add_mem(box
, sizeof(PACKAGE_STRING
" stream output") - 1,
1005 (uint8_t*)PACKAGE_STRING
" stream output");
1006 box_gather(udta
, box
);
1011 vlc_meta_t
*p_meta
= p_mux
->p_sout
->p_meta
;
1013 #define ADD_META_BOX(type, box_string) { \
1015 if (vlc_meta_Get(p_meta, vlc_meta_##type)) \
1016 box = box_new("\251" box_string); \
1018 bo_add_16be(box, strlen(vlc_meta_Get(p_meta, vlc_meta_##type))); \
1019 bo_add_16be(box, 0); \
1020 bo_add_mem(box, strlen(vlc_meta_Get(p_meta, vlc_meta_##type)), \
1021 (uint8_t*)(vlc_meta_Get(p_meta, vlc_meta_##type))); \
1022 box_gather(udta, box); \
1025 ADD_META_BOX(Title
, "nam");
1026 ADD_META_BOX(Artist
, "ART");
1027 ADD_META_BOX(Genre
, "gen");
1028 ADD_META_BOX(Copyright
, "cpy");
1029 ADD_META_BOX(Description
, "des");
1030 ADD_META_BOX(Date
, "day");
1031 ADD_META_BOX(URL
, "url");
1038 static bo_t
*GetSounBox(vlc_object_t
*p_obj
, mp4mux_trackinfo_t
*p_track
, bool b_mov
)
1042 bool b_descr
= true;
1043 vlc_fourcc_t codec
= p_track
->fmt
.i_codec
;
1046 if (codec
== VLC_CODEC_MPGA
) {
1049 memcpy(fcc
, ".mp3", 4);
1051 memcpy(fcc
, "mp4a", 4);
1052 } else if (codec
== VLC_CODEC_A52
) {
1053 memcpy(fcc
, "ac-3", 4);
1054 } else if (codec
== VLC_CODEC_EAC3
) {
1055 memcpy(fcc
, "ec-3", 4);
1056 } else if (codec
== VLC_CODEC_DTS
) {
1057 memcpy(fcc
, "DTS ", 4);
1058 } else if (codec
== VLC_CODEC_WMAP
) {
1059 memcpy(fcc
, "wma ", 4);
1061 vlc_fourcc_to_char(codec
, fcc
);
1063 bo_t
*soun
= box_new(fcc
);
1066 for (int i
= 0; i
< 6; i
++)
1067 bo_add_8(soun
, 0); // reserved;
1068 bo_add_16be(soun
, 1); // data-reference-index
1070 /* SoundDescription */
1071 if (b_mov
&& codec
== VLC_CODEC_MP4A
)
1072 bo_add_16be(soun
, 1); // version 1;
1074 bo_add_16be(soun
, 0); // version 0;
1075 bo_add_16be(soun
, 0); // revision level (0)
1076 bo_add_32be(soun
, 0); // vendor
1078 bo_add_16be(soun
, p_track
->fmt
.audio
.i_channels
);
1080 bo_add_16be(soun
, p_track
->fmt
.audio
.i_bitspersample
?
1081 p_track
->fmt
.audio
.i_bitspersample
: 16);
1082 bo_add_16be(soun
, -2); // compression id
1083 bo_add_16be(soun
, 0); // packet size (0)
1084 bo_add_16be(soun
, p_track
->fmt
.audio
.i_rate
); // sampleratehi
1085 bo_add_16be(soun
, 0); // sampleratelo
1087 /* Extended data for SoundDescription V1 */
1088 if (b_mov
&& p_track
->fmt
.i_codec
== VLC_CODEC_MP4A
) {
1089 /* samples per packet */
1090 bo_add_32be(soun
, p_track
->fmt
.audio
.i_frame_length
);
1091 bo_add_32be(soun
, 1536); /* bytes per packet */
1092 bo_add_32be(soun
, 2); /* bytes per frame */
1093 /* bytes per sample */
1094 bo_add_32be(soun
, 2 /*p_fmt->audio.i_bitspersample/8 */);
1097 /* Add an ES Descriptor */
1101 if (b_mov
&& codec
== VLC_CODEC_MP4A
)
1102 box
= GetWaveTag(p_track
);
1103 else if (codec
== VLC_CODEC_AMR_NB
)
1104 box
= GetDamrTag(&p_track
->fmt
);
1105 else if (codec
== VLC_CODEC_A52
)
1106 box
= GetDac3Tag(p_track
->a52_frame
);
1107 else if (codec
== VLC_CODEC_EAC3
)
1108 box
= GetDec3Tag(&p_track
->fmt
, p_track
->a52_frame
);
1109 else if (codec
== VLC_CODEC_WMAP
)
1110 box
= GetWaveFormatExTag(&p_track
->fmt
, "wfex");
1112 box
= GetESDS(p_track
);
1115 box_gather(soun
, box
);
1121 static bo_t
*GetVideBox(vlc_object_t
*p_obj
, mp4mux_trackinfo_t
*p_track
, bool b_mov
)
1128 switch(p_track
->fmt
.i_codec
)
1130 case VLC_CODEC_MP4V
:
1131 case VLC_CODEC_MPGV
: memcpy(fcc
, "mp4v", 4); break;
1132 case VLC_CODEC_MJPG
: memcpy(fcc
, "mjpa", 4); break;
1133 case VLC_CODEC_SVQ1
: memcpy(fcc
, "SVQ1", 4); break;
1134 case VLC_CODEC_SVQ3
: memcpy(fcc
, "SVQ3", 4); break;
1135 case VLC_CODEC_H263
: memcpy(fcc
, "s263", 4); break;
1136 case VLC_CODEC_H264
: memcpy(fcc
, "avc1", 4); break;
1137 case VLC_CODEC_VC1
: memcpy(fcc
, "vc-1", 4); break;
1138 /* FIXME: find a way to know if no non-VCL units are in the stream (->hvc1)
1139 * see 14496-15 8.4.1.1.1 */
1140 case VLC_CODEC_HEVC
: memcpy(fcc
, "hev1", 4); break;
1141 case VLC_CODEC_YV12
: memcpy(fcc
, "yv12", 4); break;
1142 case VLC_CODEC_YUYV
: memcpy(fcc
, "yuy2", 4); break;
1144 vlc_fourcc_to_char(p_track
->fmt
.i_codec
, fcc
);
1148 bo_t
*vide
= box_new(fcc
);
1151 for (int i
= 0; i
< 6; i
++)
1152 bo_add_8(vide
, 0); // reserved;
1153 bo_add_16be(vide
, 1); // data-reference-index
1155 bo_add_16be(vide
, 0); // predefined;
1156 bo_add_16be(vide
, 0); // reserved;
1157 for (int i
= 0; i
< 3; i
++)
1158 bo_add_32be(vide
, 0); // predefined;
1160 bo_add_16be(vide
, p_track
->fmt
.video
.i_width
); // i_width
1161 bo_add_16be(vide
, p_track
->fmt
.video
.i_height
); // i_height
1163 bo_add_32be(vide
, 0x00480000); // h 72dpi
1164 bo_add_32be(vide
, 0x00480000); // v 72dpi
1166 bo_add_32be(vide
, 0); // data size, always 0
1167 bo_add_16be(vide
, 1); // frames count per sample
1170 for (int i
= 0; i
< 32; i
++)
1173 bo_add_16be(vide
, 0x18); // depth
1174 bo_add_16be(vide
, 0xffff); // predefined
1176 /* add an ES Descriptor */
1177 switch(p_track
->fmt
.i_codec
)
1179 case VLC_CODEC_MP4V
:
1180 case VLC_CODEC_MPGV
:
1181 box_gather(vide
, GetESDS(p_track
));
1184 case VLC_CODEC_H263
:
1185 box_gather(vide
, GetD263Tag());
1188 case VLC_CODEC_SVQ3
:
1189 box_gather(vide
, GetSVQ3Tag(&p_track
->fmt
));
1192 case VLC_CODEC_H264
:
1193 box_gather(vide
, GetAvcCTag(&p_track
->fmt
));
1197 box_gather(vide
, GetxxxxTag(&p_track
->fmt
, "dvc1"));
1200 case VLC_CODEC_HEVC
:
1201 /* Write HvcC without forcing VPS/SPS/PPS/SEI array_completeness */
1202 box_gather(vide
, GetHvcCTag(&p_track
->fmt
, false));
1209 static bo_t
*GetTextBox(void)
1211 bo_t
*text
= box_new("text");
1215 for (int i
= 0; i
< 6; i
++)
1216 bo_add_8(text
, 0); // reserved;
1217 bo_add_16be(text
, 1); // data-reference-index
1219 bo_add_32be(text
, 0); // display flags
1220 bo_add_32be(text
, 0); // justification
1221 for (int i
= 0; i
< 3; i
++)
1222 bo_add_16be(text
, 0); // back ground color
1224 bo_add_16be(text
, 0); // box text
1225 bo_add_16be(text
, 0); // box text
1226 bo_add_16be(text
, 0); // box text
1227 bo_add_16be(text
, 0); // box text
1229 bo_add_64be(text
, 0); // reserved
1230 for (int i
= 0; i
< 3; i
++)
1231 bo_add_16be(text
, 0xff); // foreground color
1234 bo_add_mem(text
, 9, (uint8_t*)"Helvetica");
1239 static int64_t GetScaledEntryDuration( const mp4mux_entry_t
*p_entry
, uint32_t i_timescale
,
1240 mtime_t
*pi_total_mtime
, int64_t *pi_total_scaled
)
1242 const mtime_t i_totalscaledtototalmtime
= *pi_total_scaled
* CLOCK_FREQ
/ i_timescale
;
1243 const mtime_t i_diff
= *pi_total_mtime
- i_totalscaledtototalmtime
;
1245 /* Ensure to compensate the drift due to loss from time, and from scale, conversions */
1246 int64_t i_scaled
= (p_entry
->i_length
+ i_diff
) * i_timescale
/ CLOCK_FREQ
;
1247 *pi_total_mtime
+= p_entry
->i_length
;
1248 *pi_total_scaled
+= i_scaled
;
1253 static bo_t
*GetStblBox(vlc_object_t
*p_obj
, mp4mux_trackinfo_t
*p_track
, bool b_mov
, bool b_stco64
)
1255 /* sample description */
1256 bo_t
*stsd
= box_full_new("stsd", 0, 0);
1259 bo_add_32be(stsd
, 1);
1260 if (p_track
->fmt
.i_cat
== AUDIO_ES
)
1261 box_gather(stsd
, GetSounBox(p_obj
, p_track
, b_mov
));
1262 else if (p_track
->fmt
.i_cat
== VIDEO_ES
)
1263 box_gather(stsd
, GetVideBox(p_obj
, p_track
, b_mov
));
1264 else if (p_track
->fmt
.i_cat
== SPU_ES
)
1265 box_gather(stsd
, GetTextBox());
1267 /* chunk offset table */
1271 /* 64 bits version */
1272 stco
= box_full_new("co64", 0, 0);
1274 /* 32 bits version */
1275 stco
= box_full_new("stco", 0, 0);
1282 bo_add_32be(stco
, 0); // entry-count (fixed latter)
1284 /* sample to chunk table */
1285 bo_t
*stsc
= box_full_new("stsc", 0, 0);
1292 bo_add_32be(stsc
, 0); // entry-count (fixed latter)
1294 unsigned i_chunk
= 0;
1295 unsigned i_stsc_last_val
= 0, i_stsc_entries
= 0;
1296 for (unsigned i
= 0; i
< p_track
->i_entry_count
; i_chunk
++) {
1297 mp4mux_entry_t
*entry
= p_track
->entry
;
1301 bo_add_64be(stco
, entry
[i
].i_pos
);
1303 bo_add_32be(stco
, entry
[i
].i_pos
);
1305 for (; i
< p_track
->i_entry_count
; i
++)
1306 if (i
>= p_track
->i_entry_count
- 1 ||
1307 entry
[i
].i_pos
+ entry
[i
].i_size
!= entry
[i
+1].i_pos
) {
1312 /* Add entry to the stsc table */
1313 if (i_stsc_last_val
!= i
- i_first
) {
1314 bo_add_32be(stsc
, 1 + i_chunk
); // first-chunk
1315 bo_add_32be(stsc
, i
- i_first
) ; // samples-per-chunk
1316 bo_add_32be(stsc
, 1); // sample-descr-index
1317 i_stsc_last_val
= i
- i_first
;
1322 /* Fix stco entry count */
1323 bo_swap_32be(stco
, 12, i_chunk
);
1325 msg_Dbg(p_obj
, "created %d chunks (stco)", i_chunk
);
1327 /* Fix stsc entry count */
1328 bo_swap_32be(stsc
, 12, i_stsc_entries
);
1331 bo_t
*stts
= box_full_new("stts", 0, 0);
1339 bo_add_32be(stts
, 0); // entry-count (fixed latter)
1341 mtime_t i_total_mtime
= 0;
1342 int64_t i_total_scaled
= 0;
1343 unsigned i_index
= 0;
1344 for (unsigned i
= 0; i
< p_track
->i_entry_count
; i_index
++) {
1347 int64_t i_scaled
= GetScaledEntryDuration(&p_track
->entry
[i
], p_track
->i_timescale
,
1348 &i_total_mtime
, &i_total_scaled
);
1349 for (unsigned j
=i
+1; j
< p_track
->i_entry_count
; j
++)
1351 mtime_t i_total_mtime_next
= i_total_mtime
;
1352 int64_t i_total_scaled_next
= i_total_scaled
;
1353 int64_t i_scalednext
= GetScaledEntryDuration(&p_track
->entry
[j
], p_track
->i_timescale
,
1354 &i_total_mtime_next
, &i_total_scaled_next
);
1355 if( i_scalednext
!= i_scaled
)
1358 i_total_mtime
= i_total_mtime_next
;
1359 i_total_scaled
= i_total_scaled_next
;
1363 bo_add_32be(stts
, ++i
- i_first
); // sample-count
1364 bo_add_32be(stts
, i_scaled
); // sample-delta
1366 bo_swap_32be(stts
, 12, i_index
);
1368 //msg_Dbg(p_obj, "total sout duration %"PRId64" reconverted from scaled %"PRId64,
1369 // i_total_mtime, i_total_scaled * CLOCK_FREQ / p_track->i_timescale );
1371 /* composition time handling */
1373 if ( p_track
->b_hasbframes
&& (ctts
= box_full_new("ctts", 0, 0)) )
1375 bo_add_32be(ctts
, 0);
1377 for (unsigned i
= 0; i
< p_track
->i_entry_count
; i_index
++)
1380 mtime_t i_offset
= p_track
->entry
[i
].i_pts_dts
;
1382 for (; i
< p_track
->i_entry_count
; ++i
)
1383 if (i
== p_track
->i_entry_count
|| p_track
->entry
[i
].i_pts_dts
!= i_offset
)
1386 bo_add_32be(ctts
, i
- i_first
); // sample-count
1387 bo_add_32be(ctts
, i_offset
* p_track
->i_timescale
/ CLOCK_FREQ
); // sample-offset
1389 bo_swap_32be(ctts
, 12, i_index
);
1392 bo_t
*stsz
= box_full_new("stsz", 0, 0);
1401 for (unsigned i
= 0; i
< p_track
->i_entry_count
; i
++)
1404 i_size
= p_track
->entry
[i
].i_size
;
1405 else if ( p_track
->entry
[i
].i_size
!= i_size
)
1411 bo_add_32be(stsz
, i_size
); // sample-size
1412 bo_add_32be(stsz
, p_track
->i_entry_count
); // sample-count
1413 if ( i_size
== 0 ) // all samples have different size
1415 for (unsigned i
= 0; i
< p_track
->i_entry_count
; i
++)
1416 bo_add_32be(stsz
, p_track
->entry
[i
].i_size
); // sample-size
1419 /* create stss table */
1422 if ( p_track
->fmt
.i_cat
== VIDEO_ES
|| p_track
->fmt
.i_cat
== AUDIO_ES
)
1424 mtime_t i_interval
= -1;
1425 for (unsigned i
= 0; i
< p_track
->i_entry_count
; i
++)
1427 if ( i_interval
!= -1 )
1429 i_interval
+= p_track
->entry
[i
].i_length
+ p_track
->entry
[i
].i_pts_dts
;
1430 if ( i_interval
< CLOCK_FREQ
* 2 )
1434 if (p_track
->entry
[i
].i_flags
& BLOCK_FLAG_TYPE_I
) {
1436 stss
= box_full_new("stss", 0, 0);
1439 bo_add_32be(stss
, 0); /* fixed later */
1441 bo_add_32be(stss
, 1 + i
);
1449 bo_swap_32be(stss
, 12, i_index
);
1451 /* Now gather all boxes into stbl */
1452 bo_t
*stbl
= box_new("stbl");
1463 box_gather(stbl
, stsd
);
1464 box_gather(stbl
, stts
);
1466 box_gather(stbl
, stss
);
1468 box_gather(stbl
, ctts
);
1469 box_gather(stbl
, stsc
);
1470 box_gather(stbl
, stsz
);
1471 p_track
->i_stco_pos
= stbl
->b
->i_buffer
+ 16;
1472 box_gather(stbl
, stco
);
1477 bo_t
* mp4mux_GetMoovBox(vlc_object_t
*p_obj
, mp4mux_trackinfo_t
**pp_tracks
, unsigned int i_tracks
,
1478 int64_t i_movie_duration
,
1479 bool b_fragmented
, bool b_mov
, bool b_64_ext
, bool b_stco64
)
1483 uint32_t i_movie_timescale
= 90000;
1484 int64_t i_timestamp
= get_timestamp();
1486 /* Important for smooth streaming where its (not muxed here) media time offsets
1487 * are in timescale == track timescale */
1489 i_movie_timescale
= pp_tracks
[0]->i_timescale
;
1491 moov
= box_new("moov");
1494 /* Create general info */
1495 if( i_movie_duration
== 0 && !b_fragmented
)
1497 for (unsigned int i
= 0; i
< i_tracks
; i
++) {
1498 mp4mux_trackinfo_t
*p_stream
= pp_tracks
[i
];
1499 i_movie_duration
= __MAX(i_movie_duration
, p_stream
->i_read_duration
);
1502 msg_Dbg(p_obj
, "movie duration %"PRId64
"s", i_movie_duration
/ CLOCK_FREQ
);
1504 i_movie_duration
= i_movie_duration
* i_movie_timescale
/ CLOCK_FREQ
;
1507 /* *** add /moov/mvhd *** */
1509 mvhd
= box_full_new("mvhd", 0, 0);
1515 bo_add_32be(mvhd
, i_timestamp
); // creation time
1516 bo_add_32be(mvhd
, i_timestamp
); // modification time
1517 bo_add_32be(mvhd
, i_movie_timescale
); // timescale
1518 bo_add_32be(mvhd
, i_movie_duration
); // duration
1520 mvhd
= box_full_new("mvhd", 1, 0);
1526 bo_add_64be(mvhd
, i_timestamp
); // creation time
1527 bo_add_64be(mvhd
, i_timestamp
); // modification time
1528 bo_add_32be(mvhd
, i_movie_timescale
); // timescale
1529 bo_add_64be(mvhd
, i_movie_duration
); // duration
1531 bo_add_32be(mvhd
, 0x10000); // rate
1532 bo_add_16be(mvhd
, 0x100); // volume
1533 bo_add_16be(mvhd
, 0); // reserved
1534 for (int i
= 0; i
< 2; i
++)
1535 bo_add_32be(mvhd
, 0); // reserved
1537 uint32_t mvhd_matrix
[9] = { 0x10000, 0, 0, 0, 0x10000, 0, 0, 0, 0x40000000 };
1539 for (int i
= 0; i
< 9; i
++)
1540 bo_add_32be(mvhd
, mvhd_matrix
[i
]);// matrix
1541 for (int i
= 0; i
< 6; i
++)
1542 bo_add_32be(mvhd
, 0); // pre-defined
1544 /* Next available track id */
1545 bo_add_32be(mvhd
, (i_tracks
) ? pp_tracks
[i_tracks
-1]->i_track_id
+ 1: 1); // next-track-id
1547 box_gather(moov
, mvhd
);
1549 for (unsigned int i_trak
= 0; i_trak
< i_tracks
; i_trak
++) {
1550 mp4mux_trackinfo_t
*p_stream
= pp_tracks
[i_trak
];
1552 mtime_t i_stream_duration
;
1553 if ( !b_fragmented
)
1554 i_stream_duration
= p_stream
->i_read_duration
* i_movie_timescale
/ CLOCK_FREQ
;
1556 i_stream_duration
= 0;
1558 /* *** add /moov/trak *** */
1559 bo_t
*trak
= box_new("trak");
1563 /* *** add /moov/trak/tkhd *** */
1567 tkhd
= box_full_new("tkhd", 0, 0x0f);
1569 tkhd
= box_full_new("tkhd", 0, 1);
1575 bo_add_32be(tkhd
, i_timestamp
); // creation time
1576 bo_add_32be(tkhd
, i_timestamp
); // modification time
1577 bo_add_32be(tkhd
, p_stream
->i_track_id
);
1578 bo_add_32be(tkhd
, 0); // reserved 0
1579 bo_add_32be(tkhd
, i_stream_duration
); // duration
1582 tkhd
= box_full_new("tkhd", 1, 0x0f);
1584 tkhd
= box_full_new("tkhd", 1, 1);
1590 bo_add_64be(tkhd
, i_timestamp
); // creation time
1591 bo_add_64be(tkhd
, i_timestamp
); // modification time
1592 bo_add_32be(tkhd
, p_stream
->i_track_id
);
1593 bo_add_32be(tkhd
, 0); // reserved 0
1594 bo_add_64be(tkhd
, i_stream_duration
); // duration
1597 for (int i
= 0; i
< 2; i
++)
1598 bo_add_32be(tkhd
, 0); // reserved
1599 bo_add_16be(tkhd
, 0); // layer
1600 bo_add_16be(tkhd
, 0); // pre-defined
1602 bo_add_16be(tkhd
, p_stream
->fmt
.i_cat
== AUDIO_ES
? 0x100 : 0);
1603 bo_add_16be(tkhd
, 0); // reserved
1604 matrix_apply_rotation(&p_stream
->fmt
, mvhd_matrix
);
1605 for (int i
= 0; i
< 9; i
++)
1606 bo_add_32be(tkhd
, mvhd_matrix
[i
]); // matrix
1607 if (p_stream
->fmt
.i_cat
== AUDIO_ES
) {
1608 bo_add_32be(tkhd
, 0); // width (presentation)
1609 bo_add_32be(tkhd
, 0); // height(presentation)
1610 } else if (p_stream
->fmt
.i_cat
== VIDEO_ES
) {
1611 int i_width
= p_stream
->fmt
.video
.i_width
<< 16;
1612 if (p_stream
->fmt
.video
.i_sar_num
> 0 && p_stream
->fmt
.video
.i_sar_den
> 0) {
1613 i_width
= (int64_t)p_stream
->fmt
.video
.i_sar_num
*
1614 ((int64_t)p_stream
->fmt
.video
.i_width
<< 16) /
1615 p_stream
->fmt
.video
.i_sar_den
;
1617 // width (presentation)
1618 bo_add_32be(tkhd
, i_width
);
1619 // height(presentation)
1620 bo_add_32be(tkhd
, p_stream
->fmt
.video
.i_height
<< 16);
1622 int i_width
= 320 << 16;
1624 for (unsigned int i
= 0; i
< i_tracks
; i
++) {
1625 mp4mux_trackinfo_t
*tk
= pp_tracks
[i
];
1626 if (tk
->fmt
.i_cat
== VIDEO_ES
) {
1627 if (tk
->fmt
.video
.i_sar_num
> 0 &&
1628 tk
->fmt
.video
.i_sar_den
> 0)
1629 i_width
= (int64_t)tk
->fmt
.video
.i_sar_num
*
1630 ((int64_t)tk
->fmt
.video
.i_width
<< 16) /
1631 tk
->fmt
.video
.i_sar_den
;
1633 i_width
= tk
->fmt
.video
.i_width
<< 16;
1634 i_height
= tk
->fmt
.video
.i_height
;
1638 bo_add_32be(tkhd
, i_width
); // width (presentation)
1639 bo_add_32be(tkhd
, i_height
<< 16); // height(presentation)
1642 box_gather(trak
, tkhd
);
1644 /* *** add /moov/trak/edts and elst */
1645 bo_t
*edts
= GetEDTS(p_stream
, i_movie_timescale
, b_64_ext
);
1647 box_gather(trak
, edts
);
1649 /* *** add /moov/trak/mdia *** */
1650 bo_t
*mdia
= box_new("mdia");
1660 mdhd
= box_full_new("mdhd", 0, 0);
1667 bo_add_32be(mdhd
, i_timestamp
); // creation time
1668 bo_add_32be(mdhd
, i_timestamp
); // modification time
1669 bo_add_32be(mdhd
, p_stream
->i_timescale
); // timescale
1670 bo_add_32be(mdhd
, i_stream_duration
* p_stream
->i_timescale
/ i_movie_timescale
); // duration
1672 mdhd
= box_full_new("mdhd", 1, 0);
1679 bo_add_64be(mdhd
, i_timestamp
); // creation time
1680 bo_add_64be(mdhd
, i_timestamp
); // modification time
1681 bo_add_32be(mdhd
, p_stream
->i_timescale
); // timescale
1682 bo_add_64be(mdhd
, i_stream_duration
* p_stream
->i_timescale
/ i_movie_timescale
); // duration
1685 if (p_stream
->fmt
.psz_language
) {
1686 char *psz
= p_stream
->fmt
.psz_language
;
1687 const iso639_lang_t
*pl
= NULL
;
1688 uint16_t lang
= 0x0;
1690 if (strlen(psz
) == 2)
1691 pl
= GetLang_1(psz
);
1692 else if (strlen(psz
) == 3) {
1693 pl
= GetLang_2B(psz
);
1694 if (!strcmp(pl
->psz_iso639_1
, "??"))
1695 pl
= GetLang_2T(psz
);
1698 if (pl
&& strcmp(pl
->psz_iso639_1
, "??"))
1699 lang
= ((pl
->psz_iso639_2T
[0] - 0x60) << 10) |
1700 ((pl
->psz_iso639_2T
[1] - 0x60) << 5) |
1701 ((pl
->psz_iso639_2T
[2] - 0x60));
1702 bo_add_16be(mdhd
, lang
); // language
1704 bo_add_16be(mdhd
, 0 ); // language
1705 bo_add_16be(mdhd
, 0 ); // predefined
1706 box_gather(mdia
, mdhd
);
1708 /* handler reference */
1709 bo_t
*hdlr
= box_full_new("hdlr", 0, 0);
1718 bo_add_fourcc(hdlr
, "mhlr"); // media handler
1720 bo_add_32be(hdlr
, 0);
1722 if (p_stream
->fmt
.i_cat
== AUDIO_ES
)
1723 bo_add_fourcc(hdlr
, "soun");
1724 else if (p_stream
->fmt
.i_cat
== VIDEO_ES
)
1725 bo_add_fourcc(hdlr
, "vide");
1726 else if (p_stream
->fmt
.i_cat
== SPU_ES
)
1727 bo_add_fourcc(hdlr
, "text");
1729 bo_add_32be(hdlr
, 0); // reserved
1730 bo_add_32be(hdlr
, 0); // reserved
1731 bo_add_32be(hdlr
, 0); // reserved
1734 bo_add_8(hdlr
, 12); /* Pascal string for .mov */
1736 if (p_stream
->fmt
.i_cat
== AUDIO_ES
)
1737 bo_add_mem(hdlr
, 12, (uint8_t*)"SoundHandler");
1738 else if (p_stream
->fmt
.i_cat
== VIDEO_ES
)
1739 bo_add_mem(hdlr
, 12, (uint8_t*)"VideoHandler");
1741 bo_add_mem(hdlr
, 12, (uint8_t*)"Text Handler");
1744 bo_add_8(hdlr
, 0); /* asciiz string for .mp4, yes that's BRAIN DAMAGED F**K MP4 */
1746 box_gather(mdia
, hdlr
);
1749 bo_t
*minf
= box_new("minf");
1758 if (p_stream
->fmt
.i_cat
== AUDIO_ES
) {
1759 bo_t
*smhd
= box_full_new("smhd", 0, 0);
1762 bo_add_16be(smhd
, 0); // balance
1763 bo_add_16be(smhd
, 0); // reserved
1765 box_gather(minf
, smhd
);
1767 } else if (p_stream
->fmt
.i_cat
== VIDEO_ES
) {
1768 bo_t
*vmhd
= box_full_new("vmhd", 0, 1);
1771 bo_add_16be(vmhd
, 0); // graphicsmode
1772 for (int i
= 0; i
< 3; i
++)
1773 bo_add_16be(vmhd
, 0); // opcolor
1774 box_gather(minf
, vmhd
);
1776 } else if (p_stream
->fmt
.i_cat
== SPU_ES
) {
1777 bo_t
*gmin
= box_full_new("gmin", 0, 1);
1780 bo_add_16be(gmin
, 0); // graphicsmode
1781 for (int i
= 0; i
< 3; i
++)
1782 bo_add_16be(gmin
, 0); // opcolor
1783 bo_add_16be(gmin
, 0); // balance
1784 bo_add_16be(gmin
, 0); // reserved
1786 bo_t
*gmhd
= box_new("gmhd");
1789 box_gather(gmhd
, gmin
);
1790 box_gather(minf
, gmhd
);
1797 bo_t
*dref
= box_full_new("dref", 0, 0);
1800 bo_add_32be(dref
, 1);
1802 bo_t
*url
= box_full_new("url ", 0, 0x01);
1804 box_gather(dref
, url
);
1806 bo_t
*dinf
= box_new("dinf");
1809 box_gather(dinf
, dref
);
1811 /* append dinf to mdia */
1812 box_gather(minf
, dinf
);
1821 uint32_t i_backup
= p_stream
->i_entry_count
;
1822 p_stream
->i_entry_count
= 0;
1823 stbl
= GetStblBox(p_obj
, p_stream
, b_mov
, b_stco64
);
1824 p_stream
->i_entry_count
= i_backup
;
1827 stbl
= GetStblBox(p_obj
, p_stream
, b_mov
, b_stco64
);
1829 /* append stbl to minf */
1830 p_stream
->i_stco_pos
+= minf
->b
->i_buffer
;
1831 box_gather(minf
, stbl
);
1833 /* append minf to mdia */
1834 p_stream
->i_stco_pos
+= mdia
->b
->i_buffer
;
1835 box_gather(mdia
, minf
);
1837 /* append mdia to trak */
1838 p_stream
->i_stco_pos
+= trak
->b
->i_buffer
;
1839 box_gather(trak
, mdia
);
1841 /* append trak to moov */
1842 p_stream
->i_stco_pos
+= moov
->b
->i_buffer
;
1843 box_gather(moov
, trak
);
1846 /* Add user data tags */
1847 box_gather(moov
, GetUdtaTag(pp_tracks
, i_tracks
));
1851 bo_t
*mvex
= box_new("mvex");
1854 if( i_movie_duration
)
1856 bo_t
*mehd
= box_full_new("mehd", b_64_ext
? 1 : 0, 0);
1860 bo_add_64be(mehd
, i_movie_duration
* i_movie_timescale
/ CLOCK_FREQ
);
1862 bo_add_32be(mehd
, i_movie_duration
* i_movie_timescale
/ CLOCK_FREQ
);
1863 box_gather(mvex
, mehd
);
1866 for (unsigned int i_trak
= 0; mvex
&& i_trak
< i_tracks
; i_trak
++)
1868 mp4mux_trackinfo_t
*p_stream
= pp_tracks
[i_trak
];
1870 /* Try to find some defaults */
1871 if ( p_stream
->i_entry_count
)
1873 // FIXME: find highest occurence
1874 p_stream
->i_trex_default_length
= p_stream
->entry
[0].i_length
;
1875 p_stream
->i_trex_default_size
= p_stream
->entry
[0].i_size
;
1878 /* *** add /mvex/trex *** */
1879 bo_t
*trex
= box_full_new("trex", 0, 0);
1880 bo_add_32be(trex
, p_stream
->i_track_id
);
1881 bo_add_32be(trex
, 1); // sample desc index
1882 bo_add_32be(trex
, (uint64_t)p_stream
->i_trex_default_length
* p_stream
->i_timescale
/ CLOCK_FREQ
); // sample duration
1883 bo_add_32be(trex
, p_stream
->i_trex_default_size
); // sample size
1884 bo_add_32be(trex
, 0); // sample flags
1885 box_gather(mvex
, trex
);
1887 box_gather(moov
, mvex
);
1892 box_fix(moov
, moov
->b
->i_buffer
);
1896 bo_t
*mp4mux_GetFtyp(vlc_fourcc_t major
, uint32_t minor
, vlc_fourcc_t extra
[], size_t i_fourcc
)
1898 bo_t
*box
= box_new("ftyp");
1901 bo_add_fourcc(box
, &major
);
1902 bo_add_32be (box
, minor
);
1903 for(size_t i
=0; i
<i_fourcc
; i
++)
1904 bo_add_fourcc(box
, &extra
[i
]);
1910 box_fix(box
, box
->b
->i_buffer
);
1915 bool mp4mux_CanMux(vlc_object_t
*p_obj
, const es_format_t
*p_fmt
)
1917 switch(p_fmt
->i_codec
)
1921 case VLC_CODEC_EAC3
:
1922 case VLC_CODEC_MP4A
:
1923 case VLC_CODEC_MP4V
:
1924 case VLC_CODEC_MPGA
:
1926 case VLC_CODEC_MPGV
:
1927 case VLC_CODEC_MP2V
:
1928 case VLC_CODEC_MP1V
:
1929 case VLC_CODEC_MJPG
:
1930 case VLC_CODEC_MJPGB
:
1931 case VLC_CODEC_SVQ1
:
1932 case VLC_CODEC_SVQ3
:
1933 case VLC_CODEC_H263
:
1934 case VLC_CODEC_AMR_NB
:
1935 case VLC_CODEC_AMR_WB
:
1936 case VLC_CODEC_YV12
:
1937 case VLC_CODEC_YUYV
:
1939 case VLC_CODEC_WMAP
:
1941 case VLC_CODEC_H264
:
1942 if(!p_fmt
->i_extra
&& p_obj
)
1943 msg_Warn(p_obj
, "H264 muxing from AnnexB source will set an incorrect default profile");
1945 case VLC_CODEC_HEVC
:
1946 if(!p_fmt
->i_extra
&& p_obj
)
1947 msg_Err(p_obj
, "HEVC muxing from AnnexB source is unsupported");
1949 case VLC_CODEC_SUBT
:
1951 msg_Warn(p_obj
, "subtitle track added like in .mov (even when creating .mp4)");