]> git.sesse.net Git - ffmpeg/blob - libavformat/movenc.c
* enabling DV-in-QT
[ffmpeg] / 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 static int mov_write_audio_tag(ByteIOContext *pb, MOVTrack* track)
240 {
241     int pos = url_ftell(pb);
242     put_be32(pb, 0); /* size */
243
244     if(track->enc->codec_id == CODEC_ID_PCM_MULAW)
245       put_tag(pb, "ulaw");
246     else if(track->enc->codec_id == CODEC_ID_PCM_ALAW)
247       put_tag(pb, "alaw");
248     else if(track->enc->codec_id == CODEC_ID_ADPCM_IMA_QT)
249       put_tag(pb, "ima4");
250     else if(track->enc->codec_id == CODEC_ID_MACE3)
251       put_tag(pb, "MAC3");
252     else if(track->enc->codec_id == CODEC_ID_MACE6)
253       put_tag(pb, "MAC6");
254     else if(track->enc->codec_id == CODEC_ID_AAC)
255       put_tag(pb, "mp4a");
256     else if(track->enc->codec_id == CODEC_ID_AMR_NB)
257       put_tag(pb, "samr");
258     else if(track->enc->codec_id == CODEC_ID_PCM_S16BE)
259       put_tag(pb, "twos");
260     else if(track->enc->codec_id == CODEC_ID_PCM_S16LE)
261       put_tag(pb, "sowt");
262     else
263       put_tag(pb, "    ");
264
265     put_be32(pb, 0); /* Reserved */
266     put_be16(pb, 0); /* Reserved */
267     put_be16(pb, 1); /* Data-reference index, XXX  == 1 */
268
269     /* SoundDescription */
270     if(track->mode == MODE_MOV && track->enc->codec_id == CODEC_ID_AAC)
271         put_be16(pb, 1); /* Version 1 */
272     else
273         put_be16(pb, 0); /* Version 0 */
274     put_be16(pb, 0); /* Revision level */
275     put_be32(pb, 0); /* Reserved */
276
277     put_be16(pb, track->enc->channels); /* Number of channels */
278     /* TODO: Currently hard-coded to 16-bit, there doesn't seem
279                  to be a good way to get number of bits of audio */
280     put_be16(pb, 0x10); /* Reserved */
281     put_be16(pb, 0xfffe); /* compression ID (= 0) */
282     put_be16(pb, 0xac); /* packet size (= 0) */
283     put_be16(pb, track->timescale); /* Time scale */
284     put_be16(pb, 0); /* Reserved */
285
286     if(track->mode == MODE_MOV && track->enc->codec_id == CODEC_ID_AAC)
287     {
288         /* SoundDescription V1 extended info */
289         put_be32(pb, track->enc->frame_size); /* Samples per packet  */
290         put_be32(pb, 1536); /* Bytes per packet */
291         put_be32(pb, 2); /* Bytes per frame */
292         put_be32(pb, 2); /* Bytes per sample */
293     }
294
295     if(track->enc->codec_id == CODEC_ID_AAC) {
296         if( track->mode == MODE_MOV ) mov_write_wave_tag(pb, track);
297         else mov_write_esds_tag(pb, track);
298     }
299     if(track->enc->codec_id == CODEC_ID_AMR_NB)
300         mov_write_damr_tag(pb);
301     return updateSize (pb, pos);
302 }
303
304 static int mov_write_d263_tag(ByteIOContext *pb)
305 {
306     put_be32(pb, 0xf); /* size */
307     put_tag(pb, "d263");
308     put_tag(pb, "FFMP");
309     put_be16(pb, 0x0a);
310     put_byte(pb, 0);
311     return 0xf;
312 }
313
314 /* TODO: No idea about these values */
315 static int mov_write_svq3_tag(ByteIOContext *pb)
316 {
317     put_be32(pb, 0x15);
318     put_tag(pb, "SMI ");
319     put_tag(pb, "SEQH");
320     put_be32(pb, 0x5);
321     put_be32(pb, 0xe2c0211d);
322     put_be32(pb, 0xc0000000);
323     put_byte(pb, 0);   
324     return 0x15;
325 }
326
327 static unsigned int descrLength(unsigned int len)
328 {
329     if (len < 0x00000080)
330         return 2 + len;
331     else if (len < 0x00004000)
332         return 3 + len;
333     else if(len < 0x00200000)
334         return 4 + len;
335     else
336         return 5 + len;
337 }
338
339 static void putDescr(ByteIOContext *pb, int tag, int size)
340 {
341     uint32_t len;
342     uint8_t  vals[4];
343
344     len = size;
345     vals[3] = (uint8_t)(len & 0x7f);
346     len >>= 7;
347     vals[2] = (uint8_t)((len & 0x7f) | 0x80); 
348     len >>= 7;
349     vals[1] = (uint8_t)((len & 0x7f) | 0x80); 
350     len >>= 7;
351     vals[0] = (uint8_t)((len & 0x7f) | 0x80);
352
353     put_byte(pb, tag); // DescriptorTag
354
355     if (size < 0x00000080)
356     {
357         put_byte(pb, vals[3]);
358     }
359     else if (size < 0x00004000)
360     {
361         put_byte(pb, vals[2]);
362         put_byte(pb, vals[3]);
363     }
364     else if (size < 0x00200000)
365     {
366         put_byte(pb, vals[1]);
367         put_byte(pb, vals[2]);
368         put_byte(pb, vals[3]);
369     }
370     else if (size < 0x10000000)
371     {
372         put_byte(pb, vals[0]);
373         put_byte(pb, vals[1]);
374         put_byte(pb, vals[2]);
375         put_byte(pb, vals[3]);
376     }
377 }
378
379 static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack* track) // Basic
380 {
381     int decoderSpecificInfoLen = track->vosLen ? descrLength(track->vosLen):0;
382     int pos = url_ftell(pb);
383
384     put_be32(pb, 0);               // size
385     put_tag(pb, "esds");
386     put_be32(pb, 0);               // Version
387
388     // ES descriptor
389     putDescr(pb, 0x03, 3 + descrLength(13 + decoderSpecificInfoLen) +
390              descrLength(1));
391     put_be16(pb, 0x0001);          // ID (= 1)
392     put_byte(pb, 0x00);            // flags (= no flags)
393
394     // DecoderConfig descriptor
395     putDescr(pb, 0x04, 13 + decoderSpecificInfoLen);
396
397     if(track->enc->codec_id == CODEC_ID_AAC)
398         put_byte(pb, 0x40);        // Object type indication
399     else if(track->enc->codec_id == CODEC_ID_MPEG4)
400         put_byte(pb, 0x20);        // Object type indication (Visual 14496-2)
401
402     if(track->enc->codec_type == CODEC_TYPE_AUDIO)
403         put_byte(pb, 0x15);            // flags (= Audiostream)
404     else
405         put_byte(pb, 0x11);            // flags (= Visualstream)
406
407     put_byte(pb, 0x0);             // Buffersize DB (24 bits)
408     put_be16(pb, 0x0dd2);          // Buffersize DB
409
410     // TODO: find real values for these
411     put_be32(pb, 0x0002e918);     // maxbitrate
412     put_be32(pb, 0x00017e6b);     // avg bitrate
413
414     if (track->vosLen)
415     {
416         // DecoderSpecific info descriptor
417         putDescr(pb, 0x05, track->vosLen);
418         put_buffer(pb, track->vosData, track->vosLen);
419     }
420
421     // SL descriptor
422     putDescr(pb, 0x06, 1);
423     put_byte(pb, 0x02);
424     return updateSize (pb, pos);
425 }
426
427 static int mov_write_video_tag(ByteIOContext *pb, MOVTrack* track)
428 {
429     int pos = url_ftell(pb);
430     put_be32(pb, 0); /* size */
431     if(track->enc->codec_id == CODEC_ID_SVQ1)
432       put_tag(pb, "SVQ1");
433     else if(track->enc->codec_id == CODEC_ID_SVQ3)
434       put_tag(pb, "SVQ3");
435     else if(track->enc->codec_id == CODEC_ID_MPEG4)
436       put_tag(pb, "mp4v");
437     else if(track->enc->codec_id == CODEC_ID_H263)
438       put_tag(pb, "s263");
439     else if(track->enc->codec_id == CODEC_ID_DVVIDEO)
440       put_tag(pb, "dvc ");
441     else
442       put_tag(pb, "    "); /* Unknown tag */
443
444     put_be32(pb, 0); /* Reserved */
445     put_be16(pb, 0); /* Reserved */
446     put_be16(pb, 1); /* Data-reference index */
447
448     put_be32(pb, 0); /* Reserved (= 02000c) */
449     put_be32(pb, 0); /* Reserved ("SVis")*/
450     put_be32(pb, 0); /* Reserved */
451     put_be32(pb, 0); /* Reserved (400)*/
452     put_be16(pb, track->enc->width); /* Video width */
453     put_be16(pb, track->enc->height); /* Video height */
454     put_be32(pb, 0x00480000); /* Reserved */
455     put_be32(pb, 0x00480000); /* Reserved */
456     put_be32(pb, 0); /* Reserved */
457     put_be32(pb, 0); /* Reserved */
458     put_be32(pb, 0); /* Reserved */
459     put_be32(pb, 0); /* Reserved */
460     put_be32(pb, 0); /* Reserved */
461     put_be32(pb, 0); /* Reserved */
462
463     put_be16(pb, 0); /* Reserved */
464     put_be32(pb, 0); /* Reserved */
465     put_be32(pb, 0); /* Reserved */
466     put_be32(pb, 0); /* Reserved */
467     put_be16(pb, 0x18); /* Reserved */
468     put_be16(pb, 0xffff); /* Reserved */
469     if(track->enc->codec_id == CODEC_ID_MPEG4)
470         mov_write_esds_tag(pb, track);
471     else if(track->enc->codec_id == CODEC_ID_H263)
472         mov_write_d263_tag(pb);
473     else if(track->enc->codec_id == CODEC_ID_SVQ3)
474         mov_write_svq3_tag(pb);    
475
476     return updateSize (pb, pos);
477 }
478
479 static int mov_write_stsd_tag(ByteIOContext *pb, MOVTrack* track)
480 {
481     int pos = url_ftell(pb);
482     put_be32(pb, 0); /* size */
483     put_tag(pb, "stsd");
484     put_be32(pb, 0); /* version & flags */
485     put_be32(pb, 1); /* entry count */
486     if (track->enc->codec_type == CODEC_TYPE_VIDEO)
487         mov_write_video_tag(pb, track);
488     else if (track->enc->codec_type == CODEC_TYPE_AUDIO)
489         mov_write_audio_tag(pb, track);
490     return updateSize(pb, pos);
491 }
492
493 /* TODO?: Currently all samples/frames seem to have same duration */
494 /* Time to sample atom */
495 static int mov_write_stts_tag(ByteIOContext *pb, MOVTrack* track)
496 {
497     put_be32(pb, 0x18); /* size */
498     put_tag(pb, "stts");
499     put_be32(pb, 0); /* version & flags */
500     put_be32(pb, 1); /* entry count */
501
502     put_be32(pb, track->sampleCount); /* sample count */
503     put_be32(pb, track->sampleDuration); /* sample duration */
504     return 0x18;
505 }
506
507 static int mov_write_dref_tag(ByteIOContext *pb)
508 {
509     put_be32(pb, 28); /* size */
510     put_tag(pb, "dref");
511     put_be32(pb, 0); /* version & flags */
512     put_be32(pb, 1); /* entry count */
513
514     put_be32(pb, 0xc); /* size */
515     put_tag(pb, "url ");
516     put_be32(pb, 1); /* version & flags */
517
518     return 28;
519 }
520
521 static int mov_write_stbl_tag(ByteIOContext *pb, MOVTrack* track)
522 {
523     int pos = url_ftell(pb);
524     put_be32(pb, 0); /* size */
525     put_tag(pb, "stbl");
526     mov_write_stsd_tag(pb, track);
527     mov_write_stts_tag(pb, track);
528     if (track->enc->codec_type == CODEC_TYPE_VIDEO &&
529         track->hasKeyframes)
530         mov_write_stss_tag(pb, track);
531     mov_write_stsc_tag(pb, track);
532     mov_write_stsz_tag(pb, track);
533     mov_write_stco_tag(pb, track);
534     return updateSize(pb, pos);
535 }
536
537 static int mov_write_dinf_tag(ByteIOContext *pb)
538 {
539     int pos = url_ftell(pb);
540     put_be32(pb, 0); /* size */
541     put_tag(pb, "dinf");
542     mov_write_dref_tag(pb);
543     return updateSize(pb, pos);
544 }
545
546 static int mov_write_smhd_tag(ByteIOContext *pb)
547 {
548     put_be32(pb, 16); /* size */
549     put_tag(pb, "smhd");
550     put_be32(pb, 0); /* version & flags */
551     put_be16(pb, 0); /* reserved (balance, normally = 0) */
552     put_be16(pb, 0); /* reserved */
553     return 16;
554 }
555
556 static int mov_write_vmhd_tag(ByteIOContext *pb)
557 {
558     put_be32(pb, 0x14); /* size (always 0x14) */
559     put_tag(pb, "vmhd");
560     put_be32(pb, 0x01); /* version & flags */
561     put_be64(pb, 0); /* reserved (graphics mode = copy) */
562     return 0x14;
563 }
564
565 static int mov_write_minf_tag(ByteIOContext *pb, MOVTrack* track)
566 {
567     int pos = url_ftell(pb);
568     put_be32(pb, 0); /* size */
569     put_tag(pb, "minf");
570     if(track->enc->codec_type == CODEC_TYPE_VIDEO)
571         mov_write_vmhd_tag(pb);
572     else
573         mov_write_smhd_tag(pb);
574     mov_write_dinf_tag(pb);
575     mov_write_stbl_tag(pb, track);
576     return updateSize(pb, pos);
577 }
578
579 static int mov_write_hdlr_tag(ByteIOContext *pb, MOVTrack* track)
580 {
581     char *str;
582     int pos = url_ftell(pb);
583     put_be32(pb, 0); /* size */
584     put_tag(pb, "hdlr");
585     put_be32(pb, 0); /* Version & flags */
586     if (track->mode == MODE_MOV)
587         put_tag(pb, "mhlr"); /* handler */
588     else
589         put_be32(pb, 0); /* reserved */
590     if(track->enc->codec_type == CODEC_TYPE_VIDEO)
591         put_tag(pb, "vide"); /* handler type */
592     else
593         put_tag(pb, "soun"); /* handler type */
594     put_be32(pb ,0); /* reserved */
595     put_be32(pb ,0); /* reserved */
596     put_be32(pb ,0); /* reserved */
597     if(track->enc->codec_type == CODEC_TYPE_VIDEO)
598         str = "VideoHandler";
599     else
600         str = "SoundHandler";
601     put_byte(pb, strlen(str)); /* string counter */
602     put_buffer(pb, str, strlen(str));
603     return updateSize(pb, pos);
604 }
605
606 static int mov_write_mdhd_tag(ByteIOContext *pb, MOVTrack* track)
607 {
608     put_be32(pb, 32); /* size */
609     put_tag(pb, "mdhd");
610     put_be32(pb, 0); /* Version & flags */
611     put_be32(pb, track->time); /* creation time */
612     put_be32(pb, track->time); /* modification time */
613     put_be32(pb, track->timescale); /* time scale (sample rate for audio) */ 
614     put_be32(pb, track->trackDuration); /* duration */
615     put_be16(pb, 0); /* language, 0 = english */
616     put_be16(pb, 0); /* reserved (quality) */
617     return 32;
618 }
619
620 static int mov_write_mdia_tag(ByteIOContext *pb, MOVTrack* track)
621 {
622     int pos = url_ftell(pb);
623     put_be32(pb, 0); /* size */
624     put_tag(pb, "mdia");
625     mov_write_mdhd_tag(pb, track);
626     mov_write_hdlr_tag(pb, track);
627     mov_write_minf_tag(pb, track);
628     return updateSize(pb, pos);
629 }
630
631 static int mov_write_tkhd_tag(ByteIOContext *pb, MOVTrack* track)
632 {
633     int64_t maxTrackLenTemp;
634     put_be32(pb, 0x5c); /* size (always 0x5c) */
635     put_tag(pb, "tkhd");
636     put_be32(pb, 0xf); /* version & flags (track enabled) */
637     put_be32(pb, track->time); /* creation time */
638     put_be32(pb, track->time); /* modification time */
639     put_be32(pb, track->trackID); /* track-id */
640     put_be32(pb, 0); /* reserved */
641     maxTrackLenTemp = ((int64_t)globalTimescale*(int64_t)track->trackDuration)/(int64_t)track->timescale;
642     put_be32(pb, (long)maxTrackLenTemp); /* duration */
643
644     put_be32(pb, 0); /* reserved */
645     put_be32(pb, 0); /* reserved */
646     put_be32(pb, 0x0); /* reserved (Layer & Alternate group) */
647     /* Volume, only for audio */
648     if(track->enc->codec_type == CODEC_TYPE_AUDIO)
649         put_be16(pb, 0x0100);
650     else
651         put_be16(pb, 0);
652     put_be16(pb, 0); /* reserved */
653
654     /* Matrix structure */
655     put_be32(pb, 0x00010000); /* reserved */
656     put_be32(pb, 0x0); /* reserved */
657     put_be32(pb, 0x0); /* reserved */
658     put_be32(pb, 0x0); /* reserved */
659     put_be32(pb, 0x00010000); /* reserved */
660     put_be32(pb, 0x0); /* reserved */
661     put_be32(pb, 0x0); /* reserved */
662     put_be32(pb, 0x0); /* reserved */
663     put_be32(pb, 0x40000000); /* reserved */
664
665     /* Track width and height, for visual only */
666     if(track->enc->codec_type == CODEC_TYPE_VIDEO) {
667         double sample_aspect_ratio = av_q2d(track->enc->sample_aspect_ratio);
668         if( !sample_aspect_ratio ) sample_aspect_ratio = 1;
669         put_be32(pb, sample_aspect_ratio * track->enc->width*0x10000);
670         put_be32(pb, track->enc->height*0x10000);
671     }
672     else {
673         put_be32(pb, 0);
674         put_be32(pb, 0);
675     }
676     return 0x5c;
677 }
678
679 static int mov_write_trak_tag(ByteIOContext *pb, MOVTrack* track)
680 {
681     int pos = url_ftell(pb);
682     put_be32(pb, 0); /* size */
683     put_tag(pb, "trak");
684     mov_write_tkhd_tag(pb, track);
685     mov_write_mdia_tag(pb, track);
686     return updateSize(pb, pos);
687 }
688
689 /* TODO: Not sorted out, but not necessary either */
690 static int mov_write_iods_tag(ByteIOContext *pb, MOVContext *mov)
691 {
692     put_be32(pb, 0x15); /* size */
693     put_tag(pb, "iods");
694     put_be32(pb, 0);    /* version & flags */
695     put_be16(pb, 0x1007);
696     put_byte(pb, 0);
697     put_be16(pb, 0x4fff);
698     put_be16(pb, 0xfffe);
699     put_be16(pb, 0x01ff);
700     return 0x15;
701 }
702
703 static int mov_write_mvhd_tag(ByteIOContext *pb, MOVContext *mov)
704 {
705     int maxTrackID = 1, maxTrackLen = 0, i;
706     int64_t maxTrackLenTemp;
707
708     put_be32(pb, 0x6c); /* size (always 0x6c) */
709     put_tag(pb, "mvhd");
710     put_be32(pb, 0); /* version & flags */
711     put_be32(pb, mov->time); /* creation time */
712     put_be32(pb, mov->time); /* modification time */
713     put_be32(pb, mov->timescale); /* timescale */
714     for (i=0; i<MAX_STREAMS; i++) {
715         if(mov->tracks[i].entry > 0) {
716             maxTrackLenTemp = ((int64_t)globalTimescale*(int64_t)mov->tracks[i].trackDuration)/(int64_t)mov->tracks[i].timescale;
717             if(maxTrackLen < maxTrackLenTemp)
718                 maxTrackLen = maxTrackLenTemp;
719             if(maxTrackID < mov->tracks[i].trackID)
720                 maxTrackID = mov->tracks[i].trackID;
721         }
722     }
723     put_be32(pb, maxTrackLen); /* duration of longest track */
724
725     put_be32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */
726     put_be16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */
727     put_be16(pb, 0); /* reserved */
728     put_be32(pb, 0); /* reserved */
729     put_be32(pb, 0); /* reserved */
730
731     /* Matrix structure */
732     put_be32(pb, 0x00010000); /* reserved */
733     put_be32(pb, 0x0); /* reserved */
734     put_be32(pb, 0x0); /* reserved */
735     put_be32(pb, 0x0); /* reserved */
736     put_be32(pb, 0x00010000); /* reserved */
737     put_be32(pb, 0x0); /* reserved */
738     put_be32(pb, 0x0); /* reserved */
739     put_be32(pb, 0x0); /* reserved */
740     put_be32(pb, 0x40000000); /* reserved */
741
742     put_be32(pb, 0); /* reserved (preview time) */
743     put_be32(pb, 0); /* reserved (preview duration) */
744     put_be32(pb, 0); /* reserved (poster time) */
745     put_be32(pb, 0); /* reserved (selection time) */
746     put_be32(pb, 0); /* reserved (selection duration) */
747     put_be32(pb, 0); /* reserved (current time) */
748     put_be32(pb, maxTrackID+1); /* Next track id */
749     return 0x6c;
750 }
751
752 static int mov_write_udta_tag(ByteIOContext *pb, MOVContext* mov,
753                               AVFormatContext *s)
754 {
755     int pos = url_ftell(pb);
756     int i;
757
758     put_be32(pb, 0); /* size */
759     put_tag(pb, "udta");
760
761     /* Requirements */
762     for (i=0; i<MAX_STREAMS; i++) {
763         if(mov->tracks[i].entry <= 0) continue;
764         if (mov->tracks[i].enc->codec_id == CODEC_ID_AAC ||
765             mov->tracks[i].enc->codec_id == CODEC_ID_MPEG4) {
766             int pos = url_ftell(pb);
767             put_be32(pb, 0); /* size */
768             put_tag(pb, "\251req");
769             put_be16(pb, sizeof("QuickTime 6.0 or greater") - 1);
770             put_be16(pb, 0);
771             put_buffer(pb, "QuickTime 6.0 or greater",
772                        sizeof("QuickTime 6.0 or greater") - 1);
773             updateSize(pb, pos);
774             break;
775         }
776     }
777
778     /* Encoder */
779     {
780         int pos = url_ftell(pb);
781         put_be32(pb, 0); /* size */
782         put_tag(pb, "\251enc");
783         put_be16(pb, sizeof(LIBAVFORMAT_IDENT) - 1); /* string length */
784         put_be16(pb, 0);
785         put_buffer(pb, LIBAVFORMAT_IDENT, sizeof(LIBAVFORMAT_IDENT) - 1);
786         updateSize(pb, pos);
787     }
788
789     if( s->title[0] )
790     {
791         int pos = url_ftell(pb);
792         put_be32(pb, 0); /* size */
793         put_tag(pb, "\251nam");
794         put_be16(pb, strlen(s->title)); /* string length */
795         put_be16(pb, 0);
796         put_buffer(pb, s->title, strlen(s->title));
797         updateSize(pb, pos);
798     }
799
800     if( s->author[0] )
801     {
802         int pos = url_ftell(pb);
803         put_be32(pb, 0); /* size */
804         put_tag(pb, /*"\251aut"*/ "\251day" );
805         put_be16(pb, strlen(s->author)); /* string length */
806         put_be16(pb, 0);
807         put_buffer(pb, s->author, strlen(s->author));
808         updateSize(pb, pos);
809     }
810
811     if( s->comment[0] )
812     {
813         int pos = url_ftell(pb);
814         put_be32(pb, 0); /* size */
815         put_tag(pb, "\251des");
816         put_be16(pb, strlen(s->comment)); /* string length */
817         put_be16(pb, 0);
818         put_buffer(pb, s->comment, strlen(s->comment));
819         updateSize(pb, pos);
820     }
821
822     return updateSize(pb, pos);
823 }
824
825 static int mov_write_moov_tag(ByteIOContext *pb, MOVContext *mov,
826                               AVFormatContext *s)
827 {
828     int pos, i;
829     pos = url_ftell(pb);
830     put_be32(pb, 0); /* size placeholder*/
831     put_tag(pb, "moov");
832     mov->timescale = globalTimescale;
833
834     for (i=0; i<MAX_STREAMS; i++) {
835         if(mov->tracks[i].entry <= 0) continue;
836
837         if(mov->tracks[i].enc->codec_type == CODEC_TYPE_VIDEO) {
838             mov->tracks[i].timescale = mov->tracks[i].enc->frame_rate;
839             mov->tracks[i].sampleDuration = mov->tracks[i].enc->frame_rate_base;
840         }
841         else if(mov->tracks[i].enc->codec_type == CODEC_TYPE_AUDIO) {
842             /* If AMR, track timescale = 8000, AMR_WB = 16000 */
843             if(mov->tracks[i].enc->codec_id == CODEC_ID_AMR_NB) {
844                 mov->tracks[i].sampleDuration = 160;  // Bytes per chunk
845                 mov->tracks[i].timescale = 8000;
846             }
847             else {
848                 mov->tracks[i].timescale = mov->tracks[i].enc->sample_rate;
849                 mov->tracks[i].sampleDuration = mov->tracks[i].enc->frame_size;
850             }
851         }
852
853         mov->tracks[i].trackDuration = 
854             mov->tracks[i].sampleCount * mov->tracks[i].sampleDuration;
855         mov->tracks[i].time = mov->time;
856         mov->tracks[i].trackID = i+1;
857     }
858
859     mov_write_mvhd_tag(pb, mov);
860     //mov_write_iods_tag(pb, mov);
861     for (i=0; i<MAX_STREAMS; i++) {
862         if(mov->tracks[i].entry > 0) {
863             mov_write_trak_tag(pb, &(mov->tracks[i]));
864         }
865     }
866
867     mov_write_udta_tag(pb, mov, s);
868
869     return updateSize(pb, pos);
870 }
871
872 int mov_write_mdat_tag(ByteIOContext *pb, MOVContext* mov)
873 {
874     mov->mdat_pos = url_ftell(pb); 
875     put_be32(pb, 0); /* size placeholder*/
876     put_tag(pb, "mdat");
877     return 0;
878 }
879
880 /* TODO: This needs to be more general */
881 int mov_write_ftyp_tag(ByteIOContext *pb, AVFormatContext *s)
882 {
883     MOVContext *mov = s->priv_data;
884
885     put_be32(pb, 0x14 ); /* size */
886     put_tag(pb, "ftyp");
887
888     if ( mov->mode == MODE_3GP )
889         put_tag(pb, "3gp4");
890     else
891         put_tag(pb, "isom");
892
893     put_be32(pb, 0x200 );
894
895     if ( mov->mode == MODE_3GP )
896         put_tag(pb, "3gp4");
897     else
898         put_tag(pb, "mp41");
899
900     return 0x14;
901 }
902
903 static int mov_write_header(AVFormatContext *s)
904 {
905     ByteIOContext *pb = &s->pb;
906     MOVContext *mov = s->priv_data;
907     int i;
908
909     /* Default mode == MP4 */
910     mov->mode = MODE_MP4;
911
912     if (s->oformat != NULL) {
913         if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;
914         else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;
915
916         if ( mov->mode == MODE_3GP || mov->mode == MODE_MP4 )
917             mov_write_ftyp_tag(pb,s);
918     }
919
920     for (i=0; i<MAX_STREAMS; i++) {
921         mov->tracks[i].mode = mov->mode;
922     }
923
924     put_flush_packet(pb);
925
926     return 0;
927 }
928
929 static int Timestamp(void) {
930     return 1067949799U+(24107*86400); //its the modification time of this line :)
931 }
932
933 static int mov_write_packet(AVFormatContext *s, int stream_index,
934                             const uint8_t *buf, int size, int64_t pts)
935 {
936     MOVContext *mov = s->priv_data;
937     ByteIOContext *pb = &s->pb;
938     AVCodecContext *enc = &s->streams[stream_index]->codec;
939     MOVTrack* trk = &mov->tracks[stream_index];
940     int cl, id;
941     unsigned int samplesInChunk = 0;
942
943     if (url_is_streamed(&s->pb)) return 0; /* Can't handle that */
944     if (!size) return 0; /* Discard 0 sized packets */
945
946     if (enc->codec_type == CODEC_TYPE_VIDEO ) {
947         samplesInChunk = 1;
948     }
949     else if (enc->codec_type == CODEC_TYPE_AUDIO ) {
950         if( enc->codec_id == CODEC_ID_AMR_NB) {
951             /* We must find out how many AMR blocks there are in one packet */
952             static uint16_t packed_size[16] =
953                 {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 0};
954             int len = 0;
955
956             while (len < size && samplesInChunk < 100) {
957                 len += packed_size[(buf[len] >> 3) & 0x0F];
958                 samplesInChunk++;
959             }
960         }
961         else if(enc->codec_id == CODEC_ID_PCM_ALAW) {
962             samplesInChunk = size/enc->channels;
963         }
964         else {
965             samplesInChunk = 1;
966         }
967     }
968
969     if ((enc->codec_id == CODEC_ID_MPEG4 || enc->codec_id == CODEC_ID_AAC)
970         && trk->vosLen == 0) {
971         assert(enc->extradata_size);
972
973         trk->vosLen = enc->extradata_size;
974         trk->vosData = av_malloc(trk->vosLen);
975         memcpy(trk->vosData, enc->extradata, trk->vosLen);
976     }
977
978     cl = trk->entry / MOV_INDEX_CLUSTER_SIZE;
979     id = trk->entry % MOV_INDEX_CLUSTER_SIZE;
980
981     if (trk->ents_allocated <= trk->entry) {
982         trk->cluster = av_realloc(trk->cluster, (cl+1)*sizeof(void*)); 
983         if (!trk->cluster)
984             return -1;
985         trk->cluster[cl] = av_malloc(MOV_INDEX_CLUSTER_SIZE*sizeof(MOVIentry));
986         if (!trk->cluster[cl])
987             return -1;
988         trk->ents_allocated += MOV_INDEX_CLUSTER_SIZE;
989     }
990     if (mov->mdat_written == 0) {
991         mov_write_mdat_tag(pb, mov);
992         mov->mdat_written = 1;
993         mov->time = Timestamp();
994     }
995
996     trk->cluster[cl][id].pos = url_ftell(pb);
997     trk->cluster[cl][id].samplesInChunk = samplesInChunk;
998     trk->cluster[cl][id].size = size;
999     trk->cluster[cl][id].entries = samplesInChunk;
1000     if(enc->codec_type == CODEC_TYPE_VIDEO) {
1001         trk->cluster[cl][id].key_frame = enc->coded_frame->key_frame;
1002         if(enc->coded_frame->pict_type == FF_I_TYPE)
1003             trk->hasKeyframes = 1;
1004     }
1005     trk->enc = enc;
1006     trk->entry++;
1007     trk->sampleCount += samplesInChunk;
1008     trk->mdat_size += size;
1009
1010     put_buffer(pb, buf, size);
1011
1012     put_flush_packet(pb);
1013     return 0;
1014 }
1015
1016 static int mov_write_trailer(AVFormatContext *s)
1017 {
1018     MOVContext *mov = s->priv_data;
1019     ByteIOContext *pb = &s->pb;
1020     int res = 0;
1021     int i, j;
1022
1023     offset_t moov_pos = url_ftell(pb);
1024
1025     /* Write size of mdat tag */
1026     for (i=0, j=0; i<MAX_STREAMS; i++) {
1027         if(mov->tracks[i].ents_allocated > 0) {
1028             j += mov->tracks[i].mdat_size;
1029         }
1030     }
1031     url_fseek(pb, mov->mdat_pos, SEEK_SET);
1032     put_be32(pb, j+8);
1033     url_fseek(pb, moov_pos, SEEK_SET);
1034
1035     mov_write_moov_tag(pb, mov, s);
1036
1037     for (i=0; i<MAX_STREAMS; i++) {
1038         for (j=0; j<mov->tracks[i].ents_allocated/MOV_INDEX_CLUSTER_SIZE; j++) {
1039             av_free(mov->tracks[i].cluster[j]);
1040         }
1041         av_free(mov->tracks[i].cluster);
1042         if( mov->tracks[i].vosLen ) av_free( mov->tracks[i].vosData );
1043
1044         mov->tracks[i].cluster = NULL;
1045         mov->tracks[i].ents_allocated = mov->tracks[i].entry = 0;
1046     }
1047
1048     put_flush_packet(pb);
1049
1050     return res;
1051 }
1052
1053 static AVOutputFormat mov_oformat = {
1054     "mov",
1055     "mov format",
1056     NULL,
1057     "mov",
1058     sizeof(MOVContext),
1059     CODEC_ID_AAC,
1060     CODEC_ID_MPEG4,
1061     mov_write_header,
1062     mov_write_packet,
1063     mov_write_trailer,
1064 };
1065
1066 static AVOutputFormat _3gp_oformat = {
1067     "3gp",
1068     "3gp format",
1069     NULL,
1070     "3gp",
1071     sizeof(MOVContext),
1072     CODEC_ID_AMR_NB,
1073     CODEC_ID_H263,
1074     mov_write_header,
1075     mov_write_packet,
1076     mov_write_trailer,
1077 };
1078
1079 static AVOutputFormat mp4_oformat = {
1080     "mp4",
1081     "mp4 format",
1082     "application/mp4",
1083     "mp4,m4a",
1084     sizeof(MOVContext),
1085     CODEC_ID_AAC,
1086     CODEC_ID_MPEG4,
1087     mov_write_header,
1088     mov_write_packet,
1089     mov_write_trailer,
1090 };
1091
1092 int movenc_init(void)
1093 {
1094     av_register_output_format(&mov_oformat);
1095     av_register_output_format(&_3gp_oformat);
1096     av_register_output_format(&mp4_oformat);
1097     return 0;
1098 }