9c6783ea624a1bdb369472e66f4708ba6f9861f6
[libav.git] / libavformat / movenc.c
1 /*
2 * MOV, 3GP, MP4 encoder.
3 * Copyright (c) 2003 Thomas Raivio.
4 * Copyright (c) 2004 Gildas Bazin <gbazin at videolan dot org>.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20 #include "avformat.h"
21 #include "avi.h"
22 #include "avio.h"
23
24 #undef NDEBUG
25 #include <assert.h>
26
27 #define MOV_INDEX_CLUSTER_SIZE 16384
28 #define globalTimescale 1000
29
30 #define MODE_MP4 0
31 #define MODE_MOV 1
32 #define MODE_3GP 2
33
34 typedef struct MOVIentry {
35 unsigned int flags, pos, size;
36 unsigned int samplesInChunk;
37 char key_frame;
38 unsigned int entries;
39 } MOVIentry;
40
41 typedef struct MOVIndex {
42 int mode;
43 int entry;
44 int mdat_size;
45 int ents_allocated;
46 long timescale;
47 long time;
48 long trackDuration;
49 long sampleCount;
50 long sampleDuration;
51 int hasKeyframes;
52 int trackID;
53 AVCodecContext *enc;
54
55 int vosLen;
56 uint8_t *vosData;
57 MOVIentry** cluster;
58 } MOVTrack;
59
60 typedef struct {
61 int mode;
62 long time;
63 int nb_streams;
64 int mdat_written;
65 offset_t mdat_pos;
66 long timescale;
67 MOVTrack tracks[MAX_STREAMS];
68 } MOVContext;
69
70 static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack* track);
71
72 //FIXME supprt 64bit varaint with wide placeholders
73 static int updateSize (ByteIOContext *pb, int pos)
74 {
75 long curpos = url_ftell(pb);
76 url_fseek(pb, pos, SEEK_SET);
77 put_be32(pb, curpos - pos); /* rewrite size */
78 url_fseek(pb, curpos, SEEK_SET);
79
80 return curpos - pos;
81 }
82
83 /* Chunk offset atom */
84 static int mov_write_stco_tag(ByteIOContext *pb, MOVTrack* track)
85 {
86 int i;
87 int pos = url_ftell(pb);
88 put_be32(pb, 0); /* size */
89 put_tag(pb, "stco");
90 put_be32(pb, 0); /* version & flags */
91 put_be32(pb, track->entry); /* entry count */
92 for (i=0; i<track->entry; i++) {
93 int cl = i / MOV_INDEX_CLUSTER_SIZE;
94 int id = i % MOV_INDEX_CLUSTER_SIZE;
95 put_be32(pb, track->cluster[cl][id].pos);
96 }
97 return updateSize (pb, pos);
98 }
99
100 /* Sample size atom */
101 static int mov_write_stsz_tag(ByteIOContext *pb, MOVTrack* track)
102 {
103 int equalChunks = 1;
104 int i, j, entries = 0, tst = -1, oldtst = -1;
105
106 int pos = url_ftell(pb);
107 put_be32(pb, 0); /* size */
108 put_tag(pb, "stsz");
109 put_be32(pb, 0); /* version & flags */
110
111 for (i=0; i<track->entry; i++) {
112 int cl = i / MOV_INDEX_CLUSTER_SIZE;
113 int id = i % MOV_INDEX_CLUSTER_SIZE;
114 tst = track->cluster[cl][id].size/track->cluster[cl][id].entries;
115 if(oldtst != -1 && tst != oldtst) {
116 equalChunks = 0;
117 }
118 oldtst = tst;
119 entries += track->cluster[cl][id].entries;
120 }
121 if (equalChunks) {
122 int sSize = track->cluster[0][0].size/track->cluster[0][0].entries;
123 put_be32(pb, sSize); // sample size
124 put_be32(pb, entries); // sample count
125 }
126 else {
127 put_be32(pb, 0); // sample size
128 put_be32(pb, entries); // sample count
129 for (i=0; i<track->entry; i++) {
130 int cl = i / MOV_INDEX_CLUSTER_SIZE;
131 int id = i % MOV_INDEX_CLUSTER_SIZE;
132 for ( j=0; j<track->cluster[cl][id].entries; j++) {
133 put_be32(pb, track->cluster[cl][id].size /
134 track->cluster[cl][id].entries);
135 }
136 }
137 }
138 return updateSize (pb, pos);
139 }
140
141 /* Sample to chunk atom */
142 static int mov_write_stsc_tag(ByteIOContext *pb, MOVTrack* track)
143 {
144 int index = 0, oldval = -1, i, entryPos, curpos;
145
146 int pos = url_ftell(pb);
147 put_be32(pb, 0); /* size */
148 put_tag(pb, "stsc");
149 put_be32(pb, 0); // version & flags
150 entryPos = url_ftell(pb);
151 put_be32(pb, track->entry); // entry count
152 for (i=0; i<track->entry; i++) {
153 int cl = i / MOV_INDEX_CLUSTER_SIZE;
154 int id = i % MOV_INDEX_CLUSTER_SIZE;
155 if(oldval != track->cluster[cl][id].samplesInChunk)
156 {
157 put_be32(pb, i+1); // first chunk
158 put_be32(pb, track->cluster[cl][id].samplesInChunk); // samples per chunk
159 put_be32(pb, 0x1); // sample description index
160 oldval = track->cluster[cl][id].samplesInChunk;
161 index++;
162 }
163 }
164 curpos = url_ftell(pb);
165 url_fseek(pb, entryPos, SEEK_SET);
166 put_be32(pb, index); // rewrite size
167 url_fseek(pb, curpos, SEEK_SET);
168
169 return updateSize (pb, pos);
170 }
171
172 /* Sync sample atom */
173 static int mov_write_stss_tag(ByteIOContext *pb, MOVTrack* track)
174 {
175 long curpos;
176 int i, index = 0, entryPos;
177 int pos = url_ftell(pb);
178 put_be32(pb, 0); // size
179 put_tag(pb, "stss");
180 put_be32(pb, 0); // version & flags
181 entryPos = url_ftell(pb);
182 put_be32(pb, track->entry); // entry count
183 for (i=0; i<track->entry; i++) {
184 int cl = i / MOV_INDEX_CLUSTER_SIZE;
185 int id = i % MOV_INDEX_CLUSTER_SIZE;
186 if(track->cluster[cl][id].key_frame == 1) {
187 put_be32(pb, i+1);
188 index++;
189 }
190 }
191 curpos = url_ftell(pb);
192 url_fseek(pb, entryPos, SEEK_SET);
193 put_be32(pb, index); // rewrite size
194 url_fseek(pb, curpos, SEEK_SET);
195 return updateSize (pb, pos);
196 }
197
198 static int mov_write_damr_tag(ByteIOContext *pb)
199 {
200 put_be32(pb, 0x11); /* size */
201 put_tag(pb, "damr");
202 put_tag(pb, "FFMP");
203 put_byte(pb, 0);
204
205 put_be16(pb, 0x80); /* Mode set (all modes for AMR_NB) */
206 put_be16(pb, 0xa); /* Mode change period (no restriction) */
207 //put_be16(pb, 0x81ff); /* Mode set (all modes for AMR_NB) */
208 //put_be16(pb, 1); /* Mode change period (no restriction) */
209 return 0x11;
210 }
211
212 static int mov_write_wave_tag(ByteIOContext *pb, MOVTrack* track)
213 {
214 int pos = url_ftell(pb);
215
216 put_be32(pb, 0); /* size */
217 put_tag(pb, "wave");
218
219 put_be32(pb, 12); /* size */
220 put_tag(pb, "frma");
221 put_tag(pb, "mp4a");
222
223 put_be32(pb, 12); /* size */
224 put_tag(pb, "mp4a");
225 put_be32(pb, 0);
226
227 mov_write_esds_tag(pb, track);
228
229 put_be32(pb, 12); /* size */
230 put_tag(pb, "srcq");
231 put_be32(pb, 0x40);
232
233 put_be32(pb, 8); /* size */
234 put_be32(pb, 0); /* null tag */
235
236 return updateSize (pb, pos);
237 }
238
239 const CodecTag codec_movaudio_tags[] = {
240 { CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') },
241 { CODEC_ID_PCM_ALAW, MKTAG('a', 'l', 'a', 'w') },
242 { CODEC_ID_ADPCM_IMA_QT, MKTAG('i', 'm', 'a', '4') },
243 { CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') },
244 { CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') },
245 { CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') },
246 { CODEC_ID_AMR_NB, MKTAG('s', 'a', 'm', 'r') },
247 { CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') },
248 { CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') },
249 { CODEC_ID_MP3, MKTAG('.', 'm', 'p', '3') },
250 { 0, 0 },
251 };
252
253 static int mov_write_audio_tag(ByteIOContext *pb, MOVTrack* track)
254 {
255 int pos = url_ftell(pb);
256 int tag;
257
258 put_be32(pb, 0); /* size */
259
260 tag = codec_get_tag(codec_movaudio_tags, track->enc->codec_id);
261 // if no mac fcc found, try with Microsoft tags
262 if (!tag)
263 {
264 int tmp = codec_get_tag(codec_wav_tags, track->enc->codec_id);
265 tag = MKTAG('m', 's', ((tmp >> 8) & 0xff), (tmp & 0xff));
266 }
267 put_le32(pb, tag); // store it byteswapped
268
269 put_be32(pb, 0); /* Reserved */
270 put_be16(pb, 0); /* Reserved */
271 put_be16(pb, 1); /* Data-reference index, XXX == 1 */
272
273 /* SoundDescription */
274 if(track->mode == MODE_MOV && track->enc->codec_id == CODEC_ID_AAC)
275 put_be16(pb, 1); /* Version 1 */
276 else
277 put_be16(pb, 0); /* Version 0 */
278 put_be16(pb, 0); /* Revision level */
279 put_be32(pb, 0); /* Reserved */
280
281 put_be16(pb, track->enc->channels); /* Number of channels */
282 /* TODO: Currently hard-coded to 16-bit, there doesn't seem
283 to be a good way to get number of bits of audio */
284 put_be16(pb, 0x10); /* Reserved */
285 put_be16(pb, 0); /* compression ID (= 0) */
286 put_be16(pb, 0); /* packet size (= 0) */
287 put_be16(pb, track->timescale); /* Time scale */
288 put_be16(pb, 0); /* Reserved */
289
290 if(track->mode == MODE_MOV && track->enc->codec_id == CODEC_ID_AAC)
291 {
292 /* SoundDescription V1 extended info */
293 put_be32(pb, track->enc->frame_size); /* Samples per packet */
294 put_be32(pb, 1536); /* Bytes per packet */
295 put_be32(pb, 2); /* Bytes per frame */
296 put_be32(pb, 2); /* Bytes per sample */
297 }
298
299 if(track->enc->codec_id == CODEC_ID_AAC) {
300 if( track->mode == MODE_MOV ) mov_write_wave_tag(pb, track);
301 else mov_write_esds_tag(pb, track);
302 }
303 if(track->enc->codec_id == CODEC_ID_AMR_NB)
304 mov_write_damr_tag(pb);
305 return updateSize (pb, pos);
306 }
307
308 static int mov_write_d263_tag(ByteIOContext *pb)
309 {
310 put_be32(pb, 0xf); /* size */
311 put_tag(pb, "d263");
312 put_tag(pb, "FFMP");
313 put_be16(pb, 0x0a);
314 put_byte(pb, 0);
315 return 0xf;
316 }
317
318 /* TODO: No idea about these values */
319 static int mov_write_svq3_tag(ByteIOContext *pb)
320 {
321 put_be32(pb, 0x15);
322 put_tag(pb, "SMI ");
323 put_tag(pb, "SEQH");
324 put_be32(pb, 0x5);
325 put_be32(pb, 0xe2c0211d);
326 put_be32(pb, 0xc0000000);
327 put_byte(pb, 0);
328 return 0x15;
329 }
330
331 static unsigned int descrLength(unsigned int len)
332 {
333 if (len < 0x00000080)
334 return 2 + len;
335 else if (len < 0x00004000)
336 return 3 + len;
337 else if(len < 0x00200000)
338 return 4 + len;
339 else
340 return 5 + len;
341 }
342
343 static void putDescr(ByteIOContext *pb, int tag, int size)
344 {
345 uint32_t len;
346 uint8_t vals[4];
347
348 len = size;
349 vals[3] = (uint8_t)(len & 0x7f);
350 len >>= 7;
351 vals[2] = (uint8_t)((len & 0x7f) | 0x80);
352 len >>= 7;
353 vals[1] = (uint8_t)((len & 0x7f) | 0x80);
354 len >>= 7;
355 vals[0] = (uint8_t)((len & 0x7f) | 0x80);
356
357 put_byte(pb, tag); // DescriptorTag
358
359 if (size < 0x00000080)
360 {
361 put_byte(pb, vals[3]);
362 }
363 else if (size < 0x00004000)
364 {
365 put_byte(pb, vals[2]);
366 put_byte(pb, vals[3]);
367 }
368 else if (size < 0x00200000)
369 {
370 put_byte(pb, vals[1]);
371 put_byte(pb, vals[2]);
372 put_byte(pb, vals[3]);
373 }
374 else if (size < 0x10000000)
375 {
376 put_byte(pb, vals[0]);
377 put_byte(pb, vals[1]);
378 put_byte(pb, vals[2]);
379 put_byte(pb, vals[3]);
380 }
381 }
382
383 static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack* track) // Basic
384 {
385 int decoderSpecificInfoLen = track->vosLen ? descrLength(track->vosLen):0;
386 int pos = url_ftell(pb);
387
388 put_be32(pb, 0); // size
389 put_tag(pb, "esds");
390 put_be32(pb, 0); // Version
391
392 // ES descriptor
393 putDescr(pb, 0x03, 3 + descrLength(13 + decoderSpecificInfoLen) +
394 descrLength(1));
395 put_be16(pb, 0x0001); // ID (= 1)
396 put_byte(pb, 0x00); // flags (= no flags)
397
398 // DecoderConfig descriptor
399 putDescr(pb, 0x04, 13 + decoderSpecificInfoLen);
400
401 if(track->enc->codec_id == CODEC_ID_AAC)
402 put_byte(pb, 0x40); // Object type indication
403 else if(track->enc->codec_id == CODEC_ID_MPEG4)
404 put_byte(pb, 0x20); // Object type indication (Visual 14496-2)
405
406 if(track->enc->codec_type == CODEC_TYPE_AUDIO)
407 put_byte(pb, 0x15); // flags (= Audiostream)
408 else
409 put_byte(pb, 0x11); // flags (= Visualstream)
410
411 put_byte(pb, 0x0); // Buffersize DB (24 bits)
412 put_be16(pb, 0x0dd2); // Buffersize DB
413
414 // TODO: find real values for these
415 put_be32(pb, 0x0002e918); // maxbitrate
416 put_be32(pb, 0x00017e6b); // avg bitrate
417
418 if (track->vosLen)
419 {
420 // DecoderSpecific info descriptor
421 putDescr(pb, 0x05, track->vosLen);
422 put_buffer(pb, track->vosData, track->vosLen);
423 }
424
425 // SL descriptor
426 putDescr(pb, 0x06, 1);
427 put_byte(pb, 0x02);
428 return updateSize (pb, pos);
429 }
430
431 const CodecTag codec_movvideo_tags[] = {
432 { CODEC_ID_SVQ1, MKTAG('S', 'V', 'Q', '1') },
433 { CODEC_ID_SVQ3, MKTAG('S', 'V', 'Q', '3') },
434 { CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
435 { CODEC_ID_H263, MKTAG('s', '2', '6', '3') },
436 { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', ' ') },
437 { 0, 0 },
438 };
439
440 static int mov_write_video_tag(ByteIOContext *pb, MOVTrack* track)
441 {
442 int pos = url_ftell(pb);
443 int tag;
444
445 put_be32(pb, 0); /* size */
446
447 tag = codec_get_tag(codec_movvideo_tags, track->enc->codec_id);
448 // if no mac fcc found, try with Microsoft tags
449 if (!tag)
450 tag = codec_get_tag(codec_bmp_tags, track->enc->codec_id);
451 put_le32(pb, tag); // store it byteswapped
452
453 put_be32(pb, 0); /* Reserved */
454 put_be16(pb, 0); /* Reserved */
455 put_be16(pb, 1); /* Data-reference index */
456
457 put_be32(pb, 0); /* Reserved (= 02000c) */
458 put_be32(pb, 0); /* Reserved ("SVis")*/
459 put_be32(pb, 0); /* Reserved */
460 put_be32(pb, 0); /* Reserved (400)*/
461 put_be16(pb, track->enc->width); /* Video width */
462 put_be16(pb, track->enc->height); /* Video height */
463 put_be32(pb, 0x00480000); /* Reserved */
464 put_be32(pb, 0x00480000); /* Reserved */
465 put_be32(pb, 0); /* Data size (= 0) */
466 put_be16(pb, 1); /* Frame count (= 1) */
467
468 put_be32(pb, 0); /* Reserved */
469 put_be32(pb, 0); /* Reserved */
470 put_be32(pb, 0); /* Reserved */
471 put_be32(pb, 0); /* Reserved */
472 put_be32(pb, 0); /* Reserved */
473 put_be32(pb, 0); /* Reserved */
474 put_be32(pb, 0); /* Reserved */
475 put_be32(pb, 0); /* Reserved */
476
477 put_be16(pb, 0x18); /* Reserved */
478 put_be16(pb, 0xffff); /* Reserved */
479 if(track->enc->codec_id == CODEC_ID_MPEG4)
480 mov_write_esds_tag(pb, track);
481 else if(track->enc->codec_id == CODEC_ID_H263)
482 mov_write_d263_tag(pb);
483 else if(track->enc->codec_id == CODEC_ID_SVQ3)
484 mov_write_svq3_tag(pb);
485
486 return updateSize (pb, pos);
487 }
488
489 static int mov_write_stsd_tag(ByteIOContext *pb, MOVTrack* track)
490 {
491 int pos = url_ftell(pb);
492 put_be32(pb, 0); /* size */
493 put_tag(pb, "stsd");
494 put_be32(pb, 0); /* version & flags */
495 put_be32(pb, 1); /* entry count */
496 if (track->enc->codec_type == CODEC_TYPE_VIDEO)
497 mov_write_video_tag(pb, track);
498 else if (track->enc->codec_type == CODEC_TYPE_AUDIO)
499 mov_write_audio_tag(pb, track);
500 return updateSize(pb, pos);
501 }
502
503 /* TODO?: Currently all samples/frames seem to have same duration */
504 /* Time to sample atom */
505 static int mov_write_stts_tag(ByteIOContext *pb, MOVTrack* track)
506 {
507 put_be32(pb, 0x18); /* size */
508 put_tag(pb, "stts");
509 put_be32(pb, 0); /* version & flags */
510 put_be32(pb, 1); /* entry count */
511
512 put_be32(pb, track->sampleCount); /* sample count */
513 put_be32(pb, track->sampleDuration); /* sample duration */
514 return 0x18;
515 }
516
517 static int mov_write_dref_tag(ByteIOContext *pb)
518 {
519 put_be32(pb, 28); /* size */
520 put_tag(pb, "dref");
521 put_be32(pb, 0); /* version & flags */
522 put_be32(pb, 1); /* entry count */
523
524 put_be32(pb, 0xc); /* size */
525 put_tag(pb, "url ");
526 put_be32(pb, 1); /* version & flags */
527
528 return 28;
529 }
530
531 static int mov_write_stbl_tag(ByteIOContext *pb, MOVTrack* track)
532 {
533 int pos = url_ftell(pb);
534 put_be32(pb, 0); /* size */
535 put_tag(pb, "stbl");
536 mov_write_stsd_tag(pb, track);
537 mov_write_stts_tag(pb, track);
538 if (track->enc->codec_type == CODEC_TYPE_VIDEO &&
539 track->hasKeyframes)
540 mov_write_stss_tag(pb, track);
541 mov_write_stsc_tag(pb, track);
542 mov_write_stsz_tag(pb, track);
543 mov_write_stco_tag(pb, track);
544 return updateSize(pb, pos);
545 }
546
547 static int mov_write_dinf_tag(ByteIOContext *pb)
548 {
549 int pos = url_ftell(pb);
550 put_be32(pb, 0); /* size */
551 put_tag(pb, "dinf");
552 mov_write_dref_tag(pb);
553 return updateSize(pb, pos);
554 }
555
556 static int mov_write_smhd_tag(ByteIOContext *pb)
557 {
558 put_be32(pb, 16); /* size */
559 put_tag(pb, "smhd");
560 put_be32(pb, 0); /* version & flags */
561 put_be16(pb, 0); /* reserved (balance, normally = 0) */
562 put_be16(pb, 0); /* reserved */
563 return 16;
564 }
565
566 static int mov_write_vmhd_tag(ByteIOContext *pb)
567 {
568 put_be32(pb, 0x14); /* size (always 0x14) */
569 put_tag(pb, "vmhd");
570 put_be32(pb, 0x01); /* version & flags */
571 put_be64(pb, 0); /* reserved (graphics mode = copy) */
572 return 0x14;
573 }
574
575 static int mov_write_hdlr_tag(ByteIOContext *pb, MOVTrack* track)
576 {
577 char *descr, *hdlr, *hdlr_type;
578 int pos = url_ftell(pb);
579
580 if (!track) { /* no media --> data handler */
581 hdlr = "dhlr";
582 hdlr_type = "url ";
583 descr = "DataHandler";
584 } else {
585 hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
586 if (track->enc->codec_type == CODEC_TYPE_VIDEO) {
587 hdlr_type = "vide";
588 descr = "VideoHandler";
589 } else {
590 hdlr_type = "soun";
591 descr = "SoundHandler";
592 }
593 }
594
595 put_be32(pb, 0); /* size */
596 put_tag(pb, "hdlr");
597 put_be32(pb, 0); /* Version & flags */
598 put_buffer(pb, hdlr, 4); /* handler */
599 put_tag(pb, hdlr_type); /* handler type */
600 put_be32(pb ,0); /* reserved */
601 put_be32(pb ,0); /* reserved */
602 put_be32(pb ,0); /* reserved */
603 put_byte(pb, strlen(descr)); /* string counter */
604 put_buffer(pb, descr, strlen(descr)); /* handler description */
605 return updateSize(pb, pos);
606 }
607
608 static int mov_write_minf_tag(ByteIOContext *pb, MOVTrack* track)
609 {
610 int pos = url_ftell(pb);
611 put_be32(pb, 0); /* size */
612 put_tag(pb, "minf");
613 if(track->enc->codec_type == CODEC_TYPE_VIDEO)
614 mov_write_vmhd_tag(pb);
615 else
616 mov_write_smhd_tag(pb);
617 if (track->mode == MODE_MOV) /* FIXME: Why do it for MODE_MOV only ? */
618 mov_write_hdlr_tag(pb, NULL);
619 mov_write_dinf_tag(pb);
620 mov_write_stbl_tag(pb, track);
621 return updateSize(pb, pos);
622 }
623
624 static int mov_write_mdhd_tag(ByteIOContext *pb, MOVTrack* track)
625 {
626 put_be32(pb, 32); /* size */
627 put_tag(pb, "mdhd");
628 put_be32(pb, 0); /* Version & flags */
629 put_be32(pb, track->time); /* creation time */
630 put_be32(pb, track->time); /* modification time */
631 put_be32(pb, track->timescale); /* time scale (sample rate for audio) */
632 put_be32(pb, track->trackDuration); /* duration */
633 put_be16(pb, 0); /* language, 0 = english */
634 put_be16(pb, 0); /* reserved (quality) */
635 return 32;
636 }
637
638 static int mov_write_mdia_tag(ByteIOContext *pb, MOVTrack* track)
639 {
640 int pos = url_ftell(pb);
641 put_be32(pb, 0); /* size */
642 put_tag(pb, "mdia");
643 mov_write_mdhd_tag(pb, track);
644 mov_write_hdlr_tag(pb, track);
645 mov_write_minf_tag(pb, track);
646 return updateSize(pb, pos);
647 }
648
649 static int mov_write_tkhd_tag(ByteIOContext *pb, MOVTrack* track)
650 {
651 int64_t maxTrackLenTemp;
652 put_be32(pb, 0x5c); /* size (always 0x5c) */
653 put_tag(pb, "tkhd");
654 put_be32(pb, 0xf); /* version & flags (track enabled) */
655 put_be32(pb, track->time); /* creation time */
656 put_be32(pb, track->time); /* modification time */
657 put_be32(pb, track->trackID); /* track-id */
658 put_be32(pb, 0); /* reserved */
659 maxTrackLenTemp = ((int64_t)globalTimescale*(int64_t)track->trackDuration)/(int64_t)track->timescale;
660 put_be32(pb, (long)maxTrackLenTemp); /* duration */
661
662 put_be32(pb, 0); /* reserved */
663 put_be32(pb, 0); /* reserved */
664 put_be32(pb, 0x0); /* reserved (Layer & Alternate group) */
665 /* Volume, only for audio */
666 if(track->enc->codec_type == CODEC_TYPE_AUDIO)
667 put_be16(pb, 0x0100);
668 else
669 put_be16(pb, 0);
670 put_be16(pb, 0); /* reserved */
671
672 /* Matrix structure */
673 put_be32(pb, 0x00010000); /* reserved */
674 put_be32(pb, 0x0); /* reserved */
675 put_be32(pb, 0x0); /* reserved */
676 put_be32(pb, 0x0); /* reserved */
677 put_be32(pb, 0x00010000); /* reserved */
678 put_be32(pb, 0x0); /* reserved */
679 put_be32(pb, 0x0); /* reserved */
680 put_be32(pb, 0x0); /* reserved */
681 put_be32(pb, 0x40000000); /* reserved */
682
683 /* Track width and height, for visual only */
684 if(track->enc->codec_type == CODEC_TYPE_VIDEO) {
685 double sample_aspect_ratio = av_q2d(track->enc->sample_aspect_ratio);
686 if( !sample_aspect_ratio ) sample_aspect_ratio = 1;
687 put_be32(pb, sample_aspect_ratio * track->enc->width*0x10000);
688 put_be32(pb, track->enc->height*0x10000);
689 }
690 else {
691 put_be32(pb, 0);
692 put_be32(pb, 0);
693 }
694 return 0x5c;
695 }
696
697 static int mov_write_trak_tag(ByteIOContext *pb, MOVTrack* track)
698 {
699 int pos = url_ftell(pb);
700 put_be32(pb, 0); /* size */
701 put_tag(pb, "trak");
702 mov_write_tkhd_tag(pb, track);
703 mov_write_mdia_tag(pb, track);
704 return updateSize(pb, pos);
705 }
706
707 /* TODO: Not sorted out, but not necessary either */
708 static int mov_write_iods_tag(ByteIOContext *pb, MOVContext *mov)
709 {
710 put_be32(pb, 0x15); /* size */
711 put_tag(pb, "iods");
712 put_be32(pb, 0); /* version & flags */
713 put_be16(pb, 0x1007);
714 put_byte(pb, 0);
715 put_be16(pb, 0x4fff);
716 put_be16(pb, 0xfffe);
717 put_be16(pb, 0x01ff);
718 return 0x15;
719 }
720
721 static int mov_write_mvhd_tag(ByteIOContext *pb, MOVContext *mov)
722 {
723 int maxTrackID = 1, maxTrackLen = 0, i;
724 int64_t maxTrackLenTemp;
725
726 put_be32(pb, 0x6c); /* size (always 0x6c) */
727 put_tag(pb, "mvhd");
728 put_be32(pb, 0); /* version & flags */
729 put_be32(pb, mov->time); /* creation time */
730 put_be32(pb, mov->time); /* modification time */
731 put_be32(pb, mov->timescale); /* timescale */
732 for (i=0; i<MAX_STREAMS; i++) {
733 if(mov->tracks[i].entry > 0) {
734 maxTrackLenTemp = ((int64_t)globalTimescale*(int64_t)mov->tracks[i].trackDuration)/(int64_t)mov->tracks[i].timescale;
735 if(maxTrackLen < maxTrackLenTemp)
736 maxTrackLen = maxTrackLenTemp;
737 if(maxTrackID < mov->tracks[i].trackID)
738 maxTrackID = mov->tracks[i].trackID;
739 }
740 }
741 put_be32(pb, maxTrackLen); /* duration of longest track */
742
743 put_be32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */
744 put_be16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */
745 put_be16(pb, 0); /* reserved */
746 put_be32(pb, 0); /* reserved */
747 put_be32(pb, 0); /* reserved */
748
749 /* Matrix structure */
750 put_be32(pb, 0x00010000); /* reserved */
751 put_be32(pb, 0x0); /* reserved */
752 put_be32(pb, 0x0); /* reserved */
753 put_be32(pb, 0x0); /* reserved */
754 put_be32(pb, 0x00010000); /* reserved */
755 put_be32(pb, 0x0); /* reserved */
756 put_be32(pb, 0x0); /* reserved */
757 put_be32(pb, 0x0); /* reserved */
758 put_be32(pb, 0x40000000); /* reserved */
759
760 put_be32(pb, 0); /* reserved (preview time) */
761 put_be32(pb, 0); /* reserved (preview duration) */
762 put_be32(pb, 0); /* reserved (poster time) */
763 put_be32(pb, 0); /* reserved (selection time) */
764 put_be32(pb, 0); /* reserved (selection duration) */
765 put_be32(pb, 0); /* reserved (current time) */
766 put_be32(pb, maxTrackID+1); /* Next track id */
767 return 0x6c;
768 }
769
770 static int mov_write_udta_tag(ByteIOContext *pb, MOVContext* mov,
771 AVFormatContext *s)
772 {
773 int pos = url_ftell(pb);
774 int i;
775
776 put_be32(pb, 0); /* size */
777 put_tag(pb, "udta");
778
779 /* Requirements */
780 for (i=0; i<MAX_STREAMS; i++) {
781 if(mov->tracks[i].entry <= 0) continue;
782 if (mov->tracks[i].enc->codec_id == CODEC_ID_AAC ||
783 mov->tracks[i].enc->codec_id == CODEC_ID_MPEG4) {
784 int pos = url_ftell(pb);
785 put_be32(pb, 0); /* size */
786 put_tag(pb, "\251req");
787 put_be16(pb, sizeof("QuickTime 6.0 or greater") - 1);
788 put_be16(pb, 0);
789 put_buffer(pb, "QuickTime 6.0 or greater",
790 sizeof("QuickTime 6.0 or greater") - 1);
791 updateSize(pb, pos);
792 break;
793 }
794 }
795
796 /* Encoder */
797 if(!(mov->tracks[0].enc->flags & CODEC_FLAG_BITEXACT))
798 {
799 int pos = url_ftell(pb);
800 put_be32(pb, 0); /* size */
801 put_tag(pb, "\251enc");
802 put_be16(pb, sizeof(LIBAVFORMAT_IDENT) - 1); /* string length */
803 put_be16(pb, 0);
804 put_buffer(pb, LIBAVFORMAT_IDENT, sizeof(LIBAVFORMAT_IDENT) - 1);
805 updateSize(pb, pos);
806 }
807
808 if( s->title[0] )
809 {
810 int pos = url_ftell(pb);
811 put_be32(pb, 0); /* size */
812 put_tag(pb, "\251nam");
813 put_be16(pb, strlen(s->title)); /* string length */
814 put_be16(pb, 0);
815 put_buffer(pb, s->title, strlen(s->title));
816 updateSize(pb, pos);
817 }
818
819 if( s->author[0] )
820 {
821 int pos = url_ftell(pb);
822 put_be32(pb, 0); /* size */
823 put_tag(pb, /*"\251aut"*/ "\251day" );
824 put_be16(pb, strlen(s->author)); /* string length */
825 put_be16(pb, 0);
826 put_buffer(pb, s->author, strlen(s->author));
827 updateSize(pb, pos);
828 }
829
830 if( s->comment[0] )
831 {
832 int pos = url_ftell(pb);
833 put_be32(pb, 0); /* size */
834 put_tag(pb, "\251des");
835 put_be16(pb, strlen(s->comment)); /* string length */
836 put_be16(pb, 0);
837 put_buffer(pb, s->comment, strlen(s->comment));
838 updateSize(pb, pos);
839 }
840
841 return updateSize(pb, pos);
842 }
843
844 static int mov_write_moov_tag(ByteIOContext *pb, MOVContext *mov,
845 AVFormatContext *s)
846 {
847 int pos, i;
848 pos = url_ftell(pb);
849 put_be32(pb, 0); /* size placeholder*/
850 put_tag(pb, "moov");
851 mov->timescale = globalTimescale;
852
853 for (i=0; i<MAX_STREAMS; i++) {
854 if(mov->tracks[i].entry <= 0) continue;
855
856 if(mov->tracks[i].enc->codec_type == CODEC_TYPE_VIDEO) {
857 mov->tracks[i].timescale = mov->tracks[i].enc->frame_rate;
858 mov->tracks[i].sampleDuration = mov->tracks[i].enc->frame_rate_base;
859 }
860 else if(mov->tracks[i].enc->codec_type == CODEC_TYPE_AUDIO) {
861 /* If AMR, track timescale = 8000, AMR_WB = 16000 */
862 if(mov->tracks[i].enc->codec_id == CODEC_ID_AMR_NB) {
863 mov->tracks[i].sampleDuration = 160; // Bytes per chunk
864 mov->tracks[i].timescale = 8000;
865 }
866 else {
867 mov->tracks[i].timescale = mov->tracks[i].enc->sample_rate;
868 mov->tracks[i].sampleDuration = mov->tracks[i].enc->frame_size;
869 }
870 }
871
872 mov->tracks[i].trackDuration =
873 mov->tracks[i].sampleCount * mov->tracks[i].sampleDuration;
874 mov->tracks[i].time = mov->time;
875 mov->tracks[i].trackID = i+1;
876 }
877
878 mov_write_mvhd_tag(pb, mov);
879 //mov_write_iods_tag(pb, mov);
880 for (i=0; i<MAX_STREAMS; i++) {
881 if(mov->tracks[i].entry > 0) {
882 mov_write_trak_tag(pb, &(mov->tracks[i]));
883 }
884 }
885
886 mov_write_udta_tag(pb, mov, s);
887
888 return updateSize(pb, pos);
889 }
890
891 int mov_write_mdat_tag(ByteIOContext *pb, MOVContext* mov)
892 {
893 mov->mdat_pos = url_ftell(pb);
894 put_be32(pb, 0); /* size placeholder*/
895 put_tag(pb, "mdat");
896 return 0;
897 }
898
899 /* TODO: This needs to be more general */
900 int mov_write_ftyp_tag(ByteIOContext *pb, AVFormatContext *s)
901 {
902 MOVContext *mov = s->priv_data;
903
904 put_be32(pb, 0x14 ); /* size */
905 put_tag(pb, "ftyp");
906
907 if ( mov->mode == MODE_3GP )
908 put_tag(pb, "3gp4");
909 else
910 put_tag(pb, "isom");
911
912 put_be32(pb, 0x200 );
913
914 if ( mov->mode == MODE_3GP )
915 put_tag(pb, "3gp4");
916 else
917 put_tag(pb, "mp41");
918
919 return 0x14;
920 }
921
922 static int mov_write_header(AVFormatContext *s)
923 {
924 ByteIOContext *pb = &s->pb;
925 MOVContext *mov = s->priv_data;
926 int i;
927
928 for(i=0; i<s->nb_streams; i++){
929 AVCodecContext *c= &s->streams[i]->codec;
930
931 if (c->codec_type == CODEC_TYPE_VIDEO){
932 if (!codec_get_tag(codec_movvideo_tags, c->codec_id)){
933 if(!codec_get_tag(codec_bmp_tags, c->codec_id))
934 return -1;
935 else
936 av_log(s, AV_LOG_INFO, "Warning, using MS style video codec tag, the file may be unplayable!\n");
937 }
938 }else if(c->codec_type == CODEC_TYPE_AUDIO){
939 if (!codec_get_tag(codec_movaudio_tags, c->codec_id)){
940 if(!codec_get_tag(codec_wav_tags, c->codec_id))
941 return -1;
942 else
943 av_log(s, AV_LOG_INFO, "Warning, using MS style audio codec tag, the file may be unplayable!\n");
944 }
945 }
946 }
947
948 /* Default mode == MP4 */
949 mov->mode = MODE_MP4;
950
951 if (s->oformat != NULL) {
952 if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;
953 else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;
954
955 if ( mov->mode == MODE_3GP || mov->mode == MODE_MP4 )
956 mov_write_ftyp_tag(pb,s);
957 }
958
959 for (i=0; i<MAX_STREAMS; i++) {
960 mov->tracks[i].mode = mov->mode;
961 }
962
963 put_flush_packet(pb);
964
965 return 0;
966 }
967
968 static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
969 {
970 MOVContext *mov = s->priv_data;
971 ByteIOContext *pb = &s->pb;
972 AVCodecContext *enc = &s->streams[pkt->stream_index]->codec;
973 MOVTrack* trk = &mov->tracks[pkt->stream_index];
974 int cl, id;
975 unsigned int samplesInChunk = 0;
976 int size= pkt->size;
977
978 if (url_is_streamed(&s->pb)) return 0; /* Can't handle that */
979 if (!size) return 0; /* Discard 0 sized packets */
980
981 if (enc->codec_type == CODEC_TYPE_VIDEO ) {
982 samplesInChunk = 1;
983 }
984 else if (enc->codec_type == CODEC_TYPE_AUDIO ) {
985 if( enc->codec_id == CODEC_ID_AMR_NB) {
986 /* We must find out how many AMR blocks there are in one packet */
987 static uint16_t packed_size[16] =
988 {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 0};
989 int len = 0;
990
991 while (len < size && samplesInChunk < 100) {
992 len += packed_size[(pkt->data[len] >> 3) & 0x0F];
993 samplesInChunk++;
994 }
995 }
996 else if(enc->codec_id == CODEC_ID_PCM_ALAW) {
997 samplesInChunk = size/enc->channels;
998 }
999 else if(enc->codec_id == CODEC_ID_PCM_S16BE || enc->codec_id == CODEC_ID_PCM_S16LE) {
1000 samplesInChunk = size/(2*enc->channels);
1001 }
1002 else {
1003 samplesInChunk = 1;
1004 }
1005 }
1006
1007 if ((enc->codec_id == CODEC_ID_MPEG4 || enc->codec_id == CODEC_ID_AAC)
1008 && trk->vosLen == 0) {
1009 // assert(enc->extradata_size);
1010
1011 trk->vosLen = enc->extradata_size;
1012 trk->vosData = av_malloc(trk->vosLen);
1013 memcpy(trk->vosData, enc->extradata, trk->vosLen);
1014 }
1015
1016 cl = trk->entry / MOV_INDEX_CLUSTER_SIZE;
1017 id = trk->entry % MOV_INDEX_CLUSTER_SIZE;
1018
1019 if (trk->ents_allocated <= trk->entry) {
1020 trk->cluster = av_realloc(trk->cluster, (cl+1)*sizeof(void*));
1021 if (!trk->cluster)
1022 return -1;
1023 trk->cluster[cl] = av_malloc(MOV_INDEX_CLUSTER_SIZE*sizeof(MOVIentry));
1024 if (!trk->cluster[cl])
1025 return -1;
1026 trk->ents_allocated += MOV_INDEX_CLUSTER_SIZE;
1027 }
1028 if (mov->mdat_written == 0) {
1029 mov_write_mdat_tag(pb, mov);
1030 mov->mdat_written = 1;
1031 mov->time = s->timestamp;
1032 }
1033
1034 trk->cluster[cl][id].pos = url_ftell(pb);
1035 trk->cluster[cl][id].samplesInChunk = samplesInChunk;
1036 trk->cluster[cl][id].size = size;
1037 trk->cluster[cl][id].entries = samplesInChunk;
1038 if(enc->codec_type == CODEC_TYPE_VIDEO) {
1039 trk->cluster[cl][id].key_frame = !!(pkt->flags & PKT_FLAG_KEY);
1040 if(trk->cluster[cl][id].key_frame)
1041 trk->hasKeyframes = 1;
1042 }
1043 trk->enc = enc;
1044 trk->entry++;
1045 trk->sampleCount += samplesInChunk;
1046 trk->mdat_size += size;
1047
1048 put_buffer(pb, pkt->data, size);
1049
1050 put_flush_packet(pb);
1051 return 0;
1052 }
1053
1054 static int mov_write_trailer(AVFormatContext *s)
1055 {
1056 MOVContext *mov = s->priv_data;
1057 ByteIOContext *pb = &s->pb;
1058 int res = 0;
1059 int i, j;
1060
1061 offset_t moov_pos = url_ftell(pb);
1062
1063 /* Write size of mdat tag */
1064 for (i=0, j=0; i<MAX_STREAMS; i++) {
1065 if(mov->tracks[i].ents_allocated > 0) {
1066 j += mov->tracks[i].mdat_size;
1067 }
1068 }
1069 url_fseek(pb, mov->mdat_pos, SEEK_SET);
1070 put_be32(pb, j+8);
1071 url_fseek(pb, moov_pos, SEEK_SET);
1072
1073 mov_write_moov_tag(pb, mov, s);
1074
1075 for (i=0; i<MAX_STREAMS; i++) {
1076 for (j=0; j<mov->tracks[i].ents_allocated/MOV_INDEX_CLUSTER_SIZE; j++) {
1077 av_free(mov->tracks[i].cluster[j]);
1078 }
1079 av_free(mov->tracks[i].cluster);
1080 if( mov->tracks[i].vosLen ) av_free( mov->tracks[i].vosData );
1081
1082 mov->tracks[i].cluster = NULL;
1083 mov->tracks[i].ents_allocated = mov->tracks[i].entry = 0;
1084 }
1085
1086 put_flush_packet(pb);
1087
1088 return res;
1089 }
1090
1091 static AVOutputFormat mov_oformat = {
1092 "mov",
1093 "mov format",
1094 NULL,
1095 "mov",
1096 sizeof(MOVContext),
1097 CODEC_ID_AAC,
1098 CODEC_ID_MPEG4,
1099 mov_write_header,
1100 mov_write_packet,
1101 mov_write_trailer,
1102 };
1103
1104 static AVOutputFormat _3gp_oformat = {
1105 "3gp",
1106 "3gp format",
1107 NULL,
1108 "3gp",
1109 sizeof(MOVContext),
1110 CODEC_ID_AMR_NB,
1111 CODEC_ID_H263,
1112 mov_write_header,
1113 mov_write_packet,
1114 mov_write_trailer,
1115 };
1116
1117 static AVOutputFormat mp4_oformat = {
1118 "mp4",
1119 "mp4 format",
1120 "application/mp4",
1121 "mp4,m4a",
1122 sizeof(MOVContext),
1123 CODEC_ID_AAC,
1124 CODEC_ID_MPEG4,
1125 mov_write_header,
1126 mov_write_packet,
1127 mov_write_trailer,
1128 };
1129
1130 int movenc_init(void)
1131 {
1132 av_register_output_format(&mov_oformat);
1133 av_register_output_format(&_3gp_oformat);
1134 av_register_output_format(&mp4_oformat);
1135 return 0;
1136 }