0af383f960a780c175cb7a7837c2edf0a128a4da
[vlc.git] / modules / mux / mp4 / libmp4mux.c
1 /*****************************************************************************
2  * libmp4mux.c: mp4/mov muxer
3  *****************************************************************************
4  * Copyright (C) 2001, 2002, 2003, 2006, 20115 VLC authors and VideoLAN
5  *
6  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7  *          Gildas Bazin <gbazin at videolan dot org>
8  *
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.
13  *
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.
18  *
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
26
27 #include "libmp4mux.h"
28 #include "../demux/mp4/libmp4.h" /* flags */
29 #include "../packetizer/hevc_nal.h"
30 #include "../packetizer/h264_nal.h" /* h264_get_spspps */
31 #include "../packetizer/hxxx_nal.h"
32
33 #include <vlc_es.h>
34 #include <vlc_iso_lang.h>
35 #include <vlc_bits.h>
36 #include <assert.h>
37 #include <time.h>
38
39 bool mp4mux_trackinfo_Init(mp4mux_trackinfo_t *p_stream)
40 {
41     p_stream->i_track_id = 1;
42
43     es_format_Init(&p_stream->fmt, 0, 0);
44
45     p_stream->i_entry_count = 0;
46     p_stream->i_entry_max   = 1000;
47     p_stream->entry         = calloc(p_stream->i_entry_max, sizeof(mp4mux_entry_t));
48     if(!p_stream->entry)
49     {
50         es_format_Clean(&p_stream->fmt);
51         return false;
52     }
53
54     p_stream->a52_frame       = NULL;
55
56     p_stream->i_read_duration = 0;
57     p_stream->i_timescale     = CLOCK_FREQ;
58     p_stream->i_starttime     = 0;
59     p_stream->b_hasbframes    = false;
60
61     p_stream->i_stco_pos = 0;
62
63     p_stream->i_trex_default_length = 0;
64     p_stream->i_trex_default_size = 0;
65     return true;
66 }
67
68 void mp4mux_trackinfo_Clear(mp4mux_trackinfo_t *p_stream)
69 {
70     es_format_Clean(&p_stream->fmt);
71     if (p_stream->a52_frame)
72         block_Release(p_stream->a52_frame);
73     free(p_stream->entry);
74 }
75
76
77 bo_t *box_new(const char *fcc)
78 {
79     bo_t *box = malloc(sizeof(*box));
80     if (!box)
81         return NULL;
82
83     if(!bo_init(box, 1024))
84     {
85         bo_free(box);
86         return NULL;
87     }
88
89     bo_add_32be  (box, 0);
90     bo_add_fourcc(box, fcc);
91
92     return box;
93 }
94
95 bo_t *box_full_new(const char *fcc, uint8_t v, uint32_t f)
96 {
97     bo_t *box = box_new(fcc);
98     if (!box)
99         return NULL;
100
101     bo_add_8     (box, v);
102     bo_add_24be  (box, f);
103
104     return box;
105 }
106
107 void box_fix(bo_t *box, uint32_t i_size)
108 {
109     bo_set_32be(box, 0, i_size);
110 }
111
112 void box_gather (bo_t *box, bo_t *box2)
113 {
114     if(box2 && box2->b && box && box->b)
115     {
116         box_fix(box2, box2->b->i_buffer);
117         size_t i_offset = box->b->i_buffer;
118         box->b = block_Realloc(box->b, 0, box->b->i_buffer + box2->b->i_buffer);
119         memcpy(&box->b->p_buffer[i_offset], box2->b->p_buffer, box2->b->i_buffer);
120     }
121     bo_free(box2);
122 }
123
124 static inline void bo_add_mp4_tag_descr(bo_t *box, uint8_t tag, uint32_t size)
125 {
126     bo_add_8(box, tag);
127     for (int i = 3; i>0; i--)
128         bo_add_8(box, (size>>(7*i)) | 0x80);
129     bo_add_8(box, size & 0x7F);
130 }
131
132 static int64_t get_timestamp(void)
133 {
134     int64_t i_timestamp = time(NULL);
135
136     i_timestamp += 2082844800; // MOV/MP4 start date is 1/1/1904
137     // 208284480 is (((1970 - 1904) * 365) + 17) * 24 * 60 * 60
138
139     return i_timestamp;
140 }
141
142 /****************************************************************************/
143
144 static void matrix_apply_rotation(es_format_t *fmt, uint32_t mvhd_matrix[9])
145 {
146     enum video_orientation_t orientation = ORIENT_NORMAL;
147     if (fmt->i_cat == VIDEO_ES)
148         orientation = fmt->video.orientation;
149
150 #define ATAN(a, b) \
151     do { \
152         mvhd_matrix[1] = ((uint32_t)(a)) << 16; \
153         mvhd_matrix[0] = ((uint32_t)(b)) << 16; \
154     } while(0)
155
156     switch (orientation) {
157     case ORIENT_ROTATED_90:  ATAN( 1,  0); break;
158     case ORIENT_ROTATED_180: ATAN( 0, -1); break;
159     case ORIENT_ROTATED_270: ATAN(-1,  0); break;
160     default:                 ATAN( 0,  1); break;
161     }
162
163     mvhd_matrix[3] = mvhd_matrix[0] ? 0 : 0x10000;
164     mvhd_matrix[4] = mvhd_matrix[1] ? 0 : 0x10000;
165 }
166
167 static bo_t *GetESDS(mp4mux_trackinfo_t *p_track)
168 {
169     bo_t *esds;
170
171     /* */
172     int i_decoder_specific_info_size = (p_track->fmt.i_extra > 0) ? 5 + p_track->fmt.i_extra : 0;
173
174     esds = box_full_new("esds", 0, 0);
175     if(!esds)
176         return NULL;
177
178     /* Compute Max bitrate */
179     int64_t i_bitrate_avg = 0;
180     int64_t i_bitrate_max = 0;
181     /* Compute avg/max bitrate */
182     for (unsigned i = 0; i < p_track->i_entry_count; i++) {
183         i_bitrate_avg += p_track->entry[i].i_size;
184         if (p_track->entry[i].i_length > 0) {
185             int64_t i_bitrate = INT64_C(8000000) * p_track->entry[i].i_size / p_track->entry[i].i_length;
186             if (i_bitrate > i_bitrate_max)
187                 i_bitrate_max = i_bitrate;
188         }
189     }
190
191     if (p_track->i_read_duration > 0)
192         i_bitrate_avg = INT64_C(8000000) * i_bitrate_avg / p_track->i_read_duration;
193     else
194         i_bitrate_avg = 0;
195     if (i_bitrate_max <= 1)
196         i_bitrate_max = 0x7fffffff;
197
198     /* ES_Descr */
199     bo_add_mp4_tag_descr(esds, 0x03, 3 + 5 + 13 + i_decoder_specific_info_size + 5 + 1);
200     bo_add_16be(esds, p_track->i_track_id);
201     bo_add_8   (esds, 0x1f);      // flags=0|streamPriority=0x1f
202
203     /* DecoderConfigDescr */
204     bo_add_mp4_tag_descr(esds, 0x04, 13 + i_decoder_specific_info_size);
205
206     int  i_object_type_indication;
207     switch(p_track->fmt.i_codec)
208     {
209     case VLC_CODEC_MP4V:
210         i_object_type_indication = 0x20;
211         break;
212     case VLC_CODEC_MPGV:
213         if(p_track->fmt.i_original_fourcc == VLC_CODEC_MP1V)
214         {
215             i_object_type_indication = 0x6b;
216             break;
217         }
218     case VLC_CODEC_MP2V:
219         /* MPEG-I=0x6b, MPEG-II = 0x60 -> 0x65 */
220         i_object_type_indication = 0x65;
221         break;
222     case VLC_CODEC_MP1V:
223         /* MPEG-I=0x6b, MPEG-II = 0x60 -> 0x65 */
224         i_object_type_indication = 0x6b;
225         break;
226     case VLC_CODEC_MP4A:
227         /* FIXME for mpeg2-aac == 0x66->0x68 */
228         i_object_type_indication = 0x40;
229         break;
230     case VLC_CODEC_MPGA:
231         i_object_type_indication =
232             p_track->fmt.audio.i_rate < 32000 ? 0x69 : 0x6b;
233         break;
234     case VLC_CODEC_DTS:
235         i_object_type_indication = 0xa9;
236         break;
237     default:
238         i_object_type_indication = 0x00;
239         break;
240     }
241     int i_stream_type = p_track->fmt.i_cat == VIDEO_ES ? 0x04 : 0x05;
242
243     bo_add_8   (esds, i_object_type_indication);
244     bo_add_8   (esds, (i_stream_type << 2) | 1);
245     bo_add_24be(esds, 1024 * 1024);       // bufferSizeDB
246     bo_add_32be(esds, i_bitrate_max);     // maxBitrate
247     bo_add_32be(esds, i_bitrate_avg);     // avgBitrate
248
249     if (p_track->fmt.i_extra > 0) {
250         /* DecoderSpecificInfo */
251         bo_add_mp4_tag_descr(esds, 0x05, p_track->fmt.i_extra);
252
253         for (int i = 0; i < p_track->fmt.i_extra; i++)
254             bo_add_8(esds, ((uint8_t*)p_track->fmt.p_extra)[i]);
255     }
256
257     /* SL_Descr mandatory */
258     bo_add_mp4_tag_descr(esds, 0x06, 1);
259     bo_add_8    (esds, 0x02);  // sl_predefined
260
261     return esds;
262 }
263
264 static bo_t *GetWaveTag(mp4mux_trackinfo_t *p_track)
265 {
266     bo_t *wave;
267     bo_t *box;
268
269     wave = box_new("wave");
270     if(wave)
271     {
272         box = box_new("frma");
273         if(box)
274         {
275             bo_add_fourcc(box, "mp4a");
276             box_gather(wave, box);
277         }
278
279         box = box_new("mp4a");
280         if(box)
281         {
282             bo_add_32be(box, 0);
283             box_gather(wave, box);
284         }
285
286         box = GetESDS(p_track);
287         box_gather(wave, box);
288
289         box = box_new("srcq");
290         if(box)
291         {
292             bo_add_32be(box, 0x40);
293             box_gather(wave, box);
294         }
295
296         /* wazza ? */
297         bo_add_32be(wave, 8); /* new empty box */
298         bo_add_32be(wave, 0); /* box label */
299     }
300     return wave;
301 }
302
303 static bo_t *GetDec3Tag(es_format_t *p_fmt, block_t *a52_frame)
304 {
305     if (!a52_frame)
306         return NULL;
307
308     bs_t s;
309     bs_write_init(&s, a52_frame->p_buffer, sizeof(a52_frame->i_buffer));
310     bs_skip(&s, 16); // syncword
311
312     uint8_t fscod, bsid, bsmod, acmod, lfeon, strmtyp;
313
314     bsmod = 0;
315
316     strmtyp = bs_read(&s, 2);
317
318     if (strmtyp & 0x1) // dependent or reserved stream
319         return NULL;
320
321     if (bs_read(&s, 3) != 0x0) // substreamid: we don't support more than 1 stream
322         return NULL;
323
324     int numblkscod;
325     bs_skip(&s, 11); // frmsizecod
326     fscod = bs_read(&s, 2);
327     if (fscod == 0x03) {
328         bs_skip(&s, 2); // fscod2
329         numblkscod = 3;
330     } else {
331         numblkscod = bs_read(&s, 2);
332     }
333
334     acmod = bs_read(&s, 3);
335     lfeon = bs_read1(&s);
336
337     bsid = bs_read(&s, 5);
338
339     bs_skip(&s, 5); // dialnorm
340     if (bs_read1(&s)) // compre
341         bs_skip(&s, 5); // compr
342
343     if (acmod == 0) {
344         bs_skip(&s, 5); // dialnorm2
345         if (bs_read1(&s)) // compr2e
346             bs_skip(&s, 8); // compr2
347     }
348
349     if (strmtyp == 0x1) // dependent stream XXX: unsupported
350         if (bs_read1(&s)) // chanmape
351             bs_skip(&s, 16); // chanmap
352
353     /* we have to skip mixing info to read bsmod */
354     if (bs_read1(&s)) { // mixmdate
355         if (acmod > 0x2) // 2+ channels
356             bs_skip(&s, 2); // dmixmod
357         if ((acmod & 0x1) && (acmod > 0x2)) // 3 front channels
358             bs_skip(&s, 3 + 3); // ltrtcmixlev + lorocmixlev
359         if (acmod & 0x4) // surround channel
360             bs_skip(&s, 3 + 3); // ltrsurmixlev + lorosurmixlev
361         if (lfeon)
362             if (bs_read1(&s))
363                 bs_skip(&s, 5); // lfemixlevcod
364         if (strmtyp == 0) { // independent stream
365             if (bs_read1(&s)) // pgmscle
366                 bs_skip(&s, 6); // pgmscl
367             if (acmod == 0x0) // dual mono
368                 if (bs_read1(&s)) // pgmscl2e
369                     bs_skip(&s, 6); // pgmscl2
370             if (bs_read1(&s)) // extpgmscle
371                 bs_skip(&s, 6); // extpgmscl
372             uint8_t mixdef = bs_read(&s, 2);
373             if (mixdef == 0x1)
374                 bs_skip(&s, 5);
375             else if (mixdef == 0x2)
376                 bs_skip(&s, 12);
377             else if (mixdef == 0x3) {
378                 uint8_t mixdeflen = bs_read(&s, 5);
379                 bs_skip(&s, 8 * (mixdeflen + 2));
380             }
381             if (acmod < 0x2) { // mono or dual mono
382                 if (bs_read1(&s)) // paninfoe
383                     bs_skip(&s, 14); // paninfo
384                 if (acmod == 0) // dual mono
385                     if (bs_read1(&s)) // paninfo2e
386                         bs_skip(&s, 14); // paninfo2
387             }
388             if (bs_read1(&s)) { // frmmixcfginfoe
389                 static const int blocks[4] = { 1, 2, 3, 6 };
390                 int number_of_blocks = blocks[numblkscod];
391                 if (number_of_blocks == 1)
392                     bs_skip(&s, 5); // blkmixcfginfo[0]
393                 else for (int i = 0; i < number_of_blocks; i++)
394                     if (bs_read1(&s)) // blkmixcfginfoe
395                         bs_skip(&s, 5); // blkmixcfginfo[i]
396             }
397         }
398     }
399
400     if (bs_read1(&s)) // infomdate
401         bsmod = bs_read(&s, 3);
402
403     uint8_t mp4_eac3_header[5] = {0};
404     bs_init(&s, mp4_eac3_header, sizeof(mp4_eac3_header));
405
406     int data_rate = p_fmt->i_bitrate / 1000;
407     bs_write(&s, 13, data_rate);
408     bs_write(&s, 3, 0); // num_ind_sub - 1
409     bs_write(&s, 2, fscod);
410     bs_write(&s, 5, bsid);
411     bs_write(&s, 5, bsmod);
412     bs_write(&s, 3, acmod);
413     bs_write(&s, 1, lfeon);
414     bs_write(&s, 3, 0); // reserved
415     bs_write(&s, 4, 0); // num_dep_sub
416     bs_write(&s, 1, 0); // reserved
417
418     bo_t *dec3 = box_new("dec3");
419     if(dec3)
420         bo_add_mem(dec3, sizeof(mp4_eac3_header), mp4_eac3_header);
421
422     return dec3;
423 }
424
425 static bo_t *GetDac3Tag(block_t *a52_frame)
426 {
427     if (!a52_frame)
428         return NULL;
429
430     bo_t *dac3 = box_new("dac3");
431     if(!dac3)
432         return NULL;
433
434     bs_t s;
435     bs_init(&s, a52_frame->p_buffer, sizeof(a52_frame->i_buffer));
436
437     uint8_t fscod, bsid, bsmod, acmod, lfeon, frmsizecod;
438
439     bs_skip(&s, 16 + 16); // syncword + crc
440
441     fscod = bs_read(&s, 2);
442     frmsizecod = bs_read(&s, 6);
443     bsid = bs_read(&s, 5);
444     bsmod = bs_read(&s, 3);
445     acmod = bs_read(&s, 3);
446     if (acmod == 2)
447         bs_skip(&s, 2); // dsurmod
448     else {
449         if ((acmod & 1) && acmod != 1)
450             bs_skip(&s, 2); // cmixlev
451         if (acmod & 4)
452             bs_skip(&s, 2); // surmixlev
453     }
454
455     lfeon = bs_read1(&s);
456
457     uint8_t mp4_a52_header[3];
458     bs_init(&s, mp4_a52_header, sizeof(mp4_a52_header));
459
460     bs_write(&s, 2, fscod);
461     bs_write(&s, 5, bsid);
462     bs_write(&s, 3, bsmod);
463     bs_write(&s, 3, acmod);
464     bs_write(&s, 1, lfeon);
465     bs_write(&s, 5, frmsizecod >> 1); // bit_rate_code
466     bs_write(&s, 5, 0); // reserved
467
468     bo_add_mem(dac3, sizeof(mp4_a52_header), mp4_a52_header);
469
470     return dac3;
471 }
472
473 static bo_t *GetDamrTag(es_format_t *p_fmt)
474 {
475     bo_t *damr = box_new("damr");
476     if(!damr)
477         return NULL;
478
479     bo_add_fourcc(damr, "REFC");
480     bo_add_8(damr, 0);
481
482     if (p_fmt->i_codec == VLC_CODEC_AMR_NB)
483         bo_add_16be(damr, 0x81ff); /* Mode set (all modes for AMR_NB) */
484     else
485         bo_add_16be(damr, 0x83ff); /* Mode set (all modes for AMR_WB) */
486     bo_add_16be(damr, 0x1); /* Mode change period (no restriction) */
487
488     return damr;
489 }
490
491 static bo_t *GetD263Tag(void)
492 {
493     bo_t *d263 = box_new("d263");
494     if(!d263)
495         return NULL;
496
497     bo_add_fourcc(d263, "VLC ");
498     bo_add_16be(d263, 0xa);
499     bo_add_8(d263, 0);
500
501     return d263;
502 }
503
504 static void hevcParseVPS(uint8_t * p_buffer, size_t i_buffer, uint8_t *general,
505                          uint8_t * numTemporalLayer, bool * temporalIdNested)
506 {
507     if(i_buffer < 19)
508         return;
509
510     bs_t bs;
511     bs_init(&bs, p_buffer, i_buffer);
512     unsigned i_bitflow = 0;
513     bs.p_fwpriv = &i_bitflow;
514     bs.pf_forward = hxxx_bsfw_ep3b_to_rbsp;  /* Does the emulated 3bytes conversion to rbsp */
515
516     /* first two bytes are the NAL header, 3rd and 4th are:
517         vps_video_parameter_set_id(4)
518         vps_reserved_3_2bis(2)
519         vps_max_layers_minus1(6)
520         vps_max_sub_layers_minus1(3)
521         vps_temporal_id_nesting_flags
522     */
523     bs_skip( &bs, 16 + 4 + 2 + 6 );
524     *numTemporalLayer = bs_read( &bs, 3 ) + 1;
525     *temporalIdNested = bs_read1( &bs );
526
527     /* 5th & 6th are reserved 0xffff */
528     bs_skip( &bs, 16 );
529     /* copy the first 12 bytes of profile tier */
530     for(unsigned i=0; i<12; i++)
531         general[i] = bs_read( &bs, 8 );
532 }
533
534 static inline void hevc_skip_profile_tiers_level( bs_t * bs, int32_t max_sub_layer_minus1 )
535 {
536     uint8_t sub_layer_profile_present_flag[8];
537     uint8_t sub_layer_level_present_flag[8];
538
539     /* 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 */
540     bs_skip( bs, 2 + 1 + 5 + 32 + 1 + 1 + 1 + 1 + 44 + 8 );
541
542     for( int32_t i = 0; i < max_sub_layer_minus1; i++ )
543     {
544         sub_layer_profile_present_flag[i] = bs_read1( bs );
545         sub_layer_level_present_flag[i] = bs_read1( bs );
546     }
547
548     if(max_sub_layer_minus1 > 0)
549         bs_skip( bs, (8 - max_sub_layer_minus1) * 2 );
550
551     for( int32_t i = 0; i < max_sub_layer_minus1; i++ )
552     {
553         if( sub_layer_profile_present_flag[i] )
554             bs_skip( bs, 2 + 1 + 5 + 32 + 1 + 1 + 1 + 1 + 44 );
555         if( sub_layer_level_present_flag[i] )
556             bs_skip( bs, 8 );
557     }
558 }
559
560 static void hevcParseSPS(uint8_t * p_buffer, size_t i_buffer, uint8_t * chroma_idc,
561                          uint8_t *bit_depth_luma_minus8, uint8_t *bit_depth_chroma_minus8)
562 {
563     if(i_buffer < 2)
564         return;
565
566     bs_t bs;
567     bs_init(&bs, p_buffer + 2, i_buffer - 2);
568     unsigned i_bitflow = 0;
569     bs.p_fwpriv = &i_bitflow;
570     bs.pf_forward = hxxx_bsfw_ep3b_to_rbsp;  /* Does the emulated 3bytes conversion to rbsp */
571
572     /* skip vps id */
573     bs_skip(&bs, 4);
574     uint32_t sps_max_sublayer_minus1 = bs_read(&bs, 3);
575
576     /* skip nesting flag */
577     bs_skip(&bs, 1);
578
579     hevc_skip_profile_tiers_level(&bs, sps_max_sublayer_minus1);
580
581     /* skip sps id */
582     (void) bs_read_ue( &bs );
583
584     *chroma_idc = bs_read_ue(&bs);
585     if (*chroma_idc == 3)
586         bs_skip(&bs, 1);
587
588     /* skip width and heigh */
589     (void) bs_read_ue( &bs );
590     (void) bs_read_ue( &bs );
591
592     uint32_t conformance_window_flag = bs_read1(&bs);
593     if (conformance_window_flag) {
594         /* skip offsets*/
595         (void) bs_read_ue(&bs);
596         (void) bs_read_ue(&bs);
597         (void) bs_read_ue(&bs);
598         (void) bs_read_ue(&bs);
599     }
600     *bit_depth_luma_minus8 = bs_read_ue(&bs);
601     *bit_depth_chroma_minus8 = bs_read_ue(&bs);
602 }
603
604 static bo_t *GetHvcCTag(es_format_t *p_fmt, bool b_completeness)
605 {
606     /* Generate hvcC box matching iso/iec 14496-15 3rd edition */
607     bo_t *hvcC = box_new("hvcC");
608     if(!hvcC || !p_fmt->i_extra)
609         return hvcC;
610
611     struct nal {
612         size_t i_buffer;
613         uint8_t * p_buffer;
614     };
615
616     struct nal rg_vps[HEVC_VPS_MAX], rg_sps[HEVC_SPS_MAX],
617                rg_pps[HEVC_VPS_MAX], *p_sei = NULL, *p_nal = NULL;
618     uint8_t i_vps = 0, i_sps = 0, i_pps = 0, i_num_arrays = 0;
619     size_t i_sei = 0;
620
621     uint8_t * p_buffer = p_fmt->p_extra;
622     size_t i_buffer = p_fmt->i_extra;
623
624     /* Extradata is already an HEVCDecoderConfigurationRecord */
625     if(hevc_ishvcC(p_buffer, i_buffer))
626     {
627         (void) bo_add_mem(hvcC, i_buffer, p_buffer);
628         return hvcC;
629     }
630
631     uint8_t general_configuration[12] = {0};
632     uint8_t i_numTemporalLayer = 0;
633     uint8_t i_chroma_idc = 1;
634     uint8_t i_bit_depth_luma_minus8 = 0;
635     uint8_t i_bit_depth_chroma_minus8 = 0;
636     bool b_temporalIdNested = false;
637
638     uint32_t cmp = 0xFFFFFFFF;
639     while (i_buffer) {
640         /* look for start code 0X0000001 */
641         while (i_buffer) {
642             cmp = (cmp << 8) | *p_buffer;
643             if((cmp ^ UINT32_C(0x100)) <= UINT32_C(0xFF))
644                 break;
645             p_buffer++;
646             i_buffer--;
647         }
648         if (p_nal)
649             p_nal->i_buffer = p_buffer - p_nal->p_buffer - ((i_buffer)?3:0);
650
651         switch (hevc_getNALType(p_buffer)) {
652
653         case HEVC_NAL_VPS:
654             if(i_vps == HEVC_VPS_MAX)
655                 break;
656             p_nal = &rg_vps[i_vps++];
657             p_nal->p_buffer = p_buffer;
658             /* Only keep the general profile from the first VPS
659              * if there are several (this shouldn't happen so soon) */
660             if (i_vps == 1) {
661                 hevcParseVPS(p_buffer, i_buffer, general_configuration,
662                              &i_numTemporalLayer, &b_temporalIdNested);
663                 i_num_arrays++;
664             }
665             break;
666
667         case HEVC_NAL_SPS: {
668             if(i_sps == HEVC_SPS_MAX)
669                 break;
670             p_nal = &rg_sps[i_sps++];
671             p_nal->p_buffer = p_buffer;
672             if (i_sps == 1 && i_buffer > 15) {
673                 /* Get Chroma_idc and bitdepths */
674                 hevcParseSPS(p_buffer, i_buffer, &i_chroma_idc,
675                              &i_bit_depth_luma_minus8, &i_bit_depth_chroma_minus8);
676                 i_num_arrays++;
677             }
678             break;
679             }
680
681         case HEVC_NAL_PPS: {
682             if(i_pps == HEVC_PPS_MAX)
683                 break;
684             p_nal = &rg_pps[i_pps++];
685             p_nal->p_buffer = p_buffer;
686             if (i_pps == 1)
687                 i_num_arrays++;
688             break;
689             }
690
691         case HEVC_NAL_PREF_SEI:
692         case HEVC_NAL_SUFF_SEI: {
693             struct nal * p_tmp =  realloc(p_sei, sizeof(struct nal) * (i_sei + 1));
694             if (!p_tmp)
695                 break;
696             p_sei = p_tmp;
697             p_nal = &p_sei[i_sei++];
698             p_nal->p_buffer = p_buffer;
699             if(i_sei == 1)
700                 i_num_arrays++;
701             break;
702         }
703         default:
704             p_nal = NULL;
705             break;
706         }
707     }
708     bo_add_8(hvcC, 0x01);
709     bo_add_mem(hvcC, 12, general_configuration);
710     /* Don't set min spatial segmentation */
711     bo_add_16be(hvcC, 0xF000);
712     /* Don't set parallelism type since segmentation isn't set */
713     bo_add_8(hvcC, 0xFC);
714     bo_add_8(hvcC, (0xFC | (i_chroma_idc & 0x03)));
715     bo_add_8(hvcC, (0xF8 | (i_bit_depth_luma_minus8 & 0x07)));
716     bo_add_8(hvcC, (0xF8 | (i_bit_depth_chroma_minus8 & 0x07)));
717
718     /* Don't set framerate */
719     bo_add_16be(hvcC, 0x0000);
720     /* Force NAL size of 4 bytes that replace the startcode */
721     bo_add_8(hvcC, (((i_numTemporalLayer & 0x07) << 3) |
722                     (b_temporalIdNested << 2) | 0x03));
723     bo_add_8(hvcC, i_num_arrays);
724
725     if (i_vps)
726     {
727         /* Write VPS */
728         bo_add_8(hvcC, HEVC_NAL_VPS | (b_completeness ? 0x80 : 0));
729         bo_add_16be(hvcC, i_vps);
730         for (uint8_t i = 0; i < i_vps; i++) {
731             p_nal = &rg_vps[i];
732             bo_add_16be(hvcC, p_nal->i_buffer);
733             bo_add_mem(hvcC, p_nal->i_buffer, p_nal->p_buffer);
734         }
735     }
736
737     if (i_sps) {
738         /* Write SPS */
739         bo_add_8(hvcC, HEVC_NAL_SPS | (b_completeness ? 0x80 : 0));
740         bo_add_16be(hvcC, i_sps);
741         for (uint8_t i = 0; i < i_sps; i++) {
742             p_nal = &rg_sps[i];
743             bo_add_16be(hvcC, p_nal->i_buffer);
744             bo_add_mem(hvcC, p_nal->i_buffer, p_nal->p_buffer);
745         }
746     }
747
748     if (i_pps) {
749         /* Write PPS */
750         bo_add_8(hvcC, HEVC_NAL_PPS | (b_completeness ? 0x80 : 0));
751         bo_add_16be(hvcC, i_pps);
752         for (uint8_t i = 0; i < i_pps; i++) {
753             p_nal = &rg_pps[i];
754             bo_add_16be(hvcC, p_nal->i_buffer);
755             bo_add_mem(hvcC, p_nal->i_buffer, p_nal->p_buffer);
756         }
757     }
758
759     if (i_sei) {
760         /* Write SEI */
761         bo_add_8(hvcC, HEVC_NAL_PREF_SEI | (b_completeness ? 0x80 : 0));
762         bo_add_16be(hvcC, i_sei);
763         for (size_t i = 0; i < i_sei; i++) {
764             p_nal = &p_sei[i];
765             bo_add_16be(hvcC, p_nal->i_buffer);
766             bo_add_mem(hvcC, p_nal->i_buffer, p_nal->p_buffer);
767         }
768     }
769     free(p_sei);
770     return hvcC;
771 }
772
773 static bo_t *GetWaveFormatExTag(es_format_t *p_fmt, const char *tag)
774 {
775     bo_t *box = box_new(tag);
776     if(!box)
777         return NULL;
778
779     uint16_t wFormatTag;
780     fourcc_to_wf_tag(p_fmt->i_codec, &wFormatTag);
781     bo_add_16le(box, wFormatTag); //wFormatTag
782     bo_add_16le(box, p_fmt->audio.i_channels); //nChannels
783     bo_add_32le(box, p_fmt->audio.i_rate); //nSamplesPerSec
784     bo_add_32le(box, p_fmt->i_bitrate / 8); //nAvgBytesPerSec
785     bo_add_16le(box, p_fmt->audio.i_blockalign); //nBlockAlign
786     bo_add_16le(box, p_fmt->audio.i_bitspersample);  //wBitsPerSample
787     bo_add_16le(box, p_fmt->i_extra); //cbSize
788
789     bo_add_mem(box, p_fmt->i_extra, p_fmt->p_extra);
790
791     return box;
792 }
793
794 static bo_t *GetxxxxTag(es_format_t *p_fmt, const char *tag)
795 {
796     bo_t *box = box_new(tag);
797     if(!box)
798         return NULL;
799     bo_add_mem(box, p_fmt->i_extra, p_fmt->p_extra);
800     return box;
801 }
802
803 static bo_t *GetAvcCTag(es_format_t *p_fmt)
804 {
805     bo_t    *avcC = box_new("avcC");/* FIXME use better value */
806     if(!avcC)
807         return NULL;
808     uint8_t *p_sps = NULL;
809     uint8_t *p_pps = NULL;
810     size_t   i_sps_size = 0;
811     size_t   i_pps_size = 0;
812
813     if( h264_get_spspps(p_fmt->p_extra, p_fmt->i_extra,
814                         &p_sps, &i_sps_size, &p_pps, &i_pps_size) != 0 || !p_sps || !p_pps )
815     {
816         bo_free(avcC);
817         return NULL;
818     }
819
820     bo_add_8(avcC, 1);      /* configuration version */
821     bo_add_8(avcC, i_sps_size ? p_sps[1] : PROFILE_H264_MAIN);
822     bo_add_8(avcC, i_sps_size ? p_sps[2] : 64);
823     bo_add_8(avcC, i_sps_size ? p_sps[3] : 30);       /* level, 5.1 */
824     bo_add_8(avcC, 0xff);   /* 0b11111100 | lengthsize = 0x11 */
825
826     bo_add_8(avcC, 0xe0 | (i_sps_size > 0 ? 1 : 0));   /* 0b11100000 | sps_count */
827     if (i_sps_size > 0) {
828         bo_add_16be(avcC, i_sps_size);
829         bo_add_mem(avcC, i_sps_size, p_sps);
830     }
831
832     bo_add_8(avcC, (i_pps_size > 0 ? 1 : 0));   /* pps_count */
833     if (i_pps_size > 0) {
834         bo_add_16be(avcC, i_pps_size);
835         bo_add_mem(avcC, i_pps_size, p_pps);
836     }
837
838     return avcC;
839 }
840
841 /* TODO: No idea about these values */
842 static bo_t *GetSVQ3Tag(es_format_t *p_fmt)
843 {
844     bo_t *smi = box_new("SMI ");
845     if(!smi)
846         return NULL;
847
848     if (p_fmt->i_extra > 0x4e) {
849         uint8_t *p_end = &((uint8_t*)p_fmt->p_extra)[p_fmt->i_extra];
850         uint8_t *p     = &((uint8_t*)p_fmt->p_extra)[0x46];
851
852         while (p + 8 < p_end) {
853             int i_size = GetDWBE(p);
854             if (i_size <= 1) /* FIXME handle 1 as long size */
855                 break;
856             if (!strncmp((const char *)&p[4], "SMI ", 4)) {
857                 bo_add_mem(smi, p_end - p - 8, &p[8]);
858                 return smi;
859             }
860             p += i_size;
861         }
862     }
863
864     /* Create a dummy one in fallback */
865     bo_add_fourcc(smi, "SEQH");
866     bo_add_32be(smi, 0x5);
867     bo_add_32be(smi, 0xe2c0211d);
868     bo_add_8(smi, 0xc0);
869
870     return smi;
871 }
872
873 static bo_t *GetUdtaTag(mp4mux_trackinfo_t **pp_tracks, unsigned int i_tracks)
874 {
875     bo_t *udta = box_new("udta");
876     if (!udta)
877         return NULL;
878
879     /* Requirements */
880     for (unsigned int i = 0; i < i_tracks; i++) {
881         mp4mux_trackinfo_t *p_stream = pp_tracks[i];
882         vlc_fourcc_t codec = p_stream->fmt.i_codec;
883
884         if (codec == VLC_CODEC_MP4V || codec == VLC_CODEC_MP4A) {
885             bo_t *box = box_new("\251req");
886             if(!box)
887                 break;
888             /* String length */
889             bo_add_16be(box, sizeof("QuickTime 6.0 or greater") - 1);
890             bo_add_16be(box, 0);
891             bo_add_mem(box, sizeof("QuickTime 6.0 or greater") - 1,
892                         (uint8_t *)"QuickTime 6.0 or greater");
893             box_gather(udta, box);
894             break;
895         }
896     }
897
898     /* Encoder */
899     {
900         bo_t *box = box_new("\251enc");
901         if(box)
902         {
903             /* String length */
904             bo_add_16be(box, sizeof(PACKAGE_STRING " stream output") - 1);
905             bo_add_16be(box, 0);
906             bo_add_mem(box, sizeof(PACKAGE_STRING " stream output") - 1,
907                         (uint8_t*)PACKAGE_STRING " stream output");
908             box_gather(udta, box);
909         }
910     }
911 #if 0
912     /* Misc atoms */
913     vlc_meta_t *p_meta = p_mux->p_sout->p_meta;
914     if (p_meta) {
915 #define ADD_META_BOX(type, box_string) { \
916         bo_t *box = NULL;  \
917         if (vlc_meta_Get(p_meta, vlc_meta_##type)) \
918             box = box_new("\251" box_string); \
919         if (box) { \
920             bo_add_16be(box, strlen(vlc_meta_Get(p_meta, vlc_meta_##type))); \
921             bo_add_16be(box, 0); \
922             bo_add_mem(box, strlen(vlc_meta_Get(p_meta, vlc_meta_##type)), \
923                         (uint8_t*)(vlc_meta_Get(p_meta, vlc_meta_##type))); \
924             box_gather(udta, box); \
925         } }
926
927         ADD_META_BOX(Title, "nam");
928         ADD_META_BOX(Artist, "ART");
929         ADD_META_BOX(Genre, "gen");
930         ADD_META_BOX(Copyright, "cpy");
931         ADD_META_BOX(Description, "des");
932         ADD_META_BOX(Date, "day");
933         ADD_META_BOX(URL, "url");
934 #undef ADD_META_BOX
935     }
936 #endif
937     return udta;
938 }
939
940 static bo_t *GetSounBox(vlc_object_t *p_obj, mp4mux_trackinfo_t *p_track, bool b_mov)
941 {
942     VLC_UNUSED(p_obj);
943
944     bool b_descr = true;
945     vlc_fourcc_t codec = p_track->fmt.i_codec;
946     char fcc[4];
947
948     if (codec == VLC_CODEC_MPGA) {
949         if (b_mov) {
950             b_descr = false;
951             memcpy(fcc, ".mp3", 4);
952         } else
953             memcpy(fcc, "mp4a", 4);
954     } else if (codec == VLC_CODEC_A52) {
955         memcpy(fcc, "ac-3", 4);
956     } else if (codec == VLC_CODEC_EAC3) {
957         memcpy(fcc, "ec-3", 4);
958     } else if (codec == VLC_CODEC_DTS) {
959         memcpy(fcc, "DTS ", 4);
960     } else if (codec == VLC_CODEC_WMAP) {
961         memcpy(fcc, "wma ", 4);
962     } else
963         vlc_fourcc_to_char(codec, fcc);
964
965     bo_t *soun = box_new(fcc);
966     if(!soun)
967         return NULL;
968     for (int i = 0; i < 6; i++)
969         bo_add_8(soun, 0);        // reserved;
970     bo_add_16be(soun, 1);         // data-reference-index
971
972     /* SoundDescription */
973     if (b_mov && codec == VLC_CODEC_MP4A)
974         bo_add_16be(soun, 1);     // version 1;
975     else
976         bo_add_16be(soun, 0);     // version 0;
977     bo_add_16be(soun, 0);         // revision level (0)
978     bo_add_32be(soun, 0);         // vendor
979     // channel-count
980     bo_add_16be(soun, p_track->fmt.audio.i_channels);
981     // sample size
982     bo_add_16be(soun, p_track->fmt.audio.i_bitspersample ?
983                  p_track->fmt.audio.i_bitspersample : 16);
984     bo_add_16be(soun, -2);        // compression id
985     bo_add_16be(soun, 0);         // packet size (0)
986     bo_add_16be(soun, p_track->fmt.audio.i_rate); // sampleratehi
987     bo_add_16be(soun, 0);                             // sampleratelo
988
989     /* Extended data for SoundDescription V1 */
990     if (b_mov && p_track->fmt.i_codec == VLC_CODEC_MP4A) {
991         /* samples per packet */
992         bo_add_32be(soun, p_track->fmt.audio.i_frame_length);
993         bo_add_32be(soun, 1536); /* bytes per packet */
994         bo_add_32be(soun, 2);    /* bytes per frame */
995         /* bytes per sample */
996         bo_add_32be(soun, 2 /*p_fmt->audio.i_bitspersample/8 */);
997     }
998
999     /* Add an ES Descriptor */
1000     if (b_descr) {
1001         bo_t *box;
1002
1003         if (b_mov && codec == VLC_CODEC_MP4A)
1004             box = GetWaveTag(p_track);
1005         else if (codec == VLC_CODEC_AMR_NB)
1006             box = GetDamrTag(&p_track->fmt);
1007         else if (codec == VLC_CODEC_A52)
1008             box = GetDac3Tag(p_track->a52_frame);
1009         else if (codec == VLC_CODEC_EAC3)
1010             box = GetDec3Tag(&p_track->fmt, p_track->a52_frame);
1011         else if (codec == VLC_CODEC_WMAP)
1012             box = GetWaveFormatExTag(&p_track->fmt, "wfex");
1013         else
1014             box = GetESDS(p_track);
1015
1016         if (box)
1017             box_gather(soun, box);
1018     }
1019
1020     return soun;
1021 }
1022
1023 static bo_t *GetVideBox(vlc_object_t *p_obj, mp4mux_trackinfo_t *p_track, bool b_mov)
1024 {
1025     VLC_UNUSED(p_obj);
1026     VLC_UNUSED(b_mov);
1027
1028     char fcc[4];
1029
1030     switch(p_track->fmt.i_codec)
1031     {
1032     case VLC_CODEC_MP4V:
1033     case VLC_CODEC_MPGV: memcpy(fcc, "mp4v", 4); break;
1034     case VLC_CODEC_MJPG: memcpy(fcc, "mjpa", 4); break;
1035     case VLC_CODEC_SVQ1: memcpy(fcc, "SVQ1", 4); break;
1036     case VLC_CODEC_SVQ3: memcpy(fcc, "SVQ3", 4); break;
1037     case VLC_CODEC_H263: memcpy(fcc, "s263", 4); break;
1038     case VLC_CODEC_H264: memcpy(fcc, "avc1", 4); break;
1039     case VLC_CODEC_VC1 : memcpy(fcc, "vc-1", 4); break;
1040     /* FIXME: find a way to know if no non-VCL units are in the stream (->hvc1)
1041      * see 14496-15 8.4.1.1.1 */
1042     case VLC_CODEC_HEVC: memcpy(fcc, "hev1", 4); break;
1043     case VLC_CODEC_YV12: memcpy(fcc, "yv12", 4); break;
1044     case VLC_CODEC_YUYV: memcpy(fcc, "yuy2", 4); break;
1045     default:
1046         vlc_fourcc_to_char(p_track->fmt.i_codec, fcc);
1047         break;
1048     }
1049
1050     bo_t *vide = box_new(fcc);
1051     if(!vide)
1052         return NULL;
1053     for (int i = 0; i < 6; i++)
1054         bo_add_8(vide, 0);        // reserved;
1055     bo_add_16be(vide, 1);         // data-reference-index
1056
1057     bo_add_16be(vide, 0);         // predefined;
1058     bo_add_16be(vide, 0);         // reserved;
1059     for (int i = 0; i < 3; i++)
1060         bo_add_32be(vide, 0);     // predefined;
1061
1062     bo_add_16be(vide, p_track->fmt.video.i_width);  // i_width
1063     bo_add_16be(vide, p_track->fmt.video.i_height); // i_height
1064
1065     bo_add_32be(vide, 0x00480000);                // h 72dpi
1066     bo_add_32be(vide, 0x00480000);                // v 72dpi
1067
1068     bo_add_32be(vide, 0);         // data size, always 0
1069     bo_add_16be(vide, 1);         // frames count per sample
1070
1071     // compressor name;
1072     for (int i = 0; i < 32; i++)
1073         bo_add_8(vide, 0);
1074
1075     bo_add_16be(vide, 0x18);      // depth
1076     bo_add_16be(vide, 0xffff);    // predefined
1077
1078     /* add an ES Descriptor */
1079     switch(p_track->fmt.i_codec)
1080     {
1081     case VLC_CODEC_MP4V:
1082     case VLC_CODEC_MPGV:
1083         box_gather(vide, GetESDS(p_track));
1084         break;
1085
1086     case VLC_CODEC_H263:
1087         box_gather(vide, GetD263Tag());
1088         break;
1089
1090     case VLC_CODEC_SVQ3:
1091         box_gather(vide, GetSVQ3Tag(&p_track->fmt));
1092         break;
1093
1094     case VLC_CODEC_H264:
1095         box_gather(vide, GetAvcCTag(&p_track->fmt));
1096         break;
1097
1098     case VLC_CODEC_VC1:
1099         box_gather(vide, GetxxxxTag(&p_track->fmt, "dvc1"));
1100             break;
1101
1102     case VLC_CODEC_HEVC:
1103         /* Write HvcC without forcing VPS/SPS/PPS/SEI array_completeness */
1104         box_gather(vide, GetHvcCTag(&p_track->fmt, false));
1105         break;
1106     }
1107
1108     return vide;
1109 }
1110
1111 static bo_t *GetTextBox(void)
1112 {
1113     bo_t *text = box_new("text");
1114     if(!text)
1115         return NULL;
1116
1117     for (int i = 0; i < 6; i++)
1118         bo_add_8(text, 0);        // reserved;
1119     bo_add_16be(text, 1);         // data-reference-index
1120
1121     bo_add_32be(text, 0);         // display flags
1122     bo_add_32be(text, 0);         // justification
1123     for (int i = 0; i < 3; i++)
1124         bo_add_16be(text, 0);     // back ground color
1125
1126     bo_add_16be(text, 0);         // box text
1127     bo_add_16be(text, 0);         // box text
1128     bo_add_16be(text, 0);         // box text
1129     bo_add_16be(text, 0);         // box text
1130
1131     bo_add_64be(text, 0);         // reserved
1132     for (int i = 0; i < 3; i++)
1133         bo_add_16be(text, 0xff);  // foreground color
1134
1135     bo_add_8 (text, 9);
1136     bo_add_mem(text, 9, (uint8_t*)"Helvetica");
1137
1138     return text;
1139 }
1140
1141 static bo_t *GetStblBox(vlc_object_t *p_obj, mp4mux_trackinfo_t *p_track, bool b_mov, bool b_stco64)
1142 {
1143     /* sample description */
1144     bo_t *stsd = box_full_new("stsd", 0, 0);
1145     if(!stsd)
1146         return NULL;
1147     bo_add_32be(stsd, 1);
1148     if (p_track->fmt.i_cat == AUDIO_ES)
1149         box_gather(stsd, GetSounBox(p_obj, p_track, b_mov));
1150     else if (p_track->fmt.i_cat == VIDEO_ES)
1151         box_gather(stsd, GetVideBox(p_obj, p_track, b_mov));
1152     else if (p_track->fmt.i_cat == SPU_ES)
1153         box_gather(stsd, GetTextBox());
1154
1155     /* chunk offset table */
1156     bo_t *stco;
1157
1158     if (b_stco64) {
1159         /* 64 bits version */
1160         stco = box_full_new("co64", 0, 0);
1161     } else {
1162         /* 32 bits version */
1163         stco = box_full_new("stco", 0, 0);
1164     }
1165     if(!stco)
1166     {
1167         bo_free(stsd);
1168         return NULL;
1169     }
1170     bo_add_32be(stco, 0);     // entry-count (fixed latter)
1171
1172     /* sample to chunk table */
1173     bo_t *stsc = box_full_new("stsc", 0, 0);
1174     if(!stsc)
1175     {
1176         bo_free(stco);
1177         bo_free(stsd);
1178         return NULL;
1179     }
1180     bo_add_32be(stsc, 0);     // entry-count (fixed latter)
1181
1182     unsigned i_chunk = 0;
1183     unsigned i_stsc_last_val = 0, i_stsc_entries = 0;
1184     for (unsigned i = 0; i < p_track->i_entry_count; i_chunk++) {
1185         mp4mux_entry_t *entry = p_track->entry;
1186         int i_first = i;
1187
1188         if (b_stco64)
1189             bo_add_64be(stco, entry[i].i_pos);
1190         else
1191             bo_add_32be(stco, entry[i].i_pos);
1192
1193         for (; i < p_track->i_entry_count; i++)
1194             if (i >= p_track->i_entry_count - 1 ||
1195                     entry[i].i_pos + entry[i].i_size != entry[i+1].i_pos) {
1196                 i++;
1197                 break;
1198             }
1199
1200         /* Add entry to the stsc table */
1201         if (i_stsc_last_val != i - i_first) {
1202             bo_add_32be(stsc, 1 + i_chunk);   // first-chunk
1203             bo_add_32be(stsc, i - i_first) ;  // samples-per-chunk
1204             bo_add_32be(stsc, 1);             // sample-descr-index
1205             i_stsc_last_val = i - i_first;
1206             i_stsc_entries++;
1207         }
1208     }
1209
1210     /* Fix stco entry count */
1211     bo_swap_32be(stco, 12, i_chunk);
1212     if(p_obj)
1213         msg_Dbg(p_obj, "created %d chunks (stco)", i_chunk);
1214
1215     /* Fix stsc entry count */
1216     bo_swap_32be(stsc, 12, i_stsc_entries );
1217
1218     /* add stts */
1219     bo_t *stts = box_full_new("stts", 0, 0);
1220     if(!stts)
1221     {
1222         bo_free(stsd);
1223         bo_free(stco);
1224         bo_free(stsc);
1225         return NULL;
1226     }
1227     bo_add_32be(stts, 0);     // entry-count (fixed latter)
1228
1229     unsigned i_index = 0;
1230     for (unsigned i = 0; i < p_track->i_entry_count; i_index++) {
1231         int     i_first = i;
1232         mtime_t i_delta = p_track->entry[i].i_length;
1233
1234         for (; i < p_track->i_entry_count; ++i)
1235             if (i == p_track->i_entry_count || p_track->entry[i].i_length != i_delta)
1236                 break;
1237
1238         bo_add_32be(stts, i - i_first); // sample-count
1239         bo_add_32be(stts, (uint64_t)i_delta  * p_track->i_timescale / CLOCK_FREQ); // sample-delta
1240     }
1241     bo_swap_32be(stts, 12, i_index);
1242
1243     /* composition time handling */
1244     bo_t *ctts = NULL;
1245     if ( p_track->b_hasbframes && (ctts = box_full_new("ctts", 0, 0)) )
1246     {
1247         bo_add_32be(ctts, 0);
1248         i_index = 0;
1249         for (unsigned i = 0; i < p_track->i_entry_count; i_index++)
1250         {
1251             int     i_first = i;
1252             mtime_t i_offset = p_track->entry[i].i_pts_dts;
1253
1254             for (; i < p_track->i_entry_count; ++i)
1255                 if (i == p_track->i_entry_count || p_track->entry[i].i_pts_dts != i_offset)
1256                     break;
1257
1258             bo_add_32be(ctts, i - i_first); // sample-count
1259             bo_add_32be(ctts, i_offset * p_track->i_timescale / CLOCK_FREQ ); // sample-offset
1260         }
1261         bo_swap_32be(ctts, 12, i_index);
1262     }
1263
1264     bo_t *stsz = box_full_new("stsz", 0, 0);
1265     if(!stsz)
1266     {
1267         bo_free(stsd);
1268         bo_free(stco);
1269         bo_free(stts);
1270         return NULL;
1271     }
1272     int i_size = 0;
1273     for (unsigned i = 0; i < p_track->i_entry_count; i++)
1274     {
1275         if ( i == 0 )
1276             i_size = p_track->entry[i].i_size;
1277         else if ( p_track->entry[i].i_size != i_size )
1278         {
1279             i_size = 0;
1280             break;
1281         }
1282     }
1283     bo_add_32be(stsz, i_size);                         // sample-size
1284     bo_add_32be(stsz, p_track->i_entry_count);       // sample-count
1285     if ( i_size == 0 ) // all samples have different size
1286     {
1287         for (unsigned i = 0; i < p_track->i_entry_count; i++)
1288             bo_add_32be(stsz, p_track->entry[i].i_size); // sample-size
1289     }
1290
1291     /* create stss table */
1292     bo_t *stss = NULL;
1293     i_index = 0;
1294     if ( p_track->fmt.i_cat == VIDEO_ES || p_track->fmt.i_cat == AUDIO_ES )
1295     {
1296         mtime_t i_interval = -1;
1297         for (unsigned i = 0; i < p_track->i_entry_count; i++)
1298         {
1299             if ( i_interval != -1 )
1300             {
1301                 i_interval += p_track->entry[i].i_length + p_track->entry[i].i_pts_dts;
1302                 if ( i_interval < CLOCK_FREQ * 2 )
1303                     continue;
1304             }
1305
1306             if (p_track->entry[i].i_flags & BLOCK_FLAG_TYPE_I) {
1307                 if (stss == NULL) {
1308                     stss = box_full_new("stss", 0, 0);
1309                     if(!stss)
1310                         break;
1311                     bo_add_32be(stss, 0); /* fixed later */
1312                 }
1313                 bo_add_32be(stss, 1 + i);
1314                 i_index++;
1315                 i_interval = 0;
1316             }
1317         }
1318     }
1319
1320     if (stss)
1321         bo_swap_32be(stss, 12, i_index);
1322
1323     /* Now gather all boxes into stbl */
1324     bo_t *stbl = box_new("stbl");
1325     if(!stbl)
1326     {
1327         bo_free(stsd);
1328         bo_free(stco);
1329         bo_free(stts);
1330         bo_free(stsz);
1331         bo_free(stss);
1332         bo_free(ctts);
1333         return NULL;
1334     }
1335     box_gather(stbl, stsd);
1336     box_gather(stbl, stts);
1337     if (stss)
1338         box_gather(stbl, stss);
1339     if (ctts)
1340         box_gather(stbl, ctts);
1341     box_gather(stbl, stsc);
1342     box_gather(stbl, stsz);
1343     p_track->i_stco_pos = stbl->b->i_buffer + 16;
1344     box_gather(stbl, stco);
1345
1346     return stbl;
1347 }
1348
1349 bo_t * GetMoovBox(vlc_object_t *p_obj, mp4mux_trackinfo_t **pp_tracks, unsigned int i_tracks,
1350                   bool b_fragmented, bool b_mov, bool b_64_ext, bool b_stco64)
1351 {
1352     bo_t            *moov, *mvhd;
1353
1354     uint32_t        i_movie_timescale = 90000;
1355     int64_t         i_movie_duration  = 0;
1356     int64_t         i_timestamp = get_timestamp();
1357
1358     moov = box_new("moov");
1359     if(!moov)
1360         return NULL;
1361     /* Create general info */
1362     if ( !b_fragmented )
1363     {
1364         for (unsigned int i = 0; i < i_tracks; i++) {
1365             mp4mux_trackinfo_t *p_stream = pp_tracks[i];
1366             i_movie_duration = __MAX(i_movie_duration, p_stream->i_read_duration);
1367         }
1368         if(p_obj)
1369             msg_Dbg(p_obj, "movie duration %"PRId64"s", i_movie_duration / CLOCK_FREQ);
1370
1371         i_movie_duration = i_movie_duration * i_movie_timescale / CLOCK_FREQ;
1372     }
1373     else
1374         i_movie_duration = 0;
1375
1376     /* *** add /moov/mvhd *** */
1377     if (!b_64_ext) {
1378         mvhd = box_full_new("mvhd", 0, 0);
1379         if(!mvhd)
1380         {
1381             bo_free(moov);
1382             return NULL;
1383         }
1384         bo_add_32be(mvhd, i_timestamp);   // creation time
1385         bo_add_32be(mvhd, i_timestamp);   // modification time
1386         bo_add_32be(mvhd, i_movie_timescale);  // timescale
1387         bo_add_32be(mvhd, i_movie_duration);  // duration
1388     } else {
1389         mvhd = box_full_new("mvhd", 1, 0);
1390         if(!mvhd)
1391         {
1392             bo_free(moov);
1393             return NULL;
1394         }
1395         bo_add_64be(mvhd, i_timestamp);   // creation time
1396         bo_add_64be(mvhd, i_timestamp);   // modification time
1397         bo_add_32be(mvhd, i_movie_timescale);  // timescale
1398         bo_add_64be(mvhd, i_movie_duration);  // duration
1399     }
1400     bo_add_32be(mvhd, 0x10000);           // rate
1401     bo_add_16be(mvhd, 0x100);             // volume
1402     bo_add_16be(mvhd, 0);                 // reserved
1403     for (int i = 0; i < 2; i++)
1404         bo_add_32be(mvhd, 0);             // reserved
1405
1406     uint32_t mvhd_matrix[9] = { 0x10000, 0, 0, 0, 0x10000, 0, 0, 0, 0x40000000 };
1407
1408     for (int i = 0; i < 9; i++)
1409         bo_add_32be(mvhd, mvhd_matrix[i]);// matrix
1410     for (int i = 0; i < 6; i++)
1411         bo_add_32be(mvhd, 0);             // pre-defined
1412
1413     /* Next available track id */
1414     bo_add_32be(mvhd, (i_tracks) ? pp_tracks[i_tracks -1]->i_track_id + 1: 1); // next-track-id
1415
1416     box_gather(moov, mvhd);
1417
1418     for (unsigned int i_trak = 0; i_trak < i_tracks; i_trak++) {
1419         mp4mux_trackinfo_t *p_stream = pp_tracks[i_trak];
1420
1421         mtime_t i_stream_duration;
1422         if ( !b_fragmented )
1423             i_stream_duration = p_stream->i_read_duration * i_movie_timescale / CLOCK_FREQ;
1424         else
1425             i_stream_duration = 0;
1426
1427         /* *** add /moov/trak *** */
1428         bo_t *trak = box_new("trak");
1429         if(!trak)
1430             continue;
1431
1432         /* *** add /moov/trak/tkhd *** */
1433         bo_t *tkhd;
1434         if (!b_64_ext) {
1435             if (b_mov)
1436                 tkhd = box_full_new("tkhd", 0, 0x0f);
1437             else
1438                 tkhd = box_full_new("tkhd", 0, 1);
1439             if(!tkhd)
1440             {
1441                 bo_free(trak);
1442                 continue;
1443             }
1444             bo_add_32be(tkhd, i_timestamp);       // creation time
1445             bo_add_32be(tkhd, i_timestamp);       // modification time
1446             bo_add_32be(tkhd, p_stream->i_track_id);
1447             bo_add_32be(tkhd, 0);                     // reserved 0
1448             bo_add_32be(tkhd, i_stream_duration); // duration
1449         } else {
1450             if (b_mov)
1451                 tkhd = box_full_new("tkhd", 1, 0x0f);
1452             else
1453                 tkhd = box_full_new("tkhd", 1, 1);
1454             if(!tkhd)
1455             {
1456                 bo_free(trak);
1457                 continue;
1458             }
1459             bo_add_64be(tkhd, i_timestamp);       // creation time
1460             bo_add_64be(tkhd, i_timestamp);       // modification time
1461             bo_add_32be(tkhd, p_stream->i_track_id);
1462             bo_add_32be(tkhd, 0);                     // reserved 0
1463             bo_add_64be(tkhd, i_stream_duration); // duration
1464         }
1465
1466         for (int i = 0; i < 2; i++)
1467             bo_add_32be(tkhd, 0);                 // reserved
1468         bo_add_16be(tkhd, 0);                     // layer
1469         bo_add_16be(tkhd, 0);                     // pre-defined
1470         // volume
1471         bo_add_16be(tkhd, p_stream->fmt.i_cat == AUDIO_ES ? 0x100 : 0);
1472         bo_add_16be(tkhd, 0);                     // reserved
1473         matrix_apply_rotation(&p_stream->fmt, mvhd_matrix);
1474         for (int i = 0; i < 9; i++)
1475             bo_add_32be(tkhd, mvhd_matrix[i]);    // matrix
1476         if (p_stream->fmt.i_cat == AUDIO_ES) {
1477             bo_add_32be(tkhd, 0);                 // width (presentation)
1478             bo_add_32be(tkhd, 0);                 // height(presentation)
1479         } else if (p_stream->fmt.i_cat == VIDEO_ES) {
1480             int i_width = p_stream->fmt.video.i_width << 16;
1481             if (p_stream->fmt.video.i_sar_num > 0 && p_stream->fmt.video.i_sar_den > 0) {
1482                 i_width = (int64_t)p_stream->fmt.video.i_sar_num *
1483                           ((int64_t)p_stream->fmt.video.i_width << 16) /
1484                           p_stream->fmt.video.i_sar_den;
1485             }
1486             // width (presentation)
1487             bo_add_32be(tkhd, i_width);
1488             // height(presentation)
1489             bo_add_32be(tkhd, p_stream->fmt.video.i_height << 16);
1490         } else {
1491             int i_width = 320 << 16;
1492             int i_height = 200;
1493             for (unsigned int i = 0; i < i_tracks; i++) {
1494                 mp4mux_trackinfo_t *tk = pp_tracks[i];
1495                 if (tk->fmt.i_cat == VIDEO_ES) {
1496                     if (tk->fmt.video.i_sar_num > 0 &&
1497                         tk->fmt.video.i_sar_den > 0)
1498                         i_width = (int64_t)tk->fmt.video.i_sar_num *
1499                                   ((int64_t)tk->fmt.video.i_width << 16) /
1500                                   tk->fmt.video.i_sar_den;
1501                     else
1502                         i_width = tk->fmt.video.i_width << 16;
1503                     i_height = tk->fmt.video.i_height;
1504                     break;
1505                 }
1506             }
1507             bo_add_32be(tkhd, i_width);     // width (presentation)
1508             bo_add_32be(tkhd, i_height << 16);    // height(presentation)
1509         }
1510
1511         box_gather(trak, tkhd);
1512
1513         /* *** add /moov/trak/edts and elst */
1514         if ( !b_fragmented )
1515         {
1516             bo_t *elst = box_full_new("elst", b_64_ext ? 1 : 0, 0);
1517             if(elst)
1518             {
1519                 if (p_stream->i_starttime > 0) {
1520                     bo_add_32be(elst, 2);
1521
1522                     if (b_64_ext) {
1523                         bo_add_64be(elst, p_stream->i_starttime *
1524                                     i_movie_timescale / CLOCK_FREQ);
1525                         bo_add_64be(elst, -1);
1526                     } else {
1527                         bo_add_32be(elst, p_stream->i_starttime *
1528                                     i_movie_timescale / CLOCK_FREQ);
1529                         bo_add_32be(elst, -1);
1530                     }
1531                     bo_add_16be(elst, 1);
1532                     bo_add_16be(elst, 0);
1533                 } else {
1534                     bo_add_32be(elst, 1);
1535                 }
1536                 if (b_64_ext) {
1537                     bo_add_64be(elst, p_stream->i_read_duration *
1538                                 i_movie_timescale / CLOCK_FREQ);
1539                     bo_add_64be(elst, 0);
1540                 } else {
1541                     bo_add_32be(elst, p_stream->i_read_duration *
1542                                 i_movie_timescale / CLOCK_FREQ);
1543                     bo_add_32be(elst, 0);
1544                 }
1545                 bo_add_16be(elst, 1);
1546                 bo_add_16be(elst, 0);
1547
1548                 bo_t *edts = box_new("edts");
1549                 if(edts)
1550                 {
1551                     box_gather(edts, elst);
1552                     box_gather(trak, edts);
1553                 }
1554                 else bo_free(elst);
1555             }
1556         }
1557
1558         /* *** add /moov/trak/mdia *** */
1559         bo_t *mdia = box_new("mdia");
1560         if(!mdia)
1561         {
1562             bo_free(trak);
1563             continue;
1564         }
1565
1566         /* media header */
1567         bo_t *mdhd;
1568         if (!b_64_ext) {
1569             mdhd = box_full_new("mdhd", 0, 0);
1570             if(!mdhd)
1571             {
1572                 bo_free(mdia);
1573                 bo_free(trak);
1574                 continue;
1575             }
1576             bo_add_32be(mdhd, i_timestamp);   // creation time
1577             bo_add_32be(mdhd, i_timestamp);   // modification time
1578             bo_add_32be(mdhd, p_stream->i_timescale); // timescale
1579             bo_add_32be(mdhd, i_stream_duration * p_stream->i_timescale / i_movie_timescale);  // duration
1580         } else {
1581             mdhd = box_full_new("mdhd", 1, 0);
1582             if(!mdhd)
1583             {
1584                 bo_free(mdia);
1585                 bo_free(trak);
1586                 continue;
1587             }
1588             bo_add_64be(mdhd, i_timestamp);   // creation time
1589             bo_add_64be(mdhd, i_timestamp);   // modification time
1590             bo_add_32be(mdhd, p_stream->i_timescale); // timescale
1591             bo_add_64be(mdhd, i_stream_duration * p_stream->i_timescale / i_movie_timescale);  // duration
1592         }
1593
1594         if (p_stream->fmt.psz_language) {
1595             char *psz = p_stream->fmt.psz_language;
1596             const iso639_lang_t *pl = NULL;
1597             uint16_t lang = 0x0;
1598
1599             if (strlen(psz) == 2)
1600                 pl = GetLang_1(psz);
1601             else if (strlen(psz) == 3) {
1602                 pl = GetLang_2B(psz);
1603                 if (!strcmp(pl->psz_iso639_1, "??"))
1604                     pl = GetLang_2T(psz);
1605             }
1606
1607             if (pl && strcmp(pl->psz_iso639_1, "??"))
1608                 lang = ((pl->psz_iso639_2T[0] - 0x60) << 10) |
1609                        ((pl->psz_iso639_2T[1] - 0x60) <<  5) |
1610                        ((pl->psz_iso639_2T[2] - 0x60));
1611             bo_add_16be(mdhd, lang);          // language
1612         } else
1613             bo_add_16be(mdhd, 0   );          // language
1614         bo_add_16be(mdhd, 0   );              // predefined
1615         box_gather(mdia, mdhd);
1616
1617         /* handler reference */
1618         bo_t *hdlr = box_full_new("hdlr", 0, 0);
1619         if(!hdlr)
1620         {
1621             bo_free(mdia);
1622             bo_free(trak);
1623             continue;
1624         }
1625
1626         if (b_mov)
1627             bo_add_fourcc(hdlr, "mhlr");         // media handler
1628         else
1629             bo_add_32be(hdlr, 0);
1630
1631         if (p_stream->fmt.i_cat == AUDIO_ES)
1632             bo_add_fourcc(hdlr, "soun");
1633         else if (p_stream->fmt.i_cat == VIDEO_ES)
1634             bo_add_fourcc(hdlr, "vide");
1635         else if (p_stream->fmt.i_cat == SPU_ES)
1636             bo_add_fourcc(hdlr, "text");
1637
1638         bo_add_32be(hdlr, 0);         // reserved
1639         bo_add_32be(hdlr, 0);         // reserved
1640         bo_add_32be(hdlr, 0);         // reserved
1641
1642         if (b_mov)
1643             bo_add_8(hdlr, 12);   /* Pascal string for .mov */
1644
1645         if (p_stream->fmt.i_cat == AUDIO_ES)
1646             bo_add_mem(hdlr, 12, (uint8_t*)"SoundHandler");
1647         else if (p_stream->fmt.i_cat == VIDEO_ES)
1648             bo_add_mem(hdlr, 12, (uint8_t*)"VideoHandler");
1649         else
1650             bo_add_mem(hdlr, 12, (uint8_t*)"Text Handler");
1651
1652         if (!b_mov)
1653             bo_add_8(hdlr, 0);   /* asciiz string for .mp4, yes that's BRAIN DAMAGED F**K MP4 */
1654
1655         box_gather(mdia, hdlr);
1656
1657         /* minf*/
1658         bo_t *minf = box_new("minf");
1659         if(!minf)
1660         {
1661             bo_free(mdia);
1662             bo_free(trak);
1663             continue;
1664         }
1665
1666         /* add smhd|vmhd */
1667         if (p_stream->fmt.i_cat == AUDIO_ES) {
1668             bo_t *smhd = box_full_new("smhd", 0, 0);
1669             if(smhd)
1670             {
1671                 bo_add_16be(smhd, 0);     // balance
1672                 bo_add_16be(smhd, 0);     // reserved
1673
1674                 box_gather(minf, smhd);
1675             }
1676         } else if (p_stream->fmt.i_cat == VIDEO_ES) {
1677             bo_t *vmhd = box_full_new("vmhd", 0, 1);
1678             if(vmhd)
1679             {
1680                 bo_add_16be(vmhd, 0);     // graphicsmode
1681                 for (int i = 0; i < 3; i++)
1682                     bo_add_16be(vmhd, 0); // opcolor
1683                 box_gather(minf, vmhd);
1684             }
1685         } else if (p_stream->fmt.i_cat == SPU_ES) {
1686             bo_t *gmin = box_full_new("gmin", 0, 1);
1687             if(gmin)
1688             {
1689                 bo_add_16be(gmin, 0);     // graphicsmode
1690                 for (int i = 0; i < 3; i++)
1691                     bo_add_16be(gmin, 0); // opcolor
1692                 bo_add_16be(gmin, 0);     // balance
1693                 bo_add_16be(gmin, 0);     // reserved
1694
1695                 bo_t *gmhd = box_new("gmhd");
1696                 if(gmhd)
1697                 {
1698                     box_gather(gmhd, gmin);
1699                     box_gather(minf, gmhd);
1700                 }
1701                 else bo_free(gmin);
1702             }
1703         }
1704
1705         /* dinf */
1706         bo_t *dref = box_full_new("dref", 0, 0);
1707         if(dref)
1708         {
1709             bo_add_32be(dref, 1);
1710
1711             bo_t *url = box_full_new("url ", 0, 0x01);
1712             if(url)
1713                 box_gather(dref, url);
1714
1715             bo_t *dinf = box_new("dinf");
1716             if(dinf)
1717             {
1718                 box_gather(dinf, dref);
1719
1720                 /* append dinf to mdia */
1721                 box_gather(minf, dinf);
1722             }
1723             else bo_free(dref);
1724         }
1725
1726         /* add stbl */
1727         bo_t *stbl;
1728         if ( b_fragmented )
1729         {
1730             uint32_t i_backup = p_stream->i_entry_count;
1731             p_stream->i_entry_count = 0;
1732             stbl = GetStblBox(p_obj, p_stream, b_mov, b_stco64);
1733             p_stream->i_entry_count = i_backup;
1734         }
1735         else
1736             stbl = GetStblBox(p_obj, p_stream, b_mov, b_stco64);
1737
1738         /* append stbl to minf */
1739         p_stream->i_stco_pos += minf->b->i_buffer;
1740         box_gather(minf, stbl);
1741
1742         /* append minf to mdia */
1743         p_stream->i_stco_pos += mdia->b->i_buffer;
1744         box_gather(mdia, minf);
1745
1746         /* append mdia to trak */
1747         p_stream->i_stco_pos += trak->b->i_buffer;
1748         box_gather(trak, mdia);
1749
1750         /* append trak to moov */
1751         p_stream->i_stco_pos += moov->b->i_buffer;
1752         box_gather(moov, trak);
1753     }
1754
1755     /* Add user data tags */
1756     box_gather(moov, GetUdtaTag(pp_tracks, i_tracks));
1757
1758     if ( b_fragmented )
1759     {
1760         bo_t *mvex = box_new("mvex");
1761         for (unsigned int i_trak = 0; mvex && i_trak < i_tracks; i_trak++)
1762         {
1763             mp4mux_trackinfo_t *p_stream = pp_tracks[i_trak];
1764
1765             /* Try to find some defaults */
1766             if ( p_stream->i_entry_count )
1767             {
1768                 // FIXME: find highest occurence
1769                 p_stream->i_trex_default_length = p_stream->entry[0].i_length;
1770                 p_stream->i_trex_default_size = p_stream->entry[0].i_size;
1771             }
1772
1773             /* *** add /mvex/trex *** */
1774             bo_t *trex = box_full_new("trex", 0, 0);
1775             bo_add_32be(trex, p_stream->i_track_id);
1776             bo_add_32be(trex, 1); // sample desc index
1777             bo_add_32be(trex, (uint64_t)p_stream->i_trex_default_length * p_stream->i_timescale / CLOCK_FREQ); // sample duration
1778             bo_add_32be(trex, p_stream->i_trex_default_size); // sample size
1779             bo_add_32be(trex, 0); // sample flags
1780             box_gather(mvex, trex);
1781         }
1782         box_gather(moov, mvex);
1783     }
1784
1785     if(moov->b)
1786         box_fix(moov, moov->b->i_buffer);
1787     return moov;
1788 }
1789
1790 bo_t *GetFtyp(vlc_fourcc_t major, uint32_t minor, vlc_fourcc_t extra[], size_t i_fourcc)
1791 {
1792     bo_t *box = box_new("ftyp");
1793     if(box)
1794     {
1795         bo_add_fourcc(box, &major);
1796         bo_add_32be  (box, minor);
1797         for(size_t i=0; i<i_fourcc; i++)
1798             bo_add_fourcc(box, &extra[i]);
1799         if(!box->b)
1800         {
1801             free(box);
1802             return NULL;
1803         }
1804         box_fix(box, box->b->i_buffer);
1805     }
1806     return box;
1807 }