Statistics
| Branch: | Revision:

ffmpeg / libavformat / movenc.c @ ca93bc17

History | View | Annotate | Download (61.3 KB)

1
/*
2
 * MOV, 3GP, MP4 muxer
3
 * Copyright (c) 2003 Thomas Raivio.
4
 * Copyright (c) 2004 Gildas Bazin <gbazin at videolan dot org>.
5
 *
6
 * This file is part of FFmpeg.
7
 *
8
 * FFmpeg is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * FFmpeg is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with FFmpeg; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 */
22
#include "avformat.h"
23
#include "riff.h"
24
#include "avio.h"
25
#include "isom.h"
26
#include "avc.h"
27
#include "libavcodec/bitstream.h"
28

    
29
#undef NDEBUG
30
#include <assert.h>
31

    
32
#define MOV_INDEX_CLUSTER_SIZE 16384
33
#define globalTimescale 1000
34

    
35
#define MODE_MP4  0x01
36
#define MODE_MOV  0x02
37
#define MODE_3GP  0x04
38
#define MODE_PSP  0x08 // example working PSP command line:
39
// ffmpeg -i testinput.avi  -f psp -r 14.985 -s 320x240 -b 768 -ar 24000 -ab 32 M4V00001.MP4
40
#define MODE_3G2  0x10
41
#define MODE_IPOD 0x20
42

    
43
typedef struct MOVIentry {
44
    unsigned int flags, size;
45
    uint64_t     pos;
46
    unsigned int samplesInChunk;
47
    char         key_frame;
48
    unsigned int entries;
49
    int64_t      cts;
50
    int64_t      dts;
51
} MOVIentry;
52

    
53
typedef struct MOVIndex {
54
    int         mode;
55
    int         entry;
56
    long        timescale;
57
    long        time;
58
    int64_t     trackDuration;
59
    long        sampleCount;
60
    long        sampleSize;
61
    int         hasKeyframes;
62
    int         hasBframes;
63
    int         language;
64
    int         trackID;
65
    int         tag; ///< stsd fourcc
66
    AVCodecContext *enc;
67

    
68
    int         vosLen;
69
    uint8_t     *vosData;
70
    MOVIentry   *cluster;
71
    int         audio_vbr;
72
} MOVTrack;
73

    
74
typedef struct MOVContext {
75
    int     mode;
76
    int64_t time;
77
    int     nb_streams;
78
    int64_t mdat_pos;
79
    uint64_t mdat_size;
80
    long    timescale;
81
    MOVTrack tracks[MAX_STREAMS];
82
} MOVContext;
83

    
84
//FIXME support 64 bit variant with wide placeholders
85
static int64_t updateSize(ByteIOContext *pb, int64_t pos)
86
{
87
    int64_t curpos = url_ftell(pb);
88
    url_fseek(pb, pos, SEEK_SET);
89
    put_be32(pb, curpos - pos); /* rewrite size */
90
    url_fseek(pb, curpos, SEEK_SET);
91

    
92
    return curpos - pos;
93
}
94

    
95
/* Chunk offset atom */
96
static int mov_write_stco_tag(ByteIOContext *pb, MOVTrack *track)
97
{
98
    int i;
99
    int mode64 = 0; //   use 32 bit size variant if possible
100
    int64_t pos = url_ftell(pb);
101
    put_be32(pb, 0); /* size */
102
    if (pos > UINT32_MAX) {
103
        mode64 = 1;
104
        put_tag(pb, "co64");
105
    } else
106
        put_tag(pb, "stco");
107
    put_be32(pb, 0); /* version & flags */
108
    put_be32(pb, track->entry); /* entry count */
109
    for (i=0; i<track->entry; i++) {
110
        if(mode64 == 1)
111
            put_be64(pb, track->cluster[i].pos);
112
        else
113
            put_be32(pb, track->cluster[i].pos);
114
    }
115
    return updateSize(pb, pos);
116
}
117

    
118
/* Sample size atom */
119
static int mov_write_stsz_tag(ByteIOContext *pb, MOVTrack *track)
120
{
121
    int equalChunks = 1;
122
    int i, j, entries = 0, tst = -1, oldtst = -1;
123

    
124
    int64_t pos = url_ftell(pb);
125
    put_be32(pb, 0); /* size */
126
    put_tag(pb, "stsz");
127
    put_be32(pb, 0); /* version & flags */
128

    
129
    for (i=0; i<track->entry; i++) {
130
        tst = track->cluster[i].size/track->cluster[i].entries;
131
        if(oldtst != -1 && tst != oldtst) {
132
            equalChunks = 0;
133
        }
134
        oldtst = tst;
135
        entries += track->cluster[i].entries;
136
    }
137
    if (equalChunks) {
138
        int sSize = track->cluster[0].size/track->cluster[0].entries;
139
        put_be32(pb, sSize); // sample size
140
        put_be32(pb, entries); // sample count
141
    }
142
    else {
143
        put_be32(pb, 0); // sample size
144
        put_be32(pb, entries); // sample count
145
        for (i=0; i<track->entry; i++) {
146
            for (j=0; j<track->cluster[i].entries; j++) {
147
                put_be32(pb, track->cluster[i].size /
148
                         track->cluster[i].entries);
149
            }
150
        }
151
    }
152
    return updateSize(pb, pos);
153
}
154

    
155
/* Sample to chunk atom */
156
static int mov_write_stsc_tag(ByteIOContext *pb, MOVTrack *track)
157
{
158
    int index = 0, oldval = -1, i;
159
    int64_t entryPos, curpos;
160

    
161
    int64_t pos = url_ftell(pb);
162
    put_be32(pb, 0); /* size */
163
    put_tag(pb, "stsc");
164
    put_be32(pb, 0); // version & flags
165
    entryPos = url_ftell(pb);
166
    put_be32(pb, track->entry); // entry count
167
    for (i=0; i<track->entry; i++) {
168
        if(oldval != track->cluster[i].samplesInChunk)
169
        {
170
            put_be32(pb, i+1); // first chunk
171
            put_be32(pb, track->cluster[i].samplesInChunk); // samples per chunk
172
            put_be32(pb, 0x1); // sample description index
173
            oldval = track->cluster[i].samplesInChunk;
174
            index++;
175
        }
176
    }
177
    curpos = url_ftell(pb);
178
    url_fseek(pb, entryPos, SEEK_SET);
179
    put_be32(pb, index); // rewrite size
180
    url_fseek(pb, curpos, SEEK_SET);
181

    
182
    return updateSize(pb, pos);
183
}
184

    
185
/* Sync sample atom */
186
static int mov_write_stss_tag(ByteIOContext *pb, MOVTrack *track)
187
{
188
    int64_t curpos, entryPos;
189
    int i, index = 0;
190
    int64_t pos = url_ftell(pb);
191
    put_be32(pb, 0); // size
192
    put_tag(pb, "stss");
193
    put_be32(pb, 0); // version & flags
194
    entryPos = url_ftell(pb);
195
    put_be32(pb, track->entry); // entry count
196
    for (i=0; i<track->entry; i++) {
197
        if(track->cluster[i].key_frame == 1) {
198
            put_be32(pb, i+1);
199
            index++;
200
        }
201
    }
202
    curpos = url_ftell(pb);
203
    url_fseek(pb, entryPos, SEEK_SET);
204
    put_be32(pb, index); // rewrite size
205
    url_fseek(pb, curpos, SEEK_SET);
206
    return updateSize(pb, pos);
207
}
208

    
209
static int mov_write_amr_tag(ByteIOContext *pb, MOVTrack *track)
210
{
211
    put_be32(pb, 0x11); /* size */
212
    if (track->mode == MODE_MOV) put_tag(pb, "samr");
213
    else                         put_tag(pb, "damr");
214
    put_tag(pb, "FFMP");
215
    put_byte(pb, 0); /* decoder version */
216

    
217
    put_be16(pb, 0x81FF); /* Mode set (all modes for AMR_NB) */
218
    put_byte(pb, 0x00); /* Mode change period (no restriction) */
219
    put_byte(pb, 0x01); /* Frames per sample */
220
    return 0x11;
221
}
222

    
223
static int mov_write_ac3_tag(ByteIOContext *pb, MOVTrack *track)
224
{
225
    GetBitContext gbc;
226
    PutBitContext pbc;
227
    uint8_t buf[3];
228
    int fscod, bsid, bsmod, acmod, lfeon, frmsizecod;
229

    
230
    if (track->vosLen < 7)
231
        return -1;
232

    
233
    put_be32(pb, 11);
234
    put_tag(pb, "dac3");
235

    
236
    init_get_bits(&gbc, track->vosData+4, track->vosLen-4);
237
    fscod      = get_bits(&gbc, 2);
238
    frmsizecod = get_bits(&gbc, 6);
239
    bsid       = get_bits(&gbc, 5);
240
    bsmod      = get_bits(&gbc, 3);
241
    acmod      = get_bits(&gbc, 3);
242
    if (acmod == 2) {
243
        skip_bits(&gbc, 2); // dsurmod
244
    } else {
245
        if ((acmod & 1) && acmod != 1)
246
            skip_bits(&gbc, 2); // cmixlev
247
        if (acmod & 4)
248
            skip_bits(&gbc, 2); // surmixlev
249
    }
250
    lfeon = get_bits1(&gbc);
251

    
252
    init_put_bits(&pbc, buf, sizeof(buf));
253
    put_bits(&pbc, 2, fscod);
254
    put_bits(&pbc, 5, bsid);
255
    put_bits(&pbc, 3, bsmod);
256
    put_bits(&pbc, 3, acmod);
257
    put_bits(&pbc, 1, lfeon);
258
    put_bits(&pbc, 5, frmsizecod>>1); // bit_rate_code
259
    put_bits(&pbc, 5, 0); // reserved
260

    
261
    flush_put_bits(&pbc);
262
    put_buffer(pb, buf, sizeof(buf));
263

    
264
    return 11;
265
}
266

    
267
/**
268
 * This function writes extradata "as is".
269
 * Extradata must be formated like a valid atom (with size and tag)
270
 */
