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