56
57
{ "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" },
57
58
{ "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" },
58
59
{ "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" },
60
{ "disable_chpl", "Disable Nero chapter atom", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_DISABLE_CHPL}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
59
61
FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
60
62
{ "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
61
63
{ "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},
310
323
// the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio)
311
324
// plus 1 bit to indicate upstream and 1 bit set to 1 (reserved)
312
if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
325
if (track->enc->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
326
avio_w8(pb, (0x38 << 2) | 1); // flags (= NeroSubpicStream)
327
else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
313
328
avio_w8(pb, 0x15); // flags (= Audiostream)
315
330
avio_w8(pb, 0x11); // flags (= Visualstream)
480
495
put_bits(&pbc, 1, !slices); /* no slice code */
481
496
put_bits(&pbc, 1, 0); /* no bframe */
482
497
put_bits(&pbc, 1, 0); /* reserved */
483
put_bits32(&pbc, track->enc->time_base.den); /* framerate */
500
if (track->st->avg_frame_rate.num > 0 && track->st->avg_frame_rate.den > 0)
501
put_bits32(&pbc, track->st->avg_frame_rate.num / track->st->avg_frame_rate.den);
503
put_bits32(&pbc, 0xffffffff);
484
505
flush_put_bits(&pbc);
486
507
av_free(unescaped);
760
781
else if (track->enc->codec_id == AV_CODEC_ID_VC1) tag = MKTAG('v','c','-','1');
761
782
else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) tag = MKTAG('m','p','4','v');
762
783
else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) tag = MKTAG('m','p','4','a');
784
else if (track->enc->codec_id == AV_CODEC_ID_DVD_SUBTITLE) tag = MKTAG('m','p','4','s');
804
826
else if (track->enc->pix_fmt == AV_PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p');
805
827
else tag = MKTAG('d','v','p','p');
806
828
else if (track->enc->height == 720) /* HD 720 line */
807
if (track->enc->time_base.den == 50) tag = MKTAG('d','v','h','q');
829
if (track->st->time_base.den == 50) tag = MKTAG('d','v','h','q');
808
830
else tag = MKTAG('d','v','h','p');
809
831
else if (track->enc->height == 1080) /* HD 1080 line */
810
if (track->enc->time_base.den == 25) tag = MKTAG('d','v','h','5');
832
if (track->st->time_base.den == 25) tag = MKTAG('d','v','h','5');
811
833
else tag = MKTAG('d','v','h','6');
813
835
av_log(s, AV_LOG_ERROR, "unsupported height for dv codec\n");
976
998
avio_wb16(pb, 0); /* Reserved */
977
999
avio_wb16(pb, 1); /* Data-reference index */
979
if (track->enc->extradata_size)
1001
if (track->enc->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
1002
mov_write_esds_tag(pb, track);
1003
else if (track->enc->extradata_size)
980
1004
avio_write(pb, track->enc->extradata, track->enc->extradata_size);
982
1006
return update_size(pb, pos);
1030
1055
avio_wb16(pb, 1); /* Frame count (= 1) */
1032
1057
/* FIXME not sure, ISO 14496-1 draft where it shall be set to 0 */
1033
if (track->mode == MODE_MOV && track->enc->codec && track->enc->codec->name)
1034
av_strlcpy(compressor_name, track->enc->codec->name, 32);
1058
if (track->mode == MODE_MOV &&
1059
(encoder = av_dict_get(track->st->metadata, "encoder", NULL, 0)))
1060
av_strlcpy(compressor_name, encoder->value, 32);
1035
1061
avio_w8(pb, strlen(compressor_name));
1036
1062
avio_write(pb, compressor_name, 31);
1318
static int is_clcp_track(MOVTrack *track)
1320
return track->tag == MKTAG('c','7','0','8') ||
1321
track->tag == MKTAG('c','6','0','8');
1292
1324
static int mov_write_hdlr_tag(AVIOContext *pb, MOVTrack *track)
1294
1326
const char *hdlr, *descr = NULL, *hdlr_type = NULL;
1307
1339
hdlr_type = "soun";
1308
1340
descr = "SoundHandler";
1309
1341
} else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
1310
if (track->tag == MKTAG('t','x','3','g')) hdlr_type = "sbtl";
1311
else hdlr_type = "text";
1342
if (track->tag == MKTAG('t','x','3','g')) {
1344
} else if (track->tag == MKTAG('m','p','4','s')) {
1346
} else if (is_clcp_track(track)) {
1312
1351
descr = "SubtitleHandler";
1313
1352
} else if (track->enc->codec_tag == MKTAG('r','t','p',' ')) {
1314
1353
hdlr_type = "hint";
1325
1364
"Unknown hldr_type for %s / 0x%04X, writing dummy values\n",
1326
1365
tag_buf, track->enc->codec_tag);
1368
// hdlr.name is used by some players to identify the content title
1369
// of the track. So if an alternate handler description is
1370
// specified, use it.
1371
AVDictionaryEntry *t;
1372
t = av_dict_get(track->st->metadata, "handler", NULL, 0);
1373
if (t && utf8len(t->value))
1330
1378
avio_wb32(pb, 0); /* size */
1368
1416
else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
1369
1417
mov_write_smhd_tag(pb);
1370
1418
else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) {
1371
if (track->tag == MKTAG('t','e','x','t')) mov_write_gmhd_tag(pb);
1372
else mov_write_nmhd_tag(pb);
1419
if (track->tag == MKTAG('t','e','x','t') || is_clcp_track(track)) {
1420
mov_write_gmhd_tag(pb);
1422
mov_write_nmhd_tag(pb);
1373
1424
} else if (track->tag == MKTAG('r','t','p',' ')) {
1374
1425
mov_write_hmhd_tag(pb);
1375
1426
} else if (track->tag == MKTAG('t','m','c','d')) {
1429
1480
return update_size(pb, pos);
1432
static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
1483
static int mov_write_tkhd_tag(AVIOContext *pb, MOVMuxContext *mov,
1484
MOVTrack *track, AVStream *st)
1434
1486
int64_t duration = av_rescale_rnd(track->track_duration, MOV_TIMESCALE,
1435
1487
track->timescale, AV_ROUND_UP);
1436
1488
int version = duration < INT32_MAX ? 0 : 1;
1489
int flags = MOV_TKHD_FLAG_IN_MOVIE;
1494
if (mov->per_stream_grouping)
1497
group = st->codec->codec_type;
1500
if (track->flags & MOV_TRACK_ENABLED)
1501
flags |= MOV_TKHD_FLAG_ENABLED;
1438
1503
if (track->mode == MODE_ISM)
1441
1506
(version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
1442
1507
ffio_wfourcc(pb, "tkhd");
1443
1508
avio_w8(pb, version);
1444
avio_wb24(pb, (track->flags & MOV_TRACK_ENABLED) ?
1445
MOV_TKHD_FLAG_ENABLED | MOV_TKHD_FLAG_IN_MOVIE :
1446
MOV_TKHD_FLAG_IN_MOVIE);
1509
avio_wb24(pb, flags);
1447
1510
if (version == 1) {
1448
1511
avio_wb64(pb, track->time);
1449
1512
avio_wb64(pb, track->time);
1461
1524
avio_wb32(pb, 0); /* reserved */
1462
1525
avio_wb32(pb, 0); /* reserved */
1463
1526
avio_wb16(pb, 0); /* layer */
1464
avio_wb16(pb, st ? st->codec->codec_type : 0); /* alternate group) */
1527
avio_wb16(pb, group); /* alternate group) */
1465
1528
/* Volume, only for audio */
1466
1529
if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO)
1467
1530
avio_wb16(pb, 0x0100);
1517
1580
avio_wb32(pb, track->enc->height << 16);
1519
1582
avio_wb32(pb, 20);
1583
ffio_wfourcc(pb, "prof");
1585
avio_wb32(pb, width << 16);
1586
avio_wb32(pb, track->enc->height << 16);
1520
1589
ffio_wfourcc(pb, "enof");
1521
1590
avio_wb32(pb, 0);
1522
1591
avio_wb32(pb, track->enc->width << 16);
1623
1692
return len + 24;
1695
static int mov_write_track_metadata(AVIOContext *pb, AVStream *st,
1696
const char *tag, const char *str)
1698
int64_t pos = avio_tell(pb);
1699
AVDictionaryEntry *t = av_dict_get(st->metadata, str, NULL, 0);
1700
if (!t || !utf8len(t->value))
1703
avio_wb32(pb, 0); /* size */
1704
ffio_wfourcc(pb, tag); /* type */
1705
avio_write(pb, t->value, strlen(t->value)); /* UTF8 string value */
1706
return update_size(pb, pos);
1709
static int mov_write_track_udta_tag(AVIOContext *pb, MOVMuxContext *mov,
1712
AVIOContext *pb_buf;
1716
if (!st || mov->fc->flags & AVFMT_FLAG_BITEXACT)
1719
ret = avio_open_dyn_buf(&pb_buf);
1723
if (mov->mode & MODE_MP4)
1724
mov_write_track_metadata(pb_buf, st, "name", "title");
1726
if ((size = avio_close_dyn_buf(pb_buf, &buf)) > 0) {
1727
avio_wb32(pb, size + 8);
1728
ffio_wfourcc(pb, "udta");
1729
avio_write(pb, buf, size);
1626
1736
static int mov_write_trak_tag(AVIOContext *pb, MOVMuxContext *mov,
1627
1737
MOVTrack *track, AVStream *st)
1629
1739
int64_t pos = avio_tell(pb);
1630
1740
avio_wb32(pb, 0); /* size */
1631
1741
ffio_wfourcc(pb, "trak");
1632
mov_write_tkhd_tag(pb, track, st);
1742
mov_write_tkhd_tag(pb, mov, track, st);
1633
1743
if (track->mode == MODE_PSP || track->flags & MOV_TRACK_CTTS ||
1634
(track->entry && track->cluster[0].dts)) {
1744
(track->entry && track->cluster[0].dts) ||
1745
is_clcp_track(track)) {
1635
1746
if (!(mov->flags & FF_MOV_FLAG_FRAGMENT))
1636
1747
mov_write_edts_tag(pb, track); // PSP Movies require edts box
1642
1753
mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box
1643
1754
if (track->tag == MKTAG('r','t','p',' '))
1644
1755
mov_write_udta_sdp(pb, track);
1645
if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO && track->mode == MODE_MOV) {
1646
double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
1647
if (0.0 != sample_aspect_ratio && 1.0 != sample_aspect_ratio)
1756
if (track->mode == MODE_MOV) {
1757
if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {
1758
double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);
1759
if ((0.0 != sample_aspect_ratio && 1.0 != sample_aspect_ratio)) {
1760
mov_write_tapt_tag(pb, track);
1763
if (is_clcp_track(track)) {
1648
1764
mov_write_tapt_tag(pb, track);
1767
mov_write_track_udta_tag(pb, mov, st);
1650
1768
return update_size(pb, pos);
2614
2719
static void mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s)
2721
AVStream *video_st = s->streams[0];
2616
2722
AVCodecContext *video_codec = s->streams[0]->codec;
2617
2723
AVCodecContext *audio_codec = s->streams[1]->codec;
2618
2724
int audio_rate = audio_codec->sample_rate;
2619
int frame_rate = ((video_codec->time_base.den) * (0x10000)) / (video_codec->time_base.num);
2725
// TODO: should be avg_frame_rate
2726
int frame_rate = ((video_st->time_base.den) * (0x10000)) / (video_st->time_base.num);
2620
2727
int audio_kbitrate = audio_codec->bit_rate / 1000;
2621
2728
int video_kbitrate = FFMIN(video_codec->bit_rate / 1000, 800 - audio_kbitrate);
3075
3182
return AVERROR(ENOMEM);
3076
3183
track->enc->codec_type = AVMEDIA_TYPE_SUBTITLE;
3077
3184
track->enc->extradata = av_malloc(sizeof(chapter_properties));
3078
if (track->enc->extradata == NULL)
3185
if (!track->enc->extradata)
3079
3186
return AVERROR(ENOMEM);
3080
3187
track->enc->extradata_size = sizeof(chapter_properties);
3081
3188
memcpy(track->enc->extradata, chapter_properties, sizeof(chapter_properties));
3089
3196
pkt.duration = end - pkt.dts;
3091
3198
if ((t = av_dict_get(c->metadata, "title", NULL, 0))) {
3199
const char encd[12] = {
3200
0x00, 0x00, 0x00, 0x0C,
3202
0x00, 0x00, 0x01, 0x00 };
3092
3203
len = strlen(t->value);
3204
pkt.size = len + 2 + 12;
3094
3205
pkt.data = av_malloc(pkt.size);
3096
3207
return AVERROR(ENOMEM);
3097
3208
AV_WB16(pkt.data, len);
3098
3209
memcpy(pkt.data + 2, t->value, len);
3210
memcpy(pkt.data + len + 2, encd, sizeof(encd));
3099
3211
ff_mov_write_packet(s, &pkt);
3100
3212
av_freep(&pkt.data);
3178
3292
av_freep(&mov->tracks);
3295
static uint32_t rgb_to_yuv(uint32_t rgb)
3300
r = (rgb >> 16) & 0xFF;
3301
g = (rgb >> 8) & 0xFF;
3304
y = av_clip_uint8( 16. + 0.257 * r + 0.504 * g + 0.098 * b);
3305
cb = av_clip_uint8(128. - 0.148 * r - 0.291 * g + 0.439 * b);
3306
cr = av_clip_uint8(128. + 0.439 * r - 0.368 * g - 0.071 * b);
3308
return (y << 16) | (cr << 8) | cb;
3311
static int mov_create_dvd_sub_decoder_specific_info(MOVTrack *track,
3314
int i, width = 720, height = 480;
3315
int have_palette = 0, have_size = 0;
3316
uint32_t palette[16];
3317
char *cur = st->codec->extradata;
3319
while (cur && *cur) {
3320
if (strncmp("palette:", cur, 8) == 0) {
3322
count = sscanf(cur + 8,
3323
"%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
3324
"%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
3325
"%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32", "
3326
"%06"PRIx32", %06"PRIx32", %06"PRIx32", %06"PRIx32"",
3327
&palette[ 0], &palette[ 1], &palette[ 2], &palette[ 3],
3328
&palette[ 4], &palette[ 5], &palette[ 6], &palette[ 7],
3329
&palette[ 8], &palette[ 9], &palette[10], &palette[11],
3330
&palette[12], &palette[13], &palette[14], &palette[15]);
3332
for (i = 0; i < count; i++) {
3333
palette[i] = rgb_to_yuv(palette[i]);
3336
} else if (!strncmp("size:", cur, 5)) {
3337
sscanf(cur + 5, "%dx%d", &width, &height);
3340
if (have_palette && have_size)
3342
cur += strcspn(cur, "\n\r");
3343
cur += strspn(cur, "\n\r");
3346
track->vos_data = av_malloc(16*4);
3347
if (!track->vos_data)
3348
return AVERROR(ENOMEM);
3349
for (i = 0; i < 16; i++) {
3350
AV_WB32(track->vos_data + i * 4, palette[i]);
3352
track->vos_len = 16 * 4;
3354
st->codec->width = width;
3355
st->codec->height = track->height = height;
3181
3360
static int mov_write_header(AVFormatContext *s)
3183
3362
AVIOContext *pb = s->pb;
3292
3474
track->height = track->tag >> 24 == 'n' ? 486 : 576;
3294
track->timescale = st->codec->time_base.den;
3476
track->timescale = st->time_base.den;
3295
3477
if (track->mode == MODE_MOV && track->timescale > 100000)
3296
3478
av_log(s, AV_LOG_WARNING,
3297
3479
"WARNING codec timebase is very high. If duration is too long,\n"
3321
3503
} else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
3322
track->timescale = st->codec->time_base.den;
3504
track->timescale = st->time_base.den;
3323
3505
} else if (st->codec->codec_type == AVMEDIA_TYPE_DATA) {
3324
track->timescale = st->codec->time_base.den;
3506
track->timescale = st->time_base.den;
3326
3508
if (!track->height)
3327
3509
track->height = st->codec->height;
3335
3517
/* copy extradata if it exists */
3336
3518
if (st->codec->extradata_size) {
3337
track->vos_len = st->codec->extradata_size;
3338
track->vos_data = av_malloc(track->vos_len);
3339
memcpy(track->vos_data, st->codec->extradata, track->vos_len);
3519
if (st->codec->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
3520
mov_create_dvd_sub_decoder_specific_info(track, st);
3522
track->vos_len = st->codec->extradata_size;
3523
track->vos_data = av_malloc(track->vos_len);
3524
memcpy(track->vos_data, st->codec->extradata, track->vos_len);