271
static int mov_write_extradata_tag(ByteIOContext *pb, MOVTrack *track)
272
{
273
    put_buffer(pb, track->enc->extradata, track->enc->extradata_size);
274
    return track->enc->extradata_size;
275
}
276

    
277
static int mov_write_enda_tag(ByteIOContext *pb)
278
{
279
    put_be32(pb, 10);
280
    put_tag(pb, "enda");
281
    put_be16(pb, 1); /* little endian */
282
    return 10;
283
}
284

    
285
static unsigned int descrLength(unsigned int len)
286
{
287
    int i;
288
    for(i=1; len>>(7*i); i++);
289
    return len + 1 + i;
290
}
291

    
292
static void putDescr(ByteIOContext *pb, int tag, unsigned int size)
293
{
294
    int i= descrLength(size) - size - 2;
295
    put_byte(pb, tag);
296
    for(; i>0; i--)
297
        put_byte(pb, (size>>(7*i)) | 0x80);
298
    put_byte(pb, size & 0x7F);
299
}
300

    
301
static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack *track) // Basic
302
{
303
    int64_t pos = url_ftell(pb);
304
    int decoderSpecificInfoLen = track->vosLen ? descrLength(track->vosLen):0;
305

    
306
    put_be32(pb, 0); // size
307
    put_tag(pb, "esds");
308
    put_be32(pb, 0); // Version
309

    
310
    // ES descriptor
311
    putDescr(pb, 0x03, 3 + descrLength(13 + decoderSpecificInfoLen) +
312
             descrLength(1));
313
    put_be16(pb, track->trackID);
314
    put_byte(pb, 0x00); // flags (= no flags)
315

    
316
    // DecoderConfig descriptor
317
    putDescr(pb, 0x04, 13 + decoderSpecificInfoLen);
318

    
319
    // Object type indication
320
    if ((track->enc->codec_id == CODEC_ID_MP2 ||
321
         track->enc->codec_id == CODEC_ID_MP3) &&
322
        track->enc->sample_rate > 24000)
323
        put_byte(pb, 0x6B); // 11172-3
324
    else
325
        put_byte(pb, codec_get_tag(ff_mp4_obj_type, track->enc->codec_id));
326

    
327
    // the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio)
328
    // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
329
    if(track->enc->codec_type == CODEC_TYPE_AUDIO)
330
        put_byte(pb, 0x15); // flags (= Audiostream)
331
    else
332
        put_byte(pb, 0x11); // flags (= Visualstream)
333

    
334
    put_byte(pb,  track->enc->rc_buffer_size>>(3+16));    // Buffersize DB (24 bits)
335
    put_be16(pb, (track->enc->rc_buffer_size>>3)&0xFFFF); // Buffersize DB
336

    
337
    put_be32(pb, FFMAX(track->enc->bit_rate, track->enc->rc_max_rate)); // maxbitrate (FIXME should be max rate in any 1 sec window)
338
    if(track->enc->rc_max_rate != track->enc->rc_min_rate || track->enc->rc_min_rate==0)
339
        put_be32(pb, 0); // vbr
340
    else
341
        put_be32(pb, track->enc->rc_max_rate); // avg bitrate
342

    
343
    if (track->vosLen) {
344
        // DecoderSpecific info descriptor
345
        putDescr(pb, 0x05, track->vosLen);
346
        put_buffer(pb, track->vosData, track->vosLen);
347
    }
348

    
349
    // SL descriptor
350
    putDescr(pb, 0x06, 1);
351
    put_byte(pb, 0x02);
352
    return updateSize(pb, pos);
353
}
354

    
355
static int mov_write_wave_tag(ByteIOContext *pb, MOVTrack *track)
356
{
357
    int64_t pos = url_ftell(pb);
358

    
359
    put_be32(pb, 0);     /* size */
360
    put_tag(pb, "wave");
361

    
362
    put_be32(pb, 12);    /* size */
363
    put_tag(pb, "frma");
364
    put_le32(pb, track->tag);
365

    
366
    if (track->enc->codec_id == CODEC_ID_AAC) {
367
        /* useless atom needed by mplayer, ipod, not needed by quicktime */
368
        put_be32(pb, 12); /* size */
369
        put_tag(pb, "mp4a");
370
        put_be32(pb, 0);
371
        mov_write_esds_tag(pb, track);
372
    } else if (track->enc->codec_id == CODEC_ID_PCM_S24LE ||
373
               track->enc->codec_id == CODEC_ID_PCM_S32LE) {
374
        mov_write_enda_tag(pb);
375
    } else if (track->enc->codec_id == CODEC_ID_AMR_NB) {
376
        mov_write_amr_tag(pb, track);
377
    } else if (track->enc->codec_id == CODEC_ID_AC3) {
378
        mov_write_ac3_tag(pb, track);
379
    } else if (track->enc->codec_id == CODEC_ID_ALAC) {
380
        mov_write_extradata_tag(pb, track);
381
    }
382

    
383
    put_be32(pb, 8);     /* size */
384
    put_be32(pb, 0);     /* null tag */
385

    
386
    return updateSize(pb, pos);
387
}
388

    
389
static int mov_write_glbl_tag(ByteIOContext *pb, MOVTrack *track)
390
{
391
    put_be32(pb, track->vosLen+8);
392
    put_tag(pb, "glbl");
393
    put_buffer(pb, track->vosData, track->vosLen);
394
    return 8+track->vosLen;
395
}
396

    
397
static int mov_write_audio_tag(ByteIOContext *pb, MOVTrack *track)
398
{
399
    int64_t pos = url_ftell(pb);
400
    int version = track->mode == MODE_MOV &&
401
        (track->audio_vbr ||
402
         track->enc->codec_id == CODEC_ID_PCM_S32LE ||
403
         track->enc->codec_id == CODEC_ID_PCM_S24LE);
404

    
405
    put_be32(pb, 0); /* size */
406
    put_le32(pb, track->tag); // store it byteswapped
407
    put_be32(pb, 0); /* Reserved */
408
    put_be16(pb, 0); /* Reserved */
409
    put_be16(pb, 1); /* Data-reference index, XXX  == 1 */
410

    
411
    /* SoundDescription */
412
    put_be16(pb, version); /* Version */
413
    put_be16(pb, 0); /* Revision level */
414
    put_be32(pb, 0); /* Reserved */
415

    
416
    if (track->mode == MODE_MOV) {
417
        put_be16(pb, track->enc->channels);
418
        if (track->enc->codec_id == CODEC_ID_PCM_U8 ||
419
            track->enc->codec_id == CODEC_ID_PCM_S8)
420
            put_be16(pb, 8); /* bits per sample */
421
        else
422
            put_be16(pb, 16);
423
        put_be16(pb, track->audio_vbr ? -2 : 0); /* compression ID */
424
    } else { /* reserved for mp4/3gp */
425
        put_be16(pb, 2);
426
        put_be16(pb, 16);
427
        put_be16(pb, 0);
428
    }
429

    
430
    put_be16(pb, 0); /* packet size (= 0) */
431
    put_be16(pb, track->timescale); /* Time scale */
432
    put_be16(pb, 0); /* Reserved */
433

    
434
    if(version == 1) { /* SoundDescription V1 extended info */
435
        put_be32(pb, track->enc->frame_size); /* Samples per packet */
436
        put_be32(pb, track->sampleSize / track->enc->channels); /* Bytes per packet */
437
        put_be32(pb, track->sampleSize); /* Bytes per frame */
438
        put_be32(pb, 2); /* Bytes per sample */
439
    }
440

    
441
    if(track->mode == MODE_MOV &&
442
       (track->enc->codec_id == CODEC_ID_AAC ||
443
        track->enc->codec_id == CODEC_ID_AC3 ||
444
        track->enc->codec_id == CODEC_ID_AMR_NB ||
445
        track->enc->codec_id == CODEC_ID_PCM_S24LE ||
446
        track->enc->codec_id == CODEC_ID_PCM_S32LE ||
447
        track->enc->codec_id == CODEC_ID_ALAC))
448
        mov_write_wave_tag(pb, track);
449
    else if(track->tag == MKTAG('m','p','4','a'))
450
        mov_write_esds_tag(pb, track);
451
    else if(track->enc->codec_id == CODEC_ID_AMR_NB)
452
        mov_write_amr_tag(pb, track);
453
    else if(track->enc->codec_id == CODEC_ID_AC3)
454
        mov_write_ac3_tag(pb, track);
455
    else if(track->enc->codec_id == CODEC_ID_ALAC)
456
        mov_write_extradata_tag(pb, track);
457
    else if(track->vosLen > 0)
458
        mov_write_glbl_tag(pb, track);
459

    
460
    return updateSize(pb, pos);
461
}
462

    
463
static int mov_write_d263_tag(ByteIOContext *pb)
464
{
465
    put_be32(pb, 0xf); /* size */
466
    put_tag(pb, "d263");
467
    put_tag(pb, "FFMP");
468
    put_byte(pb, 0); /* decoder version */
469
    /* FIXME use AVCodecContext level/profile, when encoder will set values */
470
    put_byte(pb, 0xa); /* level */
471
    put_byte(pb, 0); /* profile */
472
    return 0xf;
473
}
474

    
475
/* TODO: No idea about these values */
476
static int mov_write_svq3_tag(ByteIOContext *pb)
477
{
478
    put_be32(pb, 0x15);
479
    put_tag(pb, "SMI ");
480
    put_tag(pb, "SEQH");
481
    put_be32(pb, 0x5);
482
    put_be32(pb, 0xe2c0211d);
483
    put_be32(pb, 0xc0000000);
484
    put_byte(pb, 0);
485
    return 0x15;
486
}
487

    
488
static int mov_write_avcc_tag(ByteIOContext *pb, MOVTrack *track)
489
{
490
    int64_t pos = url_ftell(pb);
491

    
492
    put_be32(pb, 0);
493
    put_tag(pb, "avcC");
494
    ff_isom_write_avcc(pb, track->vosData, track->vosLen);
495
    return updateSize(pb, pos);
496
}
497

    
498
/* also used by all avid codecs (dv, imx, meridien) and their variants */
499
static int mov_write_avid_tag(ByteIOContext *pb, MOVTrack *track)
500
{
501
    int i;
502
    put_be32(pb, 24); /* size */
503
    put_tag(pb, "ACLR");
504
    put_tag(pb, "ACLR");
505
    put_tag(pb, "0001");
506
    put_be32(pb, 1); /* yuv 1 / rgb 2 ? */
507
    put_be32(pb, 0); /* unknown */
508

    
509
    put_be32(pb, 24); /* size */
510
    put_tag(pb, "APRG");
511
    put_tag(pb, "APRG");
512
    put_tag(pb, "0001");
513
    put_be32(pb, 1); /* unknown */
514
    put_be32(pb, 0); /* unknown */
515

    
516
    put_be32(pb, 120); /* size */
517
    put_tag(pb, "ARES");
518
    put_tag(pb, "ARES");
519
    put_tag(pb, "0001");
520
    put_be32(pb, AV_RB32(track->vosData + 0x28)); /* dnxhd cid, some id ? */
521
    put_be32(pb, track->enc->width);
522
    /* values below are based on samples created with quicktime and avid codecs */
523
    if (track->vosData[5] & 2) { // interlaced
524
        put_be32(pb, track->enc->height/2);
525
        put_be32(pb, 2); /* unknown */
526
        put_be32(pb, 0); /* unknown */
527
        put_be32(pb, 4); /* unknown */
528
    } else {
529
        put_be32(pb, track->enc->height);
530
        put_be32(pb, 1); /* unknown */
531
        put_be32(pb, 0); /* unknown */
532
        if (track->enc->height == 1080)
533
            put_be32(pb, 5); /* unknown */
534
        else
535
            put_be32(pb, 6); /* unknown */
536
    }
537
    /* padding */
538
    for (i = 0; i < 10; i++)
539
        put_be64(pb, 0);
540

    
541
    /* extra padding for stsd needed */
542
    put_be32(pb, 0);
543
    return 0;
544
}
545

    
546
static const AVCodecTag codec_3gp_tags[] = {
547
    { CODEC_ID_H263,   MKTAG('s','2','6','3') },
548
    { CODEC_ID_H264,   MKTAG('a','v','c','1') },
549
    { CODEC_ID_MPEG4,  MKTAG('m','p','4','v') },
550
    { CODEC_ID_AAC,    MKTAG('m','p','4','a') },
551
    { CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
552
    { CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },
553
    { CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
554
    { CODEC_ID_NONE, 0 },
555
};
556

    
557
static const AVCodecTag mov_pix_fmt_tags[] = {
558
    { PIX_FMT_YUYV422, MKTAG('y','u','v','s') },
559
    { PIX_FMT_UYVY422, MKTAG('2','v','u','y') },
560
    { PIX_FMT_BGR555,  MKTAG('r','a','w',' ') },
561
    { PIX_FMT_RGB24,   MKTAG('r','a','w',' ') },
562
    { PIX_FMT_BGR32_1, MKTAG('r','a','w',' ') },
563
};
564

    
565
static const AVCodecTag codec_ipod_tags[] = {
566
    { CODEC_ID_H264,   MKTAG('a','v','c','1') },
567
    { CODEC_ID_MPEG4,  MKTAG('m','p','4','v') },
568
    { CODEC_ID_AAC,    MKTAG('m','p','4','a') },
569
    { CODEC_ID_ALAC,   MKTAG('a','l','a','c') },
570
    { CODEC_ID_AC3,    MKTAG('a','c','-','3') },
571
    { CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
572
    { CODEC_ID_NONE, 0 },
573
};
574

    
575
static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
576
{
577
    int tag = track->enc->codec_tag;
578
    if (track->mode == MODE_MP4 || track->mode == MODE_PSP) {
579
        if (!codec_get_tag(ff_mp4_obj_type, track->enc->codec_id))
580
            return 0;
581
        if      (track->enc->codec_id == CODEC_ID_H264)      tag = MKTAG('a','v','c','1');
582
        else if (track->enc->codec_id == CODEC_ID_AC3)       tag = MKTAG('a','c','-','3');
583
        else if (track->enc->codec_id == CODEC_ID_DIRAC)     tag = MKTAG('d','r','a','c');
584
        else if (track->enc->codec_id == CODEC_ID_MOV_TEXT)  tag = MKTAG('t','x','3','g');
585
        else if (track->enc->codec_type == CODEC_TYPE_VIDEO) tag = MKTAG('m','p','4','v');
586
        else if (track->enc->codec_type == CODEC_TYPE_AUDIO) tag = MKTAG('m','p','4','a');
587
    } else if (track->mode == MODE_IPOD) {
588
        tag = codec_get_tag(codec_ipod_tags, track->enc->codec_id);
589
        if (!match_ext(s->filename, "m4a") && !match_ext(s->filename, "m4v"))
590
            av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v "
591
                   "Quicktime/Ipod might not play the file\n");
592
    } else if (track->mode & MODE_3GP) {
593
        tag = codec_get_tag(codec_3gp_tags, track->enc->codec_id);
594
    } else if (!tag || (track->enc->strict_std_compliance >= FF_COMPLIANCE_NORMAL &&
595
                        (tag == MKTAG('d','v','c','p') ||
596
                         track->enc->codec_id == CODEC_ID_RAWVIDEO))) {
597
        if (track->enc->codec_id == CODEC_ID_DVVIDEO) {
598
            if (track->enc->height == 480) /* NTSC */
599
                if  (track->enc->pix_fmt == PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n');
600
                else                                         tag = MKTAG('d','v','c',' ');
601
            else if (track->enc->pix_fmt == PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p');
602
            else if (track->enc->pix_fmt == PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
603
            else                                             tag = MKTAG('d','v','p','p');
604
        } else if (track->enc->codec_id == CODEC_ID_RAWVIDEO) {
605
            tag = codec_get_tag(mov_pix_fmt_tags, track->enc->pix_fmt);
606
            if (!tag) // restore tag
607
                tag = track->enc->codec_tag;
608
        } else {
609
            if (track->enc->codec_type == CODEC_TYPE_VIDEO) {
610
                tag = codec_get_tag(codec_movvideo_tags, track->enc->codec_id);
611
                if (!tag) { // if no mac fcc found, try with Microsoft tags
612
                    tag = codec_get_tag(codec_bmp_tags, track->enc->codec_id);
613
                    if (tag)
614
                        av_log(s, AV_LOG_INFO, "Warning, using MS style video codec tag, "
615
                               "the file may be unplayable!\n");
616
                }
617
            } else if (track->enc->codec_type == CODEC_TYPE_AUDIO) {
618
                tag = codec_get_tag(codec_movaudio_tags, track->enc->codec_id);
619
                if (!tag) { // if no mac fcc found, try with Microsoft tags
620
                    int ms_tag = codec_get_tag(codec_wav_tags, track->enc->codec_id);
621
                    if (ms_tag) {
622
                        tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));
623
                        av_log(s, AV_LOG_INFO, "Warning, using MS style audio codec tag, "
624
                               "the file may be unplayable!\n");
625
                    }
626
                }
627
            } else if (track->enc->codec_type == CODEC_TYPE_SUBTITLE) {
628
                tag = codec_get_tag(ff_codec_movsubtitle_tags, track->enc->codec_id);
629
            }
630
        }
631
    }
632
    return tag;
633
}
634

    
635
/** Write uuid atom.
636
 * Needed to make file play in iPods running newest firmware
637
 * goes after avcC atom in moov.trak.mdia.minf.stbl.stsd.avc1
638
 */
639
static int mov_write_uuid_tag_ipod(ByteIOContext *pb)
640
{
641
    put_be32(pb, 28);
642
    put_tag(pb, "uuid");
643
    put_be32(pb, 0x6b6840f2);
644
    put_be32(pb, 0x5f244fc5);
645
    put_be32(pb, 0xba39a51b);
646
    put_be32(pb, 0xcf0323f3);
647
    put_be32(pb, 0x0);
648
    return 28;
649
}
650

    
651
static int mov_write_subtitle_tag(ByteIOContext *pb, MOVTrack *track)
652
{
653
    int64_t pos = url_ftell(pb);
654
    put_be32(pb, 0);    /* size */
655
    put_le32(pb, track->tag); // store it byteswapped
656
    put_be32(pb, 0);    /* Reserved */
657
    put_be16(pb, 0);    /* Reserved */
658
    put_be16(pb, 1);    /* Data-reference index */
659

    
660
    if (track->enc->extradata_size)
661
        put_buffer(pb, track->enc->extradata, track->enc->extradata_size);
662

    
663
    return updateSize(pb, pos);
664
}
665

    
666
static int mov_write_video_tag(ByteIOContext *pb, MOVTrack *track)
667
{
668
    int64_t pos = url_ftell(pb);
669
    char compressor_name[32];
670

    
671
    put_be32(pb, 0); /* size */
672
    put_le32(pb, track->tag); // store it byteswapped
673
    put_be32(pb, 0); /* Reserved */
674
    put_be16(pb, 0); /* Reserved */
675
    put_be16(pb, 1); /* Data-reference index */
676

    
677
    put_be16(pb, 0); /* Codec stream version */
678
    put_be16(pb, 0); /* Codec stream revision (=0) */
679
    if (track->mode == MODE_MOV) {
680
        put_tag(pb, "FFMP"); /* Vendor */
681
        if(track->enc->codec_id == CODEC_ID_RAWVIDEO) {
682
            put_be32(pb, 0); /* Temporal Quality */
683
            put_be32(pb, 0x400); /* Spatial Quality = lossless*/
684
        } else {
685
            put_be32(pb, 0x200); /* Temporal Quality = normal */
686
            put_be32(pb, 0x200); /* Spatial Quality = normal */
687
        }
688
    } else {
689
        put_be32(pb, 0); /* Reserved */
690
        put_be32(pb, 0); /* Reserved */
691
        put_be32(pb, 0); /* Reserved */
692
    }
693
    put_be16(pb, track->enc->width); /* Video width */
694
    put_be16(pb, track->enc->height); /* Video height */
695
    put_be32(pb, 0x00480000); /* Horizontal resolution 72dpi */
696
    put_be32(pb, 0x00480000); /* Vertical resolution 72dpi */
697
    put_be32(pb, 0); /* Data size (= 0) */
698
    put_be16(pb, 1); /* Frame count (= 1) */
699

    
700
    memset(compressor_name,0,32);
701
    /* FIXME not sure, ISO 14496-1 draft where it shall be set to 0 */
702
    if (track->mode == MODE_MOV && track->enc->codec && track->enc->codec->name)
703
        strncpy(compressor_name,track->enc->codec->name,31);
704
    put_byte(pb, strlen(compressor_name));
705
    put_buffer(pb, compressor_name, 31);
706

    
707
    if (track->mode == MODE_MOV && track->enc->bits_per_coded_sample)
708
        put_be16(pb, track->enc->bits_per_coded_sample);
709
    else
710
        put_be16(pb, 0x18); /* Reserved */
711
    put_be16(pb, 0xffff); /* Reserved */
712
    if(track->tag == MKTAG('m','p','4','v'))
713
        mov_write_esds_tag(pb, track);
714
    else if(track->enc->codec_id == CODEC_ID_H263)
715
        mov_write_d263_tag(pb);
716
    else if(track->enc->codec_id == CODEC_ID_SVQ3)
717
        mov_write_svq3_tag(pb);
718
    else if(track->enc->codec_id == CODEC_ID_DNXHD)
719
        mov_write_avid_tag(pb, track);
720
    else if(track->enc->codec_id == CODEC_ID_H264) {
721
        mov_write_avcc_tag(pb, track);
722
        if(track->mode == MODE_IPOD)
723
            mov_write_uuid_tag_ipod(pb);
724
    } else if(track->vosLen > 0)
725
        mov_write_glbl_tag(pb, track);
726

    
727
    return updateSize(pb, pos);
728
}
729

    
730
static int mov_write_stsd_tag(ByteIOContext *pb, MOVTrack *track)
731
{
732
    int64_t pos = url_ftell(pb);
733
    put_be32(pb, 0); /* size */
734
    put_tag(pb, "stsd");
735
    put_be32(pb, 0); /* version & flags */
736
    put_be32(pb, 1); /* entry count */
737
    if (track->enc->codec_type == CODEC_TYPE_VIDEO)
738
        mov_write_video_tag(pb, track);
739
    else if (track->enc->codec_type == CODEC_TYPE_AUDIO)
740
        mov_write_audio_tag(pb, track);
741
    else if (track->enc->codec_type == CODEC_TYPE_SUBTITLE)
742
        mov_write_subtitle_tag(pb, track);
743
    return updateSize(pb, pos);
744
}
745

    
746
static int mov_write_ctts_tag(ByteIOContext *pb, MOVTrack *track)
747
{
748
    MOVStts *ctts_entries;
749
    uint32_t entries = 0;
750
    uint32_t atom_size;
751
    int i;
752

    
753
    ctts_entries = av_malloc((track->entry + 1) * sizeof(*ctts_entries)); /* worst case */
754
    ctts_entries[0].count = 1;
755
    ctts_entries[0].duration = track->cluster[0].cts;
756
    for (i=1; i<track->entry; i++) {
757
        if (track->cluster[i].cts == ctts_entries[entries].duration) {
758
            ctts_entries[entries].count++; /* compress */
759
        } else {
760
            entries++;
761
            ctts_entries[entries].duration = track->cluster[i].cts;
762
            ctts_entries[entries].count = 1;
763
        }
764
    }
765
    entries++; /* last one */
766
    atom_size = 16 + (entries * 8);
767
    put_be32(pb, atom_size); /* size */
768
    put_tag(pb, "ctts");
769
    put_be32(pb, 0); /* version & flags */
770
    put_be32(pb, entries); /* entry count */
771
    for (i=0; i<entries; i++) {
772
        put_be32(pb, ctts_entries[i].count);
773
        put_be32(pb, ctts_entries[i].duration);
774
    }
775
    av_free(ctts_entries);
776
    return atom_size;
777
}
778

    
779
/* Time to sample atom */
780
static int mov_write_stts_tag(ByteIOContext *pb, MOVTrack *track)
781
{
782
    MOVStts *stts_entries;
783
    uint32_t entries = -1;
784
    uint32_t atom_size;
785
    int i;
786

    
787
    if (track->enc->codec_type == CODEC_TYPE_AUDIO && !track->audio_vbr) {
788
        stts_entries = av_malloc(sizeof(*stts_entries)); /* one entry */
789
        stts_entries[0].count = track->sampleCount;
790
        stts_entries[0].duration = 1;
791
        entries = 1;
792
    } else {
793
        stts_entries = av_malloc(track->entry * sizeof(*stts_entries)); /* worst case */
794
        for (i=0; i<track->entry; i++) {
795
            int64_t duration = i + 1 == track->entry ?
796
                track->trackDuration - track->cluster[i].dts + track->cluster[0].dts : /* readjusting */
797
                track->cluster[i+1].dts - track->cluster[i].dts;
798
            if (i && duration == stts_entries[entries].duration) {
799
                stts_entries[entries].count++; /* compress */
800
            } else {
801
                entries++;
802
                stts_entries[entries].duration = duration;
803
                stts_entries[entries].count = 1;
804
            }
805
        }
806
        entries++; /* last one */
807
    }
808
    atom_size = 16 + (entries * 8);
809
    put_be32(pb, atom_size); /* size */
810
    put_tag(pb, "stts");
811
    put_be32(pb, 0); /* version & flags */
812
    put_be32(pb, entries); /* entry count */
813
    for (i=0; i<entries; i++) {
814
        put_be32(pb, stts_entries[i].count);
815
        put_be32(pb, stts_entries[i].duration);
816
    }
817
    av_free(stts_entries);
818
    return atom_size;
819
}
820

    
821
static int mov_write_dref_tag(ByteIOContext *pb)
822
{
823
    put_be32(pb, 28); /* size */
824
    put_tag(pb, "dref");
825
    put_be32(pb, 0); /* version & flags */
826
    put_be32(pb, 1); /* entry count */
827

    
828
    put_be32(pb, 0xc); /* size */
829
    put_tag(pb, "url ");
830
    put_be32(pb, 1); /* version & flags */
831

    
832
    return 28;
833
}
834

    
835
static int mov_write_stbl_tag(ByteIOContext *pb, MOVTrack *track)
836
{
837
    int64_t pos = url_ftell(pb);
838
    put_be32(pb, 0); /* size */
839
    put_tag(pb, "stbl");
840
    mov_write_stsd_tag(pb, track);
841
    mov_write_stts_tag(pb, track);
842
    if (track->enc->codec_type == CODEC_TYPE_VIDEO &&
843
        track->hasKeyframes && track->hasKeyframes < track->entry)
844
        mov_write_stss_tag(pb, track);
845
    if (track->enc->codec_type == CODEC_TYPE_VIDEO &&
846
        track->hasBframes)
847
        mov_write_ctts_tag(pb, track);
848
    mov_write_stsc_tag(pb, track);
849
    mov_write_stsz_tag(pb, track);
850
    mov_write_stco_tag(pb, track);
851
    return updateSize(pb, pos);
852
}
853

    
854
static int mov_write_dinf_tag(ByteIOContext *pb)
855
{
856
    int64_t pos = url_ftell(pb);
857
    put_be32(pb, 0); /* size */
858
    put_tag(pb, "dinf");
859
    mov_write_dref_tag(pb);
860
    return updateSize(pb, pos);
861
}
862

    
863
static int mov_write_nmhd_tag(ByteIOContext *pb)
864
{
865
    put_be32(pb, 12);
866
    put_tag(pb, "nmhd");
867
    put_be32(pb, 0);
868
    return 12;
869
}
870

    
871
static int mov_write_gmhd_tag(ByteIOContext *pb)
872
{
873
    put_be32(pb, 0x20);   /* size */
874
    put_tag(pb, "gmhd");
875
    put_be32(pb, 0x18);   /* gmin size */
876
    put_tag(pb, "gmin");  /* generic media info */
877
    put_be32(pb, 0);      /* version & flags */
878
    put_be16(pb, 0x40);   /* graphics mode = */
879
    put_be16(pb, 0x8000); /* opColor (r?) */
880
    put_be16(pb, 0x8000); /* opColor (g?) */
881
    put_be16(pb, 0x8000); /* opColor (b?) */
882
    put_be16(pb, 0);      /* balance */
883
    put_be16(pb, 0);      /* reserved */
884
    return 0x20;
885
}
886

    
887
static int mov_write_smhd_tag(ByteIOContext *pb)
888
{
889
    put_be32(pb, 16); /* size */
890
    put_tag(pb, "smhd");
891
    put_be32(pb, 0); /* version & flags */
892
    put_be16(pb, 0); /* reserved (balance, normally = 0) */
893
    put_be16(pb, 0); /* reserved */
894
    return 16;
895
}
896

    
897
static int mov_write_vmhd_tag(ByteIOContext *pb)
898
{
899
    put_be32(pb, 0x14); /* size (always 0x14) */
900
    put_tag(pb, "vmhd");
901
    put_be32(pb, 0x01); /* version & flags */
902
    put_be64(pb, 0); /* reserved (graphics mode = copy) */
903
    return 0x14;
904
}
905

    
906
static int mov_write_hdlr_tag(ByteIOContext *pb, MOVTrack *track)
907
{
908
    const char *hdlr, *descr = NULL, *hdlr_type = NULL;
909
    int64_t pos = url_ftell(pb);
910

    
911
    if (!track) { /* no media --> data handler */
912
        hdlr = "dhlr";
913
        hdlr_type = "url ";
914
        descr = "DataHandler";
915
    } else {
916
        hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
917
        if (track->enc->codec_type == CODEC_TYPE_VIDEO) {
918
            hdlr_type = "vide";
919
            descr = "VideoHandler";
920
        } else if (track->enc->codec_type == CODEC_TYPE_AUDIO) {
921
            hdlr_type = "soun";
922
            descr = "SoundHandler";
923
        } else if (track->enc->codec_type == CODEC_TYPE_SUBTITLE) {
924
            if (track->mode == MODE_IPOD) hdlr_type = "sbtl";
925
            else                          hdlr_type = "text";
926
            descr = "SubtitleHandler";
927
        }
928
    }
929

    
930
    put_be32(pb, 0); /* size */
931
    put_tag(pb, "hdlr");
932
    put_be32(pb, 0); /* Version & flags */
933
    put_buffer(pb, hdlr, 4); /* handler */
934
    put_tag(pb, hdlr_type); /* handler type */
935
    put_be32(pb ,0); /* reserved */
936
    put_be32(pb ,0); /* reserved */
937
    put_be32(pb ,0); /* reserved */
938
    put_byte(pb, strlen(descr)); /* string counter */
939
    put_buffer(pb, descr, strlen(descr)); /* handler description */
940
    return updateSize(pb, pos);
941
}
942

    
943
static int mov_write_minf_tag(ByteIOContext *pb, MOVTrack *track)
944
{
945
    int64_t pos = url_ftell(pb);
946
    put_be32(pb, 0); /* size */
947
    put_tag(pb, "minf");
948
    if(track->enc->codec_type == CODEC_TYPE_VIDEO)
949
        mov_write_vmhd_tag(pb);
950
    else if (track->enc->codec_type == CODEC_TYPE_AUDIO)
951
        mov_write_smhd_tag(pb);
952
    else if (track->enc->codec_type == CODEC_TYPE_SUBTITLE) {
953
        if (track->mode == MODE_MOV) mov_write_gmhd_tag(pb);
954
        else                         mov_write_nmhd_tag(pb);
955
    }
956
    if (track->mode == MODE_MOV) /* FIXME: Why do it for MODE_MOV only ? */
957
        mov_write_hdlr_tag(pb, NULL);
958
    mov_write_dinf_tag(pb);
959
    mov_write_stbl_tag(pb, track);
960
    return updateSize(pb, pos);
961
}
962

    
963
static int mov_write_mdhd_tag(ByteIOContext *pb, MOVTrack *track)
964
{
965
    int version = track->trackDuration < INT32_MAX ? 0 : 1;
966

    
967
    (version == 1) ? put_be32(pb, 44) : put_be32(pb, 32); /* size */
968
    put_tag(pb, "mdhd");
969
    put_byte(pb, version);
970
    put_be24(pb, 0); /* flags */
971
    if (version == 1) {
972
        put_be64(pb, track->time);
973
        put_be64(pb, track->time);
974
    } else {
975
        put_be32(pb, track->time); /* creation time */
976
        put_be32(pb, track->time); /* modification time */
977
    }
978
    put_be32(pb, track->timescale); /* time scale (sample rate for audio) */
979
    (version == 1) ? put_be64(pb, track->trackDuration) : put_be32(pb, track->trackDuration); /* duration */
980
    put_be16(pb, track->language); /* language */
981
    put_be16(pb, 0); /* reserved (quality) */
982

    
983
    if(version!=0 && track->mode == MODE_MOV){
984
        av_log(NULL, AV_LOG_ERROR,
985
            "FATAL error, file duration too long for timebase, this file will not be\n"
986
            "playable with quicktime. Choose a different timebase or a different\n"
987
            "container format\n");
988
    }
989

    
990
    return 32;
991
}
992

    
993
static int mov_write_mdia_tag(ByteIOContext *pb, MOVTrack *track)
994
{
995
    int64_t pos = url_ftell(pb);
996
    put_be32(pb, 0); /* size */
997
    put_tag(pb, "mdia");
998
    mov_write_mdhd_tag(pb, track);
999
    mov_write_hdlr_tag(pb, track);
1000
    mov_write_minf_tag(pb, track);
1001
    return updateSize(pb, pos);
1002
}
1003

    
1004
static int mov_write_tkhd_tag(ByteIOContext *pb, MOVTrack *track, AVStream *st)
1005
{
1006
    int64_t duration = av_rescale_rnd(track->trackDuration, globalTimescale, track->timescale, AV_ROUND_UP);
1007
    int version = duration < INT32_MAX ? 0 : 1;
1008

    
1009
    (version == 1) ? put_be32(pb, 104) : put_be32(pb, 92); /* size */
1010
    put_tag(pb, "tkhd");
1011
    put_byte(pb, version);
1012
    put_be24(pb, 0xf); /* flags (track enabled) */
1013
    if (version == 1) {
1014
        put_be64(pb, track->time);
1015
        put_be64(pb, track->time);
1016
    } else {
1017
        put_be32(pb, track->time); /* creation time */
1018
        put_be32(pb, track->time); /* modification time */
1019
    }
1020
    put_be32(pb, track->trackID); /* track-id */
1021
    put_be32(pb, 0); /* reserved */
1022
    (version == 1) ? put_be64(pb, duration) : put_be32(pb, duration);
1023

    
1024
    put_be32(pb, 0); /* reserved */
1025
    put_be32(pb, 0); /* reserved */
1026
    put_be32(pb, 0x0); /* reserved (Layer & Alternate group) */
1027
    /* Volume, only for audio */
1028
    if(track->enc->codec_type == CODEC_TYPE_AUDIO)
1029
        put_be16(pb, 0x0100);
1030
    else
1031
        put_be16(pb, 0);
1032
    put_be16(pb, 0); /* reserved */
1033

    
1034
    /* Matrix structure */
1035
    put_be32(pb, 0x00010000); /* reserved */
1036
    put_be32(pb, 0x0); /* reserved */
1037
    put_be32(pb, 0x0); /* reserved */
1038
    put_be32(pb, 0x0); /* reserved */
1039
    put_be32(pb, 0x00010000); /* reserved */
1040
    put_be32(pb, 0x0); /* reserved */
1041
    put_be32(pb, 0x0); /* reserved */
1042
    put_be32(pb, 0x0); /* reserved */
1043
    put_be32(pb, 0x40000000); /* reserved */
1044

    
1045
    /* Track width and height, for visual only */
1046
    if(track->enc->codec_type == CODEC_TYPE_VIDEO ||
1047
       track->enc->codec_type == CODEC_TYPE_SUBTITLE) {
1048
        double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
1049
        if(!sample_aspect_ratio) sample_aspect_ratio = 1;
1050
        put_be32(pb, sample_aspect_ratio * track->enc->width*0x10000);
1051
        put_be32(pb, track->enc->height*0x10000);
1052
    }
1053
    else {
1054
        put_be32(pb, 0);
1055
        put_be32(pb, 0);
1056
    }
1057
    return 0x5c;
1058
}
1059

    
1060
// This box seems important for the psp playback ... without it the movie seems to hang
1061
static int mov_write_edts_tag(ByteIOContext *pb, MOVTrack *track)
1062
{
1063
    put_be32(pb, 0x24); /* size  */
1064
    put_tag(pb, "edts");
1065
    put_be32(pb, 0x1c); /* size  */
1066
    put_tag(pb, "elst");
1067
    put_be32(pb, 0x0);
1068
    put_be32(pb, 0x1);
1069

    
1070
    put_be32(pb, av_rescale_rnd(track->trackDuration, globalTimescale, track->timescale, AV_ROUND_UP)); /* duration   ... doesn't seem to effect psp */
1071

    
1072
    put_be32(pb, track->cluster[0].cts); /* first pts is cts since dts is 0 */
1073
    put_be32(pb, 0x00010000);
1074
    return 0x24;
1075
}
1076

    
1077
// goes at the end of each track!  ... Critical for PSP playback ("Incompatible data" without it)
1078
static int mov_write_uuid_tag_psp(ByteIOContext *pb, MOVTrack *mov)
1079
{
1080
    put_be32(pb, 0x34); /* size ... reports as 28 in mp4box! */
1081
    put_tag(pb, "uuid");
1082
    put_tag(pb, "USMT");
1083
    put_be32(pb, 0x21d24fce);
1084
    put_be32(pb, 0xbb88695c);
1085
    put_be32(pb, 0xfac9c740);
1086
    put_be32(pb, 0x1c);     // another size here!
1087
    put_tag(pb, "MTDT");
1088
    put_be32(pb, 0x00010012);
1089
    put_be32(pb, 0x0a);
1090
    put_be32(pb, 0x55c40000);
1091
    put_be32(pb, 0x1);
1092
    put_be32(pb, 0x0);
1093
    return 0x34;
1094
}
1095

    
1096
static int mov_write_trak_tag(ByteIOContext *pb, MOVTrack *track, AVStream *st)
1097
{
1098
    int64_t pos = url_ftell(pb);
1099
    put_be32(pb, 0); /* size */
1100
    put_tag(pb, "trak");
1101
    mov_write_tkhd_tag(pb, track, st);
1102
    if (track->mode == MODE_PSP || track->hasBframes)
1103
        mov_write_edts_tag(pb, track);  // PSP Movies require edts box
1104
    mov_write_mdia_tag(pb, track);
1105
    if (track->mode == MODE_PSP)
1106
        mov_write_uuid_tag_psp(pb,track);  // PSP Movies require this uuid box
1107
    return updateSize(pb, pos);
1108
}
1109

    
1110
#if 0
1111
/* TODO: Not sorted out, but not necessary either */
1112
static int mov_write_iods_tag(ByteIOContext *pb, MOVContext *mov)
1113
{
1114
    put_be32(pb, 0x15); /* size */
1115
    put_tag(pb, "iods");
1116
    put_be32(pb, 0);    /* version & flags */
1117
    put_be16(pb, 0x1007);
1118
    put_byte(pb, 0);
1119
    put_be16(pb, 0x4fff);
1120
    put_be16(pb, 0xfffe);
1121
    put_be16(pb, 0x01ff);
1122
    return 0x15;
1123
}
1124
#endif
1125

    
1126
static int mov_write_mvhd_tag(ByteIOContext *pb, MOVContext *mov)
1127
{
1128
    int maxTrackID = 1, i;
1129
    int64_t maxTrackLenTemp, maxTrackLen = 0;
1130
    int version;
1131

    
1132
    for (i=0; i<mov->nb_streams; i++) {
1133
        if(mov->tracks[i].entry > 0) {
1134
            maxTrackLenTemp = av_rescale_rnd(mov->tracks[i].trackDuration, globalTimescale, mov->tracks[i].timescale, AV_ROUND_UP);
1135
            if(maxTrackLen < maxTrackLenTemp)
1136
                maxTrackLen = maxTrackLenTemp;
1137
            if(maxTrackID < mov->tracks[i].trackID)
1138
                maxTrackID = mov->tracks[i].trackID;
1139
        }
1140
    }
1141

    
1142
    version = maxTrackLen < UINT32_MAX ? 0 : 1;
1143
    (version == 1) ? put_be32(pb, 120) : put_be32(pb, 108); /* size */
1144
    put_tag(pb, "mvhd");
1145
    put_byte(pb, version);
1146
    put_be24(pb, 0); /* flags */
1147
    if (version == 1) {
1148
        put_be64(pb, mov->time);
1149
        put_be64(pb, mov->time);
1150
    } else {
1151
        put_be32(pb, mov->time); /* creation time */
1152
        put_be32(pb, mov->time); /* modification time */
1153
    }
1154
    put_be32(pb, mov->timescale); /* timescale */
1155
    (version == 1) ? put_be64(pb, maxTrackLen) : put_be32(pb, maxTrackLen); /* duration of longest track */
1156

    
1157
    put_be32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */
1158
    put_be16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */
1159
    put_be16(pb, 0); /* reserved */
1160
    put_be32(pb, 0); /* reserved */
1161
    put_be32(pb, 0); /* reserved */
1162

    
1163
    /* Matrix structure */
1164
    put_be32(pb, 0x00010000); /* reserved */
1165
    put_be32(pb, 0x0); /* reserved */
1166
    put_be32(pb, 0x0); /* reserved */
1167
    put_be32(pb, 0x0); /* reserved */
1168
    put_be32(pb, 0x00010000); /* reserved */
1169
    put_be32(pb, 0x0); /* reserved */
1170
    put_be32(pb, 0x0); /* reserved */
1171
    put_be32(pb, 0x0); /* reserved */
1172
    put_be32(pb, 0x40000000); /* reserved */
1173

    
1174
    put_be32(pb, 0); /* reserved (preview time) */
1175
    put_be32(pb, 0); /* reserved (preview duration) */
1176
    put_be32(pb, 0); /* reserved (poster time) */
1177
    put_be32(pb, 0); /* reserved (selection time) */
1178
    put_be32(pb, 0); /* reserved (selection duration) */
1179
    put_be32(pb, 0); /* reserved (current time) */
1180
    put_be32(pb, maxTrackID+1); /* Next track id */
1181
    return 0x6c;
1182
}
1183

    
1184
static int mov_write_itunes_hdlr_tag(ByteIOContext *pb, MOVContext *mov,
1185
                                     AVFormatContext *s)
1186
{
1187
    int64_t pos = url_ftell(pb);
1188
    put_be32(pb, 0); /* size */
1189
    put_tag(pb, "hdlr");
1190
    put_be32(pb, 0);
1191
    put_be32(pb, 0);
1192
    put_tag(pb, "mdir");
1193
    put_tag(pb, "appl");
1194
    put_be32(pb, 0);
1195
    put_be32(pb, 0);
1196
    put_be16(pb, 0);
1197
    return updateSize(pb, pos);
1198
}
1199

    
1200
/* helper function to write a data tag with the specified string as data */
1201
static int mov_write_string_data_tag(ByteIOContext *pb, const char *data, int long_style)
1202
{
1203
    if(long_style){
1204
        int64_t pos = url_ftell(pb);
1205
        put_be32(pb, 0); /* size */
1206
        put_tag(pb, "data");
1207
        put_be32(pb, 1);
1208
        put_be32(pb, 0);
1209
        put_buffer(pb, data, strlen(data));
1210
        return updateSize(pb, pos);
1211
    }else{
1212
        put_be16(pb, strlen(data)); /* string length */
1213
        put_be16(pb, 0);
1214
        put_buffer(pb, data, strlen(data));
1215
        return strlen(data) + 4;
1216
    }
1217
}
1218

    
1219
static int mov_write_string_tag(ByteIOContext *pb, const char *name, const char *value, int long_style){
1220
    int size = 0;
1221
    if (value && value[0]) {
1222
        int64_t pos = url_ftell(pb);
1223
        put_be32(pb, 0); /* size */
1224
        put_tag(pb, name);
1225
        mov_write_string_data_tag(pb, value, long_style);
1226
        size= updateSize(pb, pos);
1227
    }
1228
    return size;
1229
}
1230

    
1231
/* iTunes year */
1232
static int mov_write_day_tag(ByteIOContext *pb, int year, int long_style)
1233
{
1234
    if(year){
1235
        char year_str[5];
1236
        snprintf(year_str, sizeof(year_str), "%04d", year);
1237
        return mov_write_string_tag(pb, "\251day", year_str, long_style);
1238
    }else
1239
        return 0;
1240
}
1241

    
1242
/* iTunes track number */
1243
static int mov_write_trkn_tag(ByteIOContext *pb, MOVContext *mov,
1244
                              AVFormatContext *s)
1245
{
1246
    int size = 0;
1247
    if (s->track) {
1248
        int64_t pos = url_ftell(pb);
1249
        put_be32(pb, 0); /* size */
1250
        put_tag(pb, "trkn");
1251
        {
1252
            int64_t pos = url_ftell(pb);
1253
            put_be32(pb, 0); /* size */
1254
            put_tag(pb, "data");
1255
            put_be32(pb, 0);        // 8 bytes empty
1256
            put_be32(pb, 0);
1257
            put_be16(pb, 0);        // empty
1258
            put_be16(pb, s->track); // track number
1259
            put_be16(pb, 0);        // total track number
1260
            put_be16(pb, 0);        // empty
1261
            updateSize(pb, pos);
1262
        }
1263
        size = updateSize(pb, pos);
1264
    }
1265
    return size;
1266
}
1267

    
1268
/* iTunes meta data list */
1269
static int mov_write_ilst_tag(ByteIOContext *pb, MOVContext *mov,
1270
                              AVFormatContext *s)
1271
{
1272
    int64_t pos = url_ftell(pb);
1273
    put_be32(pb, 0); /* size */
1274
    put_tag(pb, "ilst");
1275
    mov_write_string_tag(pb, "\251nam", s->title         , 1);
1276
    mov_write_string_tag(pb, "\251ART", s->author        , 1);
1277
    mov_write_string_tag(pb, "\251wrt", s->author        , 1);
1278
    mov_write_string_tag(pb, "\251alb", s->album         , 1);
1279
    mov_write_day_tag(pb, s->year ,1);
1280
    mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 1);
1281
    mov_write_string_tag(pb, "\251cmt", s->comment       , 1);
1282
    mov_write_string_tag(pb, "\251gen", s->genre         , 1);
1283
    mov_write_string_tag(pb, "\251cpy", s->copyright     , 1);
1284
    mov_write_trkn_tag(pb, mov, s);
1285
    return updateSize(pb, pos);
1286
}
1287

    
1288
/* iTunes meta data tag */
1289
static int mov_write_meta_tag(ByteIOContext *pb, MOVContext *mov,
1290
                              AVFormatContext *s)
1291
{
1292
    int size = 0;
1293

    
1294
    // only save meta tag if required
1295
    if (s->title[0] || s->author[0] || s->album[0] || s->year ||
1296
        s->comment[0] || s->genre[0] || s->track) {
1297
        int64_t pos = url_ftell(pb);
1298
        put_be32(pb, 0); /* size */
1299
        put_tag(pb, "meta");
1300
        put_be32(pb, 0);
1301
        mov_write_itunes_hdlr_tag(pb, mov, s);
1302
        mov_write_ilst_tag(pb, mov, s);
1303
        size = updateSize(pb, pos);
1304
    }
1305
    return size;
1306
}
1307

    
1308
static int utf8len(const uint8_t *b)
1309
{
1310
    int len=0;
1311
    int val;
1312
    while(*b){
1313
        GET_UTF8(val, *b++, return -1;)
1314
        len++;
1315
    }
1316
    return len;
1317
}
1318

    
1319
static int ascii_to_wc(ByteIOContext *pb, const uint8_t *b)
1320
{
1321
    int val;
1322
    while(*b){
1323
        GET_UTF8(val, *b++, return -1;)
1324
        put_be16(pb, val);
1325
    }
1326
    put_be16(pb, 0x00);
1327
    return 0;
1328
}
1329

    
1330
static uint16_t language_code(const char *str)
1331
{
1332
    return (((str[0]-0x60) & 0x1F) << 10) + (((str[1]-0x60) & 0x1F) << 5) + ((str[2]-0x60) & 0x1F);
1333
}
1334

    
1335
static int mov_write_3gp_udta_tag(ByteIOContext *pb, AVFormatContext *s,
1336
                                  const char *tag, const char *str)
1337
{
1338
    int64_t pos = url_ftell(pb);
1339
    if (!utf8len(str))
1340
        return 0;
1341
    put_be32(pb, 0);   /* size */
1342
    put_tag (pb, tag); /* type */
1343
    put_be32(pb, 0);   /* version + flags */
1344
    if (!strcmp(tag, "yrrc"))
1345
        put_be16(pb, s->year);
1346
    else {
1347
        put_be16(pb, language_code("eng")); /* language */
1348
        ascii_to_wc(pb, str);
1349
        if (!strcmp(tag, "albm") && s->year)
1350
            put_byte(pb, s->year);
1351
    }
1352
    return updateSize(pb, pos);
1353
}
1354

    
1355
static int mov_write_udta_tag(ByteIOContext *pb, MOVContext *mov,
1356
                              AVFormatContext *s)
1357
{
1358
    int i;
1359
    int bitexact = 0;
1360

    
1361
    for (i = 0; i < s->nb_streams; i++)
1362
        if (mov->tracks[i].enc->flags & CODEC_FLAG_BITEXACT) {
1363
            bitexact = 1;
1364
            break;
1365
        }
1366

    
1367
    if (!bitexact && (s->title[0] || s->author[0] || s->album[0] || s->year ||
1368
                      s->comment[0] || s->genre[0]  || s->track)) {
1369
        int64_t pos = url_ftell(pb);
1370

    
1371
        put_be32(pb, 0); /* size */
1372
        put_tag(pb, "udta");
1373

    
1374
        if (mov->mode & MODE_3GP) {
1375
            mov_write_3gp_udta_tag(pb, s, "titl", s->title);
1376
            mov_write_3gp_udta_tag(pb, s, "auth", s->author);
1377
            mov_write_3gp_udta_tag(pb, s, "gnre", s->genre);
1378
            mov_write_3gp_udta_tag(pb, s, "dscp", s->comment);
1379
            mov_write_3gp_udta_tag(pb, s, "albm", s->album);
1380
            mov_write_3gp_udta_tag(pb, s, "cprt", s->copyright);
1381
            mov_write_3gp_udta_tag(pb, s, "yrrc", "nil");
1382
        } else if (mov->mode == MODE_MOV) { // the title field breaks gtkpod with mp4 and my suspicion is that stuff is not valid in mp4
1383
            mov_write_string_tag(pb, "\251nam", s->title         , 0);
1384
            mov_write_string_tag(pb, "\251aut", s->author        , 0);
1385
            mov_write_string_tag(pb, "\251alb", s->album         , 0);
1386
            mov_write_day_tag(pb, s->year, 0);
1387
            mov_write_string_tag(pb, "\251enc", LIBAVFORMAT_IDENT, 0);
1388
            mov_write_string_tag(pb, "\251des", s->comment       , 0);
1389
            mov_write_string_tag(pb, "\251gen", s->genre         , 0);
1390
            mov_write_string_tag(pb, "\251cpy", s->copyright     , 0);
1391
        } else {
1392
            /* iTunes meta data */
1393
            mov_write_meta_tag(pb, mov, s);
1394
        }
1395
        return updateSize(pb, pos);
1396
    }
1397

    
1398
    return 0;
1399
}
1400

    
1401
static void mov_write_psp_udta_tag(ByteIOContext *pb,
1402
                                  const char *str, const char *lang, int type)
1403
{
1404
    int len = utf8len(str)+1;
1405
    if(len<=0)
1406
        return;
1407
    put_be16(pb, len*2+10);            /* size */
1408
    put_be32(pb, type);                /* type */
1409
    put_be16(pb, language_code(lang)); /* language */
1410
    put_be16(pb, 0x01);                /* ? */
1411
    ascii_to_wc(pb, str);
1412
}
1413

    
1414
static int mov_write_uuidusmt_tag(ByteIOContext *pb, AVFormatContext *s)
1415
{
1416
    int64_t pos, pos2;
1417

    
1418
    if (s->title[0]) {
1419
        pos = url_ftell(pb);
1420
        put_be32(pb, 0); /* size placeholder*/
1421
        put_tag(pb, "uuid");
1422
        put_tag(pb, "USMT");
1423
        put_be32(pb, 0x21d24fce); /* 96 bit UUID */
1424
        put_be32(pb, 0xbb88695c);
1425
        put_be32(pb, 0xfac9c740);
1426

    
1427
        pos2 = url_ftell(pb);
1428
        put_be32(pb, 0); /* size placeholder*/
1429
        put_tag(pb, "MTDT");
1430
        put_be16(pb, 4);
1431

    
1432
        // ?
1433
        put_be16(pb, 0x0C);                 /* size */
1434
        put_be32(pb, 0x0B);                 /* type */
1435
        put_be16(pb, language_code("und")); /* language */
1436
        put_be16(pb, 0x0);                  /* ? */
1437
        put_be16(pb, 0x021C);               /* data */
1438

    
1439
        mov_write_psp_udta_tag(pb, LIBAVCODEC_IDENT,      "eng", 0x04);
1440
        mov_write_psp_udta_tag(pb, s->title,              "eng", 0x01);
1441
//        snprintf(dt,32,"%04d/%02d/%02d %02d:%02d:%02d",t_st->tm_year+1900,t_st->tm_mon+1,t_st->tm_mday,t_st->tm_hour,t_st->tm_min,t_st->tm_sec);
1442
        mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03);
1443

    
1444
        updateSize(pb, pos2);
1445
        return updateSize(pb, pos);
1446
    }
1447

    
1448
    return 0;
1449
}
1450

    
1451
static int mov_write_moov_tag(ByteIOContext *pb, MOVContext *mov,
1452
                              AVFormatContext *s)
1453
{
1454
    int i;
1455
    int64_t pos = url_ftell(pb);
1456
    put_be32(pb, 0); /* size placeholder*/
1457
    put_tag(pb, "moov");
1458
    mov->timescale = globalTimescale;
1459

    
1460
    for (i=0; i<mov->nb_streams; i++) {
1461
        if(mov->tracks[i].entry <= 0) continue;
1462

    
1463
        mov->tracks[i].time = mov->time;
1464
        mov->tracks[i].trackID = i+1;
1465
    }
1466

    
1467
    mov_write_mvhd_tag(pb, mov);
1468
    //mov_write_iods_tag(pb, mov);
1469
    for (i=0; i<mov->nb_streams; i++) {
1470
        if(mov->tracks[i].entry > 0) {
1471
            mov_write_trak_tag(pb, &(mov->tracks[i]), s->streams[i]);
1472
        }
1473
    }
1474

    
1475
    if (mov->mode == MODE_PSP)
1476
        mov_write_uuidusmt_tag(pb, s);
1477
    else
1478
        mov_write_udta_tag(pb, mov, s);
1479

    
1480
    return updateSize(pb, pos);
1481
}
1482

    
1483
static int mov_write_mdat_tag(ByteIOContext *pb, MOVContext *mov)
1484
{
1485
    put_be32(pb, 8);    // placeholder for extended size field (64 bit)
1486
    put_tag(pb, mov->mode == MODE_MOV ? "wide" : "free");
1487

    
1488
    mov->mdat_pos = url_ftell(pb);
1489
    put_be32(pb, 0); /* size placeholder*/
1490
    put_tag(pb, "mdat");
1491
    return 0;
1492
}
1493

    
1494
/* TODO: This needs to be more general */
1495
static int mov_write_ftyp_tag(ByteIOContext *pb, AVFormatContext *s)
1496
{
1497
    MOVContext *mov = s->priv_data;
1498
    int64_t pos = url_ftell(pb);
1499
    int has_h264 = 0, has_video = 0;
1500
    int minor = 0x200;
1501
    int i;
1502

    
1503
    for (i = 0; i < s->nb_streams; i++) {
1504
        AVStream *st = s->streams[i];
1505
        if (st->codec->codec_type == CODEC_TYPE_VIDEO)
1506
            has_video = 1;
1507
        if (st->codec->codec_id == CODEC_ID_H264)
1508
            has_h264 = 1;
1509
    }
1510

    
1511
    put_be32(pb, 0); /* size */
1512
    put_tag(pb, "ftyp");
1513

    
1514
    if (mov->mode == MODE_3GP) {
1515
        put_tag(pb, has_h264 ? "3gp6"  : "3gp4");
1516
        minor =     has_h264 ?   0x100 :   0x200;
1517
    } else if (mov->mode & MODE_3G2) {
1518
        put_tag(pb, has_h264 ? "3g2b"  : "3g2a");
1519
        minor =     has_h264 ? 0x20000 : 0x10000;
1520
    }else if (mov->mode == MODE_PSP)
1521
        put_tag(pb, "MSNV");
1522
    else if (mov->mode == MODE_MP4)
1523
        put_tag(pb, "isom");
1524
    else if (mov->mode == MODE_IPOD)
1525
        put_tag(pb, has_video ? "M4V ":"M4A ");
1526
    else
1527
        put_tag(pb, "qt  ");
1528

    
1529
    put_be32(pb, minor);
1530

    
1531
    if(mov->mode == MODE_MOV)
1532
        put_tag(pb, "qt  ");
1533
    else{
1534
        put_tag(pb, "isom");
1535
        put_tag(pb, "iso2");
1536
        if(has_h264)
1537
            put_tag(pb, "avc1");
1538
    }
1539

    
1540
    if (mov->mode == MODE_3GP)
1541
        put_tag(pb, has_h264 ? "3gp6":"3gp4");
1542
    else if (mov->mode & MODE_3G2)
1543
        put_tag(pb, has_h264 ? "3g2b":"3g2a");
1544
    else if (mov->mode == MODE_PSP)
1545
        put_tag(pb, "MSNV");
1546
    else if (mov->mode == MODE_MP4)
1547
        put_tag(pb, "mp41");
1548
    return updateSize(pb, pos);
1549
}
1550

    
1551
static void mov_write_uuidprof_tag(ByteIOContext *pb, AVFormatContext *s)
1552
{
1553
    AVCodecContext *VideoCodec = s->streams[0]->codec;
1554
    AVCodecContext *AudioCodec = s->streams[1]->codec;
1555
    int AudioRate = AudioCodec->sample_rate;
1556
    int FrameRate = ((VideoCodec->time_base.den) * (0x10000))/ (VideoCodec->time_base.num);
1557
    int audio_kbitrate= AudioCodec->bit_rate / 1000;
1558
    int video_kbitrate= FFMIN(VideoCodec->bit_rate / 1000, 800 - audio_kbitrate);
1559

    
1560
    put_be32(pb, 0x94); /* size */
1561
    put_tag(pb, "uuid");
1562
    put_tag(pb, "PROF");
1563

    
1564
    put_be32(pb, 0x21d24fce); /* 96 bit UUID */
1565
    put_be32(pb, 0xbb88695c);
1566
    put_be32(pb, 0xfac9c740);
1567

    
1568
    put_be32(pb, 0x0);  /* ? */
1569
    put_be32(pb, 0x3);  /* 3 sections ? */
1570

    
1571
    put_be32(pb, 0x14); /* size */
1572
    put_tag(pb, "FPRF");
1573
    put_be32(pb, 0x0);  /* ? */
1574
    put_be32(pb, 0x0);  /* ? */
1575
    put_be32(pb, 0x0);  /* ? */
1576

    
1577
    put_be32(pb, 0x2c);  /* size */
1578
    put_tag(pb, "APRF");   /* audio */
1579
    put_be32(pb, 0x0);
1580
    put_be32(pb, 0x2);   /* TrackID */
1581
    put_tag(pb, "mp4a");
1582
    put_be32(pb, 0x20f);
1583
    put_be32(pb, 0x0);
1584
    put_be32(pb, audio_kbitrate);
1585
    put_be32(pb, audio_kbitrate);
1586
    put_be32(pb, AudioRate);
1587
    put_be32(pb, AudioCodec->channels);
1588

    
1589
    put_be32(pb, 0x34);  /* size */
1590
    put_tag(pb, "VPRF");   /* video */
1591
    put_be32(pb, 0x0);
1592
    put_be32(pb, 0x1);    /* TrackID */
1593
    if (VideoCodec->codec_id == CODEC_ID_H264) {
1594
        put_tag(pb, "avc1");
1595
        put_be16(pb, 0x014D);
1596
        put_be16(pb, 0x0015);
1597
    } else {
1598
        put_tag(pb, "mp4v");
1599
        put_be16(pb, 0x0000);
1600
        put_be16(pb, 0x0103);
1601
    }
1602
    put_be32(pb, 0x0);
1603
    put_be32(pb, video_kbitrate);
1604
    put_be32(pb, video_kbitrate);
1605
    put_be32(pb, FrameRate);
1606
    put_be32(pb, FrameRate);
1607
    put_be16(pb, VideoCodec->width);
1608
    put_be16(pb, VideoCodec->height);
1609
    put_be32(pb, 0x010001); /* ? */
1610
}
1611

    
1612
static int mov_write_header(AVFormatContext *s)
1613
{
1614
    ByteIOContext *pb = s->pb;
1615
    MOVContext *mov = s->priv_data;
1616
    int i;
1617

    
1618
    if (url_is_streamed(s->pb)) {
1619
        av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
1620
        return -1;
1621
    }
1622

    
1623
    /* Default mode == MP4 */
1624
    mov->mode = MODE_MP4;
1625

    
1626
    if (s->oformat != NULL) {
1627
        if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;
1628
        else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3GP|MODE_3G2;
1629
        else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;
1630
        else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;
1631
        else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD;
1632

    
1633
        mov_write_ftyp_tag(pb,s);
1634
        if (mov->mode == MODE_PSP) {
1635
            if (s->nb_streams != 2) {
1636
                av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
1637
                return -1;
1638
            }
1639
            mov_write_uuidprof_tag(pb,s);
1640
        }
1641
    }
1642

    
1643
    for(i=0; i<s->nb_streams; i++){
1644
        AVStream *st= s->streams[i];
1645
        MOVTrack *track= &mov->tracks[i];
1646

    
1647
        track->enc = st->codec;
1648
        track->language = ff_mov_iso639_to_lang(st->language, mov->mode != MODE_MOV);
1649
        track->mode = mov->mode;
1650
        track->tag = mov_find_codec_tag(s, track);
1651
        if (!track->tag) {
1652
            av_log(s, AV_LOG_ERROR, "track %d: could not find tag, "
1653
                   "codec not currently supported in container\n", i);
1654
            return -1;
1655
        }
1656
        if(st->codec->codec_type == CODEC_TYPE_VIDEO){
1657
            track->timescale = st->codec->time_base.den;
1658
            av_set_pts_info(st, 64, 1, st->codec->time_base.den);
1659
            if (track->mode == MODE_MOV && track->timescale > 100000)
1660
                av_log(s, AV_LOG_WARNING,
1661
                       "WARNING codec timebase is very high. If duration is too long,\n"
1662
                       "file may not be playable by quicktime. Specify a shorter timebase\n"
1663
                       "or choose different container.\n");
1664
        }else if(st->codec->codec_type == CODEC_TYPE_AUDIO){
1665
            track->timescale = st->codec->sample_rate;
1666
            av_set_pts_info(st, 64, 1, st->codec->sample_rate);
1667
            if(!st->codec->frame_size && !av_get_bits_per_sample(st->codec->codec_id)) {
1668
                av_log(s, AV_LOG_ERROR, "track %d: codec frame size is not set\n", i);
1669
                return -1;
1670
            }else if(st->codec->frame_size > 1){ /* assume compressed audio */
1671
                track->audio_vbr = 1;
1672
            }else{
1673
                st->codec->frame_size = 1;
1674
                track->sampleSize = (av_get_bits_per_sample(st->codec->codec_id) >> 3) * st->codec->channels;
1675
            }
1676
            if(track->mode != MODE_MOV &&
1677
               track->enc->codec_id == CODEC_ID_MP3 && track->enc->sample_rate < 16000){
1678
                av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not supported\n",
1679
                       i, track->enc->sample_rate);
1680
                return -1;
1681
            }
1682
        }else if(st->codec->codec_type == CODEC_TYPE_SUBTITLE){
1683
            track->timescale = st->codec->time_base.den;
1684
            av_set_pts_info(st, 64, 1, st->codec->time_base.den);
1685
        }
1686
    }
1687

    
1688
    mov_write_mdat_tag(pb, mov);
1689
    mov->time = s->timestamp + 0x7C25B080; //1970 based -> 1904 based
1690
    mov->nb_streams = s->nb_streams;
1691

    
1692
    put_flush_packet(pb);
1693

    
1694
    return 0;
1695
}
1696

    
1697
static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
1698
{
1699
    MOVContext *mov = s->priv_data;
1700
    ByteIOContext *pb = s->pb;
1701
    MOVTrack *trk = &mov->tracks[pkt->stream_index];
1702
    AVCodecContext *enc = trk->enc;
1703
    unsigned int samplesInChunk = 0;
1704
    int size= pkt->size;
1705

    
1706
    if (url_is_streamed(s->pb)) return 0; /* Can't handle that */
1707
    if (!size) return 0; /* Discard 0 sized packets */
1708

    
1709
    if (enc->codec_id == CODEC_ID_AMR_NB) {
1710
        /* We must find out how many AMR blocks there are in one packet */
1711
        static uint16_t packed_size[16] =
1712
            {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 0};
1713
        int len = 0;
1714

    
1715
        while (len < size && samplesInChunk < 100) {
1716
            len += packed_size[(pkt->data[len] >> 3) & 0x0F];
1717
            samplesInChunk++;
1718
        }
1719
        if(samplesInChunk > 1){
1720
            av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
1721
            return -1;
1722
        }
1723
    } else if (trk->sampleSize)
1724
        samplesInChunk = size/trk->sampleSize;
1725
    else
1726
        samplesInChunk = 1;
1727

    
1728
    /* copy extradata if it exists */
1729
    if (trk->vosLen == 0 && enc->extradata_size > 0) {
1730
        trk->vosLen = enc->extradata_size;
1731
        trk->vosData = av_malloc(trk->vosLen);
1732
        memcpy(trk->vosData, enc->extradata, trk->vosLen);
1733
    }
1734

    
1735
    if ((enc->codec_id == CODEC_ID_DNXHD ||
1736
                enc->codec_id == CODEC_ID_AC3) && !trk->vosLen) {
1737
        /* copy frame to create needed atoms */
1738
        trk->vosLen = size;
1739
        trk->vosData = av_malloc(size);
1740
        if (!trk->vosData)
1741
            return AVERROR(ENOMEM);
1742
        memcpy(trk->vosData, pkt->data, size);
1743
    }
1744

    
1745
    if (!(trk->entry % MOV_INDEX_CLUSTER_SIZE)) {
1746
        trk->cluster = av_realloc(trk->cluster, (trk->entry + MOV_INDEX_CLUSTER_SIZE) * sizeof(*trk->cluster));
1747
        if (!trk->cluster)
1748
            return -1;
1749
    }
1750

    
1751
    trk->cluster[trk->entry].pos = url_ftell(pb);
1752
    trk->cluster[trk->entry].samplesInChunk = samplesInChunk;
1753
    trk->cluster[trk->entry].size = size;
1754
    trk->cluster[trk->entry].entries = samplesInChunk;
1755
    trk->cluster[trk->entry].dts = pkt->dts;
1756
    trk->trackDuration = pkt->dts - trk->cluster[0].dts + pkt->duration;
1757

    
1758
    if (pkt->pts == AV_NOPTS_VALUE) {
1759
        av_log(s, AV_LOG_WARNING, "pts has no value\n");
1760
        pkt->pts = pkt->dts;
1761
    }
1762
    if (pkt->dts != pkt->pts)
1763
        trk->hasBframes = 1;
1764
    trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
1765
    trk->cluster[trk->entry].key_frame = !!(pkt->flags & PKT_FLAG_KEY);
1766
    if(trk->cluster[trk->entry].key_frame)
1767
        trk->hasKeyframes++;
1768
    trk->entry++;
1769
    trk->sampleCount += samplesInChunk;
1770
    mov->mdat_size += size;
1771

    
1772
    if (enc->codec_id == CODEC_ID_H264 && trk->vosLen > 0 && *(uint8_t *)trk->vosData != 1) {
1773
        /* from x264 or from bytestream h264 */
1774
        /* nal reformating needed */
1775
        ff_avc_parse_nal_units(pb, pkt->data, pkt->size);
1776
    } else {
1777
        put_buffer(pb, pkt->data, size);
1778
    }
1779

    
1780
    put_flush_packet(pb);
1781
    return 0;
1782
}
1783

    
1784
static int mov_write_trailer(AVFormatContext *s)
1785
{
1786
    MOVContext *mov = s->priv_data;
1787
    ByteIOContext *pb = s->pb;
1788
    int res = 0;
1789
    int i;
1790

    
1791
    int64_t moov_pos = url_ftell(pb);
1792

    
1793
    /* Write size of mdat tag */
1794
    if (mov->mdat_size+8 <= UINT32_MAX) {
1795
        url_fseek(pb, mov->mdat_pos, SEEK_SET);
1796
        put_be32(pb, mov->mdat_size+8);
1797
    } else {
1798
        /* overwrite 'wide' placeholder atom */
1799
        url_fseek(pb, mov->mdat_pos - 8, SEEK_SET);
1800
        put_be32(pb, 1); /* special value: real atom size will be 64 bit value after tag field */
1801
        put_tag(pb, "mdat");
1802
        put_be64(pb, mov->mdat_size+16);
1803
    }
1804
    url_fseek(pb, moov_pos, SEEK_SET);
1805

    
1806
    mov_write_moov_tag(pb, mov, s);
1807

    
1808
    for (i=0; i<mov->nb_streams; i++) {
1809
        av_freep(&mov->tracks[i].cluster);
1810

    
1811
        if(mov->tracks[i].vosLen) av_free(mov->tracks[i].vosData);
1812

    
1813
    }
1814

    
1815
    put_flush_packet(pb);
1816

    
1817
    return res;
1818
}
1819

    
1820
#if CONFIG_MOV_MUXER
1821
AVOutputFormat mov_muxer = {
1822
    "mov",
1823
    NULL_IF_CONFIG_SMALL("MOV format"),
1824
    NULL,
1825
    "mov",
1826
    sizeof(MOVContext),
1827
    CODEC_ID_AAC,
1828
    CODEC_ID_MPEG4,
1829
    mov_write_header,
1830
    mov_write_packet,
1831
    mov_write_trailer,
1832
    .flags = AVFMT_GLOBALHEADER,
1833
    .codec_tag = (const AVCodecTag* const []){codec_movvideo_tags, codec_movaudio_tags, 0},
1834
};
1835
#endif
1836
#if CONFIG_TGP_MUXER
1837
AVOutputFormat tgp_muxer = {
1838
    "3gp",
1839
    NULL_IF_CONFIG_SMALL("3GP format"),
1840
    NULL,
1841
    "3gp",
1842
    sizeof(MOVContext),
1843
    CODEC_ID_AMR_NB,
1844
    CODEC_ID_H263,
1845
    mov_write_header,
1846
    mov_write_packet,
1847
    mov_write_trailer,
1848
    .flags = AVFMT_GLOBALHEADER,
1849
    .codec_tag = (const AVCodecTag* const []){codec_3gp_tags, 0},
1850
};
1851
#endif
1852
#if CONFIG_MP4_MUXER
1853
AVOutputFormat mp4_muxer = {
1854
    "mp4",
1855
    NULL_IF_CONFIG_SMALL("MP4 format"),
1856
    "application/mp4",
1857
    "mp4",
1858
    sizeof(MOVContext),
1859
    CODEC_ID_AAC,
1860
    CODEC_ID_MPEG4,
1861
    mov_write_header,
1862
    mov_write_packet,
1863
    mov_write_trailer,
1864
    .flags = AVFMT_GLOBALHEADER,
1865
    .codec_tag = (const AVCodecTag* const []){ff_mp4_obj_type, 0},
1866
};
1867
#endif
1868
#if CONFIG_PSP_MUXER
1869
AVOutputFormat psp_muxer = {
1870
    "psp",
1871
    NULL_IF_CONFIG_SMALL("PSP MP4 format"),
1872
    NULL,
1873
    "mp4,psp",
1874
    sizeof(MOVContext),
1875
    CODEC_ID_AAC,
1876
    CODEC_ID_MPEG4,
1877
    mov_write_header,
1878
    mov_write_packet,
1879
    mov_write_trailer,
1880
    .flags = AVFMT_GLOBALHEADER,
1881
    .codec_tag = (const AVCodecTag* const []){ff_mp4_obj_type, 0},
1882
};
1883
#endif
1884
#if CONFIG_TG2_MUXER
1885
AVOutputFormat tg2_muxer = {
1886
    "3g2",
1887
    NULL_IF_CONFIG_SMALL("3GP2 format"),
1888
    NULL,
1889
    "3g2",
1890
    sizeof(MOVContext),
1891
    CODEC_ID_AMR_NB,
1892
    CODEC_ID_H263,
1893
    mov_write_header,
1894
    mov_write_packet,
1895
    mov_write_trailer,
1896
    .flags = AVFMT_GLOBALHEADER,
1897
    .codec_tag = (const AVCodecTag* const []){codec_3gp_tags, 0},
1898
};
1899
#endif
1900
#if CONFIG_IPOD_MUXER
1901
AVOutputFormat ipod_muxer = {
1902
    "ipod",
1903
    NULL_IF_CONFIG_SMALL("iPod H.264 MP4 format"),
1904
    "application/mp4",
1905
    "m4v,m4a",
1906
    sizeof(MOVContext),
1907
    CODEC_ID_AAC,
1908
    CODEC_ID_H264,
1909
    mov_write_header,
1910
    mov_write_packet,
1911
    mov_write_trailer,
1912
    .flags = AVFMT_GLOBALHEADER,
1913
    .codec_tag = (const AVCodecTag* const []){ff_mp4_obj_type, 0},
1914
};
1915
#endif