00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "avformat.h"
00025 #include "riff.h"
00026 #include "avio.h"
00027 #include "isom.h"
00028 #include "avc.h"
00029 #include "libavcodec/get_bits.h"
00030 #include "libavcodec/put_bits.h"
00031
00032 #undef NDEBUG
00033 #include <assert.h>
00034
00035 #define MOV_INDEX_CLUSTER_SIZE 16384
00036 #define MOV_TIMESCALE 1000
00037
00038 #define MODE_MP4 0x01
00039 #define MODE_MOV 0x02
00040 #define MODE_3GP 0x04
00041 #define MODE_PSP 0x08 // example working PSP command line:
00042
00043 #define MODE_3G2 0x10
00044 #define MODE_IPOD 0x20
00045
00046 typedef struct MOVIentry {
00047 unsigned int size;
00048 uint64_t pos;
00049 unsigned int samplesInChunk;
00050 unsigned int entries;
00051 int cts;
00052 int64_t dts;
00053 #define MOV_SYNC_SAMPLE 0x0001
00054 #define MOV_PARTIAL_SYNC_SAMPLE 0x0002
00055 uint32_t flags;
00056 } MOVIentry;
00057
00058 typedef struct MOVIndex {
00059 int mode;
00060 int entry;
00061 unsigned timescale;
00062 uint64_t time;
00063 int64_t trackDuration;
00064 long sampleCount;
00065 long sampleSize;
00066 int hasKeyframes;
00067 #define MOV_TRACK_CTTS 0x0001
00068 #define MOV_TRACK_STPS 0x0002
00069 uint32_t flags;
00070 int language;
00071 int trackID;
00072 int tag;
00073 AVCodecContext *enc;
00074
00075 int vosLen;
00076 uint8_t *vosData;
00077 MOVIentry *cluster;
00078 int audio_vbr;
00079 int height;
00080 } MOVTrack;
00081
00082 typedef struct MOVMuxContext {
00083 int mode;
00084 int64_t time;
00085 int nb_streams;
00086 int64_t mdat_pos;
00087 uint64_t mdat_size;
00088 MOVTrack *tracks;
00089 } MOVMuxContext;
00090
00091
00092 static int64_t updateSize(ByteIOContext *pb, int64_t pos)
00093 {
00094 int64_t curpos = url_ftell(pb);
00095 url_fseek(pb, pos, SEEK_SET);
00096 put_be32(pb, curpos - pos);
00097 url_fseek(pb, curpos, SEEK_SET);
00098
00099 return curpos - pos;
00100 }
00101
00102
00103 static int mov_write_stco_tag(ByteIOContext *pb, MOVTrack *track)
00104 {
00105 int i;
00106 int mode64 = 0;
00107 int64_t pos = url_ftell(pb);
00108 put_be32(pb, 0);
00109 if (pos > UINT32_MAX) {
00110 mode64 = 1;
00111 put_tag(pb, "co64");
00112 } else
00113 put_tag(pb, "stco");
00114 put_be32(pb, 0);
00115 put_be32(pb, track->entry);
00116 for (i=0; i<track->entry; i++) {
00117 if(mode64 == 1)
00118 put_be64(pb, track->cluster[i].pos);
00119 else
00120 put_be32(pb, track->cluster[i].pos);
00121 }
00122 return updateSize(pb, pos);
00123 }
00124
00125
00126 static int mov_write_stsz_tag(ByteIOContext *pb, MOVTrack *track)
00127 {
00128 int equalChunks = 1;
00129 int i, j, entries = 0, tst = -1, oldtst = -1;
00130
00131 int64_t pos = url_ftell(pb);
00132 put_be32(pb, 0);
00133 put_tag(pb, "stsz");
00134 put_be32(pb, 0);
00135
00136 for (i=0; i<track->entry; i++) {
00137 tst = track->cluster[i].size/track->cluster[i].entries;
00138 if(oldtst != -1 && tst != oldtst) {
00139 equalChunks = 0;
00140 }
00141 oldtst = tst;
00142 entries += track->cluster[i].entries;
00143 }
00144 if (equalChunks) {
00145 int sSize = track->cluster[0].size/track->cluster[0].entries;
00146 put_be32(pb, sSize);
00147 put_be32(pb, entries);
00148 }
00149 else {
00150 put_be32(pb, 0);
00151 put_be32(pb, entries);
00152 for (i=0; i<track->entry; i++) {
00153 for (j=0; j<track->cluster[i].entries; j++) {
00154 put_be32(pb, track->cluster[i].size /
00155 track->cluster[i].entries);
00156 }
00157 }
00158 }
00159 return updateSize(pb, pos);
00160 }
00161
00162
00163 static int mov_write_stsc_tag(ByteIOContext *pb, MOVTrack *track)
00164 {
00165 int index = 0, oldval = -1, i;
00166 int64_t entryPos, curpos;
00167
00168 int64_t pos = url_ftell(pb);
00169 put_be32(pb, 0);
00170 put_tag(pb, "stsc");
00171 put_be32(pb, 0);
00172 entryPos = url_ftell(pb);
00173 put_be32(pb, track->entry);
00174 for (i=0; i<track->entry; i++) {
00175 if(oldval != track->cluster[i].samplesInChunk)
00176 {
00177 put_be32(pb, i+1);
00178 put_be32(pb, track->cluster[i].samplesInChunk);
00179 put_be32(pb, 0x1);
00180 oldval = track->cluster[i].samplesInChunk;
00181 index++;
00182 }
00183 }
00184 curpos = url_ftell(pb);
00185 url_fseek(pb, entryPos, SEEK_SET);
00186 put_be32(pb, index);
00187 url_fseek(pb, curpos, SEEK_SET);
00188
00189 return updateSize(pb, pos);
00190 }
00191
00192
00193 static int mov_write_stss_tag(ByteIOContext *pb, MOVTrack *track, uint32_t flag)
00194 {
00195 int64_t curpos, entryPos;
00196 int i, index = 0;
00197 int64_t pos = url_ftell(pb);
00198 put_be32(pb, 0);
00199 put_tag(pb, flag == MOV_SYNC_SAMPLE ? "stss" : "stps");
00200 put_be32(pb, 0);
00201 entryPos = url_ftell(pb);
00202 put_be32(pb, track->entry);
00203 for (i=0; i<track->entry; i++) {
00204 if (track->cluster[i].flags & flag) {
00205 put_be32(pb, i+1);
00206 index++;
00207 }
00208 }
00209 curpos = url_ftell(pb);
00210 url_fseek(pb, entryPos, SEEK_SET);
00211 put_be32(pb, index);
00212 url_fseek(pb, curpos, SEEK_SET);
00213 return updateSize(pb, pos);
00214 }
00215
00216 static int mov_write_amr_tag(ByteIOContext *pb, MOVTrack *track)
00217 {
00218 put_be32(pb, 0x11);
00219 if (track->mode == MODE_MOV) put_tag(pb, "samr");
00220 else put_tag(pb, "damr");
00221 put_tag(pb, "FFMP");
00222 put_byte(pb, 0);
00223
00224 put_be16(pb, 0x81FF);
00225 put_byte(pb, 0x00);
00226 put_byte(pb, 0x01);
00227 return 0x11;
00228 }
00229
00230 static int mov_write_ac3_tag(ByteIOContext *pb, MOVTrack *track)
00231 {
00232 GetBitContext gbc;
00233 PutBitContext pbc;
00234 uint8_t buf[3];
00235 int fscod, bsid, bsmod, acmod, lfeon, frmsizecod;
00236
00237 if (track->vosLen < 7)
00238 return -1;
00239
00240 put_be32(pb, 11);
00241 put_tag(pb, "dac3");
00242
00243 init_get_bits(&gbc, track->vosData+4, track->vosLen-4);
00244 fscod = get_bits(&gbc, 2);
00245 frmsizecod = get_bits(&gbc, 6);
00246 bsid = get_bits(&gbc, 5);
00247 bsmod = get_bits(&gbc, 3);
00248 acmod = get_bits(&gbc, 3);
00249 if (acmod == 2) {
00250 skip_bits(&gbc, 2);
00251 } else {
00252 if ((acmod & 1) && acmod != 1)
00253 skip_bits(&gbc, 2);
00254 if (acmod & 4)
00255 skip_bits(&gbc, 2);
00256 }
00257 lfeon = get_bits1(&gbc);
00258
00259 init_put_bits(&pbc, buf, sizeof(buf));
00260 put_bits(&pbc, 2, fscod);
00261 put_bits(&pbc, 5, bsid);
00262 put_bits(&pbc, 3, bsmod);
00263 put_bits(&pbc, 3, acmod);
00264 put_bits(&pbc, 1, lfeon);
00265 put_bits(&pbc, 5, frmsizecod>>1);
00266 put_bits(&pbc, 5, 0);
00267
00268 flush_put_bits(&pbc);
00269 put_buffer(pb, buf, sizeof(buf));
00270
00271 return 11;
00272 }
00273
00278 static int mov_write_extradata_tag(ByteIOContext *pb, MOVTrack *track)
00279 {
00280 put_buffer(pb, track->enc->extradata, track->enc->extradata_size);
00281 return track->enc->extradata_size;
00282 }
00283
00284 static int mov_write_enda_tag(ByteIOContext *pb)
00285 {
00286 put_be32(pb, 10);
00287 put_tag(pb, "enda");
00288 put_be16(pb, 1);
00289 return 10;
00290 }
00291
00292 static unsigned int descrLength(unsigned int len)
00293 {
00294 int i;
00295 for(i=1; len>>(7*i); i++);
00296 return len + 1 + i;
00297 }
00298
00299 static void putDescr(ByteIOContext *pb, int tag, unsigned int size)
00300 {
00301 int i= descrLength(size) - size - 2;
00302 put_byte(pb, tag);
00303 for(; i>0; i--)
00304 put_byte(pb, (size>>(7*i)) | 0x80);
00305 put_byte(pb, size & 0x7F);
00306 }
00307
00308 static int mov_write_esds_tag(ByteIOContext *pb, MOVTrack *track)
00309 {
00310 int64_t pos = url_ftell(pb);
00311 int decoderSpecificInfoLen = track->vosLen ? descrLength(track->vosLen):0;
00312
00313 put_be32(pb, 0);
00314 put_tag(pb, "esds");
00315 put_be32(pb, 0);
00316
00317
00318 putDescr(pb, 0x03, 3 + descrLength(13 + decoderSpecificInfoLen) +
00319 descrLength(1));
00320 put_be16(pb, track->trackID);
00321 put_byte(pb, 0x00);
00322
00323
00324 putDescr(pb, 0x04, 13 + decoderSpecificInfoLen);
00325
00326
00327 if ((track->enc->codec_id == CODEC_ID_MP2 ||
00328 track->enc->codec_id == CODEC_ID_MP3) &&
00329 track->enc->sample_rate > 24000)
00330 put_byte(pb, 0x6B);
00331 else
00332 put_byte(pb, ff_codec_get_tag(ff_mp4_obj_type, track->enc->codec_id));
00333
00334
00335
00336 if(track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
00337 put_byte(pb, 0x15);
00338 else
00339 put_byte(pb, 0x11);
00340
00341 put_byte(pb, track->enc->rc_buffer_size>>(3+16));
00342 put_be16(pb, (track->enc->rc_buffer_size>>3)&0xFFFF);
00343
00344 put_be32(pb, FFMAX(track->enc->bit_rate, track->enc->rc_max_rate));
00345 if(track->enc->rc_max_rate != track->enc->rc_min_rate || track->enc->rc_min_rate==0)
00346 put_be32(pb, 0);
00347 else
00348 put_be32(pb, track->enc->rc_max_rate);
00349
00350 if (track->vosLen) {
00351
00352 putDescr(pb, 0x05, track->vosLen);
00353 put_buffer(pb, track->vosData, track->vosLen);
00354 }
00355
00356
00357 putDescr(pb, 0x06, 1);
00358 put_byte(pb, 0x02);
00359 return updateSize(pb, pos);
00360 }
00361
00362 static int mov_pcm_le_gt16(enum CodecID codec_id)
00363 {
00364 return codec_id == CODEC_ID_PCM_S24LE ||
00365 codec_id == CODEC_ID_PCM_S32LE ||
00366 codec_id == CODEC_ID_PCM_F32LE ||
00367 codec_id == CODEC_ID_PCM_F64LE;
00368 }
00369
00370 static int mov_write_wave_tag(ByteIOContext *pb, MOVTrack *track)
00371 {
00372 int64_t pos = url_ftell(pb);
00373
00374 put_be32(pb, 0);
00375 put_tag(pb, "wave");
00376
00377 put_be32(pb, 12);
00378 put_tag(pb, "frma");
00379 put_le32(pb, track->tag);
00380
00381 if (track->enc->codec_id == CODEC_ID_AAC) {
00382
00383 put_be32(pb, 12);
00384 put_tag(pb, "mp4a");
00385 put_be32(pb, 0);
00386 mov_write_esds_tag(pb, track);
00387 } else if (mov_pcm_le_gt16(track->enc->codec_id)) {
00388 mov_write_enda_tag(pb);
00389 } else if (track->enc->codec_id == CODEC_ID_AMR_NB) {
00390 mov_write_amr_tag(pb, track);
00391 } else if (track->enc->codec_id == CODEC_ID_AC3) {
00392 mov_write_ac3_tag(pb, track);
00393 } else if (track->enc->codec_id == CODEC_ID_ALAC) {
00394 mov_write_extradata_tag(pb, track);
00395 }
00396
00397 put_be32(pb, 8);
00398 put_be32(pb, 0);
00399
00400 return updateSize(pb, pos);
00401 }
00402
00403 static int mov_write_glbl_tag(ByteIOContext *pb, MOVTrack *track)
00404 {
00405 put_be32(pb, track->vosLen+8);
00406 put_tag(pb, "glbl");
00407 put_buffer(pb, track->vosData, track->vosLen);
00408 return 8+track->vosLen;
00409 }
00410
00415 static int mov_get_lpcm_flags(enum CodecID codec_id)
00416 {
00417 switch (codec_id) {
00418 case CODEC_ID_PCM_F32BE:
00419 case CODEC_ID_PCM_F64BE:
00420 return 11;
00421 case CODEC_ID_PCM_F32LE:
00422 case CODEC_ID_PCM_F64LE:
00423 return 9;
00424 case CODEC_ID_PCM_U8:
00425 return 10;
00426 case CODEC_ID_PCM_S16BE:
00427 case CODEC_ID_PCM_S24BE:
00428 case CODEC_ID_PCM_S32BE:
00429 return 14;
00430 case CODEC_ID_PCM_S8:
00431 case CODEC_ID_PCM_S16LE:
00432 case CODEC_ID_PCM_S24LE:
00433 case CODEC_ID_PCM_S32LE:
00434 return 12;
00435 default:
00436 return 0;
00437 }
00438 }
00439
00440 static int mov_write_audio_tag(ByteIOContext *pb, MOVTrack *track)
00441 {
00442 int64_t pos = url_ftell(pb);
00443 int version = 0;
00444 uint32_t tag = track->tag;
00445
00446 if (track->mode == MODE_MOV) {
00447 if (track->timescale > UINT16_MAX) {
00448 if (mov_get_lpcm_flags(track->enc->codec_id))
00449 tag = AV_RL32("lpcm");
00450 version = 2;
00451 } else if (track->audio_vbr || mov_pcm_le_gt16(track->enc->codec_id)) {
00452 version = 1;
00453 }
00454 }
00455
00456 put_be32(pb, 0);
00457 put_le32(pb, tag);
00458 put_be32(pb, 0);
00459 put_be16(pb, 0);
00460 put_be16(pb, 1);
00461
00462
00463 put_be16(pb, version);
00464 put_be16(pb, 0);
00465 put_be32(pb, 0);
00466
00467 if (version == 2) {
00468 put_be16(pb, 3);
00469 put_be16(pb, 16);
00470 put_be16(pb, 0xfffe);
00471 put_be16(pb, 0);
00472 put_be32(pb, 0x00010000);
00473 put_be32(pb, 72);
00474 put_be64(pb, av_dbl2int(track->timescale));
00475 put_be32(pb, track->enc->channels);
00476 put_be32(pb, 0x7F000000);
00477 put_be32(pb, av_get_bits_per_sample(track->enc->codec_id));
00478 put_be32(pb, mov_get_lpcm_flags(track->enc->codec_id));
00479 put_be32(pb, track->sampleSize);
00480 put_be32(pb, track->enc->frame_size);
00481 } else {
00482 if (track->mode == MODE_MOV) {
00483 put_be16(pb, track->enc->channels);
00484 if (track->enc->codec_id == CODEC_ID_PCM_U8 ||
00485 track->enc->codec_id == CODEC_ID_PCM_S8)
00486 put_be16(pb, 8);
00487 else
00488 put_be16(pb, 16);
00489 put_be16(pb, track->audio_vbr ? -2 : 0);
00490 } else {
00491 put_be16(pb, 2);
00492 put_be16(pb, 16);
00493 put_be16(pb, 0);
00494 }
00495
00496 put_be16(pb, 0);
00497 put_be16(pb, track->timescale);
00498 put_be16(pb, 0);
00499 }
00500
00501 if(version == 1) {
00502 put_be32(pb, track->enc->frame_size);
00503 put_be32(pb, track->sampleSize / track->enc->channels);
00504 put_be32(pb, track->sampleSize);
00505 put_be32(pb, 2);
00506 }
00507
00508 if(track->mode == MODE_MOV &&
00509 (track->enc->codec_id == CODEC_ID_AAC ||
00510 track->enc->codec_id == CODEC_ID_AC3 ||
00511 track->enc->codec_id == CODEC_ID_AMR_NB ||
00512 track->enc->codec_id == CODEC_ID_ALAC ||
00513 mov_pcm_le_gt16(track->enc->codec_id)))
00514 mov_write_wave_tag(pb, track);
00515 else if(track->tag == MKTAG('m','p','4','a'))
00516 mov_write_esds_tag(pb, track);
00517 else if(track->enc->codec_id == CODEC_ID_AMR_NB)
00518 mov_write_amr_tag(pb, track);
00519 else if(track->enc->codec_id == CODEC_ID_AC3)
00520 mov_write_ac3_tag(pb, track);
00521 else if(track->enc->codec_id == CODEC_ID_ALAC)
00522 mov_write_extradata_tag(pb, track);
00523 else if(track->vosLen > 0)
00524 mov_write_glbl_tag(pb, track);
00525
00526 return updateSize(pb, pos);
00527 }
00528
00529 static int mov_write_d263_tag(ByteIOContext *pb)
00530 {
00531 put_be32(pb, 0xf);
00532 put_tag(pb, "d263");
00533 put_tag(pb, "FFMP");
00534 put_byte(pb, 0);
00535
00536 put_byte(pb, 0xa);
00537 put_byte(pb, 0);
00538 return 0xf;
00539 }
00540
00541
00542 static int mov_write_svq3_tag(ByteIOContext *pb)
00543 {
00544 put_be32(pb, 0x15);
00545 put_tag(pb, "SMI ");
00546 put_tag(pb, "SEQH");
00547 put_be32(pb, 0x5);
00548 put_be32(pb, 0xe2c0211d);
00549 put_be32(pb, 0xc0000000);
00550 put_byte(pb, 0);
00551 return 0x15;
00552 }
00553
00554 static int mov_write_avcc_tag(ByteIOContext *pb, MOVTrack *track)
00555 {
00556 int64_t pos = url_ftell(pb);
00557
00558 put_be32(pb, 0);
00559 put_tag(pb, "avcC");
00560 ff_isom_write_avcc(pb, track->vosData, track->vosLen);
00561 return updateSize(pb, pos);
00562 }
00563
00564
00565 static int mov_write_avid_tag(ByteIOContext *pb, MOVTrack *track)
00566 {
00567 int i;
00568 put_be32(pb, 24);
00569 put_tag(pb, "ACLR");
00570 put_tag(pb, "ACLR");
00571 put_tag(pb, "0001");
00572 put_be32(pb, 1);
00573 put_be32(pb, 0);
00574
00575 put_be32(pb, 24);
00576 put_tag(pb, "APRG");
00577 put_tag(pb, "APRG");
00578 put_tag(pb, "0001");
00579 put_be32(pb, 1);
00580 put_be32(pb, 0);
00581
00582 put_be32(pb, 120);
00583 put_tag(pb, "ARES");
00584 put_tag(pb, "ARES");
00585 put_tag(pb, "0001");
00586 put_be32(pb, AV_RB32(track->vosData + 0x28));
00587 put_be32(pb, track->enc->width);
00588
00589 if (track->vosData[5] & 2) {
00590 put_be32(pb, track->enc->height/2);
00591 put_be32(pb, 2);
00592 put_be32(pb, 0);
00593 put_be32(pb, 4);
00594 } else {
00595 put_be32(pb, track->enc->height);
00596 put_be32(pb, 1);
00597 put_be32(pb, 0);
00598 if (track->enc->height == 1080)
00599 put_be32(pb, 5);
00600 else
00601 put_be32(pb, 6);
00602 }
00603
00604 for (i = 0; i < 10; i++)
00605 put_be64(pb, 0);
00606
00607
00608 put_be32(pb, 0);
00609 return 0;
00610 }
00611
00612 static int mp4_get_codec_tag(AVFormatContext *s, MOVTrack *track)
00613 {
00614 int tag = track->enc->codec_tag;
00615
00616 if (!ff_codec_get_tag(ff_mp4_obj_type, track->enc->codec_id))
00617 return 0;
00618
00619 if (track->enc->codec_id == CODEC_ID_H264) tag = MKTAG('a','v','c','1');
00620 else if (track->enc->codec_id == CODEC_ID_AC3) tag = MKTAG('a','c','-','3');
00621 else if (track->enc->codec_id == CODEC_ID_DIRAC) tag = MKTAG('d','r','a','c');
00622 else if (track->enc->codec_id == CODEC_ID_MOV_TEXT) tag = MKTAG('t','x','3','g');
00623 else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) tag = MKTAG('m','p','4','v');
00624 else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) tag = MKTAG('m','p','4','a');
00625
00626 return tag;
00627 }
00628
00629 static const AVCodecTag codec_ipod_tags[] = {
00630 { CODEC_ID_H264, MKTAG('a','v','c','1') },
00631 { CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
00632 { CODEC_ID_AAC, MKTAG('m','p','4','a') },
00633 { CODEC_ID_ALAC, MKTAG('a','l','a','c') },
00634 { CODEC_ID_AC3, MKTAG('a','c','-','3') },
00635 { CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
00636 { CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') },
00637 { CODEC_ID_NONE, 0 },
00638 };
00639
00640 static int ipod_get_codec_tag(AVFormatContext *s, MOVTrack *track)
00641 {
00642 int tag = track->enc->codec_tag;
00643
00644
00645 if (!(track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE &&
00646 (tag == MKTAG('t','x','3','g') ||
00647 tag == MKTAG('t','e','x','t'))))
00648 tag = ff_codec_get_tag(codec_ipod_tags, track->enc->codec_id);
00649
00650 if (!av_match_ext(s->filename, "m4a") && !av_match_ext(s->filename, "m4v"))
00651 av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v "
00652 "Quicktime/Ipod might not play the file\n");
00653
00654 return tag;
00655 }
00656
00657 static int mov_get_dv_codec_tag(AVFormatContext *s, MOVTrack *track)
00658 {
00659 int tag;
00660
00661 if (track->enc->height == 480)
00662 if (track->enc->pix_fmt == PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n');
00663 else tag = MKTAG('d','v','c',' ');
00664 else if (track->enc->pix_fmt == PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p');
00665 else if (track->enc->pix_fmt == PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
00666 else tag = MKTAG('d','v','p','p');
00667
00668 return tag;
00669 }
00670
00671 static const struct {
00672 enum PixelFormat pix_fmt;
00673 uint32_t tag;
00674 unsigned bps;
00675 } mov_pix_fmt_tags[] = {
00676 { PIX_FMT_YUYV422, MKTAG('y','u','v','s'), 0 },
00677 { PIX_FMT_UYVY422, MKTAG('2','v','u','y'), 0 },
00678 { PIX_FMT_BGR555, MKTAG('r','a','w',' '), 16 },
00679 { PIX_FMT_RGB555LE,MKTAG('L','5','5','5'), 16 },
00680 { PIX_FMT_RGB565LE,MKTAG('L','5','6','5'), 16 },
00681 { PIX_FMT_RGB565BE,MKTAG('B','5','6','5'), 16 },
00682 { PIX_FMT_RGB24, MKTAG('r','a','w',' '), 24 },
00683 { PIX_FMT_BGR24, MKTAG('2','4','B','G'), 24 },
00684 { PIX_FMT_ARGB, MKTAG('r','a','w',' '), 32 },
00685 { PIX_FMT_BGRA, MKTAG('B','G','R','A'), 32 },
00686 { PIX_FMT_RGBA, MKTAG('R','G','B','A'), 32 },
00687 };
00688
00689 static int mov_get_rawvideo_codec_tag(AVFormatContext *s, MOVTrack *track)
00690 {
00691 int tag = track->enc->codec_tag;
00692 int i;
00693
00694 for (i = 0; i < FF_ARRAY_ELEMS(mov_pix_fmt_tags); i++) {
00695 if (track->enc->pix_fmt == mov_pix_fmt_tags[i].pix_fmt) {
00696 tag = mov_pix_fmt_tags[i].tag;
00697 track->enc->bits_per_coded_sample = mov_pix_fmt_tags[i].bps;
00698 break;
00699 }
00700 }
00701
00702 return tag;
00703 }
00704
00705 static int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
00706 {
00707 int tag = track->enc->codec_tag;
00708
00709 if (!tag || (track->enc->strict_std_compliance >= FF_COMPLIANCE_NORMAL &&
00710 (tag == MKTAG('d','v','c','p') ||
00711 track->enc->codec_id == CODEC_ID_RAWVIDEO ||
00712 av_get_bits_per_sample(track->enc->codec_id)))) {
00713 if (track->enc->codec_id == CODEC_ID_DVVIDEO)
00714 tag = mov_get_dv_codec_tag(s, track);
00715 else if (track->enc->codec_id == CODEC_ID_RAWVIDEO)
00716 tag = mov_get_rawvideo_codec_tag(s, track);
00717 else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
00718 tag = ff_codec_get_tag(codec_movvideo_tags, track->enc->codec_id);
00719 if (!tag) {
00720 tag = ff_codec_get_tag(ff_codec_bmp_tags, track->enc->codec_id);
00721 if (tag)
00722 av_log(s, AV_LOG_INFO, "Warning, using MS style video codec tag, "
00723 "the file may be unplayable!\n");
00724 }
00725 } else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) {
00726 tag = ff_codec_get_tag(codec_movaudio_tags, track->enc->codec_id);
00727 if (!tag) {
00728 int ms_tag = ff_codec_get_tag(ff_codec_wav_tags, track->enc->codec_id);
00729 if (ms_tag) {
00730 tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));
00731 av_log(s, AV_LOG_INFO, "Warning, using MS style audio codec tag, "
00732 "the file may be unplayable!\n");
00733 }
00734 }
00735 } else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)
00736 tag = ff_codec_get_tag(ff_codec_movsubtitle_tags, track->enc->codec_id);
00737 }
00738
00739 return tag;
00740 }
00741
00742 static const AVCodecTag codec_3gp_tags[] = {
00743 { CODEC_ID_H263, MKTAG('s','2','6','3') },
00744 { CODEC_ID_H264, MKTAG('a','v','c','1') },
00745 { CODEC_ID_MPEG4, MKTAG('m','p','4','v') },
00746 { CODEC_ID_AAC, MKTAG('m','p','4','a') },
00747 { CODEC_ID_AMR_NB, MKTAG('s','a','m','r') },
00748 { CODEC_ID_AMR_WB, MKTAG('s','a','w','b') },
00749 { CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
00750 { CODEC_ID_NONE, 0 },
00751 };
00752
00753 static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
00754 {
00755 int tag = track->enc->codec_tag;
00756
00757 if (track->mode == MODE_MP4 || track->mode == MODE_PSP)
00758 tag = mp4_get_codec_tag(s, track);
00759 else if (track->mode == MODE_IPOD)
00760 tag = ipod_get_codec_tag(s, track);
00761 else if (track->mode & MODE_3GP)
00762 tag = ff_codec_get_tag(codec_3gp_tags, track->enc->codec_id);
00763 else
00764 tag = mov_get_codec_tag(s, track);
00765
00766 return tag;
00767 }
00768
00773 static int mov_write_uuid_tag_ipod(ByteIOContext *pb)
00774 {
00775 put_be32(pb, 28);
00776 put_tag(pb, "uuid");
00777 put_be32(pb, 0x6b6840f2);
00778 put_be32(pb, 0x5f244fc5);
00779 put_be32(pb, 0xba39a51b);
00780 put_be32(pb, 0xcf0323f3);
00781 put_be32(pb, 0x0);
00782 return 28;
00783 }
00784
00785 static int mov_write_subtitle_tag(ByteIOContext *pb, MOVTrack *track)
00786 {
00787 int64_t pos = url_ftell(pb);
00788 put_be32(pb, 0);
00789 put_le32(pb, track->tag);
00790 put_be32(pb, 0);
00791 put_be16(pb, 0);
00792 put_be16(pb, 1);
00793
00794 if (track->enc->extradata_size)
00795 put_buffer(pb, track->enc->extradata, track->enc->extradata_size);
00796
00797 return updateSize(pb, pos);
00798 }
00799
00800 static int mov_write_video_tag(ByteIOContext *pb, MOVTrack *track)
00801 {
00802 int64_t pos = url_ftell(pb);
00803 char compressor_name[32];
00804
00805 put_be32(pb, 0);
00806 put_le32(pb, track->tag);
00807 put_be32(pb, 0);
00808 put_be16(pb, 0);
00809 put_be16(pb, 1);
00810
00811 put_be16(pb, 0);
00812 put_be16(pb, 0);
00813 if (track->mode == MODE_MOV) {
00814 put_tag(pb, "FFMP");
00815 if(track->enc->codec_id == CODEC_ID_RAWVIDEO) {
00816 put_be32(pb, 0);
00817 put_be32(pb, 0x400);
00818 } else {
00819 put_be32(pb, 0x200);
00820 put_be32(pb, 0x200);
00821 }
00822 } else {
00823 put_be32(pb, 0);
00824 put_be32(pb, 0);
00825 put_be32(pb, 0);
00826 }
00827 put_be16(pb, track->enc->width);
00828 put_be16(pb, track->height);
00829 put_be32(pb, 0x00480000);
00830 put_be32(pb, 0x00480000);
00831 put_be32(pb, 0);
00832 put_be16(pb, 1);
00833
00834 memset(compressor_name,0,32);
00835
00836 if (track->mode == MODE_MOV && track->enc->codec && track->enc->codec->name)
00837 strncpy(compressor_name,track->enc->codec->name,31);
00838 put_byte(pb, strlen(compressor_name));
00839 put_buffer(pb, compressor_name, 31);
00840
00841 if (track->mode == MODE_MOV && track->enc->bits_per_coded_sample)
00842 put_be16(pb, track->enc->bits_per_coded_sample);
00843 else
00844 put_be16(pb, 0x18);
00845 put_be16(pb, 0xffff);
00846 if(track->tag == MKTAG('m','p','4','v'))
00847 mov_write_esds_tag(pb, track);
00848 else if(track->enc->codec_id == CODEC_ID_H263)
00849 mov_write_d263_tag(pb);
00850 else if(track->enc->codec_id == CODEC_ID_SVQ3)
00851 mov_write_svq3_tag(pb);
00852 else if(track->enc->codec_id == CODEC_ID_DNXHD)
00853 mov_write_avid_tag(pb, track);
00854 else if(track->enc->codec_id == CODEC_ID_H264) {
00855 mov_write_avcc_tag(pb, track);
00856 if(track->mode == MODE_IPOD)
00857 mov_write_uuid_tag_ipod(pb);
00858 } else if(track->vosLen > 0)
00859 mov_write_glbl_tag(pb, track);
00860
00861 return updateSize(pb, pos);
00862 }
00863
00864 static int mov_write_stsd_tag(ByteIOContext *pb, MOVTrack *track)
00865 {
00866 int64_t pos = url_ftell(pb);
00867 put_be32(pb, 0);
00868 put_tag(pb, "stsd");
00869 put_be32(pb, 0);
00870 put_be32(pb, 1);
00871 if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO)
00872 mov_write_video_tag(pb, track);
00873 else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
00874 mov_write_audio_tag(pb, track);
00875 else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)
00876 mov_write_subtitle_tag(pb, track);
00877 return updateSize(pb, pos);
00878 }
00879
00880 static int mov_write_ctts_tag(ByteIOContext *pb, MOVTrack *track)
00881 {
00882 MOVStts *ctts_entries;
00883 uint32_t entries = 0;
00884 uint32_t atom_size;
00885 int i;
00886
00887 ctts_entries = av_malloc((track->entry + 1) * sizeof(*ctts_entries));
00888 ctts_entries[0].count = 1;
00889 ctts_entries[0].duration = track->cluster[0].cts;
00890 for (i=1; i<track->entry; i++) {
00891 if (track->cluster[i].cts == ctts_entries[entries].duration) {
00892 ctts_entries[entries].count++;
00893 } else {
00894 entries++;
00895 ctts_entries[entries].duration = track->cluster[i].cts;
00896 ctts_entries[entries].count = 1;
00897 }
00898 }
00899 entries++;
00900 atom_size = 16 + (entries * 8);
00901 put_be32(pb, atom_size);
00902 put_tag(pb, "ctts");
00903 put_be32(pb, 0);
00904 put_be32(pb, entries);
00905 for (i=0; i<entries; i++) {
00906 put_be32(pb, ctts_entries[i].count);
00907 put_be32(pb, ctts_entries[i].duration);
00908 }
00909 av_free(ctts_entries);
00910 return atom_size;
00911 }
00912
00913
00914 static int mov_write_stts_tag(ByteIOContext *pb, MOVTrack *track)
00915 {
00916 MOVStts *stts_entries;
00917 uint32_t entries = -1;
00918 uint32_t atom_size;
00919 int i;
00920
00921 if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO && !track->audio_vbr) {
00922 stts_entries = av_malloc(sizeof(*stts_entries));
00923 stts_entries[0].count = track->sampleCount;
00924 stts_entries[0].duration = 1;
00925 entries = 1;
00926 } else {
00927 stts_entries = av_malloc(track->entry * sizeof(*stts_entries));
00928 for (i=0; i<track->entry; i++) {
00929 int64_t duration = i + 1 == track->entry ?
00930 track->trackDuration - track->cluster[i].dts + track->cluster[0].dts :
00931 track->cluster[i+1].dts - track->cluster[i].dts;
00932 if (i && duration == stts_entries[entries].duration) {
00933 stts_entries[entries].count++;
00934 } else {
00935 entries++;
00936 stts_entries[entries].duration = duration;
00937 stts_entries[entries].count = 1;
00938 }
00939 }
00940 entries++;
00941 }
00942 atom_size = 16 + (entries * 8);
00943 put_be32(pb, atom_size);
00944 put_tag(pb, "stts");
00945 put_be32(pb, 0);
00946 put_be32(pb, entries);
00947 for (i=0; i<entries; i++) {
00948 put_be32(pb, stts_entries[i].count);
00949 put_be32(pb, stts_entries[i].duration);
00950 }
00951 av_free(stts_entries);
00952 return atom_size;
00953 }
00954
00955 static int mov_write_dref_tag(ByteIOContext *pb)
00956 {
00957 put_be32(pb, 28);
00958 put_tag(pb, "dref");
00959 put_be32(pb, 0);
00960 put_be32(pb, 1);
00961
00962 put_be32(pb, 0xc);
00963 put_tag(pb, "url ");
00964 put_be32(pb, 1);
00965
00966 return 28;
00967 }
00968
00969 static int mov_write_stbl_tag(ByteIOContext *pb, MOVTrack *track)
00970 {
00971 int64_t pos = url_ftell(pb);
00972 put_be32(pb, 0);
00973 put_tag(pb, "stbl");
00974 mov_write_stsd_tag(pb, track);
00975 mov_write_stts_tag(pb, track);
00976 if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO &&
00977 track->hasKeyframes && track->hasKeyframes < track->entry)
00978 mov_write_stss_tag(pb, track, MOV_SYNC_SAMPLE);
00979 if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS)
00980 mov_write_stss_tag(pb, track, MOV_PARTIAL_SYNC_SAMPLE);
00981 if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO &&
00982 track->flags & MOV_TRACK_CTTS)
00983 mov_write_ctts_tag(pb, track);
00984 mov_write_stsc_tag(pb, track);
00985 mov_write_stsz_tag(pb, track);
00986 mov_write_stco_tag(pb, track);
00987 return updateSize(pb, pos);
00988 }
00989
00990 static int mov_write_dinf_tag(ByteIOContext *pb)
00991 {
00992 int64_t pos = url_ftell(pb);
00993 put_be32(pb, 0);
00994 put_tag(pb, "dinf");
00995 mov_write_dref_tag(pb);
00996 return updateSize(pb, pos);
00997 }
00998
00999 static int mov_write_nmhd_tag(ByteIOContext *pb)
01000 {
01001 put_be32(pb, 12);
01002 put_tag(pb, "nmhd");
01003 put_be32(pb, 0);
01004 return 12;
01005 }
01006
01007 static int mov_write_gmhd_tag(ByteIOContext *pb)
01008 {
01009 put_be32(pb, 0x20);
01010 put_tag(pb, "gmhd");
01011 put_be32(pb, 0x18);
01012 put_tag(pb, "gmin");
01013 put_be32(pb, 0);
01014 put_be16(pb, 0x40);
01015 put_be16(pb, 0x8000);
01016 put_be16(pb, 0x8000);
01017 put_be16(pb, 0x8000);
01018 put_be16(pb, 0);
01019 put_be16(pb, 0);
01020 return 0x20;
01021 }
01022
01023 static int mov_write_smhd_tag(ByteIOContext *pb)
01024 {
01025 put_be32(pb, 16);
01026 put_tag(pb, "smhd");
01027 put_be32(pb, 0);
01028 put_be16(pb, 0);
01029 put_be16(pb, 0);
01030 return 16;
01031 }
01032
01033 static int mov_write_vmhd_tag(ByteIOContext *pb)
01034 {
01035 put_be32(pb, 0x14);
01036 put_tag(pb, "vmhd");
01037 put_be32(pb, 0x01);
01038 put_be64(pb, 0);
01039 return 0x14;
01040 }
01041
01042 static int mov_write_hdlr_tag(ByteIOContext *pb, MOVTrack *track)
01043 {
01044 const char *hdlr, *descr = NULL, *hdlr_type = NULL;
01045 int64_t pos = url_ftell(pb);
01046
01047 if (!track) {
01048 hdlr = "dhlr";
01049 hdlr_type = "url ";
01050 descr = "DataHandler";
01051 } else {
01052 hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
01053 if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
01054 hdlr_type = "vide";
01055 descr = "VideoHandler";
01056 } else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) {
01057 hdlr_type = "soun";
01058 descr = "SoundHandler";
01059 } else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
01060 if (track->tag == MKTAG('t','x','3','g')) hdlr_type = "sbtl";
01061 else hdlr_type = "text";
01062 descr = "SubtitleHandler";
01063 }
01064 }
01065
01066 put_be32(pb, 0);
01067 put_tag(pb, "hdlr");
01068 put_be32(pb, 0);
01069 put_buffer(pb, hdlr, 4);
01070 put_tag(pb, hdlr_type);
01071 put_be32(pb ,0);
01072 put_be32(pb ,0);
01073 put_be32(pb ,0);
01074 if (!track || track->mode == MODE_MOV)
01075 put_byte(pb, strlen(descr));
01076 put_buffer(pb, descr, strlen(descr));
01077 if (track && track->mode != MODE_MOV)
01078 put_byte(pb, 0);
01079 return updateSize(pb, pos);
01080 }
01081
01082 static int mov_write_minf_tag(ByteIOContext *pb, MOVTrack *track)
01083 {
01084 int64_t pos = url_ftell(pb);
01085 put_be32(pb, 0);
01086 put_tag(pb, "minf");
01087 if(track->enc->codec_type == AVMEDIA_TYPE_VIDEO)
01088 mov_write_vmhd_tag(pb);
01089 else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
01090 mov_write_smhd_tag(pb);
01091 else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
01092 if (track->tag == MKTAG('t','e','x','t')) mov_write_gmhd_tag(pb);
01093 else mov_write_nmhd_tag(pb);
01094 }
01095 if (track->mode == MODE_MOV)
01096 mov_write_hdlr_tag(pb, NULL);
01097 mov_write_dinf_tag(pb);
01098 mov_write_stbl_tag(pb, track);
01099 return updateSize(pb, pos);
01100 }
01101
01102 static int mov_write_mdhd_tag(ByteIOContext *pb, MOVTrack *track)
01103 {
01104 int version = track->trackDuration < INT32_MAX ? 0 : 1;
01105
01106 (version == 1) ? put_be32(pb, 44) : put_be32(pb, 32);
01107 put_tag(pb, "mdhd");
01108 put_byte(pb, version);
01109 put_be24(pb, 0);
01110 if (version == 1) {
01111 put_be64(pb, track->time);
01112 put_be64(pb, track->time);
01113 } else {
01114 put_be32(pb, track->time);
01115 put_be32(pb, track->time);
01116 }
01117 put_be32(pb, track->timescale);
01118 (version == 1) ? put_be64(pb, track->trackDuration) : put_be32(pb, track->trackDuration);
01119 put_be16(pb, track->language);
01120 put_be16(pb, 0);
01121
01122 if(version!=0 && track->mode == MODE_MOV){
01123 av_log(NULL, AV_LOG_ERROR,
01124 "FATAL error, file duration too long for timebase, this file will not be\n"
01125 "playable with quicktime. Choose a different timebase or a different\n"
01126 "container format\n");
01127 }
01128
01129 return 32;
01130 }
01131
01132 static int mov_write_mdia_tag(ByteIOContext *pb, MOVTrack *track)
01133 {
01134 int64_t pos = url_ftell(pb);
01135 put_be32(pb, 0);
01136 put_tag(pb, "mdia");
01137 mov_write_mdhd_tag(pb, track);
01138 mov_write_hdlr_tag(pb, track);
01139 mov_write_minf_tag(pb, track);
01140 return updateSize(pb, pos);
01141 }
01142
01143 static int mov_write_tkhd_tag(ByteIOContext *pb, MOVTrack *track, AVStream *st)
01144 {
01145 int64_t duration = av_rescale_rnd(track->trackDuration, MOV_TIMESCALE,
01146 track->timescale, AV_ROUND_UP);
01147 int version = duration < INT32_MAX ? 0 : 1;
01148
01149 (version == 1) ? put_be32(pb, 104) : put_be32(pb, 92);
01150 put_tag(pb, "tkhd");
01151 put_byte(pb, version);
01152 put_be24(pb, 0xf);
01153 if (version == 1) {
01154 put_be64(pb, track->time);
01155 put_be64(pb, track->time);
01156 } else {
01157 put_be32(pb, track->time);
01158 put_be32(pb, track->time);
01159 }
01160 put_be32(pb, track->trackID);
01161 put_be32(pb, 0);
01162 (version == 1) ? put_be64(pb, duration) : put_be32(pb, duration);
01163
01164 put_be32(pb, 0);
01165 put_be32(pb, 0);
01166 put_be32(pb, 0x0);
01167
01168 if(track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
01169 put_be16(pb, 0x0100);
01170 else
01171 put_be16(pb, 0);
01172 put_be16(pb, 0);
01173
01174
01175 put_be32(pb, 0x00010000);
01176 put_be32(pb, 0x0);
01177 put_be32(pb, 0x0);
01178 put_be32(pb, 0x0);
01179 put_be32(pb, 0x00010000);
01180 put_be32(pb, 0x0);
01181 put_be32(pb, 0x0);
01182 put_be32(pb, 0x0);
01183 put_be32(pb, 0x40000000);
01184
01185
01186 if(track->enc->codec_type == AVMEDIA_TYPE_VIDEO ||
01187 track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
01188 double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
01189 if(!sample_aspect_ratio || track->height != track->enc->height)
01190 sample_aspect_ratio = 1;
01191 put_be32(pb, sample_aspect_ratio * track->enc->width*0x10000);
01192 put_be32(pb, track->height*0x10000);
01193 }
01194 else {
01195 put_be32(pb, 0);
01196 put_be32(pb, 0);
01197 }
01198 return 0x5c;
01199 }
01200
01201
01202 static int mov_write_edts_tag(ByteIOContext *pb, MOVTrack *track)
01203 {
01204 put_be32(pb, 0x24);
01205 put_tag(pb, "edts");
01206 put_be32(pb, 0x1c);
01207 put_tag(pb, "elst");
01208 put_be32(pb, 0x0);
01209 put_be32(pb, 0x1);
01210
01211
01212 put_be32(pb, av_rescale_rnd(track->trackDuration, MOV_TIMESCALE,
01213 track->timescale, AV_ROUND_UP));
01214
01215 put_be32(pb, track->cluster[0].cts);
01216 put_be32(pb, 0x00010000);
01217 return 0x24;
01218 }
01219
01220
01221 static int mov_write_uuid_tag_psp(ByteIOContext *pb, MOVTrack *mov)
01222 {
01223 put_be32(pb, 0x34);
01224 put_tag(pb, "uuid");
01225 put_tag(pb, "USMT");
01226 put_be32(pb, 0x21d24fce);
01227 put_be32(pb, 0xbb88695c);
01228 put_be32(pb, 0xfac9c740);
01229 put_be32(pb, 0x1c);
01230 put_tag(pb, "MTDT");
01231 put_be32(pb, 0x00010012);
01232 put_be32(pb, 0x0a);
01233 put_be32(pb, 0x55c40000);
01234 put_be32(pb, 0x1);
01235 put_be32(pb, 0x0);
01236 return 0x34;
01237 }
01238
01239 static int mov_write_trak_tag(ByteIOContext *pb, MOVTrack *track, AVStream *st)
01240 {
01241 int64_t pos = url_ftell(pb);
01242 put_be32(pb, 0);
01243 put_tag(pb, "trak");
01244 mov_write_tkhd_tag(pb, track, st);
01245 if (track->mode == MODE_PSP || track->flags & MOV_TRACK_CTTS)
01246 mov_write_edts_tag(pb, track);
01247 mov_write_mdia_tag(pb, track);
01248 if (track->mode == MODE_PSP)
01249 mov_write_uuid_tag_psp(pb,track);
01250 return updateSize(pb, pos);
01251 }
01252
01253 #if 0
01254
01255 static int mov_write_iods_tag(ByteIOContext *pb, MOVMuxContext *mov)
01256 {
01257 put_be32(pb, 0x15);
01258 put_tag(pb, "iods");
01259 put_be32(pb, 0);
01260 put_be16(pb, 0x1007);
01261 put_byte(pb, 0);
01262 put_be16(pb, 0x4fff);
01263 put_be16(pb, 0xfffe);
01264 put_be16(pb, 0x01ff);
01265 return 0x15;
01266 }
01267 #endif
01268
01269 static int mov_write_mvhd_tag(ByteIOContext *pb, MOVMuxContext *mov)
01270 {
01271 int maxTrackID = 1, i;
01272 int64_t maxTrackLenTemp, maxTrackLen = 0;
01273 int version;
01274
01275 for (i=0; i<mov->nb_streams; i++) {
01276 if(mov->tracks[i].entry > 0) {
01277 maxTrackLenTemp = av_rescale_rnd(mov->tracks[i].trackDuration,
01278 MOV_TIMESCALE,
01279 mov->tracks[i].timescale,
01280 AV_ROUND_UP);
01281 if(maxTrackLen < maxTrackLenTemp)
01282 maxTrackLen = maxTrackLenTemp;
01283 if(maxTrackID < mov->tracks[i].trackID)
01284 maxTrackID = mov->tracks[i].trackID;
01285 }
01286 }
01287
01288 version = maxTrackLen < UINT32_MAX ? 0 : 1;
01289 (version == 1) ? put_be32(pb, 120) : put_be32(pb, 108);
01290 put_tag(pb, "mvhd");
01291 put_byte(pb, version);
01292 put_be24(pb, 0);
01293 if (version == 1) {
01294 put_be64(pb, mov->time);
01295 put_be64(pb, mov->time);
01296 } else {
01297 put_be32(pb, mov->time);
01298 put_be32(pb, mov->time);
01299 }
01300 put_be32(pb, MOV_TIMESCALE);
01301 (version == 1) ? put_be64(pb, maxTrackLen) : put_be32(pb, maxTrackLen);
01302
01303 put_be32(pb, 0x00010000);
01304 put_be16(pb, 0x0100);
01305 put_be16(pb, 0);
01306 put_be32(pb, 0);
01307 put_be32(pb, 0);
01308
01309
01310 put_be32(pb, 0x00010000);
01311 put_be32(pb, 0x0);
01312 put_be32(pb, 0x0);
01313 put_be32(pb, 0x0);
01314 put_be32(pb, 0x00010000);
01315 put_be32(pb, 0x0);
01316 put_be32(pb, 0x0);
01317 put_be32(pb, 0x0);
01318 put_be32(pb, 0x40000000);
01319
01320 put_be32(pb, 0);
01321 put_be32(pb, 0);
01322 put_be32(pb, 0);
01323 put_be32(pb, 0);
01324 put_be32(pb, 0);
01325 put_be32(pb, 0);
01326 put_be32(pb, maxTrackID+1);
01327 return 0x6c;
01328 }
01329
01330 static int mov_write_itunes_hdlr_tag(ByteIOContext *pb, MOVMuxContext *mov,
01331 AVFormatContext *s)
01332 {
01333 put_be32(pb, 33);
01334 put_tag(pb, "hdlr");
01335 put_be32(pb, 0);
01336 put_be32(pb, 0);
01337 put_tag(pb, "mdir");
01338 put_tag(pb, "appl");
01339 put_be32(pb, 0);
01340 put_be32(pb, 0);
01341 put_byte(pb, 0);
01342 return 33;
01343 }
01344
01345
01346 static int mov_write_string_data_tag(ByteIOContext *pb, const char *data, int lang, int long_style)
01347 {
01348 if(long_style){
01349 int size = 16 + strlen(data);
01350 put_be32(pb, size);
01351 put_tag(pb, "data");
01352 put_be32(pb, 1);
01353 put_be32(pb, 0);
01354 put_buffer(pb, data, strlen(data));
01355 return size;
01356 }else{
01357 if (!lang)
01358 lang = ff_mov_iso639_to_lang("und", 1);
01359 put_be16(pb, strlen(data));
01360 put_be16(pb, lang);
01361 put_buffer(pb, data, strlen(data));
01362 return strlen(data) + 4;
01363 }
01364 }
01365
01366 static int mov_write_string_tag(ByteIOContext *pb, const char *name, const char *value, int lang, int long_style){
01367 int size = 0;
01368 if (value && value[0]) {
01369 int64_t pos = url_ftell(pb);
01370 put_be32(pb, 0);
01371 put_tag(pb, name);
01372 mov_write_string_data_tag(pb, value, lang, long_style);
01373 size= updateSize(pb, pos);
01374 }
01375 return size;
01376 }
01377
01378 static int mov_write_string_metadata(AVFormatContext *s, ByteIOContext *pb,
01379 const char *name, const char *tag,
01380 int long_style)
01381 {
01382 int l, lang = 0, len, len2;
01383 AVMetadataTag *t, *t2 = NULL;
01384 char tag2[16];
01385
01386 if (!(t = av_metadata_get(s->metadata, tag, NULL, 0)))
01387 return 0;
01388
01389 len = strlen(t->key);
01390 snprintf(tag2, sizeof(tag2), "%s-", tag);
01391 while ((t2 = av_metadata_get(s->metadata, tag2, t2, AV_METADATA_IGNORE_SUFFIX))) {
01392 len2 = strlen(t2->key);
01393 if (len2 == len+4 && !strcmp(t->value, t2->value)
01394 && (l=ff_mov_iso639_to_lang(&t2->key[len2-3], 1)) >= 0) {
01395 lang = l;
01396 break;
01397 }
01398 }
01399 return mov_write_string_tag(pb, name, t->value, lang, long_style);
01400 }
01401
01402
01403 static int mov_write_trkn_tag(ByteIOContext *pb, MOVMuxContext *mov,
01404 AVFormatContext *s)
01405 {
01406 AVMetadataTag *t = av_metadata_get(s->metadata, "track", NULL, 0);
01407 int size = 0, track = t ? atoi(t->value) : 0;
01408 if (track) {
01409 put_be32(pb, 32);
01410 put_tag(pb, "trkn");
01411 put_be32(pb, 24);
01412 put_tag(pb, "data");
01413 put_be32(pb, 0);
01414 put_be32(pb, 0);
01415 put_be16(pb, 0);
01416 put_be16(pb, track);
01417 put_be16(pb, 0);
01418 put_be16(pb, 0);
01419 size = 32;
01420 }
01421 return size;
01422 }
01423
01424
01425 static int mov_write_ilst_tag(ByteIOContext *pb, MOVMuxContext *mov,
01426 AVFormatContext *s)
01427 {
01428 int64_t pos = url_ftell(pb);
01429 put_be32(pb, 0);
01430 put_tag(pb, "ilst");
01431 mov_write_string_metadata(s, pb, "\251nam", "title" , 1);
01432 mov_write_string_metadata(s, pb, "\251ART", "author" , 1);
01433 mov_write_string_metadata(s, pb, "aART", "album_artist", 1);
01434 mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1);
01435 mov_write_string_metadata(s, pb, "\251alb", "album" , 1);
01436 mov_write_string_metadata(s, pb, "\251day", "date" , 1);
01437 mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1);
01438 mov_write_string_metadata(s, pb, "\251cmt", "comment" , 1);
01439 mov_write_string_metadata(s, pb, "\251gen", "genre" , 1);
01440 mov_write_string_metadata(s, pb, "\251cpy", "copyright", 1);
01441 mov_write_string_metadata(s, pb, "\251grp", "grouping" , 1);
01442 mov_write_string_metadata(s, pb, "\251lyr", "lyrics" , 1);
01443 mov_write_string_metadata(s, pb, "desc", "description",1);
01444 mov_write_string_metadata(s, pb, "ldes", "synopsis" , 1);
01445 mov_write_string_metadata(s, pb, "tvsh", "show" , 1);
01446 mov_write_string_metadata(s, pb, "tven", "episode_id",1);
01447 mov_write_string_metadata(s, pb, "tvnn", "network" , 1);
01448 mov_write_trkn_tag(pb, mov, s);
01449 return updateSize(pb, pos);
01450 }
01451
01452
01453 static int mov_write_meta_tag(ByteIOContext *pb, MOVMuxContext *mov,
01454 AVFormatContext *s)
01455 {
01456 int size = 0;
01457 int64_t pos = url_ftell(pb);
01458 put_be32(pb, 0);
01459 put_tag(pb, "meta");
01460 put_be32(pb, 0);
01461 mov_write_itunes_hdlr_tag(pb, mov, s);
01462 mov_write_ilst_tag(pb, mov, s);
01463 size = updateSize(pb, pos);
01464 return size;
01465 }
01466
01467 static int utf8len(const uint8_t *b)
01468 {
01469 int len=0;
01470 int val;
01471 while(*b){
01472 GET_UTF8(val, *b++, return -1;)
01473 len++;
01474 }
01475 return len;
01476 }
01477
01478 static int ascii_to_wc(ByteIOContext *pb, const uint8_t *b)
01479 {
01480 int val;
01481 while(*b){
01482 GET_UTF8(val, *b++, return -1;)
01483 put_be16(pb, val);
01484 }
01485 put_be16(pb, 0x00);
01486 return 0;
01487 }
01488
01489 static uint16_t language_code(const char *str)
01490 {
01491 return (((str[0]-0x60) & 0x1F) << 10) + (((str[1]-0x60) & 0x1F) << 5) + ((str[2]-0x60) & 0x1F);
01492 }
01493
01494 static int mov_write_3gp_udta_tag(ByteIOContext *pb, AVFormatContext *s,
01495 const char *tag, const char *str)
01496 {
01497 int64_t pos = url_ftell(pb);
01498 AVMetadataTag *t = av_metadata_get(s->metadata, str, NULL, 0);
01499 if (!t || !utf8len(t->value))
01500 return 0;
01501 put_be32(pb, 0);
01502 put_tag (pb, tag);
01503 put_be32(pb, 0);
01504 if (!strcmp(tag, "yrrc"))
01505 put_be16(pb, atoi(t->value));
01506 else {
01507 put_be16(pb, language_code("eng"));
01508 put_buffer(pb, t->value, strlen(t->value)+1);
01509 if (!strcmp(tag, "albm") &&
01510 (t = av_metadata_get(s->metadata, "date", NULL, 0)))
01511 put_byte(pb, atoi(t->value));
01512 }
01513 return updateSize(pb, pos);
01514 }
01515
01516 static int mov_write_udta_tag(ByteIOContext *pb, MOVMuxContext *mov,
01517 AVFormatContext *s)
01518 {
01519 ByteIOContext *pb_buf;
01520 int i, ret, size;
01521 uint8_t *buf;
01522
01523 for (i = 0; i < s->nb_streams; i++)
01524 if (mov->tracks[i].enc->flags & CODEC_FLAG_BITEXACT) {
01525 return 0;
01526 }
01527
01528 ret = url_open_dyn_buf(&pb_buf);
01529 if(ret < 0)
01530 return ret;
01531
01532 if (mov->mode & MODE_3GP) {
01533 mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");
01534 mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");
01535 mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");
01536 mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");
01537 mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");
01538 mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
01539 mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
01540 } else if (mov->mode == MODE_MOV) {
01541 mov_write_string_metadata(s, pb_buf, "\251nam", "title" , 0);
01542 mov_write_string_metadata(s, pb_buf, "\251aut", "author" , 0);
01543 mov_write_string_metadata(s, pb_buf, "\251alb", "album" , 0);
01544 mov_write_string_metadata(s, pb_buf, "\251day", "date" , 0);
01545 mov_write_string_tag(pb_buf, "\251enc", LIBAVFORMAT_IDENT, 0, 0);
01546 mov_write_string_metadata(s, pb_buf, "\251des", "comment" , 0);
01547 mov_write_string_metadata(s, pb_buf, "\251gen", "genre" , 0);
01548 mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright" , 0);
01549 } else {
01550
01551 mov_write_meta_tag(pb_buf, mov, s);
01552 }
01553
01554 if ((size = url_close_dyn_buf(pb_buf, &buf)) > 0) {
01555 put_be32(pb, size+8);
01556 put_tag(pb, "udta");
01557 put_buffer(pb, buf, size);
01558 av_free(buf);
01559 }
01560
01561 return 0;
01562 }
01563
01564 static void mov_write_psp_udta_tag(ByteIOContext *pb,
01565 const char *str, const char *lang, int type)
01566 {
01567 int len = utf8len(str)+1;
01568 if(len<=0)
01569 return;
01570 put_be16(pb, len*2+10);
01571 put_be32(pb, type);
01572 put_be16(pb, language_code(lang));
01573 put_be16(pb, 0x01);
01574 ascii_to_wc(pb, str);
01575 }
01576
01577 static int mov_write_uuidusmt_tag(ByteIOContext *pb, AVFormatContext *s)
01578 {
01579 AVMetadataTag *title = av_metadata_get(s->metadata, "title", NULL, 0);
01580 int64_t pos, pos2;
01581
01582 if (title) {
01583 pos = url_ftell(pb);
01584 put_be32(pb, 0);
01585 put_tag(pb, "uuid");
01586 put_tag(pb, "USMT");
01587 put_be32(pb, 0x21d24fce);
01588 put_be32(pb, 0xbb88695c);
01589 put_be32(pb, 0xfac9c740);
01590
01591 pos2 = url_ftell(pb);
01592 put_be32(pb, 0);
01593 put_tag(pb, "MTDT");
01594 put_be16(pb, 4);
01595
01596
01597 put_be16(pb, 0x0C);
01598 put_be32(pb, 0x0B);
01599 put_be16(pb, language_code("und"));
01600 put_be16(pb, 0x0);
01601 put_be16(pb, 0x021C);
01602
01603 mov_write_psp_udta_tag(pb, LIBAVCODEC_IDENT, "eng", 0x04);
01604 mov_write_psp_udta_tag(pb, title->value, "eng", 0x01);
01605
01606 mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03);
01607
01608 updateSize(pb, pos2);
01609 return updateSize(pb, pos);
01610 }
01611
01612 return 0;
01613 }
01614
01615 static int mov_write_moov_tag(ByteIOContext *pb, MOVMuxContext *mov,
01616 AVFormatContext *s)
01617 {
01618 int i;
01619 int64_t pos = url_ftell(pb);
01620 put_be32(pb, 0);
01621 put_tag(pb, "moov");
01622
01623 for (i=0; i<mov->nb_streams; i++) {
01624 if(mov->tracks[i].entry <= 0) continue;
01625
01626 mov->tracks[i].time = mov->time;
01627 mov->tracks[i].trackID = i+1;
01628 }
01629
01630 mov_write_mvhd_tag(pb, mov);
01631
01632 for (i=0; i<mov->nb_streams; i++) {
01633 if(mov->tracks[i].entry > 0) {
01634 mov_write_trak_tag(pb, &(mov->tracks[i]), s->streams[i]);
01635 }
01636 }
01637
01638 if (mov->mode == MODE_PSP)
01639 mov_write_uuidusmt_tag(pb, s);
01640 else
01641 mov_write_udta_tag(pb, mov, s);
01642
01643 return updateSize(pb, pos);
01644 }
01645
01646 static int mov_write_mdat_tag(ByteIOContext *pb, MOVMuxContext *mov)
01647 {
01648 put_be32(pb, 8);
01649 put_tag(pb, mov->mode == MODE_MOV ? "wide" : "free");
01650
01651 mov->mdat_pos = url_ftell(pb);
01652 put_be32(pb, 0);
01653 put_tag(pb, "mdat");
01654 return 0;
01655 }
01656
01657
01658 static int mov_write_ftyp_tag(ByteIOContext *pb, AVFormatContext *s)
01659 {
01660 MOVMuxContext *mov = s->priv_data;
01661 int64_t pos = url_ftell(pb);
01662 int has_h264 = 0, has_video = 0;
01663 int minor = 0x200;
01664 int i;
01665
01666 for (i = 0; i < s->nb_streams; i++) {
01667 AVStream *st = s->streams[i];
01668 if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
01669 has_video = 1;
01670 if (st->codec->codec_id == CODEC_ID_H264)
01671 has_h264 = 1;
01672 }
01673
01674 put_be32(pb, 0);
01675 put_tag(pb, "ftyp");
01676
01677 if (mov->mode == MODE_3GP) {
01678 put_tag(pb, has_h264 ? "3gp6" : "3gp4");
01679 minor = has_h264 ? 0x100 : 0x200;
01680 } else if (mov->mode & MODE_3G2) {
01681 put_tag(pb, has_h264 ? "3g2b" : "3g2a");
01682 minor = has_h264 ? 0x20000 : 0x10000;
01683 }else if (mov->mode == MODE_PSP)
01684 put_tag(pb, "MSNV");
01685 else if (mov->mode == MODE_MP4)
01686 put_tag(pb, "isom");
01687 else if (mov->mode == MODE_IPOD)
01688 put_tag(pb, has_video ? "M4V ":"M4A ");
01689 else
01690 put_tag(pb, "qt ");
01691
01692 put_be32(pb, minor);
01693
01694 if(mov->mode == MODE_MOV)
01695 put_tag(pb, "qt ");
01696 else{
01697 put_tag(pb, "isom");
01698 put_tag(pb, "iso2");
01699 if(has_h264)
01700 put_tag(pb, "avc1");
01701 }
01702
01703 if (mov->mode == MODE_3GP)
01704 put_tag(pb, has_h264 ? "3gp6":"3gp4");
01705 else if (mov->mode & MODE_3G2)
01706 put_tag(pb, has_h264 ? "3g2b":"3g2a");
01707 else if (mov->mode == MODE_PSP)
01708 put_tag(pb, "MSNV");
01709 else if (mov->mode == MODE_MP4)
01710 put_tag(pb, "mp41");
01711 return updateSize(pb, pos);
01712 }
01713
01714 static void mov_write_uuidprof_tag(ByteIOContext *pb, AVFormatContext *s)
01715 {
01716 AVCodecContext *VideoCodec = s->streams[0]->codec;
01717 AVCodecContext *AudioCodec = s->streams[1]->codec;
01718 int AudioRate = AudioCodec->sample_rate;
01719 int FrameRate = ((VideoCodec->time_base.den) * (0x10000))/ (VideoCodec->time_base.num);
01720 int audio_kbitrate= AudioCodec->bit_rate / 1000;
01721 int video_kbitrate= FFMIN(VideoCodec->bit_rate / 1000, 800 - audio_kbitrate);
01722
01723 put_be32(pb, 0x94);
01724 put_tag(pb, "uuid");
01725 put_tag(pb, "PROF");
01726
01727 put_be32(pb, 0x21d24fce);
01728 put_be32(pb, 0xbb88695c);
01729 put_be32(pb, 0xfac9c740);
01730
01731 put_be32(pb, 0x0);
01732 put_be32(pb, 0x3);
01733
01734 put_be32(pb, 0x14);
01735 put_tag(pb, "FPRF");
01736 put_be32(pb, 0x0);
01737 put_be32(pb, 0x0);
01738 put_be32(pb, 0x0);
01739
01740 put_be32(pb, 0x2c);
01741 put_tag(pb, "APRF");
01742 put_be32(pb, 0x0);
01743 put_be32(pb, 0x2);
01744 put_tag(pb, "mp4a");
01745 put_be32(pb, 0x20f);
01746 put_be32(pb, 0x0);
01747 put_be32(pb, audio_kbitrate);
01748 put_be32(pb, audio_kbitrate);
01749 put_be32(pb, AudioRate);
01750 put_be32(pb, AudioCodec->channels);
01751
01752 put_be32(pb, 0x34);
01753 put_tag(pb, "VPRF");
01754 put_be32(pb, 0x0);
01755 put_be32(pb, 0x1);
01756 if (VideoCodec->codec_id == CODEC_ID_H264) {
01757 put_tag(pb, "avc1");
01758 put_be16(pb, 0x014D);
01759 put_be16(pb, 0x0015);
01760 } else {
01761 put_tag(pb, "mp4v");
01762 put_be16(pb, 0x0000);
01763 put_be16(pb, 0x0103);
01764 }
01765 put_be32(pb, 0x0);
01766 put_be32(pb, video_kbitrate);
01767 put_be32(pb, video_kbitrate);
01768 put_be32(pb, FrameRate);
01769 put_be32(pb, FrameRate);
01770 put_be16(pb, VideoCodec->width);
01771 put_be16(pb, VideoCodec->height);
01772 put_be32(pb, 0x010001);
01773 }
01774
01775 static int mov_write_header(AVFormatContext *s)
01776 {
01777 ByteIOContext *pb = s->pb;
01778 MOVMuxContext *mov = s->priv_data;
01779 int i;
01780
01781 if (url_is_streamed(s->pb)) {
01782 av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
01783 return -1;
01784 }
01785
01786
01787 mov->mode = MODE_MP4;
01788
01789 if (s->oformat != NULL) {
01790 if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;
01791 else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3GP|MODE_3G2;
01792 else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;
01793 else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;
01794 else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD;
01795
01796 mov_write_ftyp_tag(pb,s);
01797 if (mov->mode == MODE_PSP) {
01798 if (s->nb_streams != 2) {
01799 av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
01800 return -1;
01801 }
01802 mov_write_uuidprof_tag(pb,s);
01803 }
01804 }
01805
01806 mov->tracks = av_mallocz(s->nb_streams*sizeof(*mov->tracks));
01807 if (!mov->tracks)
01808 return AVERROR(ENOMEM);
01809
01810 for(i=0; i<s->nb_streams; i++){
01811 AVStream *st= s->streams[i];
01812 MOVTrack *track= &mov->tracks[i];
01813 AVMetadataTag *lang = av_metadata_get(st->metadata, "language", NULL,0);
01814
01815 track->enc = st->codec;
01816 track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);
01817 if (track->language < 0)
01818 track->language = 0;
01819 track->mode = mov->mode;
01820 track->tag = mov_find_codec_tag(s, track);
01821 if (!track->tag) {
01822 av_log(s, AV_LOG_ERROR, "track %d: could not find tag, "
01823 "codec not currently supported in container\n", i);
01824 goto error;
01825 }
01826 if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO){
01827 if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
01828 track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
01829 track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {
01830 if (st->codec->width != 720 || (st->codec->height != 608 && st->codec->height != 512)) {
01831 av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");
01832 goto error;
01833 }
01834 track->height = track->tag>>24 == 'n' ? 486 : 576;
01835 }
01836 track->timescale = st->codec->time_base.den;
01837 if (track->mode == MODE_MOV && track->timescale > 100000)
01838 av_log(s, AV_LOG_WARNING,
01839 "WARNING codec timebase is very high. If duration is too long,\n"
01840 "file may not be playable by quicktime. Specify a shorter timebase\n"
01841 "or choose different container.\n");
01842 }else if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO){
01843 track->timescale = st->codec->sample_rate;
01844 if(!st->codec->frame_size && !av_get_bits_per_sample(st->codec->codec_id)) {
01845 av_log(s, AV_LOG_ERROR, "track %d: codec frame size is not set\n", i);
01846 goto error;
01847 }else if(st->codec->frame_size > 1){
01848 track->audio_vbr = 1;
01849 }else{
01850 st->codec->frame_size = 1;
01851 track->sampleSize = (av_get_bits_per_sample(st->codec->codec_id) >> 3) * st->codec->channels;
01852 }
01853 if (track->mode != MODE_MOV) {
01854 if (track->timescale > UINT16_MAX) {
01855 av_log(s, AV_LOG_ERROR, "track %d: output format does not support "
01856 "sample rate %dhz\n", i, track->timescale);
01857 goto error;
01858 }
01859 if (track->enc->codec_id == CODEC_ID_MP3 && track->timescale < 16000) {
01860 av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not supported\n",
01861 i, track->enc->sample_rate);
01862 goto error;
01863 }
01864 }
01865 }else if(st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE){
01866 track->timescale = st->codec->time_base.den;
01867 }
01868 if (!track->height)
01869 track->height = st->codec->height;
01870
01871 av_set_pts_info(st, 64, 1, track->timescale);
01872 }
01873
01874 mov_write_mdat_tag(pb, mov);
01875 mov->time = s->timestamp + 0x7C25B080;
01876 mov->nb_streams = s->nb_streams;
01877
01878 put_flush_packet(pb);
01879
01880 return 0;
01881 error:
01882 av_freep(&mov->tracks);
01883 return -1;
01884 }
01885
01886 static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
01887 {
01888 uint32_t c = -1;
01889 int i, closed_gop = 0;
01890
01891 for (i = 0; i < pkt->size - 4; i++) {
01892 c = (c<<8) + pkt->data[i];
01893 if (c == 0x1b8) {
01894 closed_gop = pkt->data[i+4]>>6 & 0x01;
01895 } else if (c == 0x100) {
01896 int temp_ref = (pkt->data[i+1]<<2) | (pkt->data[i+2]>>6);
01897 if (!temp_ref || closed_gop)
01898 *flags = MOV_SYNC_SAMPLE;
01899 else
01900 *flags = MOV_PARTIAL_SYNC_SAMPLE;
01901 break;
01902 }
01903 }
01904 return 0;
01905 }
01906
01907 static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
01908 {
01909 MOVMuxContext *mov = s->priv_data;
01910 ByteIOContext *pb = s->pb;
01911 MOVTrack *trk = &mov->tracks[pkt->stream_index];
01912 AVCodecContext *enc = trk->enc;
01913 unsigned int samplesInChunk = 0;
01914 int size= pkt->size;
01915
01916 if (url_is_streamed(s->pb)) return 0;
01917 if (!size) return 0;
01918
01919 if (enc->codec_id == CODEC_ID_AMR_NB) {
01920
01921 static uint16_t packed_size[16] =
01922 {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 0};
01923 int len = 0;
01924
01925 while (len < size && samplesInChunk < 100) {
01926 len += packed_size[(pkt->data[len] >> 3) & 0x0F];
01927 samplesInChunk++;
01928 }
01929 if(samplesInChunk > 1){
01930 av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
01931 return -1;
01932 }
01933 } else if (trk->sampleSize)
01934 samplesInChunk = size/trk->sampleSize;
01935 else
01936 samplesInChunk = 1;
01937
01938
01939 if (trk->vosLen == 0 && enc->extradata_size > 0) {
01940 trk->vosLen = enc->extradata_size;
01941 trk->vosData = av_malloc(trk->vosLen);
01942 memcpy(trk->vosData, enc->extradata, trk->vosLen);
01943 }
01944
01945 if (enc->codec_id == CODEC_ID_H264 && trk->vosLen > 0 && *(uint8_t *)trk->vosData != 1) {
01946
01947
01948 size = ff_avc_parse_nal_units(pb, pkt->data, pkt->size);
01949 } else {
01950 put_buffer(pb, pkt->data, size);
01951 }
01952
01953 if ((enc->codec_id == CODEC_ID_DNXHD ||
01954 enc->codec_id == CODEC_ID_AC3) && !trk->vosLen) {
01955
01956 trk->vosLen = size;
01957 trk->vosData = av_malloc(size);
01958 if (!trk->vosData)
01959 return AVERROR(ENOMEM);
01960 memcpy(trk->vosData, pkt->data, size);
01961 }
01962
01963 if (!(trk->entry % MOV_INDEX_CLUSTER_SIZE)) {
01964 trk->cluster = av_realloc(trk->cluster, (trk->entry + MOV_INDEX_CLUSTER_SIZE) * sizeof(*trk->cluster));
01965 if (!trk->cluster)
01966 return -1;
01967 }
01968
01969 trk->cluster[trk->entry].pos = url_ftell(pb) - size;
01970 trk->cluster[trk->entry].samplesInChunk = samplesInChunk;
01971 trk->cluster[trk->entry].size = size;
01972 trk->cluster[trk->entry].entries = samplesInChunk;
01973 trk->cluster[trk->entry].dts = pkt->dts;
01974 trk->trackDuration = pkt->dts - trk->cluster[0].dts + pkt->duration;
01975
01976 if (pkt->pts == AV_NOPTS_VALUE) {
01977 av_log(s, AV_LOG_WARNING, "pts has no value\n");
01978 pkt->pts = pkt->dts;
01979 }
01980 if (pkt->dts != pkt->pts)
01981 trk->flags |= MOV_TRACK_CTTS;
01982 trk->cluster[trk->entry].cts = pkt->pts - pkt->dts;
01983 trk->cluster[trk->entry].flags = 0;
01984 if (pkt->flags & AV_PKT_FLAG_KEY) {
01985 if (mov->mode == MODE_MOV && enc->codec_id == CODEC_ID_MPEG2VIDEO) {
01986 mov_parse_mpeg2_frame(pkt, &trk->cluster[trk->entry].flags);
01987 if (trk->cluster[trk->entry].flags & MOV_PARTIAL_SYNC_SAMPLE)
01988 trk->flags |= MOV_TRACK_STPS;
01989 } else {
01990 trk->cluster[trk->entry].flags = MOV_SYNC_SAMPLE;
01991 }
01992 if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE)
01993 trk->hasKeyframes++;
01994 }
01995 trk->entry++;
01996 trk->sampleCount += samplesInChunk;
01997 mov->mdat_size += size;
01998
01999 put_flush_packet(pb);
02000 return 0;
02001 }
02002
02003 static int mov_write_trailer(AVFormatContext *s)
02004 {
02005 MOVMuxContext *mov = s->priv_data;
02006 ByteIOContext *pb = s->pb;
02007 int res = 0;
02008 int i;
02009
02010 int64_t moov_pos = url_ftell(pb);
02011
02012
02013 if (mov->mdat_size+8 <= UINT32_MAX) {
02014 url_fseek(pb, mov->mdat_pos, SEEK_SET);
02015 put_be32(pb, mov->mdat_size+8);
02016 } else {
02017
02018 url_fseek(pb, mov->mdat_pos - 8, SEEK_SET);
02019 put_be32(pb, 1);
02020 put_tag(pb, "mdat");
02021 put_be64(pb, mov->mdat_size+16);
02022 }
02023 url_fseek(pb, moov_pos, SEEK_SET);
02024
02025 mov_write_moov_tag(pb, mov, s);
02026
02027 for (i=0; i<mov->nb_streams; i++) {
02028 av_freep(&mov->tracks[i].cluster);
02029
02030 if(mov->tracks[i].vosLen) av_free(mov->tracks[i].vosData);
02031
02032 }
02033
02034 put_flush_packet(pb);
02035
02036 av_freep(&mov->tracks);
02037
02038 return res;
02039 }
02040
02041 #if CONFIG_MOV_MUXER
02042 AVOutputFormat mov_muxer = {
02043 "mov",
02044 NULL_IF_CONFIG_SMALL("MOV format"),
02045 NULL,
02046 "mov",
02047 sizeof(MOVMuxContext),
02048 CODEC_ID_AAC,
02049 CODEC_ID_MPEG4,
02050 mov_write_header,
02051 mov_write_packet,
02052 mov_write_trailer,
02053 .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
02054 .codec_tag = (const AVCodecTag* const []){codec_movvideo_tags, codec_movaudio_tags, 0},
02055 };
02056 #endif
02057 #if CONFIG_TGP_MUXER
02058 AVOutputFormat tgp_muxer = {
02059 "3gp",
02060 NULL_IF_CONFIG_SMALL("3GP format"),
02061 NULL,
02062 "3gp",
02063 sizeof(MOVMuxContext),
02064 CODEC_ID_AMR_NB,
02065 CODEC_ID_H263,
02066 mov_write_header,
02067 mov_write_packet,
02068 mov_write_trailer,
02069 .flags = AVFMT_GLOBALHEADER,
02070 .codec_tag = (const AVCodecTag* const []){codec_3gp_tags, 0},
02071 };
02072 #endif
02073 #if CONFIG_MP4_MUXER
02074 AVOutputFormat mp4_muxer = {
02075 "mp4",
02076 NULL_IF_CONFIG_SMALL("MP4 format"),
02077 "application/mp4",
02078 "mp4",
02079 sizeof(MOVMuxContext),
02080 CODEC_ID_AAC,
02081 CODEC_ID_MPEG4,
02082 mov_write_header,
02083 mov_write_packet,
02084 mov_write_trailer,
02085 .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS,
02086 .codec_tag = (const AVCodecTag* const []){ff_mp4_obj_type, 0},
02087 };
02088 #endif
02089 #if CONFIG_PSP_MUXER
02090 AVOutputFormat psp_muxer = {
02091 "psp",
02092 NULL_IF_CONFIG_SMALL("PSP MP4 format"),
02093 NULL,
02094 "mp4,psp",
02095 sizeof(MOVMuxContext),
02096 CODEC_ID_AAC,
02097 CODEC_ID_MPEG4,
02098 mov_write_header,
02099 mov_write_packet,
02100 mov_write_trailer,
02101 .flags = AVFMT_GLOBALHEADER,
02102 .codec_tag = (const AVCodecTag* const []){ff_mp4_obj_type, 0},
02103 };
02104 #endif
02105 #if CONFIG_TG2_MUXER
02106 AVOutputFormat tg2_muxer = {
02107 "3g2",
02108 NULL_IF_CONFIG_SMALL("3GP2 format"),
02109 NULL,
02110 "3g2",
02111 sizeof(MOVMuxContext),
02112 CODEC_ID_AMR_NB,
02113 CODEC_ID_H263,
02114 mov_write_header,
02115 mov_write_packet,
02116 mov_write_trailer,
02117 .flags = AVFMT_GLOBALHEADER,
02118 .codec_tag = (const AVCodecTag* const []){codec_3gp_tags, 0},
02119 };
02120 #endif
02121 #if CONFIG_IPOD_MUXER
02122 AVOutputFormat ipod_muxer = {
02123 "ipod",
02124 NULL_IF_CONFIG_SMALL("iPod H.264 MP4 format"),
02125 "application/mp4",
02126 "m4v,m4a",
02127 sizeof(MOVMuxContext),
02128 CODEC_ID_AAC,
02129 CODEC_ID_H264,
02130 mov_write_header,
02131 mov_write_packet,
02132 mov_write_trailer,
02133 .flags = AVFMT_GLOBALHEADER,
02134 .codec_tag = (const AVCodecTag* const []){codec_ipod_tags, 0},
02135 };
02136 #endif