32
32
#include "libavcodec/put_bits.h"
33
33
#include "internal.h"
34
34
#include "libavutil/avstring.h"
35
#include "libavutil/intfloat.h"
36
#include "libavutil/mathematics.h"
35
37
#include "libavutil/opt.h"
36
38
#include "libavutil/dict.h"
37
39
#include "rtpenc.h"
40
43
#include <assert.h>
42
45
static const AVOption options[] = {
43
{ "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), FF_OPT_TYPE_FLAGS, {.dbl = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
44
{ "rtphint", "Add RTP hint tracks", 0, FF_OPT_TYPE_CONST, {.dbl = FF_MOV_FLAG_RTP_HINT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
46
{ "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), AV_OPT_TYPE_FLAGS, {.dbl = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
47
{ "rtphint", "Add RTP hint tracks", 0, AV_OPT_TYPE_CONST, {.dbl = FF_MOV_FLAG_RTP_HINT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
45
48
FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags),
49
{ "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_INT, {.dbl = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
50
{ "iods_audio_profile", "iods audio profile atom.", offsetof(MOVMuxContext, iods_audio_profile), AV_OPT_TYPE_INT, {.dbl = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
51
{ "iods_video_profile", "iods video profile atom.", offsetof(MOVMuxContext, iods_video_profile), AV_OPT_TYPE_INT, {.dbl = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM},
49
static const AVClass mov_muxer_class = {
50
.class_name = "MOV/3GP/MP4/3G2 muxer",
51
.item_name = av_default_item_name,
53
.version = LIBAVUTIL_VERSION_INT,
55
#define MOV_CLASS(flavor)\
56
static const AVClass flavor ## _muxer_class = {\
57
.class_name = #flavor " muxer",\
58
.item_name = av_default_item_name,\
60
.version = LIBAVUTIL_VERSION_INT,\
56
63
//FIXME support 64 bit variant with wide placeholders
335
342
return updateSize(pb, pos);
345
static int mov_write_chan_tag(AVIOContext *pb, MOVTrack *track)
347
uint32_t layout_tag, bitmap;
348
int64_t pos = avio_tell(pb);
350
layout_tag = ff_mov_get_channel_layout_tag(track->enc->codec_id,
351
track->enc->channel_layout,
354
av_log(track->enc, AV_LOG_WARNING, "not writing 'chan' tag due to "
355
"lack of channel information\n");
359
avio_wb32(pb, 0); // Size
360
ffio_wfourcc(pb, "chan"); // Type
361
avio_w8(pb, 0); // Version
362
avio_wb24(pb, 0); // Flags
363
avio_wb32(pb, layout_tag); // mChannelLayoutTag
364
avio_wb32(pb, bitmap); // mChannelBitmap
365
avio_wb32(pb, 0); // mNumberChannelDescriptions
367
return updateSize(pb, pos);
338
370
static int mov_write_wave_tag(AVIOContext *pb, MOVTrack *track)
340
372
int64_t pos = avio_tell(pb);
444
471
avio_wb16(pb, 0);
445
472
avio_wb32(pb, 0x00010000);
446
473
avio_wb32(pb, 72);
447
avio_wb64(pb, av_dbl2int(track->timescale));
474
avio_wb64(pb, av_double2int(track->timescale));
448
475
avio_wb32(pb, track->enc->channels);
449
476
avio_wb32(pb, 0x7F000000);
450
477
avio_wb32(pb, av_get_bits_per_sample(track->enc->codec_id));
451
478
avio_wb32(pb, mov_get_lpcm_flags(track->enc->codec_id));
452
479
avio_wb32(pb, track->sampleSize);
453
avio_wb32(pb, track->enc->frame_size);
480
avio_wb32(pb, track->audio_vbr ? track->enc->frame_size : 1);
455
if (track->mode == MODE_MOV) {
456
avio_wb16(pb, track->enc->channels);
457
if (track->enc->codec_id == CODEC_ID_PCM_U8 ||
458
track->enc->codec_id == CODEC_ID_PCM_S8)
459
avio_wb16(pb, 8); /* bits per sample */
462
avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */
463
} else { /* reserved for mp4/3gp */
482
/* reserved for mp4/3gp */
469
487
avio_wb16(pb, 0); /* packet size (= 0) */
470
488
avio_wb16(pb, track->timescale); /* Time scale */
471
489
avio_wb16(pb, 0); /* Reserved */
474
if(version == 1) { /* SoundDescription V1 extended info */
475
avio_wb32(pb, track->enc->frame_size); /* Samples per packet */
476
avio_wb32(pb, track->sampleSize / track->enc->channels); /* Bytes per packet */
477
avio_wb32(pb, track->sampleSize); /* Bytes per frame */
478
avio_wb32(pb, 2); /* Bytes per sample */
481
492
if(track->mode == MODE_MOV &&
482
493
(track->enc->codec_id == CODEC_ID_AAC ||
483
494
track->enc->codec_id == CODEC_ID_AC3 ||
1398
1429
return updateSize(pb, pos);
1402
/* TODO: Not sorted out, but not necessary either */
1403
1432
static int mov_write_iods_tag(AVIOContext *pb, MOVMuxContext *mov)
1405
avio_wb32(pb, 0x15); /* size */
1434
int i, has_audio = 0, has_video = 0;
1435
int64_t pos = avio_tell(pb);
1436
int audio_profile = mov->iods_audio_profile;
1437
int video_profile = mov->iods_video_profile;
1438
for (i = 0; i < mov->nb_streams; i++) {
1439
if(mov->tracks[i].entry > 0) {
1440
has_audio |= mov->tracks[i].enc->codec_type == AVMEDIA_TYPE_AUDIO;
1441
has_video |= mov->tracks[i].enc->codec_type == AVMEDIA_TYPE_VIDEO;
1444
if (audio_profile < 0)
1445
audio_profile = 0xFF - has_audio;
1446
if (video_profile < 0)
1447
video_profile = 0xFF - has_video;
1448
avio_wb32(pb, 0x0); /* size */
1406
1449
ffio_wfourcc(pb, "iods");
1407
1450
avio_wb32(pb, 0); /* version & flags */
1408
avio_wb16(pb, 0x1007);
1410
avio_wb16(pb, 0x4fff);
1411
avio_wb16(pb, 0xfffe);
1412
avio_wb16(pb, 0x01ff);
1451
putDescr(pb, 0x10, 7);
1452
avio_wb16(pb, 0x004f);
1455
avio_w8(pb, audio_profile);
1456
avio_w8(pb, video_profile);
1458
return updateSize(pb, pos);
1417
1461
static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov)
2219
2271
"or choose different container.\n");
2220
2272
}else if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO){
2221
2273
track->timescale = st->codec->sample_rate;
2222
if(!st->codec->frame_size && !av_get_bits_per_sample(st->codec->codec_id)) {
2223
av_log(s, AV_LOG_ERROR, "track %d: codec frame size is not set\n", i);
2225
}else if(st->codec->codec_id == CODEC_ID_ADPCM_MS ||
2226
st->codec->codec_id == CODEC_ID_ADPCM_IMA_WAV){
2274
/* set sampleSize for PCM and ADPCM */
2275
if (av_get_bits_per_sample(st->codec->codec_id)) {
2227
2276
if (!st->codec->block_align) {
2228
av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i);
2277
av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set\n", i);
2231
2280
track->sampleSize = st->codec->block_align;
2232
}else if(st->codec->frame_size > 1){ /* assume compressed audio */
2282
/* set audio_vbr for compressed audio */
2283
if (av_get_bits_per_sample(st->codec->codec_id) < 8) {
2284
if (!st->codec->frame_size) {
2285
av_log(s, AV_LOG_ERROR, "track %d: codec frame size is not set\n", i);
2233
2288
track->audio_vbr = 1;
2235
st->codec->frame_size = 1;
2236
track->sampleSize = (av_get_bits_per_sample(st->codec->codec_id) >> 3) * st->codec->channels;
2238
2290
if (track->mode != MODE_MOV) {
2239
2291
if (track->timescale > UINT16_MAX) {
2328
2389
#if CONFIG_MOV_MUXER
2329
2391
AVOutputFormat ff_mov_muxer = {
2331
NULL_IF_CONFIG_SMALL("MOV format"),
2334
sizeof(MOVMuxContext),
2338
ff_mov_write_packet,
2393
.long_name = NULL_IF_CONFIG_SMALL("MOV format"),
2394
.extensions = "mov",
2395
.priv_data_size = sizeof(MOVMuxContext),
2396
.audio_codec = CODEC_ID_AAC,
2397
#if CONFIG_LIBX264_ENCODER
2398
.video_codec = CODEC_ID_H264,
2400
.video_codec = CODEC_ID_MPEG4,
2402
.write_header = mov_write_header,
2403
.write_packet = ff_mov_write_packet,
2404
.write_trailer = mov_write_trailer,
2340
2405
.flags = AVFMT_GLOBALHEADER,
2341
2406
.codec_tag = (const AVCodecTag* const []){codec_movvideo_tags, codec_movaudio_tags, 0},
2342
2407
.priv_class = &mov_muxer_class,
2345
2410
#if CONFIG_TGP_MUXER
2346
2412
AVOutputFormat ff_tgp_muxer = {
2348
NULL_IF_CONFIG_SMALL("3GP format"),
2351
sizeof(MOVMuxContext),
2355
ff_mov_write_packet,
2414
.long_name = NULL_IF_CONFIG_SMALL("3GP format"),
2415
.extensions = "3gp",
2416
.priv_data_size = sizeof(MOVMuxContext),
2417
.audio_codec = CODEC_ID_AMR_NB,
2418
.video_codec = CODEC_ID_H263,
2419
.write_header = mov_write_header,
2420
.write_packet = ff_mov_write_packet,
2421
.write_trailer = mov_write_trailer,
2357
2422
.flags = AVFMT_GLOBALHEADER,
2358
2423
.codec_tag = (const AVCodecTag* const []){codec_3gp_tags, 0},
2359
.priv_class = &mov_muxer_class,
2424
.priv_class = &tgp_muxer_class,
2362
2427
#if CONFIG_MP4_MUXER
2363
2429
AVOutputFormat ff_mp4_muxer = {
2365
NULL_IF_CONFIG_SMALL("MP4 format"),
2368
sizeof(MOVMuxContext),
2372
ff_mov_write_packet,
2431
.long_name = NULL_IF_CONFIG_SMALL("MP4 format"),
2432
.mime_type = "application/mp4",
2433
.extensions = "mp4",
2434
.priv_data_size = sizeof(MOVMuxContext),
2435
.audio_codec = CODEC_ID_AAC,
2436
#if CONFIG_LIBX264_ENCODER
2437
.video_codec = CODEC_ID_H264,
2439
.video_codec = CODEC_ID_MPEG4,
2441
.write_header = mov_write_header,
2442
.write_packet = ff_mov_write_packet,
2443
.write_trailer = mov_write_trailer,
2374
2444
.flags = AVFMT_GLOBALHEADER,
2375
2445
.codec_tag = (const AVCodecTag* const []){ff_mp4_obj_type, 0},
2376
.priv_class = &mov_muxer_class,
2446
.priv_class = &mp4_muxer_class,
2379
2449
#if CONFIG_PSP_MUXER
2380
2451
AVOutputFormat ff_psp_muxer = {
2382
NULL_IF_CONFIG_SMALL("PSP MP4 format"),
2385
sizeof(MOVMuxContext),
2389
ff_mov_write_packet,
2453
.long_name = NULL_IF_CONFIG_SMALL("PSP MP4 format"),
2454
.extensions = "mp4,psp",
2455
.priv_data_size = sizeof(MOVMuxContext),
2456
.audio_codec = CODEC_ID_AAC,
2457
#if CONFIG_LIBX264_ENCODER
2458
.video_codec = CODEC_ID_H264,
2460
.video_codec = CODEC_ID_MPEG4,
2462
.write_header = mov_write_header,
2463
.write_packet = ff_mov_write_packet,
2464
.write_trailer = mov_write_trailer,
2391
2465
.flags = AVFMT_GLOBALHEADER,
2392
2466
.codec_tag = (const AVCodecTag* const []){ff_mp4_obj_type, 0},
2393
.priv_class = &mov_muxer_class,
2467
.priv_class = &psp_muxer_class,
2396
2470
#if CONFIG_TG2_MUXER
2397
2472
AVOutputFormat ff_tg2_muxer = {
2399
NULL_IF_CONFIG_SMALL("3GP2 format"),
2402
sizeof(MOVMuxContext),
2406
ff_mov_write_packet,
2474
.long_name = NULL_IF_CONFIG_SMALL("3GP2 format"),
2475
.extensions = "3g2",
2476
.priv_data_size = sizeof(MOVMuxContext),
2477
.audio_codec = CODEC_ID_AMR_NB,
2478
.video_codec = CODEC_ID_H263,
2479
.write_header = mov_write_header,
2480
.write_packet = ff_mov_write_packet,
2481
.write_trailer = mov_write_trailer,
2408
2482
.flags = AVFMT_GLOBALHEADER,
2409
2483
.codec_tag = (const AVCodecTag* const []){codec_3gp_tags, 0},
2410
.priv_class = &mov_muxer_class,
2484
.priv_class = &tg2_muxer_class,
2413
2487
#if CONFIG_IPOD_MUXER
2414
2489
AVOutputFormat ff_ipod_muxer = {
2416
NULL_IF_CONFIG_SMALL("iPod H.264 MP4 format"),
2419
sizeof(MOVMuxContext),
2423
ff_mov_write_packet,
2491
.long_name = NULL_IF_CONFIG_SMALL("iPod H.264 MP4 format"),
2492
.mime_type = "application/mp4",
2493
.extensions = "m4v,m4a",
2494
.priv_data_size = sizeof(MOVMuxContext),
2495
.audio_codec = CODEC_ID_AAC,
2496
.video_codec = CODEC_ID_H264,
2497
.write_header = mov_write_header,
2498
.write_packet = ff_mov_write_packet,
2499
.write_trailer = mov_write_trailer,
2425
2500
.flags = AVFMT_GLOBALHEADER,
2426
2501
.codec_tag = (const AVCodecTag* const []){codec_ipod_tags, 0},
2427
.priv_class = &mov_muxer_class,
2502
.priv_class = &ipod_muxer_class,