demux: smooth: use es_format_Change
[vlc.git] / modules / mux / mp4 / libmp4mux.c
blobec7a8b22792cdb431365dba25e0031691ed4b42e
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 *****************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 #endif
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"
33 #include <vlc_es.h>
34 #include <vlc_iso_lang.h>
35 #include <vlc_bits.h>
36 #include <assert.h>
37 #include <time.h>
39 bool mp4mux_trackinfo_Init(mp4mux_trackinfo_t *p_stream, unsigned i_id,
40 uint32_t i_timescale)
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));
50 if(!p_stream->entry)
51 return false;
53 es_format_Init(&p_stream->fmt, UNKNOWN_ES, 0);
55 return true;
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));
71 if (!box)
72 return NULL;
74 if(!bo_init(box, 1024))
76 bo_free(box);
77 return NULL;
80 bo_add_32be (box, 0);
81 bo_add_fourcc(box, fcc);
83 return box;
86 bo_t *box_full_new(const char *fcc, uint8_t v, uint32_t f)
88 bo_t *box = box_new(fcc);
89 if (!box)
90 return NULL;
92 bo_add_8 (box, v);
93 bo_add_24be (box, f);
95 return box;
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);
110 if(likely(box->b))
111 memcpy(&box->b->p_buffer[i_offset], box2->b->p_buffer, box2->b->i_buffer);
113 bo_free(box2);
116 static inline void bo_add_mp4_tag_descr(bo_t *box, uint8_t tag, uint32_t size)
118 bo_add_8(box, tag);
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
131 return i_timestamp;
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;
142 #define ATAN(a, b) \
143 do { \
144 mvhd_matrix[1] = ((uint32_t)(a)) << 16; \
145 mvhd_matrix[0] = ((uint32_t)(b)) << 16; \
146 } while(0)
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,
162 bool b_64_ext)
164 if(b_64_ext)
166 bo_add_64be(elst, i_movie_scaled_duration);
167 bo_add_64be(elst, i_media_scaled_time);
169 else
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)
181 return NULL;
183 bo_t *edts = box_new("edts");
184 bo_t *elst = box_full_new("elst", b_64_ext ? 1 : 0, 0);
185 if(!elst || !edts)
187 bo_free(elst);
188 bo_free(edts);
189 return NULL;
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)
197 i_total_edits++;
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)
206 AddEdit(elst,
207 p_track->p_edits[i].i_start_offset * i_movietimescale / CLOCK_FREQ,
209 b_64_ext);
212 /* !WARN AGAIN! Uses different Timescales ! */
213 AddEdit(elst,
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,
216 b_64_ext);
219 box_gather(edts, elst);
220 return edts;
223 static bo_t *GetESDS(mp4mux_trackinfo_t *p_track)
225 bo_t *esds;
227 /* */
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);
231 if(!esds)
232 return NULL;
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;
249 else
250 i_bitrate_avg = 0;
251 if (i_bitrate_max <= 1)
252 i_bitrate_max = 0x7fffffff;
254 /* ES_Descr */
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)
265 case VLC_CODEC_MP4V:
266 i_object_type_indication = 0x20;
267 break;
268 case VLC_CODEC_MPGV:
269 if(p_track->fmt.i_original_fourcc == VLC_CODEC_MP1V)
271 i_object_type_indication = 0x6b;
272 break;
274 case VLC_CODEC_MP2V:
275 /* MPEG-I=0x6b, MPEG-II = 0x60 -> 0x65 */
276 i_object_type_indication = 0x65;
277 break;
278 case VLC_CODEC_MP1V:
279 /* MPEG-I=0x6b, MPEG-II = 0x60 -> 0x65 */
280 i_object_type_indication = 0x6b;
281 break;
282 case VLC_CODEC_MP4A:
283 /* FIXME for mpeg2-aac == 0x66->0x68 */
284 i_object_type_indication = 0x40;
285 break;
286 case VLC_CODEC_MPGA:
287 i_object_type_indication =
288 p_track->fmt.audio.i_rate < 32000 ? 0x69 : 0x6b;
289 break;
290 case VLC_CODEC_DTS:
291 i_object_type_indication = 0xa9;
292 break;
293 default:
294 i_object_type_indication = 0xFE; /* No profile specified */
295 break;
298 uint8_t i_stream_type;
299 switch(p_track->fmt.i_cat)
301 case VIDEO_ES:
302 i_stream_type = 0x04;
303 break;
304 case AUDIO_ES:
305 i_stream_type = 0x05;
306 break;
307 case SPU_ES:
308 i_stream_type = 0x0D;
309 break;
310 default:
311 i_stream_type = 0x20; /* Private */
312 break;
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
333 return esds;
336 static bo_t *GetWaveTag(mp4mux_trackinfo_t *p_track)
338 bo_t *wave;
339 bo_t *box;
341 wave = box_new("wave");
342 if(wave)
344 box = box_new("frma");
345 if(box)
347 bo_add_fourcc(box, "mp4a");
348 box_gather(wave, box);
351 box = box_new("mp4a");
352 if(box)
354 bo_add_32be(box, 0);
355 box_gather(wave, box);
358 box = GetESDS(p_track);
359 box_gather(wave, box);
361 box = box_new("srcq");
362 if(box)
364 bo_add_32be(box, 0x40);
365 box_gather(wave, box);
368 /* wazza ? */
369 bo_add_32be(wave, 8); /* new empty box */
370 bo_add_32be(wave, 0); /* box label */
372 return wave;
375 static bo_t *GetDec3Tag(es_format_t *p_fmt, block_t *a52_frame)
377 if (!a52_frame)
378 return NULL;
380 bs_t s;
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;
386 bsmod = 0;
388 strmtyp = bs_read(&s, 2);
390 if (strmtyp & 0x1) // dependent or reserved stream
391 return NULL;
393 if (bs_read(&s, 3) != 0x0) // substreamid: we don't support more than 1 stream
394 return NULL;
396 int numblkscod;
397 bs_skip(&s, 11); // frmsizecod
398 fscod = bs_read(&s, 2);
399 if (fscod == 0x03) {
400 bs_skip(&s, 2); // fscod2
401 numblkscod = 3;
402 } else {
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
415 if (acmod == 0) {
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
433 if (lfeon)
434 if (bs_read1(&s))
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);
445 if (mixdef == 0x1)
446 bs_skip(&s, 5);
447 else if (mixdef == 0x2)
448 bs_skip(&s, 12);
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");
491 if(dec3)
492 bo_add_mem(dec3, sizeof(mp4_eac3_header), mp4_eac3_header);
494 return dec3;
497 static bo_t *GetDac3Tag(block_t *a52_frame)
499 if (!a52_frame)
500 return NULL;
502 bo_t *dac3 = box_new("dac3");
503 if(!dac3)
504 return NULL;
506 bs_t s;
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);
518 if (acmod == 2)
519 bs_skip(&s, 2); // dsurmod
520 else {
521 if ((acmod & 1) && acmod != 1)
522 bs_skip(&s, 2); // cmixlev
523 if (acmod & 4)
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);
542 return dac3;
545 static bo_t *GetDamrTag(es_format_t *p_fmt)
547 bo_t *damr = box_new("damr");
548 if(!damr)
549 return NULL;
551 bo_add_fourcc(damr, "REFC");
552 bo_add_8(damr, 0);
554 if (p_fmt->i_codec == VLC_CODEC_AMR_NB)
555 bo_add_16be(damr, 0x81ff); /* Mode set (all modes for AMR_NB) */
556 else
557 bo_add_16be(damr, 0x83ff); /* Mode set (all modes for AMR_WB) */
558 bo_add_16be(damr, 0x1); /* Mode change period (no restriction) */
560 return damr;
563 static bo_t *GetD263Tag(void)
565 bo_t *d263 = box_new("d263");
566 if(!d263)
567 return NULL;
569 bo_add_fourcc(d263, "VLC ");
570 bo_add_16be(d263, 0xa);
571 bo_add_8(d263, 0);
573 return d263;
576 static void hevcParseVPS(uint8_t * p_buffer, size_t i_buffer, uint8_t *general,
577 uint8_t * numTemporalLayer, bool * temporalIdNested)
579 if(i_buffer < 19)
580 return;
582 bs_t bs;
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 */
600 bs_skip( &bs, 16 );
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] )
628 bs_skip( bs, 8 );
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)
635 if(i_buffer < 2)
636 return;
638 bs_t bs;
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 */
644 /* skip vps id */
645 bs_skip(&bs, 4);
646 uint32_t sps_max_sublayer_minus1 = bs_read(&bs, 3);
648 /* skip nesting flag */
649 bs_skip(&bs, 1);
651 hevc_skip_profile_tiers_level(&bs, sps_max_sublayer_minus1);
653 /* skip sps id */
654 (void) bs_read_ue( &bs );
656 *chroma_idc = bs_read_ue(&bs);
657 if (*chroma_idc == 3)
658 bs_skip(&bs, 1);
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) {
666 /* skip offsets*/
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)
681 return hvcC;
683 struct nal {
684 size_t i_buffer;
685 uint8_t * p_buffer;
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;
691 size_t i_sei = 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);
700 return hvcC;
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;
711 while (i_buffer) {
712 /* look for start code 0X0000001 */
713 while (i_buffer) {
714 cmp = (cmp << 8) | *p_buffer;
715 if((cmp ^ UINT32_C(0x100)) <= UINT32_C(0xFF))
716 break;
717 p_buffer++;
718 i_buffer--;
720 if (p_nal)
721 p_nal->i_buffer = p_buffer - p_nal->p_buffer - ((i_buffer)?3:0);
723 switch (hevc_getNALType(p_buffer)) {
725 case HEVC_NAL_VPS:
726 if(i_vps > HEVC_VPS_ID_MAX)
727 break;
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) */
732 if (i_vps == 1) {
733 hevcParseVPS(p_buffer, i_buffer, general_configuration,
734 &i_numTemporalLayer, &b_temporalIdNested);
735 i_num_arrays++;
737 break;
739 case HEVC_NAL_SPS: {
740 if(i_sps > HEVC_SPS_ID_MAX)
741 break;
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);
748 i_num_arrays++;
750 break;
753 case HEVC_NAL_PPS: {
754 if(i_pps > HEVC_PPS_ID_MAX)
755 break;
756 p_nal = &rg_pps[i_pps++];
757 p_nal->p_buffer = p_buffer;
758 if (i_pps == 1)
759 i_num_arrays++;
760 break;
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));
766 if (!p_tmp)
767 break;
768 p_sei = p_tmp;
769 p_nal = &p_sei[i_sei++];
770 p_nal->p_buffer = p_buffer;
771 if(i_sei == 1)
772 i_num_arrays++;
773 break;
775 default:
776 p_nal = NULL;
777 break;
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);
797 if (i_vps)
799 /* Write VPS */
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++) {
803 p_nal = &rg_vps[i];
804 bo_add_16be(hvcC, p_nal->i_buffer);
805 bo_add_mem(hvcC, p_nal->i_buffer, p_nal->p_buffer);
809 if (i_sps) {
810 /* Write SPS */
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++) {
814 p_nal = &rg_sps[i];
815 bo_add_16be(hvcC, p_nal->i_buffer);
816 bo_add_mem(hvcC, p_nal->i_buffer, p_nal->p_buffer);
820 if (i_pps) {
821 /* Write PPS */
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++) {
825 p_nal = &rg_pps[i];
826 bo_add_16be(hvcC, p_nal->i_buffer);
827 bo_add_mem(hvcC, p_nal->i_buffer, p_nal->p_buffer);
831 if (i_sei) {
832 /* Write SEI */
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++) {
836 p_nal = &p_sei[i];
837 bo_add_16be(hvcC, p_nal->i_buffer);
838 bo_add_mem(hvcC, p_nal->i_buffer, p_nal->p_buffer);
841 free(p_sei);
842 return hvcC;
845 static bo_t *GetWaveFormatExTag(es_format_t *p_fmt, const char *tag)
847 bo_t *box = box_new(tag);
848 if(!box)
849 return NULL;
851 uint16_t wFormatTag;
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);
863 return box;
866 static bo_t *GetxxxxTag(es_format_t *p_fmt, const char *tag)
868 bo_t *box = box_new(tag);
869 if(!box)
870 return NULL;
871 bo_add_mem(box, p_fmt->i_extra, p_fmt->p_extra);
872 return box;
875 static bo_t *GetAvcCTag(es_format_t *p_fmt)
877 bo_t *avcC = box_new("avcC");/* FIXME use better value */
878 if(!avcC)
879 return NULL;
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,
884 &p_sps, &i_sps_size,
885 &p_pps, &i_pps_size,
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 );
918 if( p_spsdata )
920 uint8_t data[3];
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 );
936 return avcC;
939 /* TODO: No idea about these values */
940 static bo_t *GetSVQ3Tag(es_format_t *p_fmt)
942 bo_t *smi = box_new("SMI ");
943 if(!smi)
944 return NULL;
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 */
953 break;
954 if (!strncmp((const char *)&p[4], "SMI ", 4)) {
955 bo_add_mem(smi, p_end - p - 8, &p[8]);
956 return smi;
958 p += i_size;
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);
966 bo_add_8(smi, 0xc0);
968 return smi;
971 static bo_t *GetUdtaTag(mp4mux_trackinfo_t **pp_tracks, unsigned int i_tracks)
973 bo_t *udta = box_new("udta");
974 if (!udta)
975 return NULL;
977 /* Requirements */
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");
984 if(!box)
985 break;
986 /* String length */
987 bo_add_16be(box, sizeof("QuickTime 6.0 or greater") - 1);
988 bo_add_16be(box, 0);
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);
992 break;
996 /* Encoder */
998 bo_t *box = box_new("\251enc");
999 if(box)
1001 /* String length */
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);
1009 #if 0
1010 /* Misc atoms */
1011 vlc_meta_t *p_meta = p_mux->p_sout->p_meta;
1012 if (p_meta) {
1013 #define ADD_META_BOX(type, box_string) { \
1014 bo_t *box = NULL; \
1015 if (vlc_meta_Get(p_meta, vlc_meta_##type)) \
1016 box = box_new("\251" box_string); \
1017 if (box) { \
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");
1032 #undef ADD_META_BOX
1034 #endif
1035 return udta;
1038 static bo_t *GetSounBox(vlc_object_t *p_obj, mp4mux_trackinfo_t *p_track, bool b_mov)
1040 VLC_UNUSED(p_obj);
1042 bool b_descr = true;
1043 vlc_fourcc_t codec = p_track->fmt.i_codec;
1044 char fcc[4];
1046 if (codec == VLC_CODEC_MPGA) {
1047 if (b_mov) {
1048 b_descr = false;
1049 memcpy(fcc, ".mp3", 4);
1050 } else
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);
1060 } else
1061 vlc_fourcc_to_char(codec, fcc);
1063 bo_t *soun = box_new(fcc);
1064 if(!soun)
1065 return NULL;
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;
1073 else
1074 bo_add_16be(soun, 0); // version 0;
1075 bo_add_16be(soun, 0); // revision level (0)
1076 bo_add_32be(soun, 0); // vendor
1077 // channel-count
1078 bo_add_16be(soun, p_track->fmt.audio.i_channels);
1079 // sample size
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 */
1098 if (b_descr) {
1099 bo_t *box;
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");
1111 else
1112 box = GetESDS(p_track);
1114 if (box)
1115 box_gather(soun, box);
1118 return soun;
1121 static bo_t *GetVideBox(vlc_object_t *p_obj, mp4mux_trackinfo_t *p_track, bool b_mov)
1123 VLC_UNUSED(p_obj);
1124 VLC_UNUSED(b_mov);
1126 char fcc[4];
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;
1143 default:
1144 vlc_fourcc_to_char(p_track->fmt.i_codec, fcc);
1145 break;
1148 bo_t *vide = box_new(fcc);
1149 if(!vide)
1150 return NULL;
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
1169 // compressor name;
1170 for (int i = 0; i < 32; i++)
1171 bo_add_8(vide, 0);
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));
1182 break;
1184 case VLC_CODEC_H263:
1185 box_gather(vide, GetD263Tag());
1186 break;
1188 case VLC_CODEC_SVQ3:
1189 box_gather(vide, GetSVQ3Tag(&p_track->fmt));
1190 break;
1192 case VLC_CODEC_H264:
1193 box_gather(vide, GetAvcCTag(&p_track->fmt));
1194 break;
1196 case VLC_CODEC_VC1:
1197 box_gather(vide, GetxxxxTag(&p_track->fmt, "dvc1"));
1198 break;
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));
1203 break;
1206 return vide;
1209 static bo_t *GetTextBox(void)
1211 bo_t *text = box_new("text");
1212 if(!text)
1213 return NULL;
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
1233 bo_add_8 (text, 9);
1234 bo_add_mem(text, 9, (uint8_t*)"Helvetica");
1236 return text;
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;
1250 return 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);
1257 if(!stsd)
1258 return NULL;
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 */
1268 bo_t *stco;
1270 if (b_stco64) {
1271 /* 64 bits version */
1272 stco = box_full_new("co64", 0, 0);
1273 } else {
1274 /* 32 bits version */
1275 stco = box_full_new("stco", 0, 0);
1277 if(!stco)
1279 bo_free(stsd);
1280 return NULL;
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);
1286 if(!stsc)
1288 bo_free(stco);
1289 bo_free(stsd);
1290 return NULL;
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;
1298 int i_first = i;
1300 if (b_stco64)
1301 bo_add_64be(stco, entry[i].i_pos);
1302 else
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) {
1308 i++;
1309 break;
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;
1318 i_stsc_entries++;
1322 /* Fix stco entry count */
1323 bo_swap_32be(stco, 12, i_chunk);
1324 if(p_obj)
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 );
1330 /* add stts */
1331 bo_t *stts = box_full_new("stts", 0, 0);
1332 if(!stts)
1334 bo_free(stsd);
1335 bo_free(stco);
1336 bo_free(stsc);
1337 return NULL;
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++) {
1345 int i_first = i;
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 )
1356 break;
1358 i_total_mtime = i_total_mtime_next;
1359 i_total_scaled = i_total_scaled_next;
1360 i = j;
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 */
1372 bo_t *ctts = NULL;
1373 if ( p_track->b_hasbframes && (ctts = box_full_new("ctts", 0, 0)) )
1375 bo_add_32be(ctts, 0);
1376 i_index = 0;
1377 for (unsigned i = 0; i < p_track->i_entry_count; i_index++)
1379 int i_first = i;
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)
1384 break;
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);
1393 if(!stsz)
1395 bo_free(stsd);
1396 bo_free(stco);
1397 bo_free(stts);
1398 return NULL;
1400 int i_size = 0;
1401 for (unsigned i = 0; i < p_track->i_entry_count; i++)
1403 if ( i == 0 )
1404 i_size = p_track->entry[i].i_size;
1405 else if ( p_track->entry[i].i_size != i_size )
1407 i_size = 0;
1408 break;
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 */
1420 bo_t *stss = NULL;
1421 i_index = 0;
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 )
1431 continue;
1434 if (p_track->entry[i].i_flags & BLOCK_FLAG_TYPE_I) {
1435 if (stss == NULL) {
1436 stss = box_full_new("stss", 0, 0);
1437 if(!stss)
1438 break;
1439 bo_add_32be(stss, 0); /* fixed later */
1441 bo_add_32be(stss, 1 + i);
1442 i_index++;
1443 i_interval = 0;
1448 if (stss)
1449 bo_swap_32be(stss, 12, i_index);
1451 /* Now gather all boxes into stbl */
1452 bo_t *stbl = box_new("stbl");
1453 if(!stbl)
1455 bo_free(stsd);
1456 bo_free(stco);
1457 bo_free(stts);
1458 bo_free(stsz);
1459 bo_free(stss);
1460 bo_free(ctts);
1461 return NULL;
1463 box_gather(stbl, stsd);
1464 box_gather(stbl, stts);
1465 if (stss)
1466 box_gather(stbl, stss);
1467 if (ctts)
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);
1474 return stbl;
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 )
1481 bo_t *moov, *mvhd;
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 */
1488 if( i_tracks == 1 )
1489 i_movie_timescale = pp_tracks[0]->i_timescale;
1491 moov = box_new("moov");
1492 if(!moov)
1493 return NULL;
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);
1501 if(p_obj)
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 *** */
1508 if (!b_64_ext) {
1509 mvhd = box_full_new("mvhd", 0, 0);
1510 if(!mvhd)
1512 bo_free(moov);
1513 return NULL;
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
1519 } else {
1520 mvhd = box_full_new("mvhd", 1, 0);
1521 if(!mvhd)
1523 bo_free(moov);
1524 return NULL;
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;
1555 else
1556 i_stream_duration = 0;
1558 /* *** add /moov/trak *** */
1559 bo_t *trak = box_new("trak");
1560 if(!trak)
1561 continue;
1563 /* *** add /moov/trak/tkhd *** */
1564 bo_t *tkhd;
1565 if (!b_64_ext) {
1566 if (b_mov)
1567 tkhd = box_full_new("tkhd", 0, 0x0f);
1568 else
1569 tkhd = box_full_new("tkhd", 0, 1);
1570 if(!tkhd)
1572 bo_free(trak);
1573 continue;
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
1580 } else {
1581 if (b_mov)
1582 tkhd = box_full_new("tkhd", 1, 0x0f);
1583 else
1584 tkhd = box_full_new("tkhd", 1, 1);
1585 if(!tkhd)
1587 bo_free(trak);
1588 continue;
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
1601 // volume
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);
1621 } else {
1622 int i_width = 320 << 16;
1623 int i_height = 200;
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;
1632 else
1633 i_width = tk->fmt.video.i_width << 16;
1634 i_height = tk->fmt.video.i_height;
1635 break;
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);
1646 if(edts)
1647 box_gather(trak, edts);
1649 /* *** add /moov/trak/mdia *** */
1650 bo_t *mdia = box_new("mdia");
1651 if(!mdia)
1653 bo_free(trak);
1654 continue;
1657 /* media header */
1658 bo_t *mdhd;
1659 if (!b_64_ext) {
1660 mdhd = box_full_new("mdhd", 0, 0);
1661 if(!mdhd)
1663 bo_free(mdia);
1664 bo_free(trak);
1665 continue;
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
1671 } else {
1672 mdhd = box_full_new("mdhd", 1, 0);
1673 if(!mdhd)
1675 bo_free(mdia);
1676 bo_free(trak);
1677 continue;
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
1703 } else
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);
1710 if(!hdlr)
1712 bo_free(mdia);
1713 bo_free(trak);
1714 continue;
1717 if (b_mov)
1718 bo_add_fourcc(hdlr, "mhlr"); // media handler
1719 else
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
1733 if (b_mov)
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");
1740 else
1741 bo_add_mem(hdlr, 12, (uint8_t*)"Text Handler");
1743 if (!b_mov)
1744 bo_add_8(hdlr, 0); /* asciiz string for .mp4, yes that's BRAIN DAMAGED F**K MP4 */
1746 box_gather(mdia, hdlr);
1748 /* minf*/
1749 bo_t *minf = box_new("minf");
1750 if(!minf)
1752 bo_free(mdia);
1753 bo_free(trak);
1754 continue;
1757 /* add smhd|vmhd */
1758 if (p_stream->fmt.i_cat == AUDIO_ES) {
1759 bo_t *smhd = box_full_new("smhd", 0, 0);
1760 if(smhd)
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);
1769 if(vmhd)
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);
1778 if(gmin)
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");
1787 if(gmhd)
1789 box_gather(gmhd, gmin);
1790 box_gather(minf, gmhd);
1792 else bo_free(gmin);
1796 /* dinf */
1797 bo_t *dref = box_full_new("dref", 0, 0);
1798 if(dref)
1800 bo_add_32be(dref, 1);
1802 bo_t *url = box_full_new("url ", 0, 0x01);
1803 if(url)
1804 box_gather(dref, url);
1806 bo_t *dinf = box_new("dinf");
1807 if(dinf)
1809 box_gather(dinf, dref);
1811 /* append dinf to mdia */
1812 box_gather(minf, dinf);
1814 else bo_free(dref);
1817 /* add stbl */
1818 bo_t *stbl;
1819 if ( b_fragmented )
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;
1826 else
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));
1849 if ( b_fragmented )
1851 bo_t *mvex = box_new("mvex");
1852 if( mvex )
1854 if( i_movie_duration )
1856 bo_t *mehd = box_full_new("mehd", b_64_ext ? 1 : 0, 0);
1857 if(mehd)
1859 if(b_64_ext)
1860 bo_add_64be(mehd, i_movie_duration * i_movie_timescale / CLOCK_FREQ);
1861 else
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);
1891 if(moov->b)
1892 box_fix(moov, moov->b->i_buffer);
1893 return moov;
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");
1899 if(box)
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]);
1905 if(!box->b)
1907 free(box);
1908 return NULL;
1910 box_fix(box, box->b->i_buffer);
1912 return box;
1915 bool mp4mux_CanMux(vlc_object_t *p_obj, const es_format_t *p_fmt)
1917 switch(p_fmt->i_codec)
1919 case VLC_CODEC_A52:
1920 case VLC_CODEC_DTS:
1921 case VLC_CODEC_EAC3:
1922 case VLC_CODEC_MP4A:
1923 case VLC_CODEC_MP4V:
1924 case VLC_CODEC_MPGA:
1925 case VLC_CODEC_MP3:
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:
1938 case VLC_CODEC_VC1:
1939 case VLC_CODEC_WMAP:
1940 break;
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");
1944 break;
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");
1948 return false;
1949 case VLC_CODEC_SUBT:
1950 if(p_obj)
1951 msg_Warn(p_obj, "subtitle track added like in .mov (even when creating .mp4)");
1952 break;
1953 default:
1954 return false;
1956 return true;