Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * MOV, 3GP, MP4 muxer
  3.  * Copyright (c) 2003 Thomas Raivio
  4.  * Copyright (c) 2004 Gildas Bazin <gbazin at videolan dot org>
  5.  * Copyright (c) 2009 Baptiste Coudurier <baptiste dot coudurier at gmail dot com>
  6.  *
  7.  * This file is part of FFmpeg.
  8.  *
  9.  * FFmpeg is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU Lesser General Public
  11.  * License as published by the Free Software Foundation; either
  12.  * version 2.1 of the License, or (at your option) any later version.
  13.  *
  14.  * FFmpeg is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17.  * Lesser General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU Lesser General Public
  20.  * License along with FFmpeg; if not, write to the Free Software
  21.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22.  */
  23.  
  24. #include "movenc.h"
  25. #include "avformat.h"
  26. #include "avio_internal.h"
  27. #include "riff.h"
  28. #include "avio.h"
  29. #include "isom.h"
  30. #include "avc.h"
  31. #include "libavcodec/get_bits.h"
  32. #include "libavcodec/put_bits.h"
  33. #include "libavcodec/vc1.h"
  34. #include "internal.h"
  35. #include "libavutil/avstring.h"
  36. #include "libavutil/intfloat.h"
  37. #include "libavutil/mathematics.h"
  38. #include "libavutil/opt.h"
  39. #include "libavutil/dict.h"
  40. #include "rtpenc.h"
  41. #include "mov_chan.h"
  42.  
  43. #undef NDEBUG
  44. #include <assert.h>
  45.  
  46. static const AVOption options[] = {
  47.     { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
  48.     { "rtphint", "Add RTP hint tracks", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_RTP_HINT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
  49.     { "moov_size", "maximum moov size so it can be placed at the begin", offsetof(MOVMuxContext, reserved_moov_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 0 },
  50.     { "empty_moov", "Make the initial moov atom empty (not supported by QuickTime)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_EMPTY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
  51.     { "frag_keyframe", "Fragment at video keyframes", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_KEYFRAME}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
  52.     { "separate_moof", "Write separate moof/mdat atoms for each track", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SEPARATE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
  53.     { "frag_custom", "Flush fragments on caller requests", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_CUSTOM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
  54.     { "isml", "Create a live smooth streaming feed (for pushing to a publishing point)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_ISML}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
  55.     { "faststart", "Run a second pass to put the index (moov atom) at the beginning of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FASTSTART}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
  56.     { "omit_tfhd_offset", "Omit the base data offset in tfhd atoms", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_OMIT_TFHD_OFFSET}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
  57.     FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
  58.     { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
  59.     { "iods_audio_profile", "iods audio profile atom.", offsetof(MOVMuxContext, iods_audio_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
  60.     { "iods_video_profile", "iods video profile atom.", offsetof(MOVMuxContext, iods_video_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
  61.     { "frag_duration", "Maximum fragment duration", offsetof(MOVMuxContext, max_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
  62.     { "min_frag_duration", "Minimum fragment duration", offsetof(MOVMuxContext, min_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
  63.     { "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
  64.     { "ism_lookahead", "Number of lookahead entries for ISM files", offsetof(MOVMuxContext, ism_lookahead), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
  65.     { "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM},
  66.     { "video_track_timescale", "set timescale of all video tracks", offsetof(MOVMuxContext, video_track_timescale), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM},
  67.     { NULL },
  68. };
  69.  
  70. #define MOV_CLASS(flavor)\
  71. static const AVClass flavor ## _muxer_class = {\
  72.     .class_name = #flavor " muxer",\
  73.     .item_name  = av_default_item_name,\
  74.     .option     = options,\
  75.     .version    = LIBAVUTIL_VERSION_INT,\
  76. };
  77.  
  78. static int get_moov_size(AVFormatContext *s);
  79.  
  80. //FIXME support 64 bit variant with wide placeholders
  81. static int64_t update_size(AVIOContext *pb, int64_t pos)
  82. {
  83.     int64_t curpos = avio_tell(pb);
  84.     avio_seek(pb, pos, SEEK_SET);
  85.     avio_wb32(pb, curpos - pos); /* rewrite size */
  86.     avio_seek(pb, curpos, SEEK_SET);
  87.  
  88.     return curpos - pos;
  89. }
  90.  
  91. static int supports_edts(MOVMuxContext *mov)
  92. {
  93.     // EDTS with fragments is tricky as we don't know the duration when its written
  94.     return (mov->use_editlist<0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) || mov->use_editlist>0;
  95. }
  96.  
  97. static int co64_required(const MOVTrack *track)
  98. {
  99.     if (track->entry > 0 && track->cluster[track->entry - 1].pos + track->data_offset > UINT32_MAX)
  100.         return 1;
  101.     return 0;
  102. }
  103.  
  104. /* Chunk offset atom */
  105. static int mov_write_stco_tag(AVIOContext *pb, MOVTrack *track)
  106. {
  107.     int i;
  108.     int mode64 = co64_required(track); // use 32 bit size variant if possible
  109.     int64_t pos = avio_tell(pb);
  110.     avio_wb32(pb, 0); /* size */
  111.     if (mode64)
  112.         ffio_wfourcc(pb, "co64");
  113.     else
  114.         ffio_wfourcc(pb, "stco");
  115.     avio_wb32(pb, 0); /* version & flags */
  116.     avio_wb32(pb, track->chunkCount); /* entry count */
  117.     for (i = 0; i < track->entry; i++) {
  118.         if (!track->cluster[i].chunkNum)
  119.             continue;
  120.         if (mode64 == 1)
  121.             avio_wb64(pb, track->cluster[i].pos + track->data_offset);
  122.         else
  123.             avio_wb32(pb, track->cluster[i].pos + track->data_offset);
  124.     }
  125.     return update_size(pb, pos);
  126. }
  127.  
  128. /* Sample size atom */
  129. static int mov_write_stsz_tag(AVIOContext *pb, MOVTrack *track)
  130. {
  131.     int equalChunks = 1;
  132.     int i, j, entries = 0, tst = -1, oldtst = -1;
  133.  
  134.     int64_t pos = avio_tell(pb);
  135.     avio_wb32(pb, 0); /* size */
  136.     ffio_wfourcc(pb, "stsz");
  137.     avio_wb32(pb, 0); /* version & flags */
  138.  
  139.     for (i = 0; i < track->entry; i++) {
  140.         tst = track->cluster[i].size / track->cluster[i].entries;
  141.         if (oldtst != -1 && tst != oldtst)
  142.             equalChunks = 0;
  143.         oldtst = tst;
  144.         entries += track->cluster[i].entries;
  145.     }
  146.     if (equalChunks && track->entry) {
  147.         int sSize = track->entry ? track->cluster[0].size / track->cluster[0].entries : 0;
  148.         sSize = FFMAX(1, sSize); // adpcm mono case could make sSize == 0
  149.         avio_wb32(pb, sSize); // sample size
  150.         avio_wb32(pb, entries); // sample count
  151.     } else {
  152.         avio_wb32(pb, 0); // sample size
  153.         avio_wb32(pb, entries); // sample count
  154.         for (i = 0; i < track->entry; i++) {
  155.             for (j = 0; j < track->cluster[i].entries; j++) {
  156.                 avio_wb32(pb, track->cluster[i].size /
  157.                           track->cluster[i].entries);
  158.             }
  159.         }
  160.     }
  161.     return update_size(pb, pos);
  162. }
  163.  
  164. /* Sample to chunk atom */
  165. static int mov_write_stsc_tag(AVIOContext *pb, MOVTrack *track)
  166. {
  167.     int index = 0, oldval = -1, i;
  168.     int64_t entryPos, curpos;
  169.  
  170.     int64_t pos = avio_tell(pb);
  171.     avio_wb32(pb, 0); /* size */
  172.     ffio_wfourcc(pb, "stsc");
  173.     avio_wb32(pb, 0); // version & flags
  174.     entryPos = avio_tell(pb);
  175.     avio_wb32(pb, track->chunkCount); // entry count
  176.     for (i = 0; i < track->entry; i++) {
  177.         if (oldval != track->cluster[i].samples_in_chunk && track->cluster[i].chunkNum) {
  178.             avio_wb32(pb, track->cluster[i].chunkNum); // first chunk
  179.             avio_wb32(pb, track->cluster[i].samples_in_chunk); // samples per chunk
  180.             avio_wb32(pb, 0x1); // sample description index
  181.             oldval = track->cluster[i].samples_in_chunk;
  182.             index++;
  183.         }
  184.     }
  185.     curpos = avio_tell(pb);
  186.     avio_seek(pb, entryPos, SEEK_SET);
  187.     avio_wb32(pb, index); // rewrite size
  188.     avio_seek(pb, curpos, SEEK_SET);
  189.  
  190.     return update_size(pb, pos);
  191. }
  192.  
  193. /* Sync sample atom */
  194. static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag)
  195. {
  196.     int64_t curpos, entryPos;
  197.     int i, index = 0;
  198.     int64_t pos = avio_tell(pb);
  199.     avio_wb32(pb, 0); // size
  200.     ffio_wfourcc(pb, flag == MOV_SYNC_SAMPLE ? "stss" : "stps");
  201.     avio_wb32(pb, 0); // version & flags
  202.     entryPos = avio_tell(pb);
  203.     avio_wb32(pb, track->entry); // entry count
  204.     for (i = 0; i < track->entry; i++) {
  205.         if (track->cluster[i].flags & flag) {
  206.             avio_wb32(pb, i + 1);
  207.             index++;
  208.         }
  209.     }
  210.     curpos = avio_tell(pb);
  211.     avio_seek(pb, entryPos, SEEK_SET);
  212.     avio_wb32(pb, index); // rewrite size
  213.     avio_seek(pb, curpos, SEEK_SET);
  214.     return update_size(pb, pos);
  215. }
  216.  
  217. static int mov_write_amr_tag(AVIOContext *pb, MOVTrack *track)
  218. {
  219.     avio_wb32(pb, 0x11); /* size */
  220.     if (track->mode == MODE_MOV) ffio_wfourcc(pb, "samr");
  221.     else                         ffio_wfourcc(pb, "damr");
  222.     ffio_wfourcc(pb, "FFMP");
  223.     avio_w8(pb, 0); /* decoder version */
  224.  
  225.     avio_wb16(pb, 0x81FF); /* Mode set (all modes for AMR_NB) */
  226.     avio_w8(pb, 0x00); /* Mode change period (no restriction) */
  227.     avio_w8(pb, 0x01); /* Frames per sample */
  228.     return 0x11;
  229. }
  230.  
  231. static int mov_write_ac3_tag(AVIOContext *pb, MOVTrack *track)
  232. {
  233.     GetBitContext gbc;
  234.     PutBitContext pbc;
  235.     uint8_t buf[3];
  236.     int fscod, bsid, bsmod, acmod, lfeon, frmsizecod;
  237.  
  238.     if (track->vos_len < 7)
  239.         return -1;
  240.  
  241.     avio_wb32(pb, 11);
  242.     ffio_wfourcc(pb, "dac3");
  243.  
  244.     init_get_bits(&gbc, track->vos_data + 4, (track->vos_len - 4) * 8);
  245.     fscod      = get_bits(&gbc, 2);
  246.     frmsizecod = get_bits(&gbc, 6);
  247.     bsid       = get_bits(&gbc, 5);
  248.     bsmod      = get_bits(&gbc, 3);
  249.     acmod      = get_bits(&gbc, 3);
  250.     if (acmod == 2) {
  251.         skip_bits(&gbc, 2); // dsurmod
  252.     } else {
  253.         if ((acmod & 1) && acmod != 1)
  254.             skip_bits(&gbc, 2); // cmixlev
  255.         if (acmod & 4)
  256.             skip_bits(&gbc, 2); // surmixlev
  257.     }
  258.     lfeon = get_bits1(&gbc);
  259.  
  260.     init_put_bits(&pbc, buf, sizeof(buf));
  261.     put_bits(&pbc, 2, fscod);
  262.     put_bits(&pbc, 5, bsid);
  263.     put_bits(&pbc, 3, bsmod);
  264.     put_bits(&pbc, 3, acmod);
  265.     put_bits(&pbc, 1, lfeon);
  266.     put_bits(&pbc, 5, frmsizecod >> 1); // bit_rate_code
  267.     put_bits(&pbc, 5, 0); // reserved
  268.  
  269.     flush_put_bits(&pbc);
  270.     avio_write(pb, buf, sizeof(buf));
  271.  
  272.     return 11;
  273. }
  274.  
  275. /**
  276.  * This function writes extradata "as is".
  277.  * Extradata must be formatted like a valid atom (with size and tag).
  278.  */
  279. static int mov_write_extradata_tag(AVIOContext *pb, MOVTrack *track)
  280. {
  281.     avio_write(pb, track->enc->extradata, track->enc->extradata_size);
  282.     return track->enc->extradata_size;
  283. }
  284.  
  285. static int mov_write_enda_tag(AVIOContext *pb)
  286. {
  287.     avio_wb32(pb, 10);
  288.     ffio_wfourcc(pb, "enda");
  289.     avio_wb16(pb, 1); /* little endian */
  290.     return 10;
  291. }
  292.  
  293. static int mov_write_enda_tag_be(AVIOContext *pb)
  294. {
  295.   avio_wb32(pb, 10);
  296.   ffio_wfourcc(pb, "enda");
  297.   avio_wb16(pb, 0); /* big endian */
  298.   return 10;
  299. }
  300.  
  301. static void put_descr(AVIOContext *pb, int tag, unsigned int size)
  302. {
  303.     int i = 3;
  304.     avio_w8(pb, tag);
  305.     for (; i > 0; i--)
  306.         avio_w8(pb, (size >> (7 * i)) | 0x80);
  307.     avio_w8(pb, size & 0x7F);
  308. }
  309.  
  310. static unsigned compute_avg_bitrate(MOVTrack *track)
  311. {
  312.     uint64_t size = 0;
  313.     int i;
  314.     if (!track->track_duration)
  315.         return 0;
  316.     for (i = 0; i < track->entry; i++)
  317.         size += track->cluster[i].size;
  318.     return size * 8 * track->timescale / track->track_duration;
  319. }
  320.  
  321. static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
  322. {
  323.     int64_t pos = avio_tell(pb);
  324.     int decoder_specific_info_len = track->vos_len ? 5 + track->vos_len : 0;
  325.     unsigned avg_bitrate;
  326.  
  327.     avio_wb32(pb, 0); // size
  328.     ffio_wfourcc(pb, "esds");
  329.     avio_wb32(pb, 0); // Version
  330.  
  331.     // ES descriptor
  332.     put_descr(pb, 0x03, 3 + 5+13 + decoder_specific_info_len + 5+1);
  333.     avio_wb16(pb, track->track_id);
  334.     avio_w8(pb, 0x00); // flags (= no flags)
  335.  
  336.     // DecoderConfig descriptor
  337.     put_descr(pb, 0x04, 13 + decoder_specific_info_len);
  338.  
  339.     // Object type indication
  340.     if ((track->enc->codec_id == AV_CODEC_ID_MP2 ||
  341.          track->enc->codec_id == AV_CODEC_ID_MP3) &&
  342.         track->enc->sample_rate > 24000)
  343.         avio_w8(pb, 0x6B); // 11172-3
  344.     else
  345.         avio_w8(pb, ff_codec_get_tag(ff_mp4_obj_type, track->enc->codec_id));
  346.  
  347.     // the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio)
  348.     // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
  349.     if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
  350.         avio_w8(pb, 0x15); // flags (= Audiostream)
  351.     else
  352.         avio_w8(pb, 0x11); // flags (= Visualstream)
  353.  
  354.     avio_wb24(pb, track->enc->rc_buffer_size >> 3); // Buffersize DB
  355.  
  356.     avg_bitrate = compute_avg_bitrate(track);
  357.     // maxbitrate (FIXME should be max rate in any 1 sec window)
  358.     avio_wb32(pb, FFMAX3(track->enc->bit_rate, track->enc->rc_max_rate, avg_bitrate));
  359.     avio_wb32(pb, avg_bitrate);
  360.  
  361.     if (track->vos_len) {
  362.         // DecoderSpecific info descriptor
  363.         put_descr(pb, 0x05, track->vos_len);
  364.         avio_write(pb, track->vos_data, track->vos_len);
  365.     }
  366.  
  367.     // SL descriptor
  368.     put_descr(pb, 0x06, 1);
  369.     avio_w8(pb, 0x02);
  370.     return update_size(pb, pos);
  371. }
  372.  
  373. static int mov_pcm_le_gt16(enum AVCodecID codec_id)
  374. {
  375.     return codec_id == AV_CODEC_ID_PCM_S24LE ||
  376.            codec_id == AV_CODEC_ID_PCM_S32LE ||
  377.            codec_id == AV_CODEC_ID_PCM_F32LE ||
  378.            codec_id == AV_CODEC_ID_PCM_F64LE;
  379. }
  380.  
  381. static int mov_pcm_be_gt16(enum AVCodecID codec_id)
  382. {
  383.     return codec_id == AV_CODEC_ID_PCM_S24BE ||
  384.            codec_id == AV_CODEC_ID_PCM_S32BE ||
  385.            codec_id == AV_CODEC_ID_PCM_F32BE ||
  386.            codec_id == AV_CODEC_ID_PCM_F64BE;
  387. }
  388.  
  389. static int mov_write_ms_tag(AVIOContext *pb, MOVTrack *track)
  390. {
  391.     int64_t pos = avio_tell(pb);
  392.     avio_wb32(pb, 0);
  393.     avio_wl32(pb, track->tag); // store it byteswapped
  394.     track->enc->codec_tag = av_bswap16(track->tag >> 16);
  395.     ff_put_wav_header(pb, track->enc);
  396.     return update_size(pb, pos);
  397. }
  398.  
  399. static int mov_write_wfex_tag(AVIOContext *pb, MOVTrack *track)
  400. {
  401.     int64_t pos = avio_tell(pb);
  402.     avio_wb32(pb, 0);
  403.     ffio_wfourcc(pb, "wfex");
  404.     ff_put_wav_header(pb, track->enc);
  405.     return update_size(pb, pos);
  406. }
  407.  
  408. static int mov_write_chan_tag(AVIOContext *pb, MOVTrack *track)
  409. {
  410.     uint32_t layout_tag, bitmap;
  411.     int64_t pos = avio_tell(pb);
  412.  
  413.     layout_tag = ff_mov_get_channel_layout_tag(track->enc->codec_id,
  414.                                                track->enc->channel_layout,
  415.                                                &bitmap);
  416.     if (!layout_tag) {
  417.         av_log(track->enc, AV_LOG_WARNING, "not writing 'chan' tag due to "
  418.                "lack of channel information\n");
  419.         return 0;
  420.     }
  421.  
  422.     avio_wb32(pb, 0);           // Size
  423.     ffio_wfourcc(pb, "chan");   // Type
  424.     avio_w8(pb, 0);             // Version
  425.     avio_wb24(pb, 0);           // Flags
  426.     avio_wb32(pb, layout_tag);  // mChannelLayoutTag
  427.     avio_wb32(pb, bitmap);      // mChannelBitmap
  428.     avio_wb32(pb, 0);           // mNumberChannelDescriptions
  429.  
  430.     return update_size(pb, pos);
  431. }
  432.  
  433. static int mov_write_wave_tag(AVIOContext *pb, MOVTrack *track)
  434. {
  435.     int64_t pos = avio_tell(pb);
  436.  
  437.     avio_wb32(pb, 0);     /* size */
  438.     ffio_wfourcc(pb, "wave");
  439.  
  440.     if (track->enc->codec_id != AV_CODEC_ID_QDM2) {
  441.     avio_wb32(pb, 12);    /* size */
  442.     ffio_wfourcc(pb, "frma");
  443.     avio_wl32(pb, track->tag);
  444.     }
  445.  
  446.     if (track->enc->codec_id == AV_CODEC_ID_AAC) {
  447.         /* useless atom needed by mplayer, ipod, not needed by quicktime */
  448.         avio_wb32(pb, 12); /* size */
  449.         ffio_wfourcc(pb, "mp4a");
  450.         avio_wb32(pb, 0);
  451.         mov_write_esds_tag(pb, track);
  452.     } else if (mov_pcm_le_gt16(track->enc->codec_id))  {
  453.       mov_write_enda_tag(pb);
  454.     } else if (mov_pcm_be_gt16(track->enc->codec_id))  {
  455.       mov_write_enda_tag_be(pb);
  456.     } else if (track->enc->codec_id == AV_CODEC_ID_AMR_NB) {
  457.         mov_write_amr_tag(pb, track);
  458.     } else if (track->enc->codec_id == AV_CODEC_ID_AC3) {
  459.         mov_write_ac3_tag(pb, track);
  460.     } else if (track->enc->codec_id == AV_CODEC_ID_ALAC ||
  461.                track->enc->codec_id == AV_CODEC_ID_QDM2) {
  462.         mov_write_extradata_tag(pb, track);
  463.     } else if (track->enc->codec_id == AV_CODEC_ID_ADPCM_MS ||
  464.                track->enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
  465.         mov_write_ms_tag(pb, track);
  466.     }
  467.  
  468.     avio_wb32(pb, 8);     /* size */
  469.     avio_wb32(pb, 0);     /* null tag */
  470.  
  471.     return update_size(pb, pos);
  472. }
  473.  
  474. static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
  475. {
  476.     uint8_t *unescaped;
  477.     const uint8_t *start, *next, *end = track->vos_data + track->vos_len;
  478.     int unescaped_size, seq_found = 0;
  479.     int level = 0, interlace = 0;
  480.     int packet_seq   = track->vc1_info.packet_seq;
  481.     int packet_entry = track->vc1_info.packet_entry;
  482.     int slices       = track->vc1_info.slices;
  483.     PutBitContext pbc;
  484.  
  485.     if (track->start_dts == AV_NOPTS_VALUE) {
  486.         /* No packets written yet, vc1_info isn't authoritative yet. */
  487.         /* Assume inline sequence and entry headers. This will be
  488.          * overwritten at the end if the file is seekable. */
  489.         packet_seq = packet_entry = 1;
  490.     }
  491.  
  492.     unescaped = av_mallocz(track->vos_len + FF_INPUT_BUFFER_PADDING_SIZE);
  493.     if (!unescaped)
  494.         return AVERROR(ENOMEM);
  495.     start = find_next_marker(track->vos_data, end);
  496.     for (next = start; next < end; start = next) {
  497.         GetBitContext gb;
  498.         int size;
  499.         next = find_next_marker(start + 4, end);
  500.         size = next - start - 4;
  501.         if (size <= 0)
  502.             continue;
  503.         unescaped_size = vc1_unescape_buffer(start + 4, size, unescaped);
  504.         init_get_bits(&gb, unescaped, 8 * unescaped_size);
  505.         if (AV_RB32(start) == VC1_CODE_SEQHDR) {
  506.             int profile = get_bits(&gb, 2);
  507.             if (profile != PROFILE_ADVANCED) {
  508.                 av_free(unescaped);
  509.                 return AVERROR(ENOSYS);
  510.             }
  511.             seq_found = 1;
  512.             level = get_bits(&gb, 3);
  513.             /* chromaformat, frmrtq_postproc, bitrtq_postproc, postprocflag,
  514.              * width, height */
  515.             skip_bits_long(&gb, 2 + 3 + 5 + 1 + 2*12);
  516.             skip_bits(&gb, 1); /* broadcast */
  517.             interlace = get_bits1(&gb);
  518.             skip_bits(&gb, 4); /* tfcntrflag, finterpflag, reserved, psf */
  519.         }
  520.     }
  521.     if (!seq_found) {
  522.         av_free(unescaped);
  523.         return AVERROR(ENOSYS);
  524.     }
  525.  
  526.     init_put_bits(&pbc, buf, 7);
  527.     /* VC1DecSpecStruc */
  528.     put_bits(&pbc, 4, 12); /* profile - advanced */
  529.     put_bits(&pbc, 3, level);
  530.     put_bits(&pbc, 1, 0); /* reserved */
  531.     /* VC1AdvDecSpecStruc */
  532.     put_bits(&pbc, 3, level);
  533.     put_bits(&pbc, 1, 0); /* cbr */
  534.     put_bits(&pbc, 6, 0); /* reserved */
  535.     put_bits(&pbc, 1, !interlace); /* no interlace */
  536.     put_bits(&pbc, 1, !packet_seq); /* no multiple seq */
  537.     put_bits(&pbc, 1, !packet_entry); /* no multiple entry */
  538.     put_bits(&pbc, 1, !slices); /* no slice code */
  539.     put_bits(&pbc, 1, 0); /* no bframe */
  540.     put_bits(&pbc, 1, 0); /* reserved */
  541.     put_bits32(&pbc, track->enc->time_base.den); /* framerate */
  542.     flush_put_bits(&pbc);
  543.  
  544.     av_free(unescaped);
  545.  
  546.     return 0;
  547. }
  548.  
  549. static int mov_write_dvc1_tag(AVIOContext *pb, MOVTrack *track)
  550. {
  551.     uint8_t buf[7] = { 0 };
  552.     int ret;
  553.  
  554.     if ((ret = mov_write_dvc1_structs(track, buf)) < 0)
  555.         return ret;
  556.  
  557.     avio_wb32(pb, track->vos_len + 8 + sizeof(buf));
  558.     ffio_wfourcc(pb, "dvc1");
  559.     track->vc1_info.struct_offset = avio_tell(pb);
  560.     avio_write(pb, buf, sizeof(buf));
  561.     avio_write(pb, track->vos_data, track->vos_len);
  562.  
  563.     return 0;
  564. }
  565.  
  566. static int mov_write_glbl_tag(AVIOContext *pb, MOVTrack *track)
  567. {
  568.     avio_wb32(pb, track->vos_len + 8);
  569.     ffio_wfourcc(pb, "glbl");
  570.     avio_write(pb, track->vos_data, track->vos_len);
  571.     return 8 + track->vos_len;
  572. }
  573.  
  574. /**
  575.  * Compute flags for 'lpcm' tag.
  576.  * See CoreAudioTypes and AudioStreamBasicDescription at Apple.
  577.  */
  578. static int mov_get_lpcm_flags(enum AVCodecID codec_id)
  579. {
  580.     switch (codec_id) {
  581.     case AV_CODEC_ID_PCM_F32BE:
  582.     case AV_CODEC_ID_PCM_F64BE:
  583.         return 11;
  584.     case AV_CODEC_ID_PCM_F32LE:
  585.     case AV_CODEC_ID_PCM_F64LE:
  586.         return 9;
  587.     case AV_CODEC_ID_PCM_U8:
  588.         return 10;
  589.     case AV_CODEC_ID_PCM_S16BE:
  590.     case AV_CODEC_ID_PCM_S24BE:
  591.     case AV_CODEC_ID_PCM_S32BE:
  592.         return 14;
  593.     case AV_CODEC_ID_PCM_S8:
  594.     case AV_CODEC_ID_PCM_S16LE:
  595.     case AV_CODEC_ID_PCM_S24LE:
  596.     case AV_CODEC_ID_PCM_S32LE:
  597.         return 12;
  598.     default:
  599.         return 0;
  600.     }
  601. }
  602.  
  603. static int get_cluster_duration(MOVTrack *track, int cluster_idx)
  604. {
  605.     int64_t next_dts;
  606.  
  607.     if (cluster_idx >= track->entry)
  608.         return 0;
  609.  
  610.     if (cluster_idx + 1 == track->entry)
  611.         next_dts = track->track_duration + track->start_dts;
  612.     else
  613.         next_dts = track->cluster[cluster_idx + 1].dts;
  614.  
  615.     return next_dts - track->cluster[cluster_idx].dts;
  616. }
  617.  
  618. static int get_samples_per_packet(MOVTrack *track)
  619. {
  620.     int i, first_duration;
  621.  
  622. // return track->enc->frame_size;
  623.  
  624.     /* use 1 for raw PCM */
  625.     if (!track->audio_vbr)
  626.         return 1;
  627.  
  628.     /* check to see if duration is constant for all clusters */
  629.     if (!track->entry)
  630.         return 0;
  631.     first_duration = get_cluster_duration(track, 0);
  632.     for (i = 1; i < track->entry; i++) {
  633.         if (get_cluster_duration(track, i) != first_duration)
  634.             return 0;
  635.     }
  636.     return first_duration;
  637. }
  638.  
  639. static int mov_write_audio_tag(AVIOContext *pb, MOVTrack *track)
  640. {
  641.     int64_t pos = avio_tell(pb);
  642.     int version = 0;
  643.     uint32_t tag = track->tag;
  644.  
  645.     if (track->mode == MODE_MOV) {
  646.         if (track->timescale > UINT16_MAX) {
  647.             if (mov_get_lpcm_flags(track->enc->codec_id))
  648.                 tag = AV_RL32("lpcm");
  649.             version = 2;
  650.         } else if (track->audio_vbr || mov_pcm_le_gt16(track->enc->codec_id) ||
  651.                    mov_pcm_be_gt16(track->enc->codec_id) ||
  652.                    track->enc->codec_id == AV_CODEC_ID_ADPCM_MS ||
  653.                    track->enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
  654.                    track->enc->codec_id == AV_CODEC_ID_QDM2) {
  655.             version = 1;
  656.         }
  657.     }
  658.  
  659.     avio_wb32(pb, 0); /* size */
  660.     avio_wl32(pb, tag); // store it byteswapped
  661.     avio_wb32(pb, 0); /* Reserved */
  662.     avio_wb16(pb, 0); /* Reserved */
  663.     avio_wb16(pb, 1); /* Data-reference index, XXX  == 1 */
  664.  
  665.     /* SoundDescription */
  666.     avio_wb16(pb, version); /* Version */
  667.     avio_wb16(pb, 0); /* Revision level */
  668.     avio_wb32(pb, 0); /* Reserved */
  669.  
  670.     if (version == 2) {
  671.         avio_wb16(pb, 3);
  672.         avio_wb16(pb, 16);
  673.         avio_wb16(pb, 0xfffe);
  674.         avio_wb16(pb, 0);
  675.         avio_wb32(pb, 0x00010000);
  676.         avio_wb32(pb, 72);
  677.         avio_wb64(pb, av_double2int(track->enc->sample_rate));
  678.         avio_wb32(pb, track->enc->channels);
  679.         avio_wb32(pb, 0x7F000000);
  680.         avio_wb32(pb, av_get_bits_per_sample(track->enc->codec_id));
  681.         avio_wb32(pb, mov_get_lpcm_flags(track->enc->codec_id));
  682.         avio_wb32(pb, track->sample_size);
  683.         avio_wb32(pb, get_samples_per_packet(track));
  684.     } else {
  685.         if (track->mode == MODE_MOV) {
  686.             avio_wb16(pb, track->enc->channels);
  687.             if (track->enc->codec_id == AV_CODEC_ID_PCM_U8 ||
  688.                 track->enc->codec_id == AV_CODEC_ID_PCM_S8)
  689.                 avio_wb16(pb, 8); /* bits per sample */
  690.             else
  691.                 avio_wb16(pb, 16);
  692.             avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */
  693.         } else { /* reserved for mp4/3gp */
  694.             avio_wb16(pb, 2);
  695.             avio_wb16(pb, 16);
  696.             avio_wb16(pb, 0);
  697.         }
  698.  
  699.         avio_wb16(pb, 0); /* packet size (= 0) */
  700.         avio_wb16(pb, track->enc->sample_rate <= UINT16_MAX ?
  701.                       track->enc->sample_rate : 0);
  702.         avio_wb16(pb, 0); /* Reserved */
  703.     }
  704.  
  705.     if (version == 1) { /* SoundDescription V1 extended info */
  706.         if (mov_pcm_le_gt16(track->enc->codec_id) ||
  707.             mov_pcm_be_gt16(track->enc->codec_id))
  708.             avio_wb32(pb, 1); /*  must be 1 for  uncompressed formats */
  709.         else
  710.             avio_wb32(pb, track->enc->frame_size); /* Samples per packet */
  711.         avio_wb32(pb, track->sample_size / track->enc->channels); /* Bytes per packet */
  712.         avio_wb32(pb, track->sample_size); /* Bytes per frame */
  713.         avio_wb32(pb, 2); /* Bytes per sample */
  714.     }
  715.  
  716.     if (track->mode == MODE_MOV &&
  717.         (track->enc->codec_id == AV_CODEC_ID_AAC           ||
  718.          track->enc->codec_id == AV_CODEC_ID_AC3           ||
  719.          track->enc->codec_id == AV_CODEC_ID_AMR_NB        ||
  720.          track->enc->codec_id == AV_CODEC_ID_ALAC          ||
  721.          track->enc->codec_id == AV_CODEC_ID_ADPCM_MS      ||
  722.          track->enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
  723.          track->enc->codec_id == AV_CODEC_ID_QDM2          ||
  724.          (mov_pcm_le_gt16(track->enc->codec_id) && version==1) ||
  725.          (mov_pcm_be_gt16(track->enc->codec_id) && version==1)))
  726.         mov_write_wave_tag(pb, track);
  727.     else if (track->tag == MKTAG('m','p','4','a'))
  728.         mov_write_esds_tag(pb, track);
  729.     else if (track->enc->codec_id == AV_CODEC_ID_AMR_NB)
  730.         mov_write_amr_tag(pb, track);
  731.     else if (track->enc->codec_id == AV_CODEC_ID_AC3)
  732.         mov_write_ac3_tag(pb, track);
  733.     else if (track->enc->codec_id == AV_CODEC_ID_ALAC)
  734.         mov_write_extradata_tag(pb, track);
  735.     else if (track->enc->codec_id == AV_CODEC_ID_WMAPRO)
  736.         mov_write_wfex_tag(pb, track);
  737.     else if (track->vos_len > 0)
  738.         mov_write_glbl_tag(pb, track);
  739.  
  740.     if (track->mode == MODE_MOV && track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
  741.         mov_write_chan_tag(pb, track);
  742.  
  743.     return update_size(pb, pos);
  744. }
  745.  
  746. static int mov_write_d263_tag(AVIOContext *pb)
  747. {
  748.     avio_wb32(pb, 0xf); /* size */
  749.     ffio_wfourcc(pb, "d263");
  750.     ffio_wfourcc(pb, "FFMP");
  751.     avio_w8(pb, 0); /* decoder version */
  752.     /* FIXME use AVCodecContext level/profile, when encoder will set values */
  753.     avio_w8(pb, 0xa); /* level */
  754.     avio_w8(pb, 0); /* profile */
  755.     return 0xf;
  756. }
  757.  
  758. static int mov_write_avcc_tag(AVIOContext *pb, MOVTrack *track)
  759. {
  760.     int64_t pos = avio_tell(pb);
  761.  
  762.     avio_wb32(pb, 0);
  763.     ffio_wfourcc(pb, "avcC");
  764.     ff_isom_write_avcc(pb, track->vos_data, track->vos_len);
  765.     return update_size(pb, pos);
  766. }
  767.  
  768. /* also used by all avid codecs (dv, imx, meridien) and their variants */
  769. static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
  770. {
  771.     int i;
  772.     avio_wb32(pb, 24); /* size */
  773.     ffio_wfourcc(pb, "ACLR");
  774.     ffio_wfourcc(pb, "ACLR");
  775.     ffio_wfourcc(pb, "0001");
  776.     avio_wb32(pb, 2); /* yuv range: full 1 / normal 2 */
  777.     avio_wb32(pb, 0); /* unknown */
  778.  
  779.     avio_wb32(pb, 24); /* size */
  780.     ffio_wfourcc(pb, "APRG");
  781.     ffio_wfourcc(pb, "APRG");
  782.     ffio_wfourcc(pb, "0001");
  783.     avio_wb32(pb, 1); /* unknown */
  784.     avio_wb32(pb, 0); /* unknown */
  785.  
  786.     avio_wb32(pb, 120); /* size */
  787.     ffio_wfourcc(pb, "ARES");
  788.     ffio_wfourcc(pb, "ARES");
  789.     ffio_wfourcc(pb, "0001");
  790.     avio_wb32(pb, AV_RB32(track->vos_data + 0x28)); /* dnxhd cid, some id ? */
  791.     avio_wb32(pb, track->enc->width);
  792.     /* values below are based on samples created with quicktime and avid codecs */
  793.     if (track->vos_data[5] & 2) { // interlaced
  794.         avio_wb32(pb, track->enc->height / 2);
  795.         avio_wb32(pb, 2); /* unknown */
  796.         avio_wb32(pb, 0); /* unknown */
  797.         avio_wb32(pb, 4); /* unknown */
  798.     } else {
  799.         avio_wb32(pb, track->enc->height);
  800.         avio_wb32(pb, 1); /* unknown */
  801.         avio_wb32(pb, 0); /* unknown */
  802.         if (track->enc->height == 1080)
  803.             avio_wb32(pb, 5); /* unknown */
  804.         else
  805.             avio_wb32(pb, 6); /* unknown */
  806.     }
  807.     /* padding */
  808.     for (i = 0; i < 10; i++)
  809.         avio_wb64(pb, 0);
  810.  
  811.     /* extra padding for stsd needed */
  812.     avio_wb32(pb, 0);
  813.     return 0;
  814. }
  815.  
  816. static int mp4_get_codec_tag(AVFormatContext *s, MOVTrack *track)
  817. {
  818.     int tag = track->enc->codec_tag;
  819.  
  820.     if (!ff_codec_get_tag(ff_mp4_obj_type, track->enc->codec_id))
  821.         return 0;
  822.  
  823.     if      (track->enc->codec_id == AV_CODEC_ID_H264)      tag = MKTAG('a','v','c','1');
  824.     else if (track->enc->codec_id == AV_CODEC_ID_AC3)       tag = MKTAG('a','c','-','3');
  825.     else if (track->enc->codec_id == AV_CODEC_ID_DIRAC)     tag = MKTAG('d','r','a','c');
  826.     else if (track->enc->codec_id == AV_CODEC_ID_MOV_TEXT)  tag = MKTAG('t','x','3','g');
  827.     else if (track->enc->codec_id == AV_CODEC_ID_VC1)       tag = MKTAG('v','c','-','1');
  828.     else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO)  tag = MKTAG('m','p','4','v');
  829.     else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)  tag = MKTAG('m','p','4','a');
  830.  
  831.     return tag;
  832. }
  833.  
  834. static const AVCodecTag codec_ipod_tags[] = {
  835.     { AV_CODEC_ID_H264,     MKTAG('a','v','c','1') },
  836.     { AV_CODEC_ID_MPEG4,    MKTAG('m','p','4','v') },
  837.     { AV_CODEC_ID_AAC,      MKTAG('m','p','4','a') },
  838.     { AV_CODEC_ID_ALAC,     MKTAG('a','l','a','c') },
  839.     { AV_CODEC_ID_AC3,      MKTAG('a','c','-','3') },
  840.     { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
  841.     { AV_CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') },
  842.     { AV_CODEC_ID_NONE, 0 },
  843. };
  844.  
  845. static int ipod_get_codec_tag(AVFormatContext *s, MOVTrack *track)
  846. {
  847.     int tag = track->enc->codec_tag;
  848.  
  849.     // keep original tag for subs, ipod supports both formats
  850.     if (!(track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE &&
  851.           (tag == MKTAG('t', 'x', '3', 'g') ||
  852.            tag == MKTAG('t', 'e', 'x', 't'))))
  853.         tag = ff_codec_get_tag(codec_ipod_tags, track->enc->codec_id);
  854.  
  855.     if (!av_match_ext(s->filename, "m4a") && !av_match_ext(s->filename, "m4v"))
  856.         av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v "
  857.                "Quicktime/Ipod might not play the file\n");
  858.  
  859.     return tag;
  860. }
  861.  
  862. static int mov_get_dv_codec_tag(AVFormatContext *s, MOVTrack *track)
  863. {
  864.     int tag;
  865.  
  866.     if (track->enc->width == 720) { /* SD */
  867.         if (track->enc->height == 480) { /* NTSC */
  868.             if  (track->enc->pix_fmt == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n');
  869.             else                                            tag = MKTAG('d','v','c',' ');
  870.        }else if (track->enc->pix_fmt == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p');
  871.         else if (track->enc->pix_fmt == AV_PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
  872.         else                                                tag = MKTAG('d','v','p','p');
  873.     } else if (track->enc->height == 720) { /* HD 720 line */
  874.         if  (track->enc->time_base.den == 50)               tag = MKTAG('d','v','h','q');
  875.         else                                                tag = MKTAG('d','v','h','p');
  876.     } else if (track->enc->height == 1080) { /* HD 1080 line */
  877.         if  (track->enc->time_base.den == 25)               tag = MKTAG('d','v','h','5');
  878.         else                                                tag = MKTAG('d','v','h','6');
  879.     } else {
  880.         av_log(s, AV_LOG_ERROR, "unsupported height for dv codec\n");
  881.         return 0;
  882.     }
  883.  
  884.     return tag;
  885. }
  886.  
  887. static AVRational find_fps(AVFormatContext *s, AVStream *st)
  888. {
  889.     AVRational rate = {st->codec->time_base.den, st->codec->time_base.num};
  890.     /* if the codec time base makes no sense, try to fallback on stream frame rate */
  891.     if (av_timecode_check_frame_rate(rate) < 0) {
  892.         av_log(s, AV_LOG_DEBUG, "timecode: tbc=%d/%d invalid, fallback on %d/%d\n",
  893.                rate.num, rate.den, st->avg_frame_rate.num, st->avg_frame_rate.den);
  894.         rate = st->avg_frame_rate;
  895.     }
  896.  
  897.     return rate;
  898. }
  899.  
  900. static int mov_get_mpeg2_xdcam_codec_tag(AVFormatContext *s, MOVTrack *track)
  901. {
  902.     int tag = MKTAG('m', '2', 'v', '1'); //fallback tag
  903.     int interlaced = track->enc->field_order > AV_FIELD_PROGRESSIVE;
  904.     AVStream *st = track->st;
  905.     int rate = av_q2d(find_fps(s, st));
  906.  
  907.     if (track->enc->pix_fmt == AV_PIX_FMT_YUV420P) {
  908.         if (track->enc->width == 1280 && track->enc->height == 720) {
  909.             if (!interlaced) {
  910.                 if      (rate == 24) tag = MKTAG('x','d','v','4');
  911.                 else if (rate == 25) tag = MKTAG('x','d','v','5');
  912.                 else if (rate == 30) tag = MKTAG('x','d','v','1');
  913.                 else if (rate == 50) tag = MKTAG('x','d','v','a');
  914.                 else if (rate == 60) tag = MKTAG('x','d','v','9');
  915.             }
  916.         } else if (track->enc->width == 1440 && track->enc->height == 1080) {
  917.             if (!interlaced) {
  918.                 if      (rate == 24) tag = MKTAG('x','d','v','6');
  919.                 else if (rate == 25) tag = MKTAG('x','d','v','7');
  920.                 else if (rate == 30) tag = MKTAG('x','d','v','8');
  921.             } else {
  922.                 if      (rate == 25) tag = MKTAG('x','d','v','3');
  923.                 else if (rate == 30) tag = MKTAG('x','d','v','2');
  924.             }
  925.         } else if (track->enc->width == 1920 && track->enc->height == 1080) {
  926.             if (!interlaced) {
  927.                 if      (rate == 24) tag = MKTAG('x','d','v','d');
  928.                 else if (rate == 25) tag = MKTAG('x','d','v','e');
  929.                 else if (rate == 30) tag = MKTAG('x','d','v','f');
  930.             } else {
  931.                 if      (rate == 25) tag = MKTAG('x','d','v','c');
  932.                 else if (rate == 30) tag = MKTAG('x','d','v','b');
  933.             }
  934.         }
  935.     } else if (track->enc->pix_fmt == AV_PIX_FMT_YUV422P) {
  936.         if (track->enc->width == 1280 && track->enc->height == 720) {
  937.             if (!interlaced) {
  938.                 if      (rate == 24) tag = MKTAG('x','d','5','4');
  939.                 else if (rate == 25) tag = MKTAG('x','d','5','5');
  940.                 else if (rate == 30) tag = MKTAG('x','d','5','1');
  941.                 else if (rate == 50) tag = MKTAG('x','d','5','a');
  942.                 else if (rate == 60) tag = MKTAG('x','d','5','9');
  943.             }
  944.         } else if (track->enc->width == 1920 && track->enc->height == 1080) {
  945.             if (!interlaced) {
  946.                 if      (rate == 24) tag = MKTAG('x','d','5','d');
  947.                 else if (rate == 25) tag = MKTAG('x','d','5','e');
  948.                 else if (rate == 30) tag = MKTAG('x','d','5','f');
  949.             } else {
  950.                 if      (rate == 25) tag = MKTAG('x','d','5','c');
  951.                 else if (rate == 30) tag = MKTAG('x','d','5','b');
  952.             }
  953.         }
  954.     }
  955.  
  956.     return tag;
  957. }
  958.  
  959. static const struct {
  960.     enum AVPixelFormat pix_fmt;
  961.     uint32_t tag;
  962.     unsigned bps;
  963. } mov_pix_fmt_tags[] = {
  964.     { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','2'),  0 },
  965.     { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','s'),  0 },
  966.     { AV_PIX_FMT_UYVY422, MKTAG('2','v','u','y'),  0 },
  967.     { AV_PIX_FMT_RGB555BE,MKTAG('r','a','w',' '), 16 },
  968.     { AV_PIX_FMT_RGB555LE,MKTAG('L','5','5','5'), 16 },
  969.     { AV_PIX_FMT_RGB565LE,MKTAG('L','5','6','5'), 16 },
  970.     { AV_PIX_FMT_RGB565BE,MKTAG('B','5','6','5'), 16 },
  971.     { AV_PIX_FMT_GRAY16BE,MKTAG('b','1','6','g'), 16 },
  972.     { AV_PIX_FMT_RGB24,   MKTAG('r','a','w',' '), 24 },
  973.     { AV_PIX_FMT_BGR24,   MKTAG('2','4','B','G'), 24 },
  974.     { AV_PIX_FMT_ARGB,    MKTAG('r','a','w',' '), 32 },
  975.     { AV_PIX_FMT_BGRA,    MKTAG('B','G','R','A'), 32 },
  976.     { AV_PIX_FMT_RGBA,    MKTAG('R','G','B','A'), 32 },
  977.     { AV_PIX_FMT_ABGR,    MKTAG('A','B','G','R'), 32 },
  978.     { AV_PIX_FMT_RGB48BE, MKTAG('b','4','8','r'), 48 },
  979. };
  980.  
  981. static int mov_get_rawvideo_codec_tag(AVFormatContext *s, MOVTrack *track)
  982. {
  983.     int tag = track->enc->codec_tag;
  984.     int i;
  985.  
  986.     for (i = 0; i < FF_ARRAY_ELEMS(mov_pix_fmt_tags); i++) {
  987.         if (track->enc->pix_fmt == mov_pix_fmt_tags[i].pix_fmt) {
  988.             tag = mov_pix_fmt_tags[i].tag;
  989.             track->enc->bits_per_coded_sample = mov_pix_fmt_tags[i].bps;
  990.             if (track->enc->codec_tag == mov_pix_fmt_tags[i].tag)
  991.                 break;
  992.         }
  993.     }
  994.  
  995.     return tag;
  996. }
  997.  
  998. static int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track)
  999. {
  1000.     int tag = track->enc->codec_tag;
  1001.  
  1002.     if (!tag || (track->enc->strict_std_compliance >= FF_COMPLIANCE_NORMAL &&
  1003.                  (track->enc->codec_id == AV_CODEC_ID_DVVIDEO ||
  1004.                   track->enc->codec_id == AV_CODEC_ID_RAWVIDEO ||
  1005.                   track->enc->codec_id == AV_CODEC_ID_H263 ||
  1006.                   track->enc->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
  1007.                   av_get_bits_per_sample(track->enc->codec_id)))) { // pcm audio
  1008.         if (track->enc->codec_id == AV_CODEC_ID_DVVIDEO)
  1009.             tag = mov_get_dv_codec_tag(s, track);
  1010.         else if (track->enc->codec_id == AV_CODEC_ID_RAWVIDEO)
  1011.             tag = mov_get_rawvideo_codec_tag(s, track);
  1012.         else if (track->enc->codec_id == AV_CODEC_ID_MPEG2VIDEO)
  1013.             tag = mov_get_mpeg2_xdcam_codec_tag(s, track);
  1014.         else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
  1015.             tag = ff_codec_get_tag(ff_codec_movvideo_tags, track->enc->codec_id);
  1016.             if (!tag) { // if no mac fcc found, try with Microsoft tags
  1017.                 tag = ff_codec_get_tag(ff_codec_bmp_tags, track->enc->codec_id);
  1018.                 if (tag)
  1019.                     av_log(s, AV_LOG_WARNING, "Using MS style video codec tag, "
  1020.                            "the file may be unplayable!\n");
  1021.             }
  1022.         } else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) {
  1023.             tag = ff_codec_get_tag(ff_codec_movaudio_tags, track->enc->codec_id);
  1024.             if (!tag) { // if no mac fcc found, try with Microsoft tags
  1025.                 int ms_tag = ff_codec_get_tag(ff_codec_wav_tags, track->enc->codec_id);
  1026.                 if (ms_tag) {
  1027.                     tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff));
  1028.                     av_log(s, AV_LOG_WARNING, "Using MS style audio codec tag, "
  1029.                            "the file may be unplayable!\n");
  1030.                 }
  1031.             }
  1032.         } else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)
  1033.             tag = ff_codec_get_tag(ff_codec_movsubtitle_tags, track->enc->codec_id);
  1034.     }
  1035.  
  1036.     return tag;
  1037. }
  1038.  
  1039. static const AVCodecTag codec_3gp_tags[] = {
  1040.     { AV_CODEC_ID_H263,     MKTAG('s','2','6','3') },
  1041.     { AV_CODEC_ID_H264,     MKTAG('a','v','c','1') },
  1042.     { AV_CODEC_ID_MPEG4,    MKTAG('m','p','4','v') },
  1043.     { AV_CODEC_ID_AAC,      MKTAG('m','p','4','a') },
  1044.     { AV_CODEC_ID_AMR_NB,   MKTAG('s','a','m','r') },
  1045.     { AV_CODEC_ID_AMR_WB,   MKTAG('s','a','w','b') },
  1046.     { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') },
  1047.     { AV_CODEC_ID_NONE, 0 },
  1048. };
  1049.  
  1050. static const AVCodecTag codec_f4v_tags[] = { // XXX: add GIF/PNG/JPEG?
  1051.     { AV_CODEC_ID_MP3,    MKTAG('.','m','p','3') },
  1052.     { AV_CODEC_ID_AAC,    MKTAG('m','p','4','a') },
  1053.     { AV_CODEC_ID_H264,   MKTAG('a','v','c','1') },
  1054.     { AV_CODEC_ID_VP6A,   MKTAG('V','P','6','A') },
  1055.     { AV_CODEC_ID_VP6F,   MKTAG('V','P','6','F') },
  1056.     { AV_CODEC_ID_NONE, 0 },
  1057. };
  1058.  
  1059. static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track)
  1060. {
  1061.     int tag;
  1062.  
  1063.     if (track->mode == MODE_MP4 || track->mode == MODE_PSP)
  1064.         tag = mp4_get_codec_tag(s, track);
  1065.     else if (track->mode == MODE_ISM) {
  1066.         tag = mp4_get_codec_tag(s, track);
  1067.         if (!tag && track->enc->codec_id == AV_CODEC_ID_WMAPRO)
  1068.             tag = MKTAG('w', 'm', 'a', ' ');
  1069.     } else if (track->mode == MODE_IPOD)
  1070.         tag = ipod_get_codec_tag(s, track);
  1071.     else if (track->mode & MODE_3GP)
  1072.         tag = ff_codec_get_tag(codec_3gp_tags, track->enc->codec_id);
  1073.     else if (track->mode == MODE_F4V)
  1074.         tag = ff_codec_get_tag(codec_f4v_tags, track->enc->codec_id);
  1075.     else
  1076.         tag = mov_get_codec_tag(s, track);
  1077.  
  1078.     return tag;
  1079. }
  1080.  
  1081. /** Write uuid atom.
  1082.  * Needed to make file play in iPods running newest firmware
  1083.  * goes after avcC atom in moov.trak.mdia.minf.stbl.stsd.avc1
  1084.  */
  1085. static int mov_write_uuid_tag_ipod(AVIOContext *pb)
  1086. {
  1087.     avio_wb32(pb, 28);
  1088.     ffio_wfourcc(pb, "uuid");
  1089.     avio_wb32(pb, 0x6b6840f2);
  1090.     avio_wb32(pb, 0x5f244fc5);
  1091.     avio_wb32(pb, 0xba39a51b);
  1092.     avio_wb32(pb, 0xcf0323f3);
  1093.     avio_wb32(pb, 0x0);
  1094.     return 28;
  1095. }
  1096.  
  1097. static const uint16_t fiel_data[] = {
  1098.     0x0000, 0x0100, 0x0201, 0x0206, 0x0209, 0x020e
  1099. };
  1100.  
  1101. static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track)
  1102. {
  1103.     unsigned mov_field_order = 0;
  1104.     if (track->enc->field_order < FF_ARRAY_ELEMS(fiel_data))
  1105.         mov_field_order = fiel_data[track->enc->field_order];
  1106.     else
  1107.         return 0;
  1108.     avio_wb32(pb, 10);
  1109.     ffio_wfourcc(pb, "fiel");
  1110.     avio_wb16(pb, mov_field_order);
  1111.     return 10;
  1112. }
  1113.  
  1114. static int mov_write_subtitle_tag(AVIOContext *pb, MOVTrack *track)
  1115. {
  1116.     int64_t pos = avio_tell(pb);
  1117.     avio_wb32(pb, 0);    /* size */
  1118.     avio_wl32(pb, track->tag); // store it byteswapped
  1119.     avio_wb32(pb, 0);    /* Reserved */
  1120.     avio_wb16(pb, 0);    /* Reserved */
  1121.     avio_wb16(pb, 1);    /* Data-reference index */
  1122.  
  1123.     if (track->enc->extradata_size)
  1124.         avio_write(pb, track->enc->extradata, track->enc->extradata_size);
  1125.  
  1126.     return update_size(pb, pos);
  1127. }
  1128.  
  1129. static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track)
  1130. {
  1131.     AVRational sar;
  1132.     av_reduce(&sar.num, &sar.den, track->enc->sample_aspect_ratio.num,
  1133.               track->enc->sample_aspect_ratio.den, INT_MAX);
  1134.  
  1135.     avio_wb32(pb, 16);
  1136.     ffio_wfourcc(pb, "pasp");
  1137.     avio_wb32(pb, sar.num);
  1138.     avio_wb32(pb, sar.den);
  1139.     return 16;
  1140. }
  1141.  
  1142. static void find_compressor(char * compressor_name, int len, MOVTrack *track)
  1143. {
  1144.     int xdcam_res =  (track->enc->width == 1280 && track->enc->height == 720)
  1145.                   || (track->enc->width == 1440 && track->enc->height == 1080)
  1146.                   || (track->enc->width == 1920 && track->enc->height == 1080);
  1147.  
  1148.     if (track->mode == MODE_MOV && track->enc->codec && track->enc->codec->name) {
  1149.         av_strlcpy(compressor_name, track->enc->codec->name, 32);
  1150.     } else if (track->enc->codec_id == AV_CODEC_ID_MPEG2VIDEO && xdcam_res) {
  1151.         int interlaced = track->enc->field_order > AV_FIELD_PROGRESSIVE;
  1152.         AVStream *st = track->st;
  1153.         int rate = av_q2d(find_fps(NULL, st));
  1154.         av_strlcatf(compressor_name, len, "XDCAM");
  1155.         if (track->enc->pix_fmt == AV_PIX_FMT_YUV422P) {
  1156.             av_strlcatf(compressor_name, len, " HD422");
  1157.         } else if(track->enc->width == 1440) {
  1158.             av_strlcatf(compressor_name, len, " HD");
  1159.         } else
  1160.             av_strlcatf(compressor_name, len, " EX");
  1161.  
  1162.         av_strlcatf(compressor_name, len, " %d%c", track->enc->height, interlaced ? 'i' : 'p');
  1163.  
  1164.         av_strlcatf(compressor_name, len, "%d", rate * (interlaced + 1));
  1165.     }
  1166. }
  1167.  
  1168. static int mov_write_video_tag(AVIOContext *pb, MOVTrack *track)
  1169. {
  1170.     int64_t pos = avio_tell(pb);
  1171.     char compressor_name[32] = { 0 };
  1172.  
  1173.     avio_wb32(pb, 0); /* size */
  1174.     avio_wl32(pb, track->tag); // store it byteswapped
  1175.     avio_wb32(pb, 0); /* Reserved */
  1176.     avio_wb16(pb, 0); /* Reserved */
  1177.     avio_wb16(pb, 1); /* Data-reference index */
  1178.  
  1179.     avio_wb16(pb, 0); /* Codec stream version */
  1180.     avio_wb16(pb, 0); /* Codec stream revision (=0) */
  1181.     if (track->mode == MODE_MOV) {
  1182.         ffio_wfourcc(pb, "FFMP"); /* Vendor */
  1183.         if (track->enc->codec_id == AV_CODEC_ID_RAWVIDEO) {
  1184.             avio_wb32(pb, 0); /* Temporal Quality */
  1185.             avio_wb32(pb, 0x400); /* Spatial Quality = lossless*/
  1186.         } else {
  1187.             avio_wb32(pb, 0x200); /* Temporal Quality = normal */
  1188.             avio_wb32(pb, 0x200); /* Spatial Quality = normal */
  1189.         }
  1190.     } else {
  1191.         avio_wb32(pb, 0); /* Reserved */
  1192.         avio_wb32(pb, 0); /* Reserved */
  1193.         avio_wb32(pb, 0); /* Reserved */
  1194.     }
  1195.     avio_wb16(pb, track->enc->width); /* Video width */
  1196.     avio_wb16(pb, track->height); /* Video height */
  1197.     avio_wb32(pb, 0x00480000); /* Horizontal resolution 72dpi */
  1198.     avio_wb32(pb, 0x00480000); /* Vertical resolution 72dpi */
  1199.     avio_wb32(pb, 0); /* Data size (= 0) */
  1200.     avio_wb16(pb, 1); /* Frame count (= 1) */
  1201.  
  1202.     /* FIXME not sure, ISO 14496-1 draft where it shall be set to 0 */
  1203.     find_compressor(compressor_name, 32, track);
  1204.     avio_w8(pb, strlen(compressor_name));
  1205.     avio_write(pb, compressor_name, 31);
  1206.  
  1207.     if (track->mode == MODE_MOV && track->enc->bits_per_coded_sample)
  1208.         avio_wb16(pb, track->enc->bits_per_coded_sample);
  1209.     else
  1210.         avio_wb16(pb, 0x18); /* Reserved */
  1211.     avio_wb16(pb, 0xffff); /* Reserved */
  1212.     if (track->tag == MKTAG('m','p','4','v'))
  1213.         mov_write_esds_tag(pb, track);
  1214.     else if (track->enc->codec_id == AV_CODEC_ID_H263)
  1215.         mov_write_d263_tag(pb);
  1216.     else if (track->enc->codec_id == AV_CODEC_ID_AVUI ||
  1217.             track->enc->codec_id == AV_CODEC_ID_SVQ3) {
  1218.         mov_write_extradata_tag(pb, track);
  1219.         avio_wb32(pb, 0);
  1220.     } else if (track->enc->codec_id == AV_CODEC_ID_DNXHD)
  1221.         mov_write_avid_tag(pb, track);
  1222.     else if (track->enc->codec_id == AV_CODEC_ID_H264) {
  1223.         mov_write_avcc_tag(pb, track);
  1224.         if (track->mode == MODE_IPOD)
  1225.             mov_write_uuid_tag_ipod(pb);
  1226.     } else if (track->enc->codec_id == AV_CODEC_ID_VC1 && track->vos_len > 0)
  1227.         mov_write_dvc1_tag(pb, track);
  1228.     else if (track->enc->codec_id == AV_CODEC_ID_VP6F ||
  1229.              track->enc->codec_id == AV_CODEC_ID_VP6A) {
  1230.         /* Don't write any potential extradata here - the cropping
  1231.          * is signalled via the normal width/height fields. */
  1232.     } else if (track->vos_len > 0)
  1233.         mov_write_glbl_tag(pb, track);
  1234.  
  1235.     if (track->enc->codec_id != AV_CODEC_ID_H264 &&
  1236.         track->enc->codec_id != AV_CODEC_ID_MPEG4 &&
  1237.         track->enc->codec_id != AV_CODEC_ID_DNXHD)
  1238.         if (track->enc->field_order != AV_FIELD_UNKNOWN)
  1239.             mov_write_fiel_tag(pb, track);
  1240.  
  1241.     if (track->enc->sample_aspect_ratio.den && track->enc->sample_aspect_ratio.num &&
  1242.         track->enc->sample_aspect_ratio.den != track->enc->sample_aspect_ratio.num) {
  1243.         mov_write_pasp_tag(pb, track);
  1244.     }
  1245.  
  1246.     return update_size(pb, pos);
  1247. }
  1248.  
  1249. static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track)
  1250. {
  1251.     int64_t pos = avio_tell(pb);
  1252.     avio_wb32(pb, 0); /* size */
  1253.     ffio_wfourcc(pb, "rtp ");
  1254.     avio_wb32(pb, 0); /* Reserved */
  1255.     avio_wb16(pb, 0); /* Reserved */
  1256.     avio_wb16(pb, 1); /* Data-reference index */
  1257.  
  1258.     avio_wb16(pb, 1); /* Hint track version */
  1259.     avio_wb16(pb, 1); /* Highest compatible version */
  1260.     avio_wb32(pb, track->max_packet_size); /* Max packet size */
  1261.  
  1262.     avio_wb32(pb, 12); /* size */
  1263.     ffio_wfourcc(pb, "tims");
  1264.     avio_wb32(pb, track->timescale);
  1265.  
  1266.     return update_size(pb, pos);
  1267. }
  1268.  
  1269. static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track)
  1270. {
  1271.     int64_t pos = avio_tell(pb);
  1272. #if 1
  1273.     int frame_duration = av_rescale(track->timescale, track->enc->time_base.num, track->enc->time_base.den);
  1274.     int nb_frames = 1.0/av_q2d(track->enc->time_base) + 0.5;
  1275.  
  1276.     if (nb_frames > 255) {
  1277.         av_log(NULL, AV_LOG_ERROR, "fps %d is too large\n", nb_frames);
  1278.         return AVERROR(EINVAL);
  1279.     }
  1280.  
  1281.     avio_wb32(pb, 0); /* size */
  1282.     ffio_wfourcc(pb, "tmcd");               /* Data format */
  1283.     avio_wb32(pb, 0);                       /* Reserved */
  1284.     avio_wb32(pb, 1);                       /* Data reference index */
  1285.     avio_wb32(pb, 0);                       /* Flags */
  1286.     avio_wb32(pb, track->timecode_flags);   /* Flags (timecode) */
  1287.     avio_wb32(pb, track->timescale);        /* Timescale */
  1288.     avio_wb32(pb, frame_duration);          /* Frame duration */
  1289.     avio_w8(pb, nb_frames);                 /* Number of frames */
  1290.     avio_wb24(pb, 0);                       /* Reserved */
  1291.     /* TODO: source reference string */
  1292. #else
  1293.  
  1294.     avio_wb32(pb, 0); /* size */
  1295.     ffio_wfourcc(pb, "tmcd");               /* Data format */
  1296.     avio_wb32(pb, 0);                       /* Reserved */
  1297.     avio_wb32(pb, 1);                       /* Data reference index */
  1298.     if (track->enc->extradata_size)
  1299.         avio_write(pb, track->enc->extradata, track->enc->extradata_size);
  1300. #endif
  1301.     return update_size(pb, pos);
  1302. }
  1303.  
  1304. static int mov_write_stsd_tag(AVIOContext *pb, MOVTrack *track)
  1305. {
  1306.     int64_t pos = avio_tell(pb);
  1307.     avio_wb32(pb, 0); /* size */
  1308.     ffio_wfourcc(pb, "stsd");
  1309.     avio_wb32(pb, 0); /* version & flags */
  1310.     avio_wb32(pb, 1); /* entry count */
  1311.     if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO)
  1312.         mov_write_video_tag(pb, track);
  1313.     else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
  1314.         mov_write_audio_tag(pb, track);
  1315.     else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)
  1316.         mov_write_subtitle_tag(pb, track);
  1317.     else if (track->enc->codec_tag == MKTAG('r','t','p',' '))
  1318.         mov_write_rtp_tag(pb, track);
  1319.     else if (track->enc->codec_tag == MKTAG('t','m','c','d'))
  1320.         mov_write_tmcd_tag(pb, track);
  1321.     return update_size(pb, pos);
  1322. }
  1323.  
  1324. static int mov_write_ctts_tag(AVIOContext *pb, MOVTrack *track)
  1325. {
  1326.     MOVStts *ctts_entries;
  1327.     uint32_t entries = 0;
  1328.     uint32_t atom_size;
  1329.     int i;
  1330.  
  1331.     ctts_entries = av_malloc((track->entry + 1) * sizeof(*ctts_entries)); /* worst case */
  1332.     ctts_entries[0].count = 1;
  1333.     ctts_entries[0].duration = track->cluster[0].cts;
  1334.     for (i = 1; i < track->entry; i++) {
  1335.         if (track->cluster[i].cts == ctts_entries[entries].duration) {
  1336.             ctts_entries[entries].count++; /* compress */
  1337.         } else {
  1338.             entries++;
  1339.             ctts_entries[entries].duration = track->cluster[i].cts;
  1340.             ctts_entries[entries].count = 1;
  1341.         }
  1342.     }
  1343.     entries++; /* last one */
  1344.     atom_size = 16 + (entries * 8);
  1345.     avio_wb32(pb, atom_size); /* size */
  1346.     ffio_wfourcc(pb, "ctts");
  1347.     avio_wb32(pb, 0); /* version & flags */
  1348.     avio_wb32(pb, entries); /* entry count */
  1349.     for (i = 0; i < entries; i++) {
  1350.         avio_wb32(pb, ctts_entries[i].count);
  1351.         avio_wb32(pb, ctts_entries[i].duration);
  1352.     }
  1353.     av_free(ctts_entries);
  1354.     return atom_size;
  1355. }
  1356.  
  1357. /* Time to sample atom */
  1358. static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track)
  1359. {
  1360.     MOVStts *stts_entries;
  1361.     uint32_t entries = -1;
  1362.     uint32_t atom_size;
  1363.     int i;
  1364.  
  1365.     if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO && !track->audio_vbr) {
  1366.         stts_entries = av_malloc(sizeof(*stts_entries)); /* one entry */
  1367.         stts_entries[0].count = track->sample_count;
  1368.         stts_entries[0].duration = 1;
  1369.         entries = 1;
  1370.     } else {
  1371.         stts_entries = track->entry ?
  1372.                        av_malloc(track->entry * sizeof(*stts_entries)) : /* worst case */
  1373.                        NULL;
  1374.         for (i = 0; i < track->entry; i++) {
  1375.             int duration = get_cluster_duration(track, i);
  1376.             if (i && duration == stts_entries[entries].duration) {
  1377.                 stts_entries[entries].count++; /* compress */
  1378.             } else {
  1379.                 entries++;
  1380.                 stts_entries[entries].duration = duration;
  1381.                 stts_entries[entries].count = 1;
  1382.             }
  1383.         }
  1384.         entries++; /* last one */
  1385.     }
  1386.     atom_size = 16 + (entries * 8);
  1387.     avio_wb32(pb, atom_size); /* size */
  1388.     ffio_wfourcc(pb, "stts");
  1389.     avio_wb32(pb, 0); /* version & flags */
  1390.     avio_wb32(pb, entries); /* entry count */
  1391.     for (i = 0; i < entries; i++) {
  1392.         avio_wb32(pb, stts_entries[i].count);
  1393.         avio_wb32(pb, stts_entries[i].duration);
  1394.     }
  1395.     av_free(stts_entries);
  1396.     return atom_size;
  1397. }
  1398.  
  1399. static int mov_write_dref_tag(AVIOContext *pb)
  1400. {
  1401.     avio_wb32(pb, 28); /* size */
  1402.     ffio_wfourcc(pb, "dref");
  1403.     avio_wb32(pb, 0); /* version & flags */
  1404.     avio_wb32(pb, 1); /* entry count */
  1405.  
  1406.     avio_wb32(pb, 0xc); /* size */
  1407.     //FIXME add the alis and rsrc atom
  1408.     ffio_wfourcc(pb, "url ");
  1409.     avio_wb32(pb, 1); /* version & flags */
  1410.  
  1411.     return 28;
  1412. }
  1413.  
  1414. static int mov_write_stbl_tag(AVIOContext *pb, MOVTrack *track)
  1415. {
  1416.     int64_t pos = avio_tell(pb);
  1417.     avio_wb32(pb, 0); /* size */
  1418.     ffio_wfourcc(pb, "stbl");
  1419.     mov_write_stsd_tag(pb, track);
  1420.     mov_write_stts_tag(pb, track);
  1421.     if ((track->enc->codec_type == AVMEDIA_TYPE_VIDEO ||
  1422.          track->enc->codec_tag == MKTAG('r','t','p',' ')) &&
  1423.         track->has_keyframes && track->has_keyframes < track->entry)
  1424.         mov_write_stss_tag(pb, track, MOV_SYNC_SAMPLE);
  1425.     if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS)
  1426.         mov_write_stss_tag(pb, track, MOV_PARTIAL_SYNC_SAMPLE);
  1427.     if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO &&
  1428.         track->flags & MOV_TRACK_CTTS)
  1429.         mov_write_ctts_tag(pb, track);
  1430.     mov_write_stsc_tag(pb, track);
  1431.     mov_write_stsz_tag(pb, track);
  1432.     mov_write_stco_tag(pb, track);
  1433.     return update_size(pb, pos);
  1434. }
  1435.  
  1436. static int mov_write_dinf_tag(AVIOContext *pb)
  1437. {
  1438.     int64_t pos = avio_tell(pb);
  1439.     avio_wb32(pb, 0); /* size */
  1440.     ffio_wfourcc(pb, "dinf");
  1441.     mov_write_dref_tag(pb);
  1442.     return update_size(pb, pos);
  1443. }
  1444.  
  1445. static int mov_write_nmhd_tag(AVIOContext *pb)
  1446. {
  1447.     avio_wb32(pb, 12);
  1448.     ffio_wfourcc(pb, "nmhd");
  1449.     avio_wb32(pb, 0);
  1450.     return 12;
  1451. }
  1452.  
  1453. static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track)
  1454. {
  1455.     int64_t pos = avio_tell(pb);
  1456.     const char *font = "Lucida Grande";
  1457.     avio_wb32(pb, 0);                   /* size */
  1458.     ffio_wfourcc(pb, "tcmi");           /* timecode media information atom */
  1459.     avio_wb32(pb, 0);                   /* version & flags */
  1460.     avio_wb16(pb, 0);                   /* text font */
  1461.     avio_wb16(pb, 0);                   /* text face */
  1462.     avio_wb16(pb, 12);                  /* text size */
  1463.     avio_wb16(pb, 0);                   /* (unknown, not in the QT specs...) */
  1464.     avio_wb16(pb, 0x0000);              /* text color (red) */
  1465.     avio_wb16(pb, 0x0000);              /* text color (green) */
  1466.     avio_wb16(pb, 0x0000);              /* text color (blue) */
  1467.     avio_wb16(pb, 0xffff);              /* background color (red) */
  1468.     avio_wb16(pb, 0xffff);              /* background color (green) */
  1469.     avio_wb16(pb, 0xffff);              /* background color (blue) */
  1470.     avio_w8(pb, strlen(font));          /* font len (part of the pascal string) */
  1471.     avio_write(pb, font, strlen(font)); /* font name */
  1472.     return update_size(pb, pos);
  1473. }
  1474.  
  1475. static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track)
  1476. {
  1477.     int64_t pos = avio_tell(pb);
  1478.     avio_wb32(pb, 0);      /* size */
  1479.     ffio_wfourcc(pb, "gmhd");
  1480.     avio_wb32(pb, 0x18);   /* gmin size */
  1481.     ffio_wfourcc(pb, "gmin");/* generic media info */
  1482.     avio_wb32(pb, 0);      /* version & flags */
  1483.     avio_wb16(pb, 0x40);   /* graphics mode = */
  1484.     avio_wb16(pb, 0x8000); /* opColor (r?) */
  1485.     avio_wb16(pb, 0x8000); /* opColor (g?) */
  1486.     avio_wb16(pb, 0x8000); /* opColor (b?) */
  1487.     avio_wb16(pb, 0);      /* balance */
  1488.     avio_wb16(pb, 0);      /* reserved */
  1489.  
  1490.     /*
  1491.      * This special text atom is required for
  1492.      * Apple Quicktime chapters. The contents
  1493.      * don't appear to be documented, so the
  1494.      * bytes are copied verbatim.
  1495.      */
  1496.     if (track->tag != MKTAG('c','6','0','8')) {
  1497.     avio_wb32(pb, 0x2C);   /* size */
  1498.     ffio_wfourcc(pb, "text");
  1499.     avio_wb16(pb, 0x01);
  1500.     avio_wb32(pb, 0x00);
  1501.     avio_wb32(pb, 0x00);
  1502.     avio_wb32(pb, 0x00);
  1503.     avio_wb32(pb, 0x01);
  1504.     avio_wb32(pb, 0x00);
  1505.     avio_wb32(pb, 0x00);
  1506.     avio_wb32(pb, 0x00);
  1507.     avio_wb32(pb, 0x00004000);
  1508.     avio_wb16(pb, 0x0000);
  1509.     }
  1510.  
  1511.     if (track->enc->codec_tag == MKTAG('t','m','c','d')) {
  1512.         int64_t tmcd_pos = avio_tell(pb);
  1513.         avio_wb32(pb, 0); /* size */
  1514.         ffio_wfourcc(pb, "tmcd");
  1515.         mov_write_tcmi_tag(pb, track);
  1516.         update_size(pb, tmcd_pos);
  1517.     }
  1518.     return update_size(pb, pos);
  1519. }
  1520.  
  1521. static int mov_write_smhd_tag(AVIOContext *pb)
  1522. {
  1523.     avio_wb32(pb, 16); /* size */
  1524.     ffio_wfourcc(pb, "smhd");
  1525.     avio_wb32(pb, 0); /* version & flags */
  1526.     avio_wb16(pb, 0); /* reserved (balance, normally = 0) */
  1527.     avio_wb16(pb, 0); /* reserved */
  1528.     return 16;
  1529. }
  1530.  
  1531. static int mov_write_vmhd_tag(AVIOContext *pb)
  1532. {
  1533.     avio_wb32(pb, 0x14); /* size (always 0x14) */
  1534.     ffio_wfourcc(pb, "vmhd");
  1535.     avio_wb32(pb, 0x01); /* version & flags */
  1536.     avio_wb64(pb, 0); /* reserved (graphics mode = copy) */
  1537.     return 0x14;
  1538. }
  1539.  
  1540. static int mov_write_hdlr_tag(AVIOContext *pb, MOVTrack *track)
  1541. {
  1542.     const char *hdlr, *descr = NULL, *hdlr_type = NULL;
  1543.     int64_t pos = avio_tell(pb);
  1544.  
  1545.     hdlr      = "dhlr";
  1546.     hdlr_type = "url ";
  1547.     descr     = "DataHandler";
  1548.  
  1549.     if (track) {
  1550.         hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0";
  1551.         if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
  1552.             hdlr_type = "vide";
  1553.             descr     = "VideoHandler";
  1554.         } else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) {
  1555.             hdlr_type = "soun";
  1556.             descr     = "SoundHandler";
  1557.         } else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
  1558.             if (track->tag == MKTAG('c','6','0','8')) {
  1559.                 hdlr_type = "clcp";
  1560.                 descr = "ClosedCaptionHandler";
  1561.             } else {
  1562.             if (track->tag == MKTAG('t','x','3','g')) hdlr_type = "sbtl";
  1563.             else                                      hdlr_type = "text";
  1564.             descr = "SubtitleHandler";
  1565.             }
  1566.         } else if (track->enc->codec_tag == MKTAG('r','t','p',' ')) {
  1567.             hdlr_type = "hint";
  1568.             descr     = "HintHandler";
  1569.         } else if (track->enc->codec_tag == MKTAG('t','m','c','d')) {
  1570.             hdlr_type = "tmcd";
  1571.             descr = "TimeCodeHandler";
  1572.         } else {
  1573.             char tag_buf[32];
  1574.             av_get_codec_tag_string(tag_buf, sizeof(tag_buf),
  1575.                                     track->enc->codec_tag);
  1576.  
  1577.             av_log(track->enc, AV_LOG_WARNING,
  1578.                    "Unknown hldr_type for %s / 0x%04X, writing dummy values\n",
  1579.                    tag_buf, track->enc->codec_tag);
  1580.         }
  1581.     }
  1582.  
  1583.     avio_wb32(pb, 0); /* size */
  1584.     ffio_wfourcc(pb, "hdlr");
  1585.     avio_wb32(pb, 0); /* Version & flags */
  1586.     avio_write(pb, hdlr, 4); /* handler */
  1587.     ffio_wfourcc(pb, hdlr_type); /* handler type */
  1588.     avio_wb32(pb, 0); /* reserved */
  1589.     avio_wb32(pb, 0); /* reserved */
  1590.     avio_wb32(pb, 0); /* reserved */
  1591.     if (!track || track->mode == MODE_MOV)
  1592.         avio_w8(pb, strlen(descr)); /* pascal string */
  1593.     avio_write(pb, descr, strlen(descr)); /* handler description */
  1594.     if (track && track->mode != MODE_MOV)
  1595.         avio_w8(pb, 0); /* c string */
  1596.     return update_size(pb, pos);
  1597. }
  1598.  
  1599. static int mov_write_hmhd_tag(AVIOContext *pb)
  1600. {
  1601.     /* This atom must be present, but leaving the values at zero
  1602.      * seems harmless. */
  1603.     avio_wb32(pb, 28); /* size */
  1604.     ffio_wfourcc(pb, "hmhd");
  1605.     avio_wb32(pb, 0); /* version, flags */
  1606.     avio_wb16(pb, 0); /* maxPDUsize */
  1607.     avio_wb16(pb, 0); /* avgPDUsize */
  1608.     avio_wb32(pb, 0); /* maxbitrate */
  1609.     avio_wb32(pb, 0); /* avgbitrate */
  1610.     avio_wb32(pb, 0); /* reserved */
  1611.     return 28;
  1612. }
  1613.  
  1614. static int mov_write_minf_tag(AVIOContext *pb, MOVTrack *track)
  1615. {
  1616.     int64_t pos = avio_tell(pb);
  1617.     avio_wb32(pb, 0); /* size */
  1618.     ffio_wfourcc(pb, "minf");
  1619.     if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO)
  1620.         mov_write_vmhd_tag(pb);
  1621.     else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
  1622.         mov_write_smhd_tag(pb);
  1623.     else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
  1624.         if (track->tag == MKTAG('t','e','x','t') || track->tag == MKTAG('c','6','0','8')) {
  1625.             mov_write_gmhd_tag(pb, track);
  1626.         } else {
  1627.             mov_write_nmhd_tag(pb);
  1628.         }
  1629.     } else if (track->tag == MKTAG('r','t','p',' ')) {
  1630.         mov_write_hmhd_tag(pb);
  1631.     } else if (track->tag == MKTAG('t','m','c','d')) {
  1632.         mov_write_gmhd_tag(pb, track);
  1633.     }
  1634.     if (track->mode == MODE_MOV) /* FIXME: Why do it for MODE_MOV only ? */
  1635.         mov_write_hdlr_tag(pb, NULL);
  1636.     mov_write_dinf_tag(pb);
  1637.     mov_write_stbl_tag(pb, track);
  1638.     return update_size(pb, pos);
  1639. }
  1640.  
  1641. static int mov_write_mdhd_tag(AVIOContext *pb, MOVTrack *track)
  1642. {
  1643.     int version = track->track_duration < INT32_MAX ? 0 : 1;
  1644.  
  1645.     if (track->mode == MODE_ISM)
  1646.         version = 1;
  1647.  
  1648.     (version == 1) ? avio_wb32(pb, 44) : avio_wb32(pb, 32); /* size */
  1649.     ffio_wfourcc(pb, "mdhd");
  1650.     avio_w8(pb, version);
  1651.     avio_wb24(pb, 0); /* flags */
  1652.     if (version == 1) {
  1653.         avio_wb64(pb, track->time);
  1654.         avio_wb64(pb, track->time);
  1655.     } else {
  1656.         avio_wb32(pb, track->time); /* creation time */
  1657.         avio_wb32(pb, track->time); /* modification time */
  1658.     }
  1659.     avio_wb32(pb, track->timescale); /* time scale (sample rate for audio) */
  1660.     if (!track->entry)
  1661.         (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
  1662.     else
  1663.         (version == 1) ? avio_wb64(pb, track->track_duration) : avio_wb32(pb, track->track_duration); /* duration */
  1664.     avio_wb16(pb, track->language); /* language */
  1665.     avio_wb16(pb, 0); /* reserved (quality) */
  1666.  
  1667.     if (version != 0 && track->mode == MODE_MOV) {
  1668.         av_log(NULL, AV_LOG_ERROR,
  1669.                "FATAL error, file duration too long for timebase, this file will not be\n"
  1670.                "playable with quicktime. Choose a different timebase or a different\n"
  1671.                "container format\n");
  1672.     }
  1673.  
  1674.     return 32;
  1675. }
  1676.  
  1677. static int mov_write_mdia_tag(AVIOContext *pb, MOVTrack *track)
  1678. {
  1679.     int64_t pos = avio_tell(pb);
  1680.     avio_wb32(pb, 0); /* size */
  1681.     ffio_wfourcc(pb, "mdia");
  1682.     mov_write_mdhd_tag(pb, track);
  1683.     mov_write_hdlr_tag(pb, track);
  1684.     mov_write_minf_tag(pb, track);
  1685.     return update_size(pb, pos);
  1686. }
  1687.  
  1688. /* transformation matrix
  1689.      |a  b  u|
  1690.      |c  d  v|
  1691.      |tx ty w| */
  1692. static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c,
  1693.                          int16_t d, int16_t tx, int16_t ty)
  1694. {
  1695.     avio_wb32(pb, a << 16);  /* 16.16 format */
  1696.     avio_wb32(pb, b << 16);  /* 16.16 format */
  1697.     avio_wb32(pb, 0);        /* u in 2.30 format */
  1698.     avio_wb32(pb, c << 16);  /* 16.16 format */
  1699.     avio_wb32(pb, d << 16);  /* 16.16 format */
  1700.     avio_wb32(pb, 0);        /* v in 2.30 format */
  1701.     avio_wb32(pb, tx << 16); /* 16.16 format */
  1702.     avio_wb32(pb, ty << 16); /* 16.16 format */
  1703.     avio_wb32(pb, 1 << 30);  /* w in 2.30 format */
  1704. }
  1705.  
  1706. static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
  1707. {
  1708.     int64_t duration = av_rescale_rnd(track->track_duration, MOV_TIMESCALE,
  1709.                                       track->timescale, AV_ROUND_UP);
  1710.     int version = duration < INT32_MAX ? 0 : 1;
  1711.     int rotation = 0;
  1712.  
  1713.     if (track->mode == MODE_ISM)
  1714.         version = 1;
  1715.  
  1716.     (version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
  1717.     ffio_wfourcc(pb, "tkhd");
  1718.     avio_w8(pb, version);
  1719.     avio_wb24(pb, (track->flags & MOV_TRACK_ENABLED) ?
  1720.                   MOV_TKHD_FLAG_ENABLED | MOV_TKHD_FLAG_IN_MOVIE :
  1721.                   MOV_TKHD_FLAG_IN_MOVIE);
  1722.     if (version == 1) {
  1723.         avio_wb64(pb, track->time);
  1724.         avio_wb64(pb, track->time);
  1725.     } else {
  1726.         avio_wb32(pb, track->time); /* creation time */
  1727.         avio_wb32(pb, track->time); /* modification time */
  1728.     }
  1729.     avio_wb32(pb, track->track_id); /* track-id */
  1730.     avio_wb32(pb, 0); /* reserved */
  1731.     if (!track->entry)
  1732.         (version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
  1733.     else
  1734.         (version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
  1735.  
  1736.     avio_wb32(pb, 0); /* reserved */
  1737.     avio_wb32(pb, 0); /* reserved */
  1738.     avio_wb16(pb, 0); /* layer */
  1739.     avio_wb16(pb, st ? st->codec->codec_type : 0); /* alternate group) */
  1740.     /* Volume, only for audio */
  1741.     if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
  1742.         avio_wb16(pb, 0x0100);
  1743.     else
  1744.         avio_wb16(pb, 0);
  1745.     avio_wb16(pb, 0); /* reserved */
  1746.  
  1747.     /* Matrix structure */
  1748.     if (st && st->metadata) {
  1749.         AVDictionaryEntry *rot = av_dict_get(st->metadata, "rotate", NULL, 0);
  1750.         rotation = (rot && rot->value) ? atoi(rot->value) : 0;
  1751.     }
  1752.     if (rotation == 90) {
  1753.         write_matrix(pb,  0,  1, -1,  0, track->enc->height, 0);
  1754.     } else if (rotation == 180) {
  1755.         write_matrix(pb, -1,  0,  0, -1, track->enc->width, track->enc->height);
  1756.     } else if (rotation == 270) {
  1757.         write_matrix(pb,  0, -1,  1,  0, 0, track->enc->width);
  1758.     } else {
  1759.         write_matrix(pb,  1,  0,  0,  1, 0, 0);
  1760.     }
  1761.     /* Track width and height, for visual only */
  1762.     if (st && (track->enc->codec_type == AVMEDIA_TYPE_VIDEO ||
  1763.                track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)) {
  1764.         if (track->mode == MODE_MOV) {
  1765.             avio_wb32(pb, track->enc->width << 16);
  1766.             avio_wb32(pb, track->height << 16);
  1767.         } else {
  1768.             double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
  1769.             if (!sample_aspect_ratio || track->height != track->enc->height)
  1770.                 sample_aspect_ratio = 1;
  1771.             avio_wb32(pb, sample_aspect_ratio * track->enc->width * 0x10000);
  1772.             avio_wb32(pb, track->height * 0x10000);
  1773.         }
  1774.     } else {
  1775.         avio_wb32(pb, 0);
  1776.         avio_wb32(pb, 0);
  1777.     }
  1778.     return 0x5c;
  1779. }
  1780.  
  1781. static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track)
  1782. {
  1783.     int32_t width = av_rescale(track->enc->sample_aspect_ratio.num, track->enc->width,
  1784.                                track->enc->sample_aspect_ratio.den);
  1785.  
  1786.     int64_t pos = avio_tell(pb);
  1787.  
  1788.     avio_wb32(pb, 0); /* size */
  1789.     ffio_wfourcc(pb, "tapt");
  1790.  
  1791.     avio_wb32(pb, 20);
  1792.     ffio_wfourcc(pb, "clef");
  1793.     avio_wb32(pb, 0);
  1794.     avio_wb32(pb, width << 16);
  1795.     avio_wb32(pb, track->enc->height << 16);
  1796.  
  1797.     avio_wb32(pb, 20);
  1798.     ffio_wfourcc(pb, "prof");
  1799.     avio_wb32(pb, 0);
  1800.     avio_wb32(pb, width << 16);
  1801.     avio_wb32(pb, track->enc->height << 16);
  1802.  
  1803.     avio_wb32(pb, 20);
  1804.     ffio_wfourcc(pb, "enof");
  1805.     avio_wb32(pb, 0);
  1806.     avio_wb32(pb, track->enc->width << 16);
  1807.     avio_wb32(pb, track->enc->height << 16);
  1808.  
  1809.     return update_size(pb, pos);
  1810. }
  1811.  
  1812. // This box seems important for the psp playback ... without it the movie seems to hang
  1813. static int mov_write_edts_tag(AVIOContext *pb, MOVTrack *track)
  1814. {
  1815.     int64_t duration = av_rescale_rnd(track->track_duration, MOV_TIMESCALE,
  1816.                                       track->timescale, AV_ROUND_UP);
  1817.     int version = duration < INT32_MAX ? 0 : 1;
  1818.     int entry_size, entry_count, size;
  1819.     int64_t delay, start_ct = track->cluster[0].cts;
  1820.     delay = av_rescale_rnd(track->cluster[0].dts + start_ct, MOV_TIMESCALE,
  1821.                            track->timescale, AV_ROUND_DOWN);
  1822.     version |= delay < INT32_MAX ? 0 : 1;
  1823.  
  1824.     entry_size = (version == 1) ? 20 : 12;
  1825.     entry_count = 1 + (delay > 0);
  1826.     size = 24 + entry_count * entry_size;
  1827.  
  1828.     /* write the atom data */
  1829.     avio_wb32(pb, size);
  1830.     ffio_wfourcc(pb, "edts");
  1831.     avio_wb32(pb, size - 8);
  1832.     ffio_wfourcc(pb, "elst");
  1833.     avio_w8(pb, version);
  1834.     avio_wb24(pb, 0); /* flags */
  1835.  
  1836.     avio_wb32(pb, entry_count);
  1837.     if (delay > 0) { /* add an empty edit to delay presentation */
  1838.         if (version == 1) {
  1839.             avio_wb64(pb, delay);
  1840.             avio_wb64(pb, -1);
  1841.         } else {
  1842.             avio_wb32(pb, delay);
  1843.             avio_wb32(pb, -1);
  1844.         }
  1845.         avio_wb32(pb, 0x00010000);
  1846.     } else {
  1847.         av_assert0(av_rescale_rnd(track->cluster[0].dts, MOV_TIMESCALE, track->timescale, AV_ROUND_DOWN) <= 0);
  1848.         start_ct  = -FFMIN(track->cluster[0].dts, 0); //FFMIN needed due to rounding
  1849.         duration += delay;
  1850.     }
  1851.  
  1852.     /* duration */
  1853.     if (version == 1) {
  1854.         avio_wb64(pb, duration);
  1855.         avio_wb64(pb, start_ct);
  1856.     } else {
  1857.         avio_wb32(pb, duration);
  1858.         avio_wb32(pb, start_ct);
  1859.     }
  1860.     avio_wb32(pb, 0x00010000);
  1861.     return size;
  1862. }
  1863.  
  1864. static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track)
  1865. {
  1866.     avio_wb32(pb, 20);   // size
  1867.     ffio_wfourcc(pb, "tref");
  1868.     avio_wb32(pb, 12);   // size (subatom)
  1869.     avio_wl32(pb, track->tref_tag);
  1870.     avio_wb32(pb, track->tref_id);
  1871.     return 20;
  1872. }
  1873.  
  1874. // goes at the end of each track!  ... Critical for PSP playback ("Incompatible data" without it)
  1875. static int mov_write_uuid_tag_psp(AVIOContext *pb, MOVTrack *mov)
  1876. {
  1877.     avio_wb32(pb, 0x34); /* size ... reports as 28 in mp4box! */
  1878.     ffio_wfourcc(pb, "uuid");
  1879.     ffio_wfourcc(pb, "USMT");
  1880.     avio_wb32(pb, 0x21d24fce);
  1881.     avio_wb32(pb, 0xbb88695c);
  1882.     avio_wb32(pb, 0xfac9c740);
  1883.     avio_wb32(pb, 0x1c);     // another size here!
  1884.     ffio_wfourcc(pb, "MTDT");
  1885.     avio_wb32(pb, 0x00010012);
  1886.     avio_wb32(pb, 0x0a);
  1887.     avio_wb32(pb, 0x55c40000);
  1888.     avio_wb32(pb, 0x1);
  1889.     avio_wb32(pb, 0x0);
  1890.     return 0x34;
  1891. }
  1892.  
  1893. static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track)
  1894. {
  1895.     AVFormatContext *ctx = track->rtp_ctx;
  1896.     char buf[1000] = "";
  1897.     int len;
  1898.  
  1899.     ff_sdp_write_media(buf, sizeof(buf), ctx->streams[0], track->src_track,
  1900.                        NULL, NULL, 0, 0, ctx);
  1901.     av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", track->track_id);
  1902.     len = strlen(buf);
  1903.  
  1904.     avio_wb32(pb, len + 24);
  1905.     ffio_wfourcc(pb, "udta");
  1906.     avio_wb32(pb, len + 16);
  1907.     ffio_wfourcc(pb, "hnti");
  1908.     avio_wb32(pb, len + 8);
  1909.     ffio_wfourcc(pb, "sdp ");
  1910.     avio_write(pb, buf, len);
  1911.     return len + 24;
  1912. }
  1913.  
  1914. static int mov_write_trak_tag(AVIOContext *pb, MOVMuxContext *mov,
  1915.                               MOVTrack *track, AVStream *st)
  1916. {
  1917.     int64_t pos = avio_tell(pb);
  1918.     avio_wb32(pb, 0); /* size */
  1919.     ffio_wfourcc(pb, "trak");
  1920.     mov_write_tkhd_tag(pb, track, st);
  1921.     if (supports_edts(mov))
  1922.         mov_write_edts_tag(pb, track);  // PSP Movies and several other cases require edts box
  1923.     if (track->tref_tag)
  1924.         mov_write_tref_tag(pb, track);
  1925.     mov_write_mdia_tag(pb, track);
  1926.     if (track->mode == MODE_PSP)
  1927.         mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box
  1928.     if (track->tag == MKTAG('r','t','p',' '))
  1929.         mov_write_udta_sdp(pb, track);
  1930.     if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO && track->mode == MODE_MOV) {
  1931.         double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
  1932.         if (st->sample_aspect_ratio.num && 1.0 != sample_aspect_ratio)
  1933.             mov_write_tapt_tag(pb, track);
  1934.     }
  1935.     return update_size(pb, pos);
  1936. }
  1937.  
  1938. static int mov_write_iods_tag(AVIOContext *pb, MOVMuxContext *mov)
  1939. {
  1940.     int i, has_audio = 0, has_video = 0;
  1941.     int64_t pos = avio_tell(pb);
  1942.     int audio_profile = mov->iods_audio_profile;
  1943.     int video_profile = mov->iods_video_profile;
  1944.     for (i = 0; i < mov->nb_streams; i++) {
  1945.         if (mov->tracks[i].entry > 0) {
  1946.             has_audio |= mov->tracks[i].enc->codec_type == AVMEDIA_TYPE_AUDIO;
  1947.             has_video |= mov->tracks[i].enc->codec_type == AVMEDIA_TYPE_VIDEO;
  1948.         }
  1949.     }
  1950.     if (audio_profile < 0)
  1951.         audio_profile = 0xFF - has_audio;
  1952.     if (video_profile < 0)
  1953.         video_profile = 0xFF - has_video;
  1954.     avio_wb32(pb, 0x0); /* size */
  1955.     ffio_wfourcc(pb, "iods");
  1956.     avio_wb32(pb, 0);    /* version & flags */
  1957.     put_descr(pb, 0x10, 7);
  1958.     avio_wb16(pb, 0x004f);
  1959.     avio_w8(pb, 0xff);
  1960.     avio_w8(pb, 0xff);
  1961.     avio_w8(pb, audio_profile);
  1962.     avio_w8(pb, video_profile);
  1963.     avio_w8(pb, 0xff);
  1964.     return update_size(pb, pos);
  1965. }
  1966.  
  1967. static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track)
  1968. {
  1969.     avio_wb32(pb, 0x20); /* size */
  1970.     ffio_wfourcc(pb, "trex");
  1971.     avio_wb32(pb, 0);   /* version & flags */
  1972.     avio_wb32(pb, track->track_id); /* track ID */
  1973.     avio_wb32(pb, 1);   /* default sample description index */
  1974.     avio_wb32(pb, 0);   /* default sample duration */
  1975.     avio_wb32(pb, 0);   /* default sample size */
  1976.     avio_wb32(pb, 0);   /* default sample flags */
  1977.     return 0;
  1978. }
  1979.  
  1980. static int mov_write_mvex_tag(AVIOContext *pb, MOVMuxContext *mov)
  1981. {
  1982.     int64_t pos = avio_tell(pb);
  1983.     int i;
  1984.     avio_wb32(pb, 0x0); /* size */
  1985.     ffio_wfourcc(pb, "mvex");
  1986.     for (i = 0; i < mov->nb_streams; i++)
  1987.         mov_write_trex_tag(pb, &mov->tracks[i]);
  1988.     return update_size(pb, pos);
  1989. }
  1990.  
  1991. static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov)
  1992. {
  1993.     int max_track_id = 1, i;
  1994.     int64_t max_track_len_temp, max_track_len = 0;
  1995.     int version;
  1996.  
  1997.     for (i = 0; i < mov->nb_streams; i++) {
  1998.         if (mov->tracks[i].entry > 0 && mov->tracks[i].timescale) {
  1999.             max_track_len_temp = av_rescale_rnd(mov->tracks[i].track_duration,
  2000.                                                 MOV_TIMESCALE,
  2001.                                                 mov->tracks[i].timescale,
  2002.                                                 AV_ROUND_UP);
  2003.             if (max_track_len < max_track_len_temp)
  2004.                 max_track_len = max_track_len_temp;
  2005.             if (max_track_id < mov->tracks[i].track_id)
  2006.                 max_track_id = mov->tracks[i].track_id;
  2007.         }
  2008.     }
  2009.  
  2010.     version = max_track_len < UINT32_MAX ? 0 : 1;
  2011.     (version == 1) ? avio_wb32(pb, 120) : avio_wb32(pb, 108); /* size */
  2012.     ffio_wfourcc(pb, "mvhd");
  2013.     avio_w8(pb, version);
  2014.     avio_wb24(pb, 0); /* flags */
  2015.     if (version == 1) {
  2016.         avio_wb64(pb, mov->time);
  2017.         avio_wb64(pb, mov->time);
  2018.     } else {
  2019.         avio_wb32(pb, mov->time); /* creation time */
  2020.         avio_wb32(pb, mov->time); /* modification time */
  2021.     }
  2022.     avio_wb32(pb, MOV_TIMESCALE);
  2023.     (version == 1) ? avio_wb64(pb, max_track_len) : avio_wb32(pb, max_track_len); /* duration of longest track */
  2024.  
  2025.     avio_wb32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */
  2026.     avio_wb16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */
  2027.     avio_wb16(pb, 0); /* reserved */
  2028.     avio_wb32(pb, 0); /* reserved */
  2029.     avio_wb32(pb, 0); /* reserved */
  2030.  
  2031.     /* Matrix structure */
  2032.     write_matrix(pb, 1, 0, 0, 1, 0, 0);
  2033.  
  2034.     avio_wb32(pb, 0); /* reserved (preview time) */
  2035.     avio_wb32(pb, 0); /* reserved (preview duration) */
  2036.     avio_wb32(pb, 0); /* reserved (poster time) */
  2037.     avio_wb32(pb, 0); /* reserved (selection time) */
  2038.     avio_wb32(pb, 0); /* reserved (selection duration) */
  2039.     avio_wb32(pb, 0); /* reserved (current time) */
  2040.     avio_wb32(pb, max_track_id + 1); /* Next track id */
  2041.     return 0x6c;
  2042. }
  2043.  
  2044. static int mov_write_itunes_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov,
  2045.                                      AVFormatContext *s)
  2046. {
  2047.     avio_wb32(pb, 33); /* size */
  2048.     ffio_wfourcc(pb, "hdlr");
  2049.     avio_wb32(pb, 0);
  2050.     avio_wb32(pb, 0);
  2051.     ffio_wfourcc(pb, "mdir");
  2052.     ffio_wfourcc(pb, "appl");
  2053.     avio_wb32(pb, 0);
  2054.     avio_wb32(pb, 0);
  2055.     avio_w8(pb, 0);
  2056.     return 33;
  2057. }
  2058.  
  2059. /* helper function to write a data tag with the specified string as data */
  2060. static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style)
  2061. {
  2062.     if (long_style) {
  2063.         int size = 16 + strlen(data);
  2064.         avio_wb32(pb, size); /* size */
  2065.         ffio_wfourcc(pb, "data");
  2066.         avio_wb32(pb, 1);
  2067.         avio_wb32(pb, 0);
  2068.         avio_write(pb, data, strlen(data));
  2069.         return size;
  2070.     } else {
  2071.         if (!lang)
  2072.             lang = ff_mov_iso639_to_lang("und", 1);
  2073.         avio_wb16(pb, strlen(data)); /* string length */
  2074.         avio_wb16(pb, lang);
  2075.         avio_write(pb, data, strlen(data));
  2076.         return strlen(data) + 4;
  2077.     }
  2078. }
  2079.  
  2080. static int mov_write_string_tag(AVIOContext *pb, const char *name,
  2081.                                 const char *value, int lang, int long_style)
  2082. {
  2083.     int size = 0;
  2084.     if (value && value[0]) {
  2085.         int64_t pos = avio_tell(pb);
  2086.         avio_wb32(pb, 0); /* size */
  2087.         ffio_wfourcc(pb, name);
  2088.         mov_write_string_data_tag(pb, value, lang, long_style);
  2089.         size = update_size(pb, pos);
  2090.     }
  2091.     return size;
  2092. }
  2093.  
  2094. static int mov_write_string_metadata(AVFormatContext *s, AVIOContext *pb,
  2095.                                      const char *name, const char *tag,
  2096.                                      int long_style)
  2097. {
  2098.     int l, lang = 0, len, len2;
  2099.     AVDictionaryEntry *t, *t2 = NULL;
  2100.     char tag2[16];
  2101.  
  2102.     if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
  2103.         return 0;
  2104.  
  2105.     len = strlen(t->key);
  2106.     snprintf(tag2, sizeof(tag2), "%s-", tag);
  2107.     while ((t2 = av_dict_get(s->metadata, tag2, t2, AV_DICT_IGNORE_SUFFIX))) {
  2108.         len2 = strlen(t2->key);
  2109.         if (len2 == len + 4 && !strcmp(t->value, t2->value)
  2110.             && (l = ff_mov_iso639_to_lang(&t2->key[len2 - 3], 1)) >= 0) {
  2111.             lang = l;
  2112.             break;
  2113.         }
  2114.     }
  2115.     return mov_write_string_tag(pb, name, t->value, lang, long_style);
  2116. }
  2117.  
  2118. /* iTunes bpm number */
  2119. static int mov_write_tmpo_tag(AVIOContext *pb, AVFormatContext *s)
  2120. {
  2121.     AVDictionaryEntry *t = av_dict_get(s->metadata, "tmpo", NULL, 0);
  2122.     int size = 0, tmpo = t ? atoi(t->value) : 0;
  2123.     if (tmpo) {
  2124.         size = 26;
  2125.         avio_wb32(pb, size);
  2126.         ffio_wfourcc(pb, "tmpo");
  2127.         avio_wb32(pb, size-8); /* size */
  2128.         ffio_wfourcc(pb, "data");
  2129.         avio_wb32(pb, 0x15);  //type specifier
  2130.         avio_wb32(pb, 0);
  2131.         avio_wb16(pb, tmpo);        // data
  2132.     }
  2133.     return size;
  2134. }
  2135.  
  2136. /* iTunes track or disc number */
  2137. static int mov_write_trkn_tag(AVIOContext *pb, MOVMuxContext *mov,
  2138.                               AVFormatContext *s, int disc)
  2139. {
  2140.     AVDictionaryEntry *t = av_dict_get(s->metadata,
  2141.                                        disc ? "disc" : "track",
  2142.                                        NULL, 0);
  2143.     int size = 0, track = t ? atoi(t->value) : 0;
  2144.     if (track) {
  2145.         int tracks = 0;
  2146.         char *slash = strchr(t->value, '/');
  2147.         if (slash)
  2148.             tracks = atoi(slash + 1);
  2149.         avio_wb32(pb, 32); /* size */
  2150.         ffio_wfourcc(pb, disc ? "disk" : "trkn");
  2151.         avio_wb32(pb, 24); /* size */
  2152.         ffio_wfourcc(pb, "data");
  2153.         avio_wb32(pb, 0);        // 8 bytes empty
  2154.         avio_wb32(pb, 0);
  2155.         avio_wb16(pb, 0);        // empty
  2156.         avio_wb16(pb, track);    // track / disc number
  2157.         avio_wb16(pb, tracks);   // total track / disc number
  2158.         avio_wb16(pb, 0);        // empty
  2159.         size = 32;
  2160.     }
  2161.     return size;
  2162. }
  2163.  
  2164. static int mov_write_int8_metadata(AVFormatContext *s, AVIOContext *pb,
  2165.                                    const char *name, const char *tag,
  2166.                                    int len)
  2167. {
  2168.     AVDictionaryEntry *t = NULL;
  2169.     uint8_t num;
  2170.     int size = 24 + len;
  2171.  
  2172.     if (len != 1 && len != 4)
  2173.         return -1;
  2174.  
  2175.     if (!(t = av_dict_get(s->metadata, tag, NULL, 0)))
  2176.         return 0;
  2177.     num = atoi(t->value);
  2178.  
  2179.     avio_wb32(pb, size);
  2180.     ffio_wfourcc(pb, name);
  2181.     avio_wb32(pb, size - 8);
  2182.     ffio_wfourcc(pb, "data");
  2183.     avio_wb32(pb, 0x15);
  2184.     avio_wb32(pb, 0);
  2185.     if (len==4) avio_wb32(pb, num);
  2186.     else        avio_w8 (pb, num);
  2187.  
  2188.     return size;
  2189. }
  2190.  
  2191. /* iTunes meta data list */
  2192. static int mov_write_ilst_tag(AVIOContext *pb, MOVMuxContext *mov,
  2193.                               AVFormatContext *s)
  2194. {
  2195.     int64_t pos = avio_tell(pb);
  2196.     avio_wb32(pb, 0); /* size */
  2197.     ffio_wfourcc(pb, "ilst");
  2198.     mov_write_string_metadata(s, pb, "\251nam", "title"    , 1);
  2199.     mov_write_string_metadata(s, pb, "\251ART", "artist"   , 1);
  2200.     mov_write_string_metadata(s, pb, "aART", "album_artist", 1);
  2201.     mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1);
  2202.     mov_write_string_metadata(s, pb, "\251alb", "album"    , 1);
  2203.     mov_write_string_metadata(s, pb, "\251day", "date"     , 1);
  2204.     mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1);
  2205.     mov_write_string_metadata(s, pb, "\251cmt", "comment"  , 1);
  2206.     mov_write_string_metadata(s, pb, "\251gen", "genre"    , 1);
  2207.     mov_write_string_metadata(s, pb, "\251cpy", "copyright", 1);
  2208.     mov_write_string_metadata(s, pb, "\251grp", "grouping" , 1);
  2209.     mov_write_string_metadata(s, pb, "\251lyr", "lyrics"   , 1);
  2210.     mov_write_string_metadata(s, pb, "desc",    "description",1);
  2211.     mov_write_string_metadata(s, pb, "ldes",    "synopsis" , 1);
  2212.     mov_write_string_metadata(s, pb, "tvsh",    "show"     , 1);
  2213.     mov_write_string_metadata(s, pb, "tven",    "episode_id",1);
  2214.     mov_write_string_metadata(s, pb, "tvnn",    "network"  , 1);
  2215.     mov_write_int8_metadata  (s, pb, "tves",    "episode_sort",4);
  2216.     mov_write_int8_metadata  (s, pb, "tvsn",    "season_number",4);
  2217.     mov_write_int8_metadata  (s, pb, "stik",    "media_type",1);
  2218.     mov_write_int8_metadata  (s, pb, "hdvd",    "hd_video",  1);
  2219.     mov_write_int8_metadata  (s, pb, "pgap",    "gapless_playback",1);
  2220.     mov_write_trkn_tag(pb, mov, s, 0); // track number
  2221.     mov_write_trkn_tag(pb, mov, s, 1); // disc number
  2222.     mov_write_tmpo_tag(pb, s);
  2223.     return update_size(pb, pos);
  2224. }
  2225.  
  2226. /* iTunes meta data tag */
  2227. static int mov_write_meta_tag(AVIOContext *pb, MOVMuxContext *mov,
  2228.                               AVFormatContext *s)
  2229. {
  2230.     int size = 0;
  2231.     int64_t pos = avio_tell(pb);
  2232.     avio_wb32(pb, 0); /* size */
  2233.     ffio_wfourcc(pb, "meta");
  2234.     avio_wb32(pb, 0);
  2235.     mov_write_itunes_hdlr_tag(pb, mov, s);
  2236.     mov_write_ilst_tag(pb, mov, s);
  2237.     size = update_size(pb, pos);
  2238.     return size;
  2239. }
  2240.  
  2241. static int utf8len(const uint8_t *b)
  2242. {
  2243.     int len = 0;
  2244.     int val;
  2245.     while (*b) {
  2246.         GET_UTF8(val, *b++, return -1;)
  2247.         len++;
  2248.     }
  2249.     return len;
  2250. }
  2251.  
  2252. static int ascii_to_wc(AVIOContext *pb, const uint8_t *b)
  2253. {
  2254.     int val;
  2255.     while (*b) {
  2256.         GET_UTF8(val, *b++, return -1;)
  2257.         avio_wb16(pb, val);
  2258.     }
  2259.     avio_wb16(pb, 0x00);
  2260.     return 0;
  2261. }
  2262.  
  2263. static uint16_t language_code(const char *str)
  2264. {
  2265.     return (((str[0] - 0x60) & 0x1F) << 10) +
  2266.            (((str[1] - 0x60) & 0x1F) <<  5) +
  2267.            (( str[2] - 0x60) & 0x1F);
  2268. }
  2269.  
  2270. static int mov_write_3gp_udta_tag(AVIOContext *pb, AVFormatContext *s,
  2271.                                   const char *tag, const char *str)
  2272. {
  2273.     int64_t pos = avio_tell(pb);
  2274.     AVDictionaryEntry *t = av_dict_get(s->metadata, str, NULL, 0);
  2275.     if (!t || !utf8len(t->value))
  2276.         return 0;
  2277.     avio_wb32(pb, 0);   /* size */
  2278.     ffio_wfourcc(pb, tag); /* type */
  2279.     avio_wb32(pb, 0);   /* version + flags */
  2280.     if (!strcmp(tag, "yrrc"))
  2281.         avio_wb16(pb, atoi(t->value));
  2282.     else {
  2283.         avio_wb16(pb, language_code("eng")); /* language */
  2284.         avio_write(pb, t->value, strlen(t->value) + 1); /* UTF8 string value */
  2285.         if (!strcmp(tag, "albm") &&
  2286.             (t = av_dict_get(s->metadata, "track", NULL, 0)))
  2287.             avio_w8(pb, atoi(t->value));
  2288.     }
  2289.     return update_size(pb, pos);
  2290. }
  2291.  
  2292. static int mov_write_chpl_tag(AVIOContext *pb, AVFormatContext *s)
  2293. {
  2294.     int64_t pos = avio_tell(pb);
  2295.     int i, nb_chapters = FFMIN(s->nb_chapters, 255);
  2296.  
  2297.     avio_wb32(pb, 0);            // size
  2298.     ffio_wfourcc(pb, "chpl");
  2299.     avio_wb32(pb, 0x01000000);   // version + flags
  2300.     avio_wb32(pb, 0);            // unknown
  2301.     avio_w8(pb, nb_chapters);
  2302.  
  2303.     for (i = 0; i < nb_chapters; i++) {
  2304.         AVChapter *c = s->chapters[i];
  2305.         AVDictionaryEntry *t;
  2306.         avio_wb64(pb, av_rescale_q(c->start, c->time_base, (AVRational){1,10000000}));
  2307.  
  2308.         if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
  2309.             int len = FFMIN(strlen(t->value), 255);
  2310.             avio_w8(pb, len);
  2311.             avio_write(pb, t->value, len);
  2312.         } else
  2313.             avio_w8(pb, 0);
  2314.     }
  2315.     return update_size(pb, pos);
  2316. }
  2317.  
  2318. static int mov_write_udta_tag(AVIOContext *pb, MOVMuxContext *mov,
  2319.                               AVFormatContext *s)
  2320. {
  2321.     AVIOContext *pb_buf;
  2322.     int i, ret, size;
  2323.     uint8_t *buf;
  2324.  
  2325.     for (i = 0; i < s->nb_streams; i++)
  2326.         if (mov->tracks[i].enc->flags & CODEC_FLAG_BITEXACT) {
  2327.             return 0;
  2328.         }
  2329.  
  2330.     ret = avio_open_dyn_buf(&pb_buf);
  2331.     if (ret < 0)
  2332.         return ret;
  2333.  
  2334.     if (mov->mode & MODE_3GP) {
  2335.         mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist");
  2336.         mov_write_3gp_udta_tag(pb_buf, s, "titl", "title");
  2337.         mov_write_3gp_udta_tag(pb_buf, s, "auth", "author");
  2338.         mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre");
  2339.         mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment");
  2340.         mov_write_3gp_udta_tag(pb_buf, s, "albm", "album");
  2341.         mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright");
  2342.         mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date");
  2343.     } else if (mov->mode == MODE_MOV) { // the title field breaks gtkpod with mp4 and my suspicion is that stuff is not valid in mp4
  2344.         mov_write_string_metadata(s, pb_buf, "\251ART", "artist",      0);
  2345.         mov_write_string_metadata(s, pb_buf, "\251nam", "title",       0);
  2346.         mov_write_string_metadata(s, pb_buf, "\251aut", "author",      0);
  2347.         mov_write_string_metadata(s, pb_buf, "\251alb", "album",       0);
  2348.         mov_write_string_metadata(s, pb_buf, "\251day", "date",        0);
  2349.         mov_write_string_metadata(s, pb_buf, "\251swr", "encoder",     0);
  2350.         // currently ignored by mov.c
  2351.         mov_write_string_metadata(s, pb_buf, "\251des", "comment",     0);
  2352.         // add support for libquicktime, this atom is also actually read by mov.c
  2353.         mov_write_string_metadata(s, pb_buf, "\251cmt", "comment",     0);
  2354.         mov_write_string_metadata(s, pb_buf, "\251gen", "genre",       0);
  2355.         mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright",   0);
  2356.     } else {
  2357.         /* iTunes meta data */
  2358.         mov_write_meta_tag(pb_buf, mov, s);
  2359.     }
  2360.  
  2361.     if (s->nb_chapters)
  2362.         mov_write_chpl_tag(pb_buf, s);
  2363.  
  2364.     if ((size = avio_close_dyn_buf(pb_buf, &buf)) > 0) {
  2365.         avio_wb32(pb, size + 8);
  2366.         ffio_wfourcc(pb, "udta");
  2367.         avio_write(pb, buf, size);
  2368.     }
  2369.     av_free(buf);
  2370.  
  2371.     return 0;
  2372. }
  2373.  
  2374. static void mov_write_psp_udta_tag(AVIOContext *pb,
  2375.                                    const char *str, const char *lang, int type)
  2376. {
  2377.     int len = utf8len(str) + 1;
  2378.     if (len <= 0)
  2379.         return;
  2380.     avio_wb16(pb, len * 2 + 10);        /* size */
  2381.     avio_wb32(pb, type);                /* type */
  2382.     avio_wb16(pb, language_code(lang)); /* language */
  2383.     avio_wb16(pb, 0x01);                /* ? */
  2384.     ascii_to_wc(pb, str);
  2385. }
  2386.  
  2387. static int mov_write_uuidusmt_tag(AVIOContext *pb, AVFormatContext *s)
  2388. {
  2389.     AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0);
  2390.     int64_t pos, pos2;
  2391.  
  2392.     if (title) {
  2393.         pos = avio_tell(pb);
  2394.         avio_wb32(pb, 0); /* size placeholder*/
  2395.         ffio_wfourcc(pb, "uuid");
  2396.         ffio_wfourcc(pb, "USMT");
  2397.         avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
  2398.         avio_wb32(pb, 0xbb88695c);
  2399.         avio_wb32(pb, 0xfac9c740);
  2400.  
  2401.         pos2 = avio_tell(pb);
  2402.         avio_wb32(pb, 0); /* size placeholder*/
  2403.         ffio_wfourcc(pb, "MTDT");
  2404.         avio_wb16(pb, 4);
  2405.  
  2406.         // ?
  2407.         avio_wb16(pb, 0x0C);                 /* size */
  2408.         avio_wb32(pb, 0x0B);                 /* type */
  2409.         avio_wb16(pb, language_code("und")); /* language */
  2410.         avio_wb16(pb, 0x0);                  /* ? */
  2411.         avio_wb16(pb, 0x021C);               /* data */
  2412.  
  2413.         mov_write_psp_udta_tag(pb, LIBAVCODEC_IDENT,      "eng", 0x04);
  2414.         mov_write_psp_udta_tag(pb, title->value,          "eng", 0x01);
  2415.         mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03);
  2416.  
  2417.         update_size(pb, pos2);
  2418.         return update_size(pb, pos);
  2419.     }
  2420.  
  2421.     return 0;
  2422. }
  2423.  
  2424. static void build_chunks(MOVTrack *trk)
  2425. {
  2426.     int i;
  2427.     MOVIentry *chunk = &trk->cluster[0];
  2428.     uint64_t chunkSize = chunk->size;
  2429.     chunk->chunkNum = 1;
  2430.     if (trk->chunkCount)
  2431.         return;
  2432.     trk->chunkCount = 1;
  2433.     for (i = 1; i<trk->entry; i++){
  2434.         if (chunk->pos + chunkSize == trk->cluster[i].pos &&
  2435.             chunkSize + trk->cluster[i].size < (1<<20)){
  2436.             chunkSize             += trk->cluster[i].size;
  2437.             chunk->samples_in_chunk += trk->cluster[i].entries;
  2438.         } else {
  2439.             trk->cluster[i].chunkNum = chunk->chunkNum+1;
  2440.             chunk=&trk->cluster[i];
  2441.             chunkSize = chunk->size;
  2442.             trk->chunkCount++;
  2443.         }
  2444.     }
  2445. }
  2446.  
  2447. static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov,
  2448.                               AVFormatContext *s)
  2449. {
  2450.     int i;
  2451.     int64_t pos = avio_tell(pb);
  2452.     avio_wb32(pb, 0); /* size placeholder*/
  2453.     ffio_wfourcc(pb, "moov");
  2454.  
  2455.     for (i = 0; i < mov->nb_streams; i++) {
  2456.         if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT))
  2457.             continue;
  2458.  
  2459.         mov->tracks[i].time     = mov->time;
  2460.         mov->tracks[i].track_id = i + 1;
  2461.  
  2462.         if (mov->tracks[i].entry)
  2463.             build_chunks(&mov->tracks[i]);
  2464.     }
  2465.  
  2466.     if (mov->chapter_track)
  2467.         for (i = 0; i < s->nb_streams; i++) {
  2468.             mov->tracks[i].tref_tag = MKTAG('c','h','a','p');
  2469.             mov->tracks[i].tref_id  = mov->tracks[mov->chapter_track].track_id;
  2470.         }
  2471.     for (i = 0; i < mov->nb_streams; i++) {
  2472.         if (mov->tracks[i].tag == MKTAG('r','t','p',' ')) {
  2473.             mov->tracks[i].tref_tag = MKTAG('h','i','n','t');
  2474.             mov->tracks[i].tref_id =
  2475.                 mov->tracks[mov->tracks[i].src_track].track_id;
  2476.         }
  2477.     }
  2478.     for (i = 0; i < mov->nb_streams; i++) {
  2479.         if (mov->tracks[i].tag == MKTAG('t','m','c','d')) {
  2480.             int src_trk = mov->tracks[i].src_track;
  2481.             mov->tracks[src_trk].tref_tag = mov->tracks[i].tag;
  2482.             mov->tracks[src_trk].tref_id  = mov->tracks[i].track_id;
  2483.             mov->tracks[i].track_duration = mov->tracks[src_trk].track_duration;
  2484.         }
  2485.     }
  2486.  
  2487.     mov_write_mvhd_tag(pb, mov);
  2488.     if (mov->mode != MODE_MOV && !mov->iods_skip)
  2489.         mov_write_iods_tag(pb, mov);
  2490.     for (i = 0; i < mov->nb_streams; i++) {
  2491.         if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT) {
  2492.             mov_write_trak_tag(pb, mov, &(mov->tracks[i]), i < s->nb_streams ? s->streams[i] : NULL);
  2493.         }
  2494.     }
  2495.     if (mov->flags & FF_MOV_FLAG_FRAGMENT)
  2496.         mov_write_mvex_tag(pb, mov); /* QuickTime requires trak to precede this */
  2497.  
  2498.     if (mov->mode == MODE_PSP)
  2499.         mov_write_uuidusmt_tag(pb, s);
  2500.     else
  2501.         mov_write_udta_tag(pb, mov, s);
  2502.  
  2503.     return update_size(pb, pos);
  2504. }
  2505.  
  2506. static void param_write_int(AVIOContext *pb, const char *name, int value)
  2507. {
  2508.     avio_printf(pb, "<param name=\"%s\" value=\"%d\" valuetype=\"data\"/>\n", name, value);
  2509. }
  2510.  
  2511. static void param_write_string(AVIOContext *pb, const char *name, const char *value)
  2512. {
  2513.     avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, value);
  2514. }
  2515.  
  2516. static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len)
  2517. {
  2518.     char buf[150];
  2519.     len = FFMIN(sizeof(buf) / 2 - 1, len);
  2520.     ff_data_to_hex(buf, value, len, 0);
  2521.     buf[2 * len] = '\0';
  2522.     avio_printf(pb, "<param name=\"%s\" value=\"%s\" valuetype=\"data\"/>\n", name, buf);
  2523. }
  2524.  
  2525. static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov)
  2526. {
  2527.     int64_t pos = avio_tell(pb);
  2528.     int i;
  2529.     static const uint8_t uuid[] = {
  2530.         0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
  2531.         0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
  2532.     };
  2533.  
  2534.     avio_wb32(pb, 0);
  2535.     ffio_wfourcc(pb, "uuid");
  2536.     avio_write(pb, uuid, sizeof(uuid));
  2537.     avio_wb32(pb, 0);
  2538.  
  2539.     avio_printf(pb, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
  2540.     avio_printf(pb, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
  2541.     avio_printf(pb, "<head>\n");
  2542.     avio_printf(pb, "<meta name=\"creator\" content=\"%s\" />\n",
  2543.                     LIBAVFORMAT_IDENT);
  2544.     avio_printf(pb, "</head>\n");
  2545.     avio_printf(pb, "<body>\n");
  2546.     avio_printf(pb, "<switch>\n");
  2547.     for (i = 0; i < mov->nb_streams; i++) {
  2548.         MOVTrack *track = &mov->tracks[i];
  2549.         const char *type;
  2550.         /* track->track_id is initialized in write_moov, and thus isn't known
  2551.          * here yet */
  2552.         int track_id = i + 1;
  2553.  
  2554.         if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
  2555.             type = "video";
  2556.         } else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) {
  2557.             type = "audio";
  2558.         } else {
  2559.             continue;
  2560.         }
  2561.         avio_printf(pb, "<%s systemBitrate=\"%d\">\n", type,
  2562.                                                        track->enc->bit_rate);
  2563.         param_write_int(pb, "systemBitrate", track->enc->bit_rate);
  2564.         param_write_int(pb, "trackID", track_id);
  2565.         if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
  2566.             if (track->enc->codec_id == AV_CODEC_ID_H264) {
  2567.                 uint8_t *ptr;
  2568.                 int size = track->enc->extradata_size;
  2569.                 if (!ff_avc_write_annexb_extradata(track->enc->extradata, &ptr,
  2570.                                                    &size)) {
  2571.                     param_write_hex(pb, "CodecPrivateData",
  2572.                                     ptr ? ptr : track->enc->extradata,
  2573.                                     size);
  2574.                     av_free(ptr);
  2575.                 }
  2576.                 param_write_string(pb, "FourCC", "H264");
  2577.             } else if (track->enc->codec_id == AV_CODEC_ID_VC1) {
  2578.                 param_write_string(pb, "FourCC", "WVC1");
  2579.                 param_write_hex(pb, "CodecPrivateData", track->enc->extradata,
  2580.                                 track->enc->extradata_size);
  2581.             }
  2582.             param_write_int(pb, "MaxWidth", track->enc->width);
  2583.             param_write_int(pb, "MaxHeight", track->enc->height);
  2584.             param_write_int(pb, "DisplayWidth", track->enc->width);
  2585.             param_write_int(pb, "DisplayHeight", track->enc->height);
  2586.         } else {
  2587.             if (track->enc->codec_id == AV_CODEC_ID_AAC) {
  2588.                 param_write_string(pb, "FourCC", "AACL");
  2589.             } else if (track->enc->codec_id == AV_CODEC_ID_WMAPRO) {
  2590.                 param_write_string(pb, "FourCC", "WMAP");
  2591.             }
  2592.             param_write_hex(pb, "CodecPrivateData", track->enc->extradata,
  2593.                             track->enc->extradata_size);
  2594.             param_write_int(pb, "AudioTag", ff_codec_get_tag(ff_codec_wav_tags,
  2595.                                                              track->enc->codec_id));
  2596.             param_write_int(pb, "Channels", track->enc->channels);
  2597.             param_write_int(pb, "SamplingRate", track->enc->sample_rate);
  2598.             param_write_int(pb, "BitsPerSample", 16);
  2599.             param_write_int(pb, "PacketSize", track->enc->block_align ?
  2600.                                               track->enc->block_align : 4);
  2601.         }
  2602.         avio_printf(pb, "</%s>\n", type);
  2603.     }
  2604.     avio_printf(pb, "</switch>\n");
  2605.     avio_printf(pb, "</body>\n");
  2606.     avio_printf(pb, "</smil>\n");
  2607.  
  2608.     return update_size(pb, pos);
  2609. }
  2610.  
  2611. static int mov_write_mfhd_tag(AVIOContext *pb, MOVMuxContext *mov)
  2612. {
  2613.     avio_wb32(pb, 16);
  2614.     ffio_wfourcc(pb, "mfhd");
  2615.     avio_wb32(pb, 0);
  2616.     avio_wb32(pb, mov->fragments);
  2617.     return 0;
  2618. }
  2619.  
  2620. static int mov_write_tfhd_tag(AVIOContext *pb, MOVMuxContext *mov,
  2621.                               MOVTrack *track, int64_t moof_offset)
  2622. {
  2623.     int64_t pos = avio_tell(pb);
  2624.     uint32_t flags = MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION |
  2625.                      MOV_TFHD_BASE_DATA_OFFSET;
  2626.     if (!track->entry) {
  2627.         flags |= MOV_TFHD_DURATION_IS_EMPTY;
  2628.     } else {
  2629.         flags |= MOV_TFHD_DEFAULT_FLAGS;
  2630.     }
  2631.     if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET)
  2632.         flags &= ~MOV_TFHD_BASE_DATA_OFFSET;
  2633.  
  2634.     /* Don't set a default sample size, the silverlight player refuses
  2635.      * to play files with that set. Don't set a default sample duration,
  2636.      * WMP freaks out if it is set. Don't set a base data offset, PIFF
  2637.      * file format says it MUST NOT be set. */
  2638.     if (track->mode == MODE_ISM)
  2639.         flags &= ~(MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION |
  2640.                    MOV_TFHD_BASE_DATA_OFFSET);
  2641.  
  2642.     avio_wb32(pb, 0); /* size placeholder */
  2643.     ffio_wfourcc(pb, "tfhd");
  2644.     avio_w8(pb, 0); /* version */
  2645.     avio_wb24(pb, flags);
  2646.  
  2647.     avio_wb32(pb, track->track_id); /* track-id */
  2648.     if (flags & MOV_TFHD_BASE_DATA_OFFSET)
  2649.         avio_wb64(pb, moof_offset);
  2650.     if (flags & MOV_TFHD_DEFAULT_DURATION) {
  2651.         track->default_duration = get_cluster_duration(track, 0);
  2652.         avio_wb32(pb, track->default_duration);
  2653.     }
  2654.     if (flags & MOV_TFHD_DEFAULT_SIZE) {
  2655.         track->default_size = track->entry ? track->cluster[0].size : 1;
  2656.         avio_wb32(pb, track->default_size);
  2657.     } else
  2658.         track->default_size = -1;
  2659.  
  2660.     if (flags & MOV_TFHD_DEFAULT_FLAGS) {
  2661.         track->default_sample_flags =
  2662.             track->enc->codec_type == AVMEDIA_TYPE_VIDEO ?
  2663.             (MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES | MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC) :
  2664.             MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO;
  2665.         avio_wb32(pb, track->default_sample_flags);
  2666.     }
  2667.  
  2668.     return update_size(pb, pos);
  2669. }
  2670.  
  2671. static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
  2672. {
  2673.     return entry->flags & MOV_SYNC_SAMPLE ? MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO :
  2674.            (MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES | MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC);
  2675. }
  2676.  
  2677. static int mov_write_trun_tag(AVIOContext *pb, MOVMuxContext *mov,
  2678.                               MOVTrack *track, int moof_size)
  2679. {
  2680.     int64_t pos = avio_tell(pb);
  2681.     uint32_t flags = MOV_TRUN_DATA_OFFSET;
  2682.     int i;
  2683.  
  2684.     for (i = 0; i < track->entry; i++) {
  2685.         if (get_cluster_duration(track, i) != track->default_duration)
  2686.             flags |= MOV_TRUN_SAMPLE_DURATION;
  2687.         if (track->cluster[i].size != track->default_size)
  2688.             flags |= MOV_TRUN_SAMPLE_SIZE;
  2689.         if (i > 0 && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
  2690.             flags |= MOV_TRUN_SAMPLE_FLAGS;
  2691.     }
  2692.     if (!(flags & MOV_TRUN_SAMPLE_FLAGS))
  2693.         flags |= MOV_TRUN_FIRST_SAMPLE_FLAGS;
  2694.     if (track->flags & MOV_TRACK_CTTS)
  2695.         flags |= MOV_TRUN_SAMPLE_CTS;
  2696.  
  2697.     avio_wb32(pb, 0); /* size placeholder */
  2698.     ffio_wfourcc(pb, "trun");
  2699.     avio_w8(pb, 0); /* version */
  2700.     avio_wb24(pb, flags);
  2701.  
  2702.     avio_wb32(pb, track->entry); /* sample count */
  2703.     if (mov->flags & FF_MOV_FLAG_OMIT_TFHD_OFFSET &&
  2704.         !(mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) &&
  2705.         track->track_id != 1)
  2706.         avio_wb32(pb, 0); /* Later tracks follow immediately after the previous one */
  2707.     else
  2708.         avio_wb32(pb, moof_size + 8 + track->data_offset +
  2709.                       track->cluster[0].pos); /* data offset */
  2710.     if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS)
  2711.         avio_wb32(pb, get_sample_flags(track, &track->cluster[0]));
  2712.  
  2713.     for (i = 0; i < track->entry; i++) {
  2714.         if (flags & MOV_TRUN_SAMPLE_DURATION)
  2715.             avio_wb32(pb, get_cluster_duration(track, i));
  2716.         if (flags & MOV_TRUN_SAMPLE_SIZE)
  2717.             avio_wb32(pb, track->cluster[i].size);
  2718.         if (flags & MOV_TRUN_SAMPLE_FLAGS)
  2719.             avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
  2720.         if (flags & MOV_TRUN_SAMPLE_CTS)
  2721.             avio_wb32(pb, track->cluster[i].cts);
  2722.     }
  2723.  
  2724.     return update_size(pb, pos);
  2725. }
  2726.  
  2727. static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track)
  2728. {
  2729.     int64_t pos = avio_tell(pb);
  2730.     static const uint8_t uuid[] = {
  2731.         0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6,
  2732.         0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2
  2733.     };
  2734.  
  2735.     avio_wb32(pb, 0); /* size placeholder */
  2736.     ffio_wfourcc(pb, "uuid");
  2737.     avio_write(pb, uuid, sizeof(uuid));
  2738.     avio_w8(pb, 1);
  2739.     avio_wb24(pb, 0);
  2740.     avio_wb64(pb, track->frag_start);
  2741.     avio_wb64(pb, track->start_dts + track->track_duration -
  2742.                   track->cluster[0].dts);
  2743.  
  2744.     return update_size(pb, pos);
  2745. }
  2746.  
  2747. static int mov_write_tfrf_tag(AVIOContext *pb, MOVMuxContext *mov,
  2748.                               MOVTrack *track, int entry)
  2749. {
  2750.     int n = track->nb_frag_info - 1 - entry, i;
  2751.     int size = 8 + 16 + 4 + 1 + 16*n;
  2752.     static const uint8_t uuid[] = {
  2753.         0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95,
  2754.         0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f
  2755.     };
  2756.  
  2757.     if (entry < 0)
  2758.         return 0;
  2759.  
  2760.     avio_seek(pb, track->frag_info[entry].tfrf_offset, SEEK_SET);
  2761.     avio_wb32(pb, size);
  2762.     ffio_wfourcc(pb, "uuid");
  2763.     avio_write(pb, uuid, sizeof(uuid));
  2764.     avio_w8(pb, 1);
  2765.     avio_wb24(pb, 0);
  2766.     avio_w8(pb, n);
  2767.     for (i = 0; i < n; i++) {
  2768.         int index = entry + 1 + i;
  2769.         avio_wb64(pb, track->frag_info[index].time);
  2770.         avio_wb64(pb, track->frag_info[index].duration);
  2771.     }
  2772.     if (n < mov->ism_lookahead) {
  2773.         int free_size = 16 * (mov->ism_lookahead - n);
  2774.         avio_wb32(pb, free_size);
  2775.         ffio_wfourcc(pb, "free");
  2776.         ffio_fill(pb, 0, free_size - 8);
  2777.     }
  2778.  
  2779.     return 0;
  2780. }
  2781.  
  2782. static int mov_write_tfrf_tags(AVIOContext *pb, MOVMuxContext *mov,
  2783.                                MOVTrack *track)
  2784. {
  2785.     int64_t pos = avio_tell(pb);
  2786.     int i;
  2787.     for (i = 0; i < mov->ism_lookahead; i++) {
  2788.         /* Update the tfrf tag for the last ism_lookahead fragments,
  2789.          * nb_frag_info - 1 is the next fragment to be written. */
  2790.         mov_write_tfrf_tag(pb, mov, track, track->nb_frag_info - 2 - i);
  2791.     }
  2792.     avio_seek(pb, pos, SEEK_SET);
  2793.     return 0;
  2794. }
  2795.  
  2796. static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov,
  2797.                               MOVTrack *track, int64_t moof_offset,
  2798.                               int moof_size)
  2799. {
  2800.     int64_t pos = avio_tell(pb);
  2801.     avio_wb32(pb, 0); /* size placeholder */
  2802.     ffio_wfourcc(pb, "traf");
  2803.  
  2804.     mov_write_tfhd_tag(pb, mov, track, moof_offset);
  2805.     mov_write_trun_tag(pb, mov, track, moof_size);
  2806.     if (mov->mode == MODE_ISM) {
  2807.         mov_write_tfxd_tag(pb, track);
  2808.  
  2809.         if (mov->ism_lookahead) {
  2810.             int i, size = 16 + 4 + 1 + 16 * mov->ism_lookahead;
  2811.  
  2812.             track->tfrf_offset = avio_tell(pb);
  2813.             avio_wb32(pb, 8 + size);
  2814.             ffio_wfourcc(pb, "free");
  2815.             for (i = 0; i < size; i++)
  2816.                 avio_w8(pb, 0);
  2817.         }
  2818.     }
  2819.  
  2820.     return update_size(pb, pos);
  2821. }
  2822.  
  2823. static int mov_write_moof_tag_internal(AVIOContext *pb, MOVMuxContext *mov,
  2824.                                        int tracks, int moof_size)
  2825. {
  2826.     int64_t pos = avio_tell(pb);
  2827.     int i;
  2828.  
  2829.     avio_wb32(pb, 0); /* size placeholder */
  2830.     ffio_wfourcc(pb, "moof");
  2831.  
  2832.     mov_write_mfhd_tag(pb, mov);
  2833.     for (i = 0; i < mov->nb_streams; i++) {
  2834.         MOVTrack *track = &mov->tracks[i];
  2835.         if (tracks >= 0 && i != tracks)
  2836.             continue;
  2837.         if (!track->entry)
  2838.             continue;
  2839.         mov_write_traf_tag(pb, mov, track, pos, moof_size);
  2840.     }
  2841.  
  2842.     return update_size(pb, pos);
  2843. }
  2844.  
  2845. static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks)
  2846. {
  2847.     AVIOContext *avio_buf;
  2848.     int ret, moof_size;
  2849.  
  2850.     if ((ret = ffio_open_null_buf(&avio_buf)) < 0)
  2851.         return ret;
  2852.     mov_write_moof_tag_internal(avio_buf, mov, tracks, 0);
  2853.     moof_size = ffio_close_null_buf(avio_buf);
  2854.     return mov_write_moof_tag_internal(pb, mov, tracks, moof_size);
  2855. }
  2856.  
  2857. static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
  2858. {
  2859.     int64_t pos = avio_tell(pb);
  2860.     int i;
  2861.  
  2862.     avio_wb32(pb, 0); /* size placeholder */
  2863.     ffio_wfourcc(pb, "tfra");
  2864.     avio_w8(pb, 1); /* version */
  2865.     avio_wb24(pb, 0);
  2866.  
  2867.     avio_wb32(pb, track->track_id);
  2868.     avio_wb32(pb, 0); /* length of traf/trun/sample num */
  2869.     avio_wb32(pb, track->nb_frag_info);
  2870.     for (i = 0; i < track->nb_frag_info; i++) {
  2871.         avio_wb64(pb, track->frag_info[i].time);
  2872.         avio_wb64(pb, track->frag_info[i].offset);
  2873.         avio_w8(pb, 1); /* traf number */
  2874.         avio_w8(pb, 1); /* trun number */
  2875.         avio_w8(pb, 1); /* sample number */
  2876.     }
  2877.  
  2878.     return update_size(pb, pos);
  2879. }
  2880.  
  2881. static int mov_write_mfra_tag(AVIOContext *pb, MOVMuxContext *mov)
  2882. {
  2883.     int64_t pos = avio_tell(pb);
  2884.     int i;
  2885.  
  2886.     avio_wb32(pb, 0); /* size placeholder */
  2887.     ffio_wfourcc(pb, "mfra");
  2888.     /* An empty mfra atom is enough to indicate to the publishing point that
  2889.      * the stream has ended. */
  2890.     if (mov->flags & FF_MOV_FLAG_ISML)
  2891.         return update_size(pb, pos);
  2892.  
  2893.     for (i = 0; i < mov->nb_streams; i++) {
  2894.         MOVTrack *track = &mov->tracks[i];
  2895.         if (track->nb_frag_info)
  2896.             mov_write_tfra_tag(pb, track);
  2897.     }
  2898.  
  2899.     avio_wb32(pb, 16);
  2900.     ffio_wfourcc(pb, "mfro");
  2901.     avio_wb32(pb, 0); /* version + flags */
  2902.     avio_wb32(pb, avio_tell(pb) + 4 - pos);
  2903.  
  2904.     return update_size(pb, pos);
  2905. }
  2906.  
  2907. static int mov_write_mdat_tag(AVIOContext *pb, MOVMuxContext *mov)
  2908. {
  2909.     avio_wb32(pb, 8);    // placeholder for extended size field (64 bit)
  2910.     ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free");
  2911.  
  2912.     mov->mdat_pos = avio_tell(pb);
  2913.     avio_wb32(pb, 0); /* size placeholder*/
  2914.     ffio_wfourcc(pb, "mdat");
  2915.     return 0;
  2916. }
  2917.  
  2918. /* TODO: This needs to be more general */
  2919. static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
  2920. {
  2921.     MOVMuxContext *mov = s->priv_data;
  2922.     int64_t pos = avio_tell(pb);
  2923.     int has_h264 = 0, has_video = 0;
  2924.     int minor = 0x200;
  2925.     int i;
  2926.  
  2927.     for (i = 0; i < s->nb_streams; i++) {
  2928.         AVStream *st = s->streams[i];
  2929.         if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
  2930.             has_video = 1;
  2931.         if (st->codec->codec_id == AV_CODEC_ID_H264)
  2932.             has_h264 = 1;
  2933.     }
  2934.  
  2935.     avio_wb32(pb, 0); /* size */
  2936.     ffio_wfourcc(pb, "ftyp");
  2937.  
  2938.     if (mov->mode == MODE_3GP) {
  2939.         ffio_wfourcc(pb, has_h264 ? "3gp6"  : "3gp4");
  2940.         minor =     has_h264 ?   0x100 :   0x200;
  2941.     } else if (mov->mode & MODE_3G2) {
  2942.         ffio_wfourcc(pb, has_h264 ? "3g2b"  : "3g2a");
  2943.         minor =     has_h264 ? 0x20000 : 0x10000;
  2944.     } else if (mov->mode == MODE_PSP)
  2945.         ffio_wfourcc(pb, "MSNV");
  2946.     else if (mov->mode == MODE_MP4)
  2947.         ffio_wfourcc(pb, "isom");
  2948.     else if (mov->mode == MODE_IPOD)
  2949.         ffio_wfourcc(pb, has_video ? "M4V ":"M4A ");
  2950.     else if (mov->mode == MODE_ISM)
  2951.         ffio_wfourcc(pb, "isml");
  2952.     else if (mov->mode == MODE_F4V)
  2953.         ffio_wfourcc(pb, "f4v ");
  2954.     else
  2955.         ffio_wfourcc(pb, "qt  ");
  2956.  
  2957.     avio_wb32(pb, minor);
  2958.  
  2959.     if (mov->mode == MODE_MOV)
  2960.         ffio_wfourcc(pb, "qt  ");
  2961.     else if (mov->mode == MODE_ISM) {
  2962.         ffio_wfourcc(pb, "piff");
  2963.         ffio_wfourcc(pb, "iso2");
  2964.     } else {
  2965.         ffio_wfourcc(pb, "isom");
  2966.         ffio_wfourcc(pb, "iso2");
  2967.         if (has_h264)
  2968.             ffio_wfourcc(pb, "avc1");
  2969.     }
  2970.  
  2971.     if (mov->mode == MODE_3GP)
  2972.         ffio_wfourcc(pb, has_h264 ? "3gp6":"3gp4");
  2973.     else if (mov->mode & MODE_3G2)
  2974.         ffio_wfourcc(pb, has_h264 ? "3g2b":"3g2a");
  2975.     else if (mov->mode == MODE_PSP)
  2976.         ffio_wfourcc(pb, "MSNV");
  2977.     else if (mov->mode == MODE_MP4)
  2978.         ffio_wfourcc(pb, "mp41");
  2979.     return update_size(pb, pos);
  2980. }
  2981.  
  2982. static void mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s)
  2983. {
  2984.     AVCodecContext *video_codec = s->streams[0]->codec;
  2985.     AVCodecContext *audio_codec = s->streams[1]->codec;
  2986.     int audio_rate = audio_codec->sample_rate;
  2987.     int frame_rate = ((video_codec->time_base.den) * (0x10000)) / (video_codec->time_base.num);
  2988.     int audio_kbitrate = audio_codec->bit_rate / 1000;
  2989.     int video_kbitrate = FFMIN(video_codec->bit_rate / 1000, 800 - audio_kbitrate);
  2990.  
  2991.     avio_wb32(pb, 0x94); /* size */
  2992.     ffio_wfourcc(pb, "uuid");
  2993.     ffio_wfourcc(pb, "PROF");
  2994.  
  2995.     avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */
  2996.     avio_wb32(pb, 0xbb88695c);
  2997.     avio_wb32(pb, 0xfac9c740);
  2998.  
  2999.     avio_wb32(pb, 0x0);  /* ? */
  3000.     avio_wb32(pb, 0x3);  /* 3 sections ? */
  3001.  
  3002.     avio_wb32(pb, 0x14); /* size */
  3003.     ffio_wfourcc(pb, "FPRF");
  3004.     avio_wb32(pb, 0x0);  /* ? */
  3005.     avio_wb32(pb, 0x0);  /* ? */
  3006.     avio_wb32(pb, 0x0);  /* ? */
  3007.  
  3008.     avio_wb32(pb, 0x2c);  /* size */
  3009.     ffio_wfourcc(pb, "APRF"); /* audio */
  3010.     avio_wb32(pb, 0x0);
  3011.     avio_wb32(pb, 0x2);   /* TrackID */
  3012.     ffio_wfourcc(pb, "mp4a");
  3013.     avio_wb32(pb, 0x20f);
  3014.     avio_wb32(pb, 0x0);
  3015.     avio_wb32(pb, audio_kbitrate);
  3016.     avio_wb32(pb, audio_kbitrate);
  3017.     avio_wb32(pb, audio_rate);
  3018.     avio_wb32(pb, audio_codec->channels);
  3019.  
  3020.     avio_wb32(pb, 0x34);  /* size */
  3021.     ffio_wfourcc(pb, "VPRF");   /* video */
  3022.     avio_wb32(pb, 0x0);
  3023.     avio_wb32(pb, 0x1);    /* TrackID */
  3024.     if (video_codec->codec_id == AV_CODEC_ID_H264) {
  3025.         ffio_wfourcc(pb, "avc1");
  3026.         avio_wb16(pb, 0x014D);
  3027.         avio_wb16(pb, 0x0015);
  3028.     } else {
  3029.         ffio_wfourcc(pb, "mp4v");
  3030.         avio_wb16(pb, 0x0000);
  3031.         avio_wb16(pb, 0x0103);
  3032.     }
  3033.     avio_wb32(pb, 0x0);
  3034.     avio_wb32(pb, video_kbitrate);
  3035.     avio_wb32(pb, video_kbitrate);
  3036.     avio_wb32(pb, frame_rate);
  3037.     avio_wb32(pb, frame_rate);
  3038.     avio_wb16(pb, video_codec->width);
  3039.     avio_wb16(pb, video_codec->height);
  3040.     avio_wb32(pb, 0x010001); /* ? */
  3041. }
  3042.  
  3043. static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags)
  3044. {
  3045.     uint32_t c = -1;
  3046.     int i, closed_gop = 0;
  3047.  
  3048.     for (i = 0; i < pkt->size - 4; i++) {
  3049.         c = (c << 8) + pkt->data[i];
  3050.         if (c == 0x1b8) { // gop
  3051.             closed_gop = pkt->data[i + 4] >> 6 & 0x01;
  3052.         } else if (c == 0x100) { // pic
  3053.             int temp_ref = (pkt->data[i + 1] << 2) | (pkt->data[i + 2] >> 6);
  3054.             if (!temp_ref || closed_gop) // I picture is not reordered
  3055.                 *flags = MOV_SYNC_SAMPLE;
  3056.             else
  3057.                 *flags = MOV_PARTIAL_SYNC_SAMPLE;
  3058.             break;
  3059.         }
  3060.     }
  3061.     return 0;
  3062. }
  3063.  
  3064. static void mov_parse_vc1_frame(AVPacket *pkt, MOVTrack *trk, int fragment)
  3065. {
  3066.     const uint8_t *start, *next, *end = pkt->data + pkt->size;
  3067.     int seq = 0, entry = 0;
  3068.     int key = pkt->flags & AV_PKT_FLAG_KEY;
  3069.     start = find_next_marker(pkt->data, end);
  3070.     for (next = start; next < end; start = next) {
  3071.         next = find_next_marker(start + 4, end);
  3072.         switch (AV_RB32(start)) {
  3073.         case VC1_CODE_SEQHDR:
  3074.             seq = 1;
  3075.             break;
  3076.         case VC1_CODE_ENTRYPOINT:
  3077.             entry = 1;
  3078.             break;
  3079.         case VC1_CODE_SLICE:
  3080.             trk->vc1_info.slices = 1;
  3081.             break;
  3082.         }
  3083.     }
  3084.     if (!trk->entry && !fragment) {
  3085.         /* First packet in first fragment */
  3086.         trk->vc1_info.first_packet_seq   = seq;
  3087.         trk->vc1_info.first_packet_entry = entry;
  3088.     } else if ((seq && !trk->vc1_info.packet_seq) ||
  3089.                (entry && !trk->vc1_info.packet_entry)) {
  3090.         int i;
  3091.         for (i = 0; i < trk->entry; i++)
  3092.             trk->cluster[i].flags &= ~MOV_SYNC_SAMPLE;
  3093.         trk->has_keyframes = 0;
  3094.         if (seq)
  3095.             trk->vc1_info.packet_seq = 1;
  3096.         if (entry)
  3097.             trk->vc1_info.packet_entry = 1;
  3098.         if (!fragment) {
  3099.             /* First fragment */
  3100.             if ((!seq   || trk->vc1_info.first_packet_seq) &&
  3101.                 (!entry || trk->vc1_info.first_packet_entry)) {
  3102.                 /* First packet had the same headers as this one, readd the
  3103.                  * sync sample flag. */
  3104.                 trk->cluster[0].flags |= MOV_SYNC_SAMPLE;
  3105.                 trk->has_keyframes = 1;
  3106.             }
  3107.         }
  3108.     }
  3109.     if (trk->vc1_info.packet_seq && trk->vc1_info.packet_entry)
  3110.         key = seq && entry;
  3111.     else if (trk->vc1_info.packet_seq)
  3112.         key = seq;
  3113.     else if (trk->vc1_info.packet_entry)
  3114.         key = entry;
  3115.     if (key) {
  3116.         trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE;
  3117.         trk->has_keyframes++;
  3118.     }
  3119. }
  3120.  
  3121. static int mov_flush_fragment(AVFormatContext *s)
  3122. {
  3123.     MOVMuxContext *mov = s->priv_data;
  3124.     int i, first_track = -1;
  3125.     int64_t mdat_size = 0;
  3126.  
  3127.     if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
  3128.         return 0;
  3129.  
  3130.     if (!(mov->flags & FF_MOV_FLAG_EMPTY_MOOV) && mov->fragments == 0) {
  3131.         int64_t pos = avio_tell(s->pb);
  3132.         uint8_t *buf;
  3133.         int buf_size, moov_size;
  3134.  
  3135.         for (i = 0; i < mov->nb_streams; i++)
  3136.             if (!mov->tracks[i].entry)
  3137.                 break;
  3138.         /* Don't write the initial moov unless all tracks have data */
  3139.         if (i < mov->nb_streams)
  3140.             return 0;
  3141.  
  3142.         moov_size = get_moov_size(s);
  3143.         for (i = 0; i < mov->nb_streams; i++)
  3144.             mov->tracks[i].data_offset = pos + moov_size + 8;
  3145.  
  3146.         mov_write_moov_tag(s->pb, mov, s);
  3147.  
  3148.         buf_size = avio_close_dyn_buf(mov->mdat_buf, &buf);
  3149.         mov->mdat_buf = NULL;
  3150.         avio_wb32(s->pb, buf_size + 8);
  3151.         ffio_wfourcc(s->pb, "mdat");
  3152.         avio_write(s->pb, buf, buf_size);
  3153.         av_free(buf);
  3154.  
  3155.         mov->fragments++;
  3156.         mov->mdat_size = 0;
  3157.         for (i = 0; i < mov->nb_streams; i++) {
  3158.             if (mov->tracks[i].entry)
  3159.                 mov->tracks[i].frag_start += mov->tracks[i].start_dts +
  3160.                                              mov->tracks[i].track_duration -
  3161.                                              mov->tracks[i].cluster[0].dts;
  3162.             mov->tracks[i].entry = 0;
  3163.         }
  3164.         avio_flush(s->pb);
  3165.         return 0;
  3166.     }
  3167.  
  3168.     for (i = 0; i < mov->nb_streams; i++) {
  3169.         MOVTrack *track = &mov->tracks[i];
  3170.         if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF)
  3171.             track->data_offset = 0;
  3172.         else
  3173.             track->data_offset = mdat_size;
  3174.         if (!track->mdat_buf)
  3175.             continue;
  3176.         mdat_size += avio_tell(track->mdat_buf);
  3177.         if (first_track < 0)
  3178.             first_track = i;
  3179.     }
  3180.  
  3181.     if (!mdat_size)
  3182.         return 0;
  3183.  
  3184.     for (i = 0; i < mov->nb_streams; i++) {
  3185.         MOVTrack *track = &mov->tracks[i];
  3186.         int buf_size, write_moof = 1, moof_tracks = -1;
  3187.         uint8_t *buf;
  3188.         int64_t duration = 0;
  3189.  
  3190.         if (track->entry)
  3191.             duration = track->start_dts + track->track_duration -
  3192.                        track->cluster[0].dts;
  3193.         if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) {
  3194.             if (!track->mdat_buf)
  3195.                 continue;
  3196.             mdat_size = avio_tell(track->mdat_buf);
  3197.             moof_tracks = i;
  3198.         } else {
  3199.             write_moof = i == first_track;
  3200.         }
  3201.  
  3202.         if (write_moof) {
  3203.             MOVFragmentInfo *info;
  3204.             avio_flush(s->pb);
  3205.             track->nb_frag_info++;
  3206.             if (track->nb_frag_info >= track->frag_info_capacity) {
  3207.                 unsigned new_capacity = track->nb_frag_info + MOV_FRAG_INFO_ALLOC_INCREMENT;
  3208.                 if (av_reallocp_array(&track->frag_info,
  3209.                                       new_capacity,
  3210.                                       sizeof(*track->frag_info)))
  3211.                     return AVERROR(ENOMEM);
  3212.                 track->frag_info_capacity = new_capacity;
  3213.             }
  3214.             info = &track->frag_info[track->nb_frag_info - 1];
  3215.             info->offset   = avio_tell(s->pb);
  3216.             info->time     = mov->tracks[i].frag_start;
  3217.             info->duration = duration;
  3218.             mov_write_tfrf_tags(s->pb, mov, track);
  3219.  
  3220.             mov_write_moof_tag(s->pb, mov, moof_tracks);
  3221.             info->tfrf_offset = track->tfrf_offset;
  3222.             mov->fragments++;
  3223.  
  3224.             avio_wb32(s->pb, mdat_size + 8);
  3225.             ffio_wfourcc(s->pb, "mdat");
  3226.         }
  3227.  
  3228.         if (track->entry)
  3229.             track->frag_start += duration;
  3230.         track->entry = 0;
  3231.         if (!track->mdat_buf)
  3232.             continue;
  3233.         buf_size = avio_close_dyn_buf(track->mdat_buf, &buf);
  3234.         track->mdat_buf = NULL;
  3235.  
  3236.         avio_write(s->pb, buf, buf_size);
  3237.         av_free(buf);
  3238.     }
  3239.  
  3240.     mov->mdat_size = 0;
  3241.  
  3242.     avio_flush(s->pb);
  3243.     return 0;
  3244. }
  3245.  
  3246. int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
  3247. {
  3248.     MOVMuxContext *mov = s->priv_data;
  3249.     AVIOContext *pb = s->pb;
  3250.     MOVTrack *trk = &mov->tracks[pkt->stream_index];
  3251.     AVCodecContext *enc = trk->enc;
  3252.     unsigned int samples_in_chunk = 0;
  3253.     int size = pkt->size;
  3254.     uint8_t *reformatted_data = NULL;
  3255.  
  3256.     if (mov->flags & FF_MOV_FLAG_FRAGMENT) {
  3257.         int ret;
  3258.         if (mov->fragments > 0) {
  3259.             if (!trk->mdat_buf) {
  3260.                 if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0)
  3261.                     return ret;
  3262.             }
  3263.             pb = trk->mdat_buf;
  3264.         } else {
  3265.             if (!mov->mdat_buf) {
  3266.                 if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0)
  3267.                     return ret;
  3268.             }
  3269.             pb = mov->mdat_buf;
  3270.         }
  3271.     }
  3272.  
  3273.     if (enc->codec_id == AV_CODEC_ID_AMR_NB) {
  3274.         /* We must find out how many AMR blocks there are in one packet */
  3275.         static uint16_t packed_size[16] =
  3276.             {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1};
  3277.         int len = 0;
  3278.  
  3279.         while (len < size && samples_in_chunk < 100) {
  3280.             len += packed_size[(pkt->data[len] >> 3) & 0x0F];
  3281.             samples_in_chunk++;
  3282.         }
  3283.         if (samples_in_chunk > 1) {
  3284.             av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n");
  3285.             return -1;
  3286.         }
  3287.     } else if (enc->codec_id == AV_CODEC_ID_ADPCM_MS ||
  3288.                enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) {
  3289.         samples_in_chunk = enc->frame_size;
  3290.     } else if (trk->sample_size)
  3291.         samples_in_chunk = size / trk->sample_size;
  3292.     else
  3293.         samples_in_chunk = 1;
  3294.  
  3295.     /* copy extradata if it exists */
  3296.     if (trk->vos_len == 0 && enc->extradata_size > 0) {
  3297.         trk->vos_len  = enc->extradata_size;
  3298.         trk->vos_data = av_malloc(trk->vos_len);
  3299.         memcpy(trk->vos_data, enc->extradata, trk->vos_len);
  3300.     }
  3301.  
  3302.     if (enc->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
  3303.         (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) {
  3304.         if (!s->streams[pkt->stream_index]->nb_frames) {
  3305.             av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: "
  3306.                    "use audio bitstream filter 'aac_adtstoasc' to fix it "
  3307.                    "('-bsf:a aac_adtstoasc' option with ffmpeg)\n");
  3308.             return -1;
  3309.         }
  3310.         av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
  3311.     }
  3312.     if (enc->codec_id == AV_CODEC_ID_H264 && trk->vos_len > 0 && *(uint8_t *)trk->vos_data != 1) {
  3313.         /* from x264 or from bytestream h264 */
  3314.         /* nal reformating needed */
  3315.         if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) {
  3316.             ff_avc_parse_nal_units_buf(pkt->data, &reformatted_data,
  3317.                                        &size);
  3318.             avio_write(pb, reformatted_data, size);
  3319.         } else {
  3320.             size = ff_avc_parse_nal_units(pb, pkt->data, pkt->size);
  3321.         }
  3322.     } else {
  3323.         avio_write(pb, pkt->data, size);
  3324.     }
  3325.  
  3326.     if ((enc->codec_id == AV_CODEC_ID_DNXHD ||
  3327.          enc->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len) {
  3328.         /* copy frame to create needed atoms */
  3329.         trk->vos_len  = size;
  3330.         trk->vos_data = av_malloc(size);
  3331.         if (!trk->vos_data)
  3332.             return AVERROR(ENOMEM);
  3333.         memcpy(trk->vos_data, pkt->data, size);
  3334.     }
  3335.  
  3336.     if (trk->entry >= trk->cluster_capacity) {
  3337.         unsigned new_capacity = 2 * (trk->entry + MOV_INDEX_CLUSTER_SIZE);
  3338.         if (av_reallocp_array(&trk->cluster, new_capacity,
  3339.                               sizeof(*trk->cluster)))
  3340.             return AVERROR(ENOMEM);
  3341.         trk->cluster_capacity = new_capacity;
  3342.     }
  3343.  
  3344.     trk->cluster[trk->entry].pos              = avio_tell(pb) - size;
  3345.     trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk;
  3346.     trk->cluster[trk->entry].chunkNum         = 0;
  3347.     trk->cluster[trk->entry].size             = size;
  3348.     trk->cluster[trk->entry].entries          = samples_in_chunk;
  3349.     trk->cluster[trk->entry].dts              = pkt->dts;
  3350.     if (!trk->entry && trk->start_dts != AV_NOPTS_VALUE) {
  3351.         /* First packet of a new fragment. We already wrote the duration
  3352.          * of the last packet of the previous fragment based on track_duration,
  3353.          * which might not exactly match our dts. Therefore adjust the dts
  3354.          * of this packet to be what the previous packets duration implies. */
  3355.         trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration;
  3356.     }
  3357.     if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !supports_edts(mov)) {
  3358.         trk->cluster[trk->entry].dts = trk->start_dts = 0;
  3359.     }
  3360.     if (trk->start_dts == AV_NOPTS_VALUE)
  3361.         trk->start_dts = pkt->dts;
  3362.     trk->track_duration = pkt->dts - trk->start_dts + pkt->duration;
  3363.     trk->last_sample_is_subtitle_end = 0;
  3364.  
  3365.     if (pkt->pts == AV_NOPTS_VALUE) {
  3366.         av_log(s, AV_LOG_WARNING, "pts has no value\n");
  3367.         pkt->pts = pkt->dts;
  3368.     }
  3369.     if (pkt->dts != pkt->pts)
  3370.         trk->flags |= MOV_TRACK_CTTS;
  3371.     trk->cluster[trk->entry].cts   = pkt->pts - pkt->dts;
  3372.     trk->cluster[trk->entry].flags = 0;
  3373.     if (enc->codec_id == AV_CODEC_ID_VC1) {
  3374.         mov_parse_vc1_frame(pkt, trk, mov->fragments);
  3375.     } else if (pkt->flags & AV_PKT_FLAG_KEY) {
  3376.         if (mov->mode == MODE_MOV && enc->codec_id == AV_CODEC_ID_MPEG2VIDEO &&
  3377.             trk->entry > 0) { // force sync sample for the first key frame
  3378.             mov_parse_mpeg2_frame(pkt, &trk->cluster[trk->entry].flags);
  3379.             if (trk->cluster[trk->entry].flags & MOV_PARTIAL_SYNC_SAMPLE)
  3380.                 trk->flags |= MOV_TRACK_STPS;
  3381.         } else {
  3382.             trk->cluster[trk->entry].flags = MOV_SYNC_SAMPLE;
  3383.         }
  3384.         if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE)
  3385.             trk->has_keyframes++;
  3386.     }
  3387.     trk->entry++;
  3388.     trk->sample_count += samples_in_chunk;
  3389.     mov->mdat_size    += size;
  3390.  
  3391.     if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams)
  3392.         ff_mov_add_hinted_packet(s, pkt, trk->hint_track, trk->entry,
  3393.                                  reformatted_data, size);
  3394.     av_free(reformatted_data);
  3395.     return 0;
  3396. }
  3397.  
  3398. static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt)
  3399. {
  3400.         MOVMuxContext *mov = s->priv_data;
  3401.         MOVTrack *trk = &mov->tracks[pkt->stream_index];
  3402.         AVCodecContext *enc = trk->enc;
  3403.         int64_t frag_duration = 0;
  3404.         int size = pkt->size;
  3405.  
  3406.         if (!pkt->size)
  3407.             return 0;             /* Discard 0 sized packets */
  3408.  
  3409.         if (trk->entry && pkt->stream_index < s->nb_streams)
  3410.             frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts,
  3411.                                          s->streams[pkt->stream_index]->time_base,
  3412.                                          AV_TIME_BASE_Q);
  3413.         if ((mov->max_fragment_duration &&
  3414.              frag_duration >= mov->max_fragment_duration) ||
  3415.              (mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) ||
  3416.              (mov->flags & FF_MOV_FLAG_FRAG_KEYFRAME &&
  3417.               enc->codec_type == AVMEDIA_TYPE_VIDEO &&
  3418.               trk->entry && pkt->flags & AV_PKT_FLAG_KEY)) {
  3419.             if (frag_duration >= mov->min_fragment_duration)
  3420.                 mov_flush_fragment(s);
  3421.         }
  3422.  
  3423.         return ff_mov_write_packet(s, pkt);
  3424. }
  3425.  
  3426. static int mov_write_subtitle_end_packet(AVFormatContext *s,
  3427.                                          int stream_index,
  3428.                                          int64_t dts) {
  3429.     AVPacket end;
  3430.     uint8_t data[2] = {0};
  3431.     int ret;
  3432.  
  3433.     av_init_packet(&end);
  3434.     end.size = sizeof(data);
  3435.     end.data = data;
  3436.     end.pts = dts;
  3437.     end.dts = dts;
  3438.     end.duration = 0;
  3439.     end.stream_index = stream_index;
  3440.  
  3441.     ret = mov_write_single_packet(s, &end);
  3442.     av_free_packet(&end);
  3443.  
  3444.     return ret;
  3445. }
  3446.  
  3447. static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
  3448. {
  3449.     if (!pkt) {
  3450.         mov_flush_fragment(s);
  3451.         return 1;
  3452.     } else {
  3453.         int i;
  3454.         MOVMuxContext *mov = s->priv_data;
  3455.  
  3456.         if (!pkt->size) return 0; /* Discard 0 sized packets */
  3457.  
  3458.         /*
  3459.          * Subtitles require special handling.
  3460.          *
  3461.          * 1) For full complaince, every track must have a sample at
  3462.          * dts == 0, which is rarely true for subtitles. So, as soon
  3463.          * as we see any packet with dts > 0, write an empty subtitle
  3464.          * at dts == 0 for any subtitle track with no samples in it.
  3465.          *
  3466.          * 2) For each subtitle track, check if the current packet's
  3467.          * dts is past the duration of the last subtitle sample. If
  3468.          * so, we now need to write an end sample for that subtitle.
  3469.          *
  3470.          * This must be done conditionally to allow for subtitles that
  3471.          * immediately replace each other, in which case an end sample
  3472.          * is not needed, and is, in fact, actively harmful.
  3473.          *
  3474.          * 3) See mov_write_trailer for how the final end sample is
  3475.          * handled.
  3476.          */
  3477.         for (i = 0; i < mov->nb_streams; i++) {
  3478.             MOVTrack *trk = &mov->tracks[i];
  3479.             int ret;
  3480.  
  3481.             if (trk->enc->codec_id == AV_CODEC_ID_MOV_TEXT &&
  3482.                 trk->track_duration < pkt->dts &&
  3483.                 (trk->entry == 0 || !trk->last_sample_is_subtitle_end)) {
  3484.                 ret = mov_write_subtitle_end_packet(s, i, trk->track_duration);
  3485.                 if (ret < 0) return ret;
  3486.                 trk->last_sample_is_subtitle_end = 1;
  3487.             }
  3488.         }
  3489.  
  3490.         return mov_write_single_packet(s, pkt);
  3491.     }
  3492. }
  3493.  
  3494. // QuickTime chapters involve an additional text track with the chapter names
  3495. // as samples, and a tref pointing from the other tracks to the chapter one.
  3496. static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
  3497. {
  3498.     AVIOContext *pb;
  3499.  
  3500.     MOVMuxContext *mov = s->priv_data;
  3501.     MOVTrack *track = &mov->tracks[tracknum];
  3502.     AVPacket pkt = { .stream_index = tracknum, .flags = AV_PKT_FLAG_KEY };
  3503.     int i, len;
  3504.  
  3505.     track->mode = mov->mode;
  3506.     track->tag = MKTAG('t','e','x','t');
  3507.     track->timescale = MOV_TIMESCALE;
  3508.     track->enc = avcodec_alloc_context3(NULL);
  3509.     if (!track->enc)
  3510.         return AVERROR(ENOMEM);
  3511.     track->enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
  3512. #if 0
  3513.     // These properties are required to make QT recognize the chapter track
  3514.     uint8_t chapter_properties[43] = { 0, 0, 0, 0, 0, 0, 0, 1, };
  3515.     if (ff_alloc_extradata(track->enc, sizeof(chapter_properties)))
  3516.         return AVERROR(ENOMEM);
  3517.     memcpy(track->enc->extradata, chapter_properties, sizeof(chapter_properties));
  3518. #else
  3519.     if (avio_open_dyn_buf(&pb) >= 0) {
  3520.         int size;
  3521.         uint8_t *buf;
  3522.  
  3523.         /* Stub header (usually for Quicktime chapter track) */
  3524.         // TextSampleEntry
  3525.         avio_wb32(pb, 0x01); // displayFlags
  3526.         avio_w8(pb, 0x00);   // horizontal justification
  3527.         avio_w8(pb, 0x00);   // vertical justification
  3528.         avio_w8(pb, 0x00);   // bgColourRed
  3529.         avio_w8(pb, 0x00);   // bgColourGreen
  3530.         avio_w8(pb, 0x00);   // bgColourBlue
  3531.         avio_w8(pb, 0x00);   // bgColourAlpha
  3532.         // BoxRecord
  3533.         avio_wb16(pb, 0x00); // defTextBoxTop
  3534.         avio_wb16(pb, 0x00); // defTextBoxLeft
  3535.         avio_wb16(pb, 0x00); // defTextBoxBottom
  3536.         avio_wb16(pb, 0x00); // defTextBoxRight
  3537.         // StyleRecord
  3538.         avio_wb16(pb, 0x00); // startChar
  3539.         avio_wb16(pb, 0x00); // endChar
  3540.         avio_wb16(pb, 0x01); // fontID
  3541.         avio_w8(pb, 0x00);   // fontStyleFlags
  3542.         avio_w8(pb, 0x00);   // fontSize
  3543.         avio_w8(pb, 0x00);   // fgColourRed
  3544.         avio_w8(pb, 0x00);   // fgColourGreen
  3545.         avio_w8(pb, 0x00);   // fgColourBlue
  3546.         avio_w8(pb, 0x00);   // fgColourAlpha
  3547.         // FontTableBox
  3548.         avio_wb32(pb, 0x0D); // box size
  3549.         ffio_wfourcc(pb, "ftab"); // box atom name
  3550.         avio_wb16(pb, 0x01); // entry count
  3551.         // FontRecord
  3552.         avio_wb16(pb, 0x01); // font ID
  3553.         avio_w8(pb, 0x00);   // font name length
  3554.  
  3555.         if ((size = avio_close_dyn_buf(pb, &buf)) > 0) {
  3556.             track->enc->extradata = buf;
  3557.             track->enc->extradata_size = size;
  3558.         } else {
  3559.             av_free(&buf);
  3560.         }
  3561.     }
  3562. #endif
  3563.  
  3564.     for (i = 0; i < s->nb_chapters; i++) {
  3565.         AVChapter *c = s->chapters[i];
  3566.         AVDictionaryEntry *t;
  3567.  
  3568.         int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,MOV_TIMESCALE});
  3569.         pkt.pts = pkt.dts = av_rescale_q(c->start, c->time_base, (AVRational){1,MOV_TIMESCALE});
  3570.         pkt.duration = end - pkt.dts;
  3571.  
  3572.         if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
  3573.             len      = strlen(t->value);
  3574.             pkt.size = len + 2;
  3575.             pkt.data = av_malloc(pkt.size);
  3576.             if (!pkt.data)
  3577.                 return AVERROR(ENOMEM);
  3578.             AV_WB16(pkt.data, len);
  3579.             memcpy(pkt.data + 2, t->value, len);
  3580.             ff_mov_write_packet(s, &pkt);
  3581.             av_freep(&pkt.data);
  3582.         }
  3583.     }
  3584.  
  3585.     return 0;
  3586. }
  3587.  
  3588. static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, const char *tcstr)
  3589. {
  3590.     int ret;
  3591.     MOVMuxContext *mov  = s->priv_data;
  3592.     MOVTrack *track     = &mov->tracks[index];
  3593.     AVStream *src_st    = s->streams[src_index];
  3594.     AVTimecode tc;
  3595.     AVPacket pkt    = {.stream_index = index, .flags = AV_PKT_FLAG_KEY, .size = 4};
  3596.     AVRational rate = find_fps(s, src_st);
  3597.  
  3598.     /* compute the frame number */
  3599.     ret = av_timecode_init_from_string(&tc, rate, tcstr, s);
  3600.     if (ret < 0)
  3601.         return ret;
  3602.  
  3603.     /* tmcd track based on video stream */
  3604.     track->mode      = mov->mode;
  3605.     track->tag       = MKTAG('t','m','c','d');
  3606.     track->src_track = src_index;
  3607.     track->timescale = mov->tracks[src_index].timescale;
  3608.     if (tc.flags & AV_TIMECODE_FLAG_DROPFRAME)
  3609.         track->timecode_flags |= MOV_TIMECODE_FLAG_DROPFRAME;
  3610.  
  3611.     /* encode context: tmcd data stream */
  3612.     track->enc = avcodec_alloc_context3(NULL);
  3613.     track->enc->codec_type = AVMEDIA_TYPE_DATA;
  3614.     track->enc->codec_tag  = track->tag;
  3615.     track->enc->time_base  = av_inv_q(rate);
  3616.  
  3617.     /* the tmcd track just contains one packet with the frame number */
  3618.     pkt.data = av_malloc(pkt.size);
  3619.     AV_WB32(pkt.data, tc.start);
  3620.     ret = ff_mov_write_packet(s, &pkt);
  3621.     av_free(pkt.data);
  3622.     return ret;
  3623. }
  3624.  
  3625. /*
  3626.  * st->disposition controls the "enabled" flag in the tkhd tag.
  3627.  * QuickTime will not play a track if it is not enabled.  So make sure
  3628.  * that one track of each type (audio, video, subtitle) is enabled.
  3629.  *
  3630.  * Subtitles are special.  For audio and video, setting "enabled" also
  3631.  * makes the track "default" (i.e. it is rendered when played). For
  3632.  * subtitles, an "enabled" subtitle is not rendered by default, but
  3633.  * if no subtitle is enabled, the subtitle menu in QuickTime will be
  3634.  * empty!
  3635.  */
  3636. static void enable_tracks(AVFormatContext *s)
  3637. {
  3638.     MOVMuxContext *mov = s->priv_data;
  3639.     int i;
  3640.     uint8_t enabled[AVMEDIA_TYPE_NB];
  3641.     int first[AVMEDIA_TYPE_NB];
  3642.  
  3643.     for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
  3644.         enabled[i] = 0;
  3645.         first[i] = -1;
  3646.     }
  3647.  
  3648.     for (i = 0; i < s->nb_streams; i++) {
  3649.         AVStream *st = s->streams[i];
  3650.  
  3651.         if (st->codec->codec_type <= AVMEDIA_TYPE_UNKNOWN ||
  3652.             st->codec->codec_type >= AVMEDIA_TYPE_NB)
  3653.             continue;
  3654.  
  3655.         if (first[st->codec->codec_type] < 0)
  3656.             first[st->codec->codec_type] = i;
  3657.         if (st->disposition & AV_DISPOSITION_DEFAULT) {
  3658.             mov->tracks[i].flags |= MOV_TRACK_ENABLED;
  3659.             enabled[st->codec->codec_type] = 1;
  3660.         }
  3661.     }
  3662.  
  3663.     for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
  3664.         switch (i) {
  3665.         case AVMEDIA_TYPE_VIDEO:
  3666.         case AVMEDIA_TYPE_AUDIO:
  3667.         case AVMEDIA_TYPE_SUBTITLE:
  3668.             if (!enabled[i] && first[i] >= 0)
  3669.                 mov->tracks[first[i]].flags |= MOV_TRACK_ENABLED;
  3670.             break;
  3671.         }
  3672.     }
  3673. }
  3674.  
  3675. static void mov_free(AVFormatContext *s)
  3676. {
  3677.     MOVMuxContext *mov = s->priv_data;
  3678.     int i;
  3679.  
  3680.     if (mov->chapter_track) {
  3681.         if (mov->tracks[mov->chapter_track].enc)
  3682.             av_freep(&mov->tracks[mov->chapter_track].enc->extradata);
  3683.         av_freep(&mov->tracks[mov->chapter_track].enc);
  3684.     }
  3685.  
  3686.     for (i = 0; i < mov->nb_streams; i++) {
  3687.         if (mov->tracks[i].tag == MKTAG('r','t','p',' '))
  3688.             ff_mov_close_hinting(&mov->tracks[i]);
  3689.         else if (mov->tracks[i].tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd)
  3690.             av_freep(&mov->tracks[i].enc);
  3691.         av_freep(&mov->tracks[i].cluster);
  3692.         av_freep(&mov->tracks[i].frag_info);
  3693.  
  3694.         if (mov->tracks[i].vos_len)
  3695.             av_freep(&mov->tracks[i].vos_data);
  3696.     }
  3697.  
  3698.     av_freep(&mov->tracks);
  3699. }
  3700.  
  3701. static int mov_write_header(AVFormatContext *s)
  3702. {
  3703.     AVIOContext *pb = s->pb;
  3704.     MOVMuxContext *mov = s->priv_data;
  3705.     AVDictionaryEntry *t, *global_tcr = av_dict_get(s->metadata, "timecode", NULL, 0);
  3706.     int i, hint_track = 0, tmcd_track = 0;
  3707.  
  3708.     /* Default mode == MP4 */
  3709.     mov->mode = MODE_MP4;
  3710.  
  3711.     if (s->oformat != NULL) {
  3712.         if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP;
  3713.         else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3GP|MODE_3G2;
  3714.         else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV;
  3715.         else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP;
  3716.         else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD;
  3717.         else if (!strcmp("ismv",s->oformat->name)) mov->mode = MODE_ISM;
  3718.         else if (!strcmp("f4v", s->oformat->name)) mov->mode = MODE_F4V;
  3719.     }
  3720.  
  3721.     /* Set the FRAGMENT flag if any of the fragmentation methods are
  3722.      * enabled. */
  3723.     if (mov->max_fragment_duration || mov->max_fragment_size ||
  3724.         mov->flags & (FF_MOV_FLAG_EMPTY_MOOV |
  3725.                       FF_MOV_FLAG_FRAG_KEYFRAME |
  3726.                       FF_MOV_FLAG_FRAG_CUSTOM))
  3727.         mov->flags |= FF_MOV_FLAG_FRAGMENT;
  3728.  
  3729.     /* Set other implicit flags immediately */
  3730.     if (mov->mode == MODE_ISM)
  3731.         mov->flags |= FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_SEPARATE_MOOF |
  3732.                       FF_MOV_FLAG_FRAGMENT;
  3733.  
  3734.     /* faststart: moov at the beginning of the file, if supported */
  3735.     if (mov->flags & FF_MOV_FLAG_FASTSTART) {
  3736.         if ((mov->flags & FF_MOV_FLAG_FRAGMENT) ||
  3737.             (s->flags & AVFMT_FLAG_CUSTOM_IO)) {
  3738.             av_log(s, AV_LOG_WARNING, "The faststart flag is incompatible "
  3739.                    "with fragmentation and custom IO, disabling faststart\n");
  3740.             mov->flags &= ~FF_MOV_FLAG_FASTSTART;
  3741.         } else
  3742.             mov->reserved_moov_size = -1;
  3743.     }
  3744.  
  3745.     if (!supports_edts(mov) && s->avoid_negative_ts < 0) {
  3746.         s->avoid_negative_ts = 1;
  3747.     }
  3748.  
  3749.     /* Non-seekable output is ok if using fragmentation. If ism_lookahead
  3750.      * is enabled, we don't support non-seekable output at all. */
  3751.     if (!s->pb->seekable &&
  3752.         (!(mov->flags & FF_MOV_FLAG_FRAGMENT) || mov->ism_lookahead)) {
  3753.         av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n");
  3754.         return AVERROR(EINVAL);
  3755.     }
  3756.  
  3757.     mov_write_ftyp_tag(pb,s);
  3758.     if (mov->mode == MODE_PSP) {
  3759.         int video_streams_nb = 0, audio_streams_nb = 0, other_streams_nb = 0;
  3760.         for (i = 0; i < s->nb_streams; i++) {
  3761.             AVStream *st = s->streams[i];
  3762.             if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
  3763.                 video_streams_nb++;
  3764.             else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
  3765.                 audio_streams_nb++;
  3766.             else
  3767.                 other_streams_nb++;
  3768.             }
  3769.  
  3770.         if (video_streams_nb != 1 || audio_streams_nb != 1 || other_streams_nb) {
  3771.             av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n");
  3772.             return AVERROR(EINVAL);
  3773.         }
  3774.         mov_write_uuidprof_tag(pb, s);
  3775.     }
  3776.  
  3777.     mov->nb_streams = s->nb_streams;
  3778.     if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
  3779.         mov->chapter_track = mov->nb_streams++;
  3780.  
  3781.     if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
  3782.         /* Add hint tracks for each audio and video stream */
  3783.         hint_track = mov->nb_streams;
  3784.         for (i = 0; i < s->nb_streams; i++) {
  3785.             AVStream *st = s->streams[i];
  3786.             if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
  3787.                 st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
  3788.                 mov->nb_streams++;
  3789.             }
  3790.         }
  3791.     }
  3792.  
  3793.     if (mov->mode == MODE_MOV) {
  3794.         tmcd_track = mov->nb_streams;
  3795.  
  3796.         /* +1 tmcd track for each video stream with a timecode */
  3797.         for (i = 0; i < s->nb_streams; i++) {
  3798.             AVStream *st = s->streams[i];
  3799.             if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
  3800.                 (global_tcr || av_dict_get(st->metadata, "timecode", NULL, 0)))
  3801.                 mov->nb_meta_tmcd++;
  3802.         }
  3803.  
  3804.         /* check if there is already a tmcd track to remux */
  3805.         if (mov->nb_meta_tmcd) {
  3806.             for (i = 0; i < s->nb_streams; i++) {
  3807.                 AVStream *st = s->streams[i];
  3808.                 if (st->codec->codec_tag == MKTAG('t','m','c','d')) {
  3809.                     av_log(s, AV_LOG_WARNING, "You requested a copy of the original timecode track "
  3810.                            "so timecode metadata are now ignored\n");
  3811.                     mov->nb_meta_tmcd = 0;
  3812.                 }
  3813.             }
  3814.         }
  3815.  
  3816.         mov->nb_streams += mov->nb_meta_tmcd;
  3817.     }
  3818.  
  3819.     // Reserve an extra stream for chapters for the case where chapters
  3820.     // are written in the trailer
  3821.     mov->tracks = av_mallocz((mov->nb_streams + 1) * sizeof(*mov->tracks));
  3822.     if (!mov->tracks)
  3823.         return AVERROR(ENOMEM);
  3824.  
  3825.     for (i = 0; i < s->nb_streams; i++) {
  3826.         AVStream *st= s->streams[i];
  3827.         MOVTrack *track= &mov->tracks[i];
  3828.         AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0);
  3829.  
  3830.         track->enc = st->codec;
  3831.         track->st = st;
  3832.         track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV);
  3833.         if (track->language < 0)
  3834.             track->language = 0;
  3835.         track->mode = mov->mode;
  3836.         track->tag  = mov_find_codec_tag(s, track);
  3837.         if (!track->tag) {
  3838.             av_log(s, AV_LOG_ERROR, "track %d: could not find tag, "
  3839.                    "codec not currently supported in container\n", i);
  3840.             goto error;
  3841.         }
  3842.         /* If hinting of this track is enabled by a later hint track,
  3843.          * this is updated. */
  3844.         track->hint_track = -1;
  3845.         track->start_dts  = AV_NOPTS_VALUE;
  3846.         if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
  3847.             if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') ||
  3848.                 track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') ||
  3849.                 track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) {
  3850.                 if (st->codec->width != 720 || (st->codec->height != 608 && st->codec->height != 512)) {
  3851.                     av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n");
  3852.                     goto error;
  3853.                 }
  3854.                 track->height = track->tag >> 24 == 'n' ? 486 : 576;
  3855.             }
  3856.             if (mov->video_track_timescale) {
  3857.                 track->timescale = mov->video_track_timescale;
  3858.             } else {
  3859.                 track->timescale = st->codec->time_base.den;
  3860.                 while(track->timescale < 10000)
  3861.                     track->timescale *= 2;
  3862.             }
  3863.             if (track->mode == MODE_MOV && track->timescale > 100000)
  3864.                 av_log(s, AV_LOG_WARNING,
  3865.                        "WARNING codec timebase is very high. If duration is too long,\n"
  3866.                        "file may not be playable by quicktime. Specify a shorter timebase\n"
  3867.                        "or choose different container.\n");
  3868.         } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
  3869.             track->timescale = st->codec->sample_rate;
  3870.             if (!st->codec->frame_size && !av_get_bits_per_sample(st->codec->codec_id)) {
  3871.                 av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i);
  3872.                 track->audio_vbr = 1;
  3873.             }else if (st->codec->codec_id == AV_CODEC_ID_ADPCM_MS ||
  3874.                      st->codec->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV ||
  3875.                      st->codec->codec_id == AV_CODEC_ID_ILBC){
  3876.                 if (!st->codec->block_align) {
  3877.                     av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);
  3878.                     goto error;
  3879.                 }
  3880.                 track->sample_size = st->codec->block_align;
  3881.             }else if (st->codec->frame_size > 1){ /* assume compressed audio */
  3882.                 track->audio_vbr = 1;
  3883.             }else{
  3884.                 track->sample_size = (av_get_bits_per_sample(st->codec->codec_id) >> 3) * st->codec->channels;
  3885.             }
  3886.             if (st->codec->codec_id == AV_CODEC_ID_ILBC) {
  3887.                 track->audio_vbr = 1;
  3888.             }
  3889.             if (track->mode != MODE_MOV &&
  3890.                 track->enc->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) {
  3891.                 av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not supported\n",
  3892.                        i, track->enc->sample_rate);
  3893.                 goto error;
  3894.             }
  3895.         } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
  3896.             track->timescale = st->codec->time_base.den;
  3897.         } else if (st->codec->codec_type == AVMEDIA_TYPE_DATA) {
  3898.             track->timescale = st->codec->time_base.den;
  3899.         } else {
  3900.             track->timescale = MOV_TIMESCALE;
  3901.         }
  3902.         if (!track->height)
  3903.             track->height = st->codec->height;
  3904.         /* The ism specific timescale isn't mandatory, but is assumed by
  3905.          * some tools, such as mp4split. */
  3906.         if (mov->mode == MODE_ISM)
  3907.             track->timescale = 10000000;
  3908.  
  3909.         avpriv_set_pts_info(st, 64, 1, track->timescale);
  3910.  
  3911.         /* copy extradata if it exists */
  3912.         if (st->codec->extradata_size) {
  3913.             track->vos_len  = st->codec->extradata_size;
  3914.             track->vos_data = av_malloc(track->vos_len);
  3915.             memcpy(track->vos_data, st->codec->extradata, track->vos_len);
  3916.         }
  3917.     }
  3918.  
  3919.     enable_tracks(s);
  3920.  
  3921.     if (mov->mode == MODE_ISM) {
  3922.         /* If no fragmentation options have been set, set a default. */
  3923.         if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME |
  3924.                             FF_MOV_FLAG_FRAG_CUSTOM)) &&
  3925.             !mov->max_fragment_duration && !mov->max_fragment_size)
  3926.             mov->flags |= FF_MOV_FLAG_FRAG_KEYFRAME;
  3927.     }
  3928.  
  3929.     if (mov->reserved_moov_size){
  3930.         mov->reserved_moov_pos= avio_tell(pb);
  3931.         if (mov->reserved_moov_size > 0)
  3932.             avio_skip(pb, mov->reserved_moov_size);
  3933.     }
  3934.  
  3935.     if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
  3936.         if (mov->flags & FF_MOV_FLAG_FASTSTART)
  3937.             mov->reserved_moov_pos = avio_tell(pb);
  3938.         mov_write_mdat_tag(pb, mov);
  3939.     }
  3940.  
  3941.     if (t = av_dict_get(s->metadata, "creation_time", NULL, 0))
  3942.         mov->time = ff_iso8601_to_unix_time(t->value);
  3943.     if (mov->time)
  3944.         mov->time += 0x7C25B080; // 1970 based -> 1904 based
  3945.  
  3946.     if (mov->chapter_track)
  3947.         if (mov_create_chapter_track(s, mov->chapter_track) < 0)
  3948.             goto error;
  3949.  
  3950.     if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
  3951.         /* Initialize the hint tracks for each audio and video stream */
  3952.         for (i = 0; i < s->nb_streams; i++) {
  3953.             AVStream *st = s->streams[i];
  3954.             if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
  3955.                 st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
  3956.                 if (ff_mov_init_hinting(s, hint_track, i) < 0)
  3957.                     goto error;
  3958.                 hint_track++;
  3959.             }
  3960.         }
  3961.     }
  3962.  
  3963.     if (mov->nb_meta_tmcd) {
  3964.         /* Initialize the tmcd tracks */
  3965.         for (i = 0; i < s->nb_streams; i++) {
  3966.             AVStream *st = s->streams[i];
  3967.             t = global_tcr;
  3968.  
  3969.             if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
  3970.                 if (!t)
  3971.                     t = av_dict_get(st->metadata, "timecode", NULL, 0);
  3972.                 if (!t)
  3973.                     continue;
  3974.                 if (mov_create_timecode_track(s, tmcd_track, i, t->value) < 0)
  3975.                     goto error;
  3976.                 tmcd_track++;
  3977.             }
  3978.         }
  3979.     }
  3980.  
  3981.     avio_flush(pb);
  3982.  
  3983.     if (mov->flags & FF_MOV_FLAG_ISML)
  3984.         mov_write_isml_manifest(pb, mov);
  3985.  
  3986.     if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV) {
  3987.         mov_write_moov_tag(pb, mov, s);
  3988.         mov->fragments++;
  3989.     }
  3990.  
  3991.     return 0;
  3992.  error:
  3993.     mov_free(s);
  3994.     return -1;
  3995. }
  3996.  
  3997. static int get_moov_size(AVFormatContext *s)
  3998. {
  3999.     int ret;
  4000.     AVIOContext *moov_buf;
  4001.     MOVMuxContext *mov = s->priv_data;
  4002.  
  4003.     if ((ret = ffio_open_null_buf(&moov_buf)) < 0)
  4004.         return ret;
  4005.     mov_write_moov_tag(moov_buf, mov, s);
  4006.     return ffio_close_null_buf(moov_buf);
  4007. }
  4008.  
  4009. /*
  4010.  * This function gets the moov size if moved to the top of the file: the chunk
  4011.  * offset table can switch between stco (32-bit entries) to co64 (64-bit
  4012.  * entries) when the moov is moved to the beginning, so the size of the moov
  4013.  * would change. It also updates the chunk offset tables.
  4014.  */
  4015. static int compute_moov_size(AVFormatContext *s)
  4016. {
  4017.     int i, moov_size, moov_size2;
  4018.     MOVMuxContext *mov = s->priv_data;
  4019.  
  4020.     moov_size = get_moov_size(s);
  4021.     if (moov_size < 0)
  4022.         return moov_size;
  4023.  
  4024.     for (i = 0; i < mov->nb_streams; i++)
  4025.         mov->tracks[i].data_offset += moov_size;
  4026.  
  4027.     moov_size2 = get_moov_size(s);
  4028.     if (moov_size2 < 0)
  4029.         return moov_size2;
  4030.  
  4031.     /* if the size changed, we just switched from stco to co64 and need to
  4032.      * update the offsets */
  4033.     if (moov_size2 != moov_size)
  4034.         for (i = 0; i < mov->nb_streams; i++)
  4035.             mov->tracks[i].data_offset += moov_size2 - moov_size;
  4036.  
  4037.     return moov_size2;
  4038. }
  4039.  
  4040. static int shift_data(AVFormatContext *s)
  4041. {
  4042.     int ret = 0, moov_size;
  4043.     MOVMuxContext *mov = s->priv_data;
  4044.     int64_t pos, pos_end = avio_tell(s->pb);
  4045.     uint8_t *buf, *read_buf[2];
  4046.     int read_buf_id = 0;
  4047.     int read_size[2];
  4048.     AVIOContext *read_pb;
  4049.  
  4050.     moov_size = compute_moov_size(s);
  4051.     if (moov_size < 0)
  4052.         return moov_size;
  4053.  
  4054.     buf = av_malloc(moov_size * 2);
  4055.     if (!buf)
  4056.         return AVERROR(ENOMEM);
  4057.     read_buf[0] = buf;
  4058.     read_buf[1] = buf + moov_size;
  4059.  
  4060.     /* Shift the data: the AVIO context of the output can only be used for
  4061.      * writing, so we re-open the same output, but for reading. It also avoids
  4062.      * a read/seek/write/seek back and forth. */
  4063.     avio_flush(s->pb);
  4064.     ret = avio_open(&read_pb, s->filename, AVIO_FLAG_READ);
  4065.     if (ret < 0) {
  4066.         av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for "
  4067.                "the second pass (faststart)\n", s->filename);
  4068.         goto end;
  4069.     }
  4070.  
  4071.     /* mark the end of the shift to up to the last data we wrote, and get ready
  4072.      * for writing */
  4073.     pos_end = avio_tell(s->pb);
  4074.     avio_seek(s->pb, mov->reserved_moov_pos + moov_size, SEEK_SET);
  4075.  
  4076.     /* start reading at where the new moov will be placed */
  4077.     avio_seek(read_pb, mov->reserved_moov_pos, SEEK_SET);
  4078.     pos = avio_tell(read_pb);
  4079.  
  4080. #define READ_BLOCK do {                                                             \
  4081.     read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], moov_size);  \
  4082.     read_buf_id ^= 1;                                                               \
  4083. } while (0)
  4084.  
  4085.     /* shift data by chunk of at most moov_size */
  4086.     READ_BLOCK;
  4087.     do {
  4088.         int n;
  4089.         READ_BLOCK;
  4090.         n = read_size[read_buf_id];
  4091.         if (n <= 0)
  4092.             break;
  4093.         avio_write(s->pb, read_buf[read_buf_id], n);
  4094.         pos += n;
  4095.     } while (pos < pos_end);
  4096.     avio_close(read_pb);
  4097.  
  4098. end:
  4099.     av_free(buf);
  4100.     return ret;
  4101. }
  4102.  
  4103. static int mov_write_trailer(AVFormatContext *s)
  4104. {
  4105.     MOVMuxContext *mov = s->priv_data;
  4106.     AVIOContext *pb = s->pb;
  4107.     int res = 0;
  4108.     int i;
  4109.     int64_t moov_pos;
  4110.  
  4111.     /*
  4112.      * Before actually writing the trailer, make sure that there are no
  4113.      * dangling subtitles, that need a terminating sample.
  4114.      */
  4115.     for (i = 0; i < mov->nb_streams; i++) {
  4116.         MOVTrack *trk = &mov->tracks[i];
  4117.         if (trk->enc->codec_id == AV_CODEC_ID_MOV_TEXT &&
  4118.             !trk->last_sample_is_subtitle_end) {
  4119.             mov_write_subtitle_end_packet(s, i, trk->track_duration);
  4120.             trk->last_sample_is_subtitle_end = 1;
  4121.         }
  4122.     }
  4123.  
  4124.     // If there were no chapters when the header was written, but there
  4125.     // are chapters now, write them in the trailer.  This only works
  4126.     // when we are not doing fragments.
  4127.     if (!mov->chapter_track && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
  4128.         if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters) {
  4129.             mov->chapter_track = mov->nb_streams++;
  4130.             if ((res = mov_create_chapter_track(s, mov->chapter_track)) < 0)
  4131.                 goto error;
  4132.         }
  4133.     }
  4134.  
  4135.     if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
  4136.         moov_pos = avio_tell(pb);
  4137.  
  4138.         /* Write size of mdat tag */
  4139.         if (mov->mdat_size + 8 <= UINT32_MAX) {
  4140.             avio_seek(pb, mov->mdat_pos, SEEK_SET);
  4141.             avio_wb32(pb, mov->mdat_size + 8);
  4142.         } else {
  4143.             /* overwrite 'wide' placeholder atom */
  4144.             avio_seek(pb, mov->mdat_pos - 8, SEEK_SET);
  4145.             /* special value: real atom size will be 64 bit value after
  4146.              * tag field */
  4147.             avio_wb32(pb, 1);
  4148.             ffio_wfourcc(pb, "mdat");
  4149.             avio_wb64(pb, mov->mdat_size + 16);
  4150.         }
  4151.         avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_moov_pos : moov_pos, SEEK_SET);
  4152.  
  4153.         if (mov->flags & FF_MOV_FLAG_FASTSTART) {
  4154.             av_log(s, AV_LOG_INFO, "Starting second pass: moving the moov atom to the beginning of the file\n");
  4155.             res = shift_data(s);
  4156.             if (res == 0) {
  4157.                 avio_seek(s->pb, mov->reserved_moov_pos, SEEK_SET);
  4158.                 mov_write_moov_tag(pb, mov, s);
  4159.             }
  4160.         } else if (mov->reserved_moov_size > 0) {
  4161.             int64_t size;
  4162.             mov_write_moov_tag(pb, mov, s);
  4163.             size = mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_moov_pos);
  4164.             if (size < 8){
  4165.                 av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size);
  4166.                 return -1;
  4167.             }
  4168.             avio_wb32(pb, size);
  4169.             ffio_wfourcc(pb, "free");
  4170.             for (i = 0; i < size; i++)
  4171.                 avio_w8(pb, 0);
  4172.             avio_seek(pb, moov_pos, SEEK_SET);
  4173.         } else {
  4174.             mov_write_moov_tag(pb, mov, s);
  4175.         }
  4176.     } else {
  4177.         mov_flush_fragment(s);
  4178.         mov_write_mfra_tag(pb, mov);
  4179.     }
  4180.  
  4181.     for (i = 0; i < mov->nb_streams; i++) {
  4182.         if (mov->flags & FF_MOV_FLAG_FRAGMENT &&
  4183.             mov->tracks[i].vc1_info.struct_offset && s->pb->seekable) {
  4184.             int64_t off = avio_tell(pb);
  4185.             uint8_t buf[7];
  4186.             if (mov_write_dvc1_structs(&mov->tracks[i], buf) >= 0) {
  4187.                 avio_seek(pb, mov->tracks[i].vc1_info.struct_offset, SEEK_SET);
  4188.                 avio_write(pb, buf, 7);
  4189.                 avio_seek(pb, off, SEEK_SET);
  4190.             }
  4191.         }
  4192.     }
  4193.  
  4194. error:
  4195.     mov_free(s);
  4196.  
  4197.     return res;
  4198. }
  4199.  
  4200. #if CONFIG_MOV_MUXER
  4201. MOV_CLASS(mov)
  4202. AVOutputFormat ff_mov_muxer = {
  4203.     .name              = "mov",
  4204.     .long_name         = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
  4205.     .extensions        = "mov",
  4206.     .priv_data_size    = sizeof(MOVMuxContext),
  4207.     .audio_codec       = AV_CODEC_ID_AAC,
  4208.     .video_codec       = CONFIG_LIBX264_ENCODER ?
  4209.                          AV_CODEC_ID_H264 : AV_CODEC_ID_MPEG4,
  4210.     .write_header      = mov_write_header,
  4211.     .write_packet      = mov_write_packet,
  4212.     .write_trailer     = mov_write_trailer,
  4213.     .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
  4214.     .codec_tag         = (const AVCodecTag* const []){
  4215.         ff_codec_movvideo_tags, ff_codec_movaudio_tags, 0
  4216.     },
  4217.     .priv_class        = &mov_muxer_class,
  4218. };
  4219. #endif
  4220. #if CONFIG_TGP_MUXER
  4221. MOV_CLASS(tgp)
  4222. AVOutputFormat ff_tgp_muxer = {
  4223.     .name              = "3gp",
  4224.     .long_name         = NULL_IF_CONFIG_SMALL("3GP (3GPP file format)"),
  4225.     .extensions        = "3gp",
  4226.     .priv_data_size    = sizeof(MOVMuxContext),
  4227.     .audio_codec       = AV_CODEC_ID_AMR_NB,
  4228.     .video_codec       = AV_CODEC_ID_H263,
  4229.     .write_header      = mov_write_header,
  4230.     .write_packet      = mov_write_packet,
  4231.     .write_trailer     = mov_write_trailer,
  4232.     .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
  4233.     .codec_tag         = (const AVCodecTag* const []){ codec_3gp_tags, 0 },
  4234.     .priv_class        = &tgp_muxer_class,
  4235. };
  4236. #endif
  4237. #if CONFIG_MP4_MUXER
  4238. MOV_CLASS(mp4)
  4239. AVOutputFormat ff_mp4_muxer = {
  4240.     .name              = "mp4",
  4241.     .long_name         = NULL_IF_CONFIG_SMALL("MP4 (MPEG-4 Part 14)"),
  4242.     .mime_type         = "application/mp4",
  4243.     .extensions        = "mp4",
  4244.     .priv_data_size    = sizeof(MOVMuxContext),
  4245.     .audio_codec       = AV_CODEC_ID_AAC,
  4246.     .video_codec       = CONFIG_LIBX264_ENCODER ?
  4247.                          AV_CODEC_ID_H264 : AV_CODEC_ID_MPEG4,
  4248.     .write_header      = mov_write_header,
  4249.     .write_packet      = mov_write_packet,
  4250.     .write_trailer     = mov_write_trailer,
  4251.     .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
  4252.     .codec_tag         = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 },
  4253.     .priv_class        = &mp4_muxer_class,
  4254. };
  4255. #endif
  4256. #if CONFIG_PSP_MUXER
  4257. MOV_CLASS(psp)
  4258. AVOutputFormat ff_psp_muxer = {
  4259.     .name              = "psp",
  4260.     .long_name         = NULL_IF_CONFIG_SMALL("PSP MP4 (MPEG-4 Part 14)"),
  4261.     .extensions        = "mp4,psp",
  4262.     .priv_data_size    = sizeof(MOVMuxContext),
  4263.     .audio_codec       = AV_CODEC_ID_AAC,
  4264.     .video_codec       = CONFIG_LIBX264_ENCODER ?
  4265.                          AV_CODEC_ID_H264 : AV_CODEC_ID_MPEG4,
  4266.     .write_header      = mov_write_header,
  4267.     .write_packet      = mov_write_packet,
  4268.     .write_trailer     = mov_write_trailer,
  4269.     .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
  4270.     .codec_tag         = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 },
  4271.     .priv_class        = &psp_muxer_class,
  4272. };
  4273. #endif
  4274. #if CONFIG_TG2_MUXER
  4275. MOV_CLASS(tg2)
  4276. AVOutputFormat ff_tg2_muxer = {
  4277.     .name              = "3g2",
  4278.     .long_name         = NULL_IF_CONFIG_SMALL("3GP2 (3GPP2 file format)"),
  4279.     .extensions        = "3g2",
  4280.     .priv_data_size    = sizeof(MOVMuxContext),
  4281.     .audio_codec       = AV_CODEC_ID_AMR_NB,
  4282.     .video_codec       = AV_CODEC_ID_H263,
  4283.     .write_header      = mov_write_header,
  4284.     .write_packet      = mov_write_packet,
  4285.     .write_trailer     = mov_write_trailer,
  4286.     .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
  4287.     .codec_tag         = (const AVCodecTag* const []){ codec_3gp_tags, 0 },
  4288.     .priv_class        = &tg2_muxer_class,
  4289. };
  4290. #endif
  4291. #if CONFIG_IPOD_MUXER
  4292. MOV_CLASS(ipod)
  4293. AVOutputFormat ff_ipod_muxer = {
  4294.     .name              = "ipod",
  4295.     .long_name         = NULL_IF_CONFIG_SMALL("iPod H.264 MP4 (MPEG-4 Part 14)"),
  4296.     .mime_type         = "application/mp4",
  4297.     .extensions        = "m4v,m4a",
  4298.     .priv_data_size    = sizeof(MOVMuxContext),
  4299.     .audio_codec       = AV_CODEC_ID_AAC,
  4300.     .video_codec       = AV_CODEC_ID_H264,
  4301.     .write_header      = mov_write_header,
  4302.     .write_packet      = mov_write_packet,
  4303.     .write_trailer     = mov_write_trailer,
  4304.     .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
  4305.     .codec_tag         = (const AVCodecTag* const []){ codec_ipod_tags, 0 },
  4306.     .priv_class        = &ipod_muxer_class,
  4307. };
  4308. #endif
  4309. #if CONFIG_ISMV_MUXER
  4310. MOV_CLASS(ismv)
  4311. AVOutputFormat ff_ismv_muxer = {
  4312.     .name              = "ismv",
  4313.     .long_name         = NULL_IF_CONFIG_SMALL("ISMV/ISMA (Smooth Streaming)"),
  4314.     .mime_type         = "application/mp4",
  4315.     .extensions        = "ismv,isma",
  4316.     .priv_data_size    = sizeof(MOVMuxContext),
  4317.     .audio_codec       = AV_CODEC_ID_AAC,
  4318.     .video_codec       = AV_CODEC_ID_H264,
  4319.     .write_header      = mov_write_header,
  4320.     .write_packet      = mov_write_packet,
  4321.     .write_trailer     = mov_write_trailer,
  4322.     .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH | AVFMT_TS_NEGATIVE,
  4323.     .codec_tag         = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 },
  4324.     .priv_class        = &ismv_muxer_class,
  4325. };
  4326. #endif
  4327. #if CONFIG_F4V_MUXER
  4328. MOV_CLASS(f4v)
  4329. AVOutputFormat ff_f4v_muxer = {
  4330.     .name              = "f4v",
  4331.     .long_name         = NULL_IF_CONFIG_SMALL("F4V Adobe Flash Video"),
  4332.     .mime_type         = "application/f4v",
  4333.     .extensions        = "f4v",
  4334.     .priv_data_size    = sizeof(MOVMuxContext),
  4335.     .audio_codec       = AV_CODEC_ID_AAC,
  4336.     .video_codec       = AV_CODEC_ID_H264,
  4337.     .write_header      = mov_write_header,
  4338.     .write_packet      = mov_write_packet,
  4339.     .write_trailer     = mov_write_trailer,
  4340.     .flags             = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH,
  4341.     .codec_tag         = (const AVCodecTag* const []){ codec_f4v_tags, 0 },
  4342.     .priv_class        = &f4v_muxer_class,
  4343. };
  4344. #endif
  4345.