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