|
|
|
@ -23,6 +23,7 @@ |
|
|
|
|
|
|
|
|
|
#include "movenc.h" |
|
|
|
|
#include "avformat.h" |
|
|
|
|
#include "avio_internal.h" |
|
|
|
|
#include "riff.h" |
|
|
|
|
#include "avio.h" |
|
|
|
|
#include "isom.h" |
|
|
|
@ -55,9 +56,9 @@ static int mov_write_stco_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
avio_wb32(pb, 0); /* size */ |
|
|
|
|
if (pos > UINT32_MAX) { |
|
|
|
|
mode64 = 1; |
|
|
|
|
put_tag(pb, "co64"); |
|
|
|
|
ffio_wfourcc(pb, "co64"); |
|
|
|
|
} else |
|
|
|
|
put_tag(pb, "stco"); |
|
|
|
|
ffio_wfourcc(pb, "stco"); |
|
|
|
|
avio_wb32(pb, 0); /* version & flags */ |
|
|
|
|
avio_wb32(pb, track->entry); /* entry count */ |
|
|
|
|
for (i=0; i<track->entry; i++) { |
|
|
|
@ -77,7 +78,7 @@ static int mov_write_stsz_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
|
|
|
|
|
int64_t pos = url_ftell(pb); |
|
|
|
|
avio_wb32(pb, 0); /* size */ |
|
|
|
|
put_tag(pb, "stsz"); |
|
|
|
|
ffio_wfourcc(pb, "stsz"); |
|
|
|
|
avio_wb32(pb, 0); /* version & flags */ |
|
|
|
|
|
|
|
|
|
for (i=0; i<track->entry; i++) { |
|
|
|
@ -114,7 +115,7 @@ static int mov_write_stsc_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
|
|
|
|
|
int64_t pos = url_ftell(pb); |
|
|
|
|
avio_wb32(pb, 0); /* size */ |
|
|
|
|
put_tag(pb, "stsc"); |
|
|
|
|
ffio_wfourcc(pb, "stsc"); |
|
|
|
|
avio_wb32(pb, 0); // version & flags
|
|
|
|
|
entryPos = url_ftell(pb); |
|
|
|
|
avio_wb32(pb, track->entry); // entry count
|
|
|
|
@ -143,7 +144,7 @@ static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag) |
|
|
|
|
int i, index = 0; |
|
|
|
|
int64_t pos = url_ftell(pb); |
|
|
|
|
avio_wb32(pb, 0); // size
|
|
|
|
|
put_tag(pb, flag == MOV_SYNC_SAMPLE ? "stss" : "stps"); |
|
|
|
|
ffio_wfourcc(pb, flag == MOV_SYNC_SAMPLE ? "stss" : "stps"); |
|
|
|
|
avio_wb32(pb, 0); // version & flags
|
|
|
|
|
entryPos = url_ftell(pb); |
|
|
|
|
avio_wb32(pb, track->entry); // entry count
|
|
|
|
@ -163,9 +164,9 @@ static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag) |
|
|
|
|
static int mov_write_amr_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
{ |
|
|
|
|
avio_wb32(pb, 0x11); /* size */ |
|
|
|
|
if (track->mode == MODE_MOV) put_tag(pb, "samr"); |
|
|
|
|
else put_tag(pb, "damr"); |
|
|
|
|
put_tag(pb, "FFMP"); |
|
|
|
|
if (track->mode == MODE_MOV) ffio_wfourcc(pb, "samr"); |
|
|
|
|
else ffio_wfourcc(pb, "damr"); |
|
|
|
|
ffio_wfourcc(pb, "FFMP"); |
|
|
|
|
avio_w8(pb, 0); /* decoder version */ |
|
|
|
|
|
|
|
|
|
avio_wb16(pb, 0x81FF); /* Mode set (all modes for AMR_NB) */ |
|
|
|
@ -185,7 +186,7 @@ static int mov_write_ac3_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
return -1; |
|
|
|
|
|
|
|
|
|
avio_wb32(pb, 11); |
|
|
|
|
put_tag(pb, "dac3"); |
|
|
|
|
ffio_wfourcc(pb, "dac3"); |
|
|
|
|
|
|
|
|
|
init_get_bits(&gbc, track->vosData+4, track->vosLen-4); |
|
|
|
|
fscod = get_bits(&gbc, 2); |
|
|
|
@ -231,7 +232,7 @@ static int mov_write_extradata_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
static int mov_write_enda_tag(AVIOContext *pb) |
|
|
|
|
{ |
|
|
|
|
avio_wb32(pb, 10); |
|
|
|
|
put_tag(pb, "enda"); |
|
|
|
|
ffio_wfourcc(pb, "enda"); |
|
|
|
|
avio_wb16(pb, 1); /* little endian */ |
|
|
|
|
return 10; |
|
|
|
|
} |
|
|
|
@ -258,7 +259,7 @@ static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic |
|
|
|
|
int decoderSpecificInfoLen = track->vosLen ? descrLength(track->vosLen):0; |
|
|
|
|
|
|
|
|
|
avio_wb32(pb, 0); // size
|
|
|
|
|
put_tag(pb, "esds"); |
|
|
|
|
ffio_wfourcc(pb, "esds"); |
|
|
|
|
avio_wb32(pb, 0); // Version
|
|
|
|
|
|
|
|
|
|
// ES descriptor
|
|
|
|
@ -329,16 +330,16 @@ static int mov_write_wave_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
int64_t pos = url_ftell(pb); |
|
|
|
|
|
|
|
|
|
avio_wb32(pb, 0); /* size */ |
|
|
|
|
put_tag(pb, "wave"); |
|
|
|
|
ffio_wfourcc(pb, "wave"); |
|
|
|
|
|
|
|
|
|
avio_wb32(pb, 12); /* size */ |
|
|
|
|
put_tag(pb, "frma"); |
|
|
|
|
ffio_wfourcc(pb, "frma"); |
|
|
|
|
avio_wl32(pb, track->tag); |
|
|
|
|
|
|
|
|
|
if (track->enc->codec_id == CODEC_ID_AAC) { |
|
|
|
|
/* useless atom needed by mplayer, ipod, not needed by quicktime */ |
|
|
|
|
avio_wb32(pb, 12); /* size */ |
|
|
|
|
put_tag(pb, "mp4a"); |
|
|
|
|
ffio_wfourcc(pb, "mp4a"); |
|
|
|
|
avio_wb32(pb, 0); |
|
|
|
|
mov_write_esds_tag(pb, track); |
|
|
|
|
} else if (mov_pcm_le_gt16(track->enc->codec_id)) { |
|
|
|
@ -363,7 +364,7 @@ static int mov_write_wave_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
static int mov_write_glbl_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
{ |
|
|
|
|
avio_wb32(pb, track->vosLen+8); |
|
|
|
|
put_tag(pb, "glbl"); |
|
|
|
|
ffio_wfourcc(pb, "glbl"); |
|
|
|
|
avio_write(pb, track->vosData, track->vosLen); |
|
|
|
|
return 8+track->vosLen; |
|
|
|
|
} |
|
|
|
@ -493,8 +494,8 @@ static int mov_write_audio_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
static int mov_write_d263_tag(AVIOContext *pb) |
|
|
|
|
{ |
|
|
|
|
avio_wb32(pb, 0xf); /* size */ |
|
|
|
|
put_tag(pb, "d263"); |
|
|
|
|
put_tag(pb, "FFMP"); |
|
|
|
|
ffio_wfourcc(pb, "d263"); |
|
|
|
|
ffio_wfourcc(pb, "FFMP"); |
|
|
|
|
avio_w8(pb, 0); /* decoder version */ |
|
|
|
|
/* FIXME use AVCodecContext level/profile, when encoder will set values */ |
|
|
|
|
avio_w8(pb, 0xa); /* level */ |
|
|
|
@ -506,8 +507,8 @@ static int mov_write_d263_tag(AVIOContext *pb) |
|
|
|
|
static int mov_write_svq3_tag(AVIOContext *pb) |
|
|
|
|
{ |
|
|
|
|
avio_wb32(pb, 0x15); |
|
|
|
|
put_tag(pb, "SMI "); |
|
|
|
|
put_tag(pb, "SEQH"); |
|
|
|
|
ffio_wfourcc(pb, "SMI "); |
|
|
|
|
ffio_wfourcc(pb, "SEQH"); |
|
|
|
|
avio_wb32(pb, 0x5); |
|
|
|
|
avio_wb32(pb, 0xe2c0211d); |
|
|
|
|
avio_wb32(pb, 0xc0000000); |
|
|
|
@ -520,7 +521,7 @@ static int mov_write_avcc_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
int64_t pos = url_ftell(pb); |
|
|
|
|
|
|
|
|
|
avio_wb32(pb, 0); |
|
|
|
|
put_tag(pb, "avcC"); |
|
|
|
|
ffio_wfourcc(pb, "avcC"); |
|
|
|
|
ff_isom_write_avcc(pb, track->vosData, track->vosLen); |
|
|
|
|
return updateSize(pb, pos); |
|
|
|
|
} |
|
|
|
@ -530,23 +531,23 @@ static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
{ |
|
|
|
|
int i; |
|
|
|
|
avio_wb32(pb, 24); /* size */ |
|
|
|
|
put_tag(pb, "ACLR"); |
|
|
|
|
put_tag(pb, "ACLR"); |
|
|
|
|
put_tag(pb, "0001"); |
|
|
|
|
ffio_wfourcc(pb, "ACLR"); |
|
|
|
|
ffio_wfourcc(pb, "ACLR"); |
|
|
|
|
ffio_wfourcc(pb, "0001"); |
|
|
|
|
avio_wb32(pb, 1); /* yuv 1 / rgb 2 ? */ |
|
|
|
|
avio_wb32(pb, 0); /* unknown */ |
|
|
|
|
|
|
|
|
|
avio_wb32(pb, 24); /* size */ |
|
|
|
|
put_tag(pb, "APRG"); |
|
|
|
|
put_tag(pb, "APRG"); |
|
|
|
|
put_tag(pb, "0001"); |
|
|
|
|
ffio_wfourcc(pb, "APRG"); |
|
|
|
|
ffio_wfourcc(pb, "APRG"); |
|
|
|
|
ffio_wfourcc(pb, "0001"); |
|
|
|
|
avio_wb32(pb, 1); /* unknown */ |
|
|
|
|
avio_wb32(pb, 0); /* unknown */ |
|
|
|
|
|
|
|
|
|
avio_wb32(pb, 120); /* size */ |
|
|
|
|
put_tag(pb, "ARES"); |
|
|
|
|
put_tag(pb, "ARES"); |
|
|
|
|
put_tag(pb, "0001"); |
|
|
|
|
ffio_wfourcc(pb, "ARES"); |
|
|
|
|
ffio_wfourcc(pb, "ARES"); |
|
|
|
|
ffio_wfourcc(pb, "0001"); |
|
|
|
|
avio_wb32(pb, AV_RB32(track->vosData + 0x28)); /* dnxhd cid, some id ? */ |
|
|
|
|
avio_wb32(pb, track->enc->width); |
|
|
|
|
/* values below are based on samples created with quicktime and avid codecs */ |
|
|
|
@ -741,7 +742,7 @@ static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track) |
|
|
|
|
static int mov_write_uuid_tag_ipod(AVIOContext *pb) |
|
|
|
|
{ |
|
|
|
|
avio_wb32(pb, 28); |
|
|
|
|
put_tag(pb, "uuid"); |
|
|
|
|
ffio_wfourcc(pb, "uuid"); |
|
|
|
|
avio_wb32(pb, 0x6b6840f2); |
|
|
|
|
avio_wb32(pb, 0x5f244fc5); |
|
|
|
|
avio_wb32(pb, 0xba39a51b); |
|
|
|
@ -772,7 +773,7 @@ static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
track->enc->sample_aspect_ratio.den, INT_MAX); |
|
|
|
|
|
|
|
|
|
avio_wb32(pb, 16); |
|
|
|
|
put_tag(pb, "pasp"); |
|
|
|
|
ffio_wfourcc(pb, "pasp"); |
|
|
|
|
avio_wb32(pb, sar.num); |
|
|
|
|
avio_wb32(pb, sar.den); |
|
|
|
|
return 16; |
|
|
|
@ -792,7 +793,7 @@ static int mov_write_video_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
avio_wb16(pb, 0); /* Codec stream version */ |
|
|
|
|
avio_wb16(pb, 0); /* Codec stream revision (=0) */ |
|
|
|
|
if (track->mode == MODE_MOV) { |
|
|
|
|
put_tag(pb, "FFMP"); /* Vendor */ |
|
|
|
|
ffio_wfourcc(pb, "FFMP"); /* Vendor */ |
|
|
|
|
if(track->enc->codec_id == CODEC_ID_RAWVIDEO) { |
|
|
|
|
avio_wb32(pb, 0); /* Temporal Quality */ |
|
|
|
|
avio_wb32(pb, 0x400); /* Spatial Quality = lossless*/ |
|
|
|
@ -852,7 +853,7 @@ static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
{ |
|
|
|
|
int64_t pos = url_ftell(pb); |
|
|
|
|
avio_wb32(pb, 0); /* size */ |
|
|
|
|
put_tag(pb, "rtp "); |
|
|
|
|
ffio_wfourcc(pb, "rtp "); |
|
|
|
|
avio_wb32(pb, 0); /* Reserved */ |
|
|
|
|
avio_wb16(pb, 0); /* Reserved */ |
|
|
|
|
avio_wb16(pb, 1); /* Data-reference index */ |
|
|
|
@ -862,7 +863,7 @@ static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
avio_wb32(pb, track->max_packet_size); /* Max packet size */ |
|
|
|
|
|
|
|
|
|
avio_wb32(pb, 12); /* size */ |
|
|
|
|
put_tag(pb, "tims"); |
|
|
|
|
ffio_wfourcc(pb, "tims"); |
|
|
|
|
avio_wb32(pb, track->timescale); |
|
|
|
|
|
|
|
|
|
return updateSize(pb, pos); |
|
|
|
@ -872,7 +873,7 @@ static int mov_write_stsd_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
{ |
|
|
|
|
int64_t pos = url_ftell(pb); |
|
|
|
|
avio_wb32(pb, 0); /* size */ |
|
|
|
|
put_tag(pb, "stsd"); |
|
|
|
|
ffio_wfourcc(pb, "stsd"); |
|
|
|
|
avio_wb32(pb, 0); /* version & flags */ |
|
|
|
|
avio_wb32(pb, 1); /* entry count */ |
|
|
|
|
if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) |
|
|
|
@ -908,7 +909,7 @@ static int mov_write_ctts_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
entries++; /* last one */ |
|
|
|
|
atom_size = 16 + (entries * 8); |
|
|
|
|
avio_wb32(pb, atom_size); /* size */ |
|
|
|
|
put_tag(pb, "ctts"); |
|
|
|
|
ffio_wfourcc(pb, "ctts"); |
|
|
|
|
avio_wb32(pb, 0); /* version & flags */ |
|
|
|
|
avio_wb32(pb, entries); /* entry count */ |
|
|
|
|
for (i=0; i<entries; i++) { |
|
|
|
@ -950,7 +951,7 @@ static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
} |
|
|
|
|
atom_size = 16 + (entries * 8); |
|
|
|
|
avio_wb32(pb, atom_size); /* size */ |
|
|
|
|
put_tag(pb, "stts"); |
|
|
|
|
ffio_wfourcc(pb, "stts"); |
|
|
|
|
avio_wb32(pb, 0); /* version & flags */ |
|
|
|
|
avio_wb32(pb, entries); /* entry count */ |
|
|
|
|
for (i=0; i<entries; i++) { |
|
|
|
@ -964,12 +965,12 @@ static int mov_write_stts_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
static int mov_write_dref_tag(AVIOContext *pb) |
|
|
|
|
{ |
|
|
|
|
avio_wb32(pb, 28); /* size */ |
|
|
|
|
put_tag(pb, "dref"); |
|
|
|
|
ffio_wfourcc(pb, "dref"); |
|
|
|
|
avio_wb32(pb, 0); /* version & flags */ |
|
|
|
|
avio_wb32(pb, 1); /* entry count */ |
|
|
|
|
|
|
|
|
|
avio_wb32(pb, 0xc); /* size */ |
|
|
|
|
put_tag(pb, "url "); |
|
|
|
|
ffio_wfourcc(pb, "url "); |
|
|
|
|
avio_wb32(pb, 1); /* version & flags */ |
|
|
|
|
|
|
|
|
|
return 28; |
|
|
|
@ -979,7 +980,7 @@ static int mov_write_stbl_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
{ |
|
|
|
|
int64_t pos = url_ftell(pb); |
|
|
|
|
avio_wb32(pb, 0); /* size */ |
|
|
|
|
put_tag(pb, "stbl"); |
|
|
|
|
ffio_wfourcc(pb, "stbl"); |
|
|
|
|
mov_write_stsd_tag(pb, track); |
|
|
|
|
mov_write_stts_tag(pb, track); |
|
|
|
|
if ((track->enc->codec_type == AVMEDIA_TYPE_VIDEO || |
|
|
|
@ -1001,7 +1002,7 @@ static int mov_write_dinf_tag(AVIOContext *pb) |
|
|
|
|
{ |
|
|
|
|
int64_t pos = url_ftell(pb); |
|
|
|
|
avio_wb32(pb, 0); /* size */ |
|
|
|
|
put_tag(pb, "dinf"); |
|
|
|
|
ffio_wfourcc(pb, "dinf"); |
|
|
|
|
mov_write_dref_tag(pb); |
|
|
|
|
return updateSize(pb, pos); |
|
|
|
|
} |
|
|
|
@ -1009,7 +1010,7 @@ static int mov_write_dinf_tag(AVIOContext *pb) |
|
|
|
|
static int mov_write_nmhd_tag(AVIOContext *pb) |
|
|
|
|
{ |
|
|
|
|
avio_wb32(pb, 12); |
|
|
|
|
put_tag(pb, "nmhd"); |
|
|
|
|
ffio_wfourcc(pb, "nmhd"); |
|
|
|
|
avio_wb32(pb, 0); |
|
|
|
|
return 12; |
|
|
|
|
} |
|
|
|
@ -1017,9 +1018,9 @@ static int mov_write_nmhd_tag(AVIOContext *pb) |
|
|
|
|
static int mov_write_gmhd_tag(AVIOContext *pb) |
|
|
|
|
{ |
|
|
|
|
avio_wb32(pb, 0x20); /* size */ |
|
|
|
|
put_tag(pb, "gmhd"); |
|
|
|
|
ffio_wfourcc(pb, "gmhd"); |
|
|
|
|
avio_wb32(pb, 0x18); /* gmin size */ |
|
|
|
|
put_tag(pb, "gmin"); /* generic media info */ |
|
|
|
|
ffio_wfourcc(pb, "gmin");/* generic media info */ |
|
|
|
|
avio_wb32(pb, 0); /* version & flags */ |
|
|
|
|
avio_wb16(pb, 0x40); /* graphics mode = */ |
|
|
|
|
avio_wb16(pb, 0x8000); /* opColor (r?) */ |
|
|
|
@ -1033,7 +1034,7 @@ static int mov_write_gmhd_tag(AVIOContext *pb) |
|
|
|
|
static int mov_write_smhd_tag(AVIOContext *pb) |
|
|
|
|
{ |
|
|
|
|
avio_wb32(pb, 16); /* size */ |
|
|
|
|
put_tag(pb, "smhd"); |
|
|
|
|
ffio_wfourcc(pb, "smhd"); |
|
|
|
|
avio_wb32(pb, 0); /* version & flags */ |
|
|
|
|
avio_wb16(pb, 0); /* reserved (balance, normally = 0) */ |
|
|
|
|
avio_wb16(pb, 0); /* reserved */ |
|
|
|
@ -1043,7 +1044,7 @@ static int mov_write_smhd_tag(AVIOContext *pb) |
|
|
|
|
static int mov_write_vmhd_tag(AVIOContext *pb) |
|
|
|
|
{ |
|
|
|
|
avio_wb32(pb, 0x14); /* size (always 0x14) */ |
|
|
|
|
put_tag(pb, "vmhd"); |
|
|
|
|
ffio_wfourcc(pb, "vmhd"); |
|
|
|
|
avio_wb32(pb, 0x01); /* version & flags */ |
|
|
|
|
avio_wb64(pb, 0); /* reserved (graphics mode = copy) */ |
|
|
|
|
return 0x14; |
|
|
|
@ -1077,10 +1078,10 @@ static int mov_write_hdlr_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
avio_wb32(pb, 0); /* size */ |
|
|
|
|
put_tag(pb, "hdlr"); |
|
|
|
|
ffio_wfourcc(pb, "hdlr"); |
|
|
|
|
avio_wb32(pb, 0); /* Version & flags */ |
|
|
|
|
avio_write(pb, hdlr, 4); /* handler */ |
|
|
|
|
put_tag(pb, hdlr_type); /* handler type */ |
|
|
|
|
ffio_wfourcc(pb, hdlr_type); /* handler type */ |
|
|
|
|
avio_wb32(pb ,0); /* reserved */ |
|
|
|
|
avio_wb32(pb ,0); /* reserved */ |
|
|
|
|
avio_wb32(pb ,0); /* reserved */ |
|
|
|
@ -1097,7 +1098,7 @@ static int mov_write_hmhd_tag(AVIOContext *pb) |
|
|
|
|
/* This atom must be present, but leaving the values at zero
|
|
|
|
|
* seems harmless. */ |
|
|
|
|
avio_wb32(pb, 28); /* size */ |
|
|
|
|
put_tag(pb, "hmhd"); |
|
|
|
|
ffio_wfourcc(pb, "hmhd"); |
|
|
|
|
avio_wb32(pb, 0); /* version, flags */ |
|
|
|
|
avio_wb16(pb, 0); /* maxPDUsize */ |
|
|
|
|
avio_wb16(pb, 0); /* avgPDUsize */ |
|
|
|
@ -1111,7 +1112,7 @@ static int mov_write_minf_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
{ |
|
|
|
|
int64_t pos = url_ftell(pb); |
|
|
|
|
avio_wb32(pb, 0); /* size */ |
|
|
|
|
put_tag(pb, "minf"); |
|
|
|
|
ffio_wfourcc(pb, "minf"); |
|
|
|
|
if(track->enc->codec_type == AVMEDIA_TYPE_VIDEO) |
|
|
|
|
mov_write_vmhd_tag(pb); |
|
|
|
|
else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) |
|
|
|
@ -1134,7 +1135,7 @@ static int mov_write_mdhd_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
int version = track->trackDuration < INT32_MAX ? 0 : 1; |
|
|
|
|
|
|
|
|
|
(version == 1) ? avio_wb32(pb, 44) : avio_wb32(pb, 32); /* size */ |
|
|
|
|
put_tag(pb, "mdhd"); |
|
|
|
|
ffio_wfourcc(pb, "mdhd"); |
|
|
|
|
avio_w8(pb, version); |
|
|
|
|
avio_wb24(pb, 0); /* flags */ |
|
|
|
|
if (version == 1) { |
|
|
|
@ -1163,7 +1164,7 @@ static int mov_write_mdia_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
{ |
|
|
|
|
int64_t pos = url_ftell(pb); |
|
|
|
|
avio_wb32(pb, 0); /* size */ |
|
|
|
|
put_tag(pb, "mdia"); |
|
|
|
|
ffio_wfourcc(pb, "mdia"); |
|
|
|
|
mov_write_mdhd_tag(pb, track); |
|
|
|
|
mov_write_hdlr_tag(pb, track); |
|
|
|
|
mov_write_minf_tag(pb, track); |
|
|
|
@ -1177,7 +1178,7 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st) |
|
|
|
|
int version = duration < INT32_MAX ? 0 : 1; |
|
|
|
|
|
|
|
|
|
(version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */ |
|
|
|
|
put_tag(pb, "tkhd"); |
|
|
|
|
ffio_wfourcc(pb, "tkhd"); |
|
|
|
|
avio_w8(pb, version); |
|
|
|
|
avio_wb24(pb, 0xf); /* flags (track enabled) */ |
|
|
|
|
if (version == 1) { |
|
|
|
@ -1232,9 +1233,9 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st) |
|
|
|
|
static int mov_write_edts_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
{ |
|
|
|
|
avio_wb32(pb, 0x24); /* size */ |
|
|
|
|
put_tag(pb, "edts"); |
|
|
|
|
ffio_wfourcc(pb, "edts"); |
|
|
|
|
avio_wb32(pb, 0x1c); /* size */ |
|
|
|
|
put_tag(pb, "elst"); |
|
|
|
|
ffio_wfourcc(pb, "elst"); |
|
|
|
|
avio_wb32(pb, 0x0); |
|
|
|
|
avio_wb32(pb, 0x1); |
|
|
|
|
|
|
|
|
@ -1250,7 +1251,7 @@ static int mov_write_edts_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
{ |
|
|
|
|
avio_wb32(pb, 20); // size
|
|
|
|
|
put_tag(pb, "tref"); |
|
|
|
|
ffio_wfourcc(pb, "tref"); |
|
|
|
|
avio_wb32(pb, 12); // size (subatom)
|
|
|
|
|
avio_wl32(pb, track->tref_tag); |
|
|
|
|
avio_wb32(pb, track->tref_id); |
|
|
|
@ -1261,13 +1262,13 @@ static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track) |
|
|
|
|
static int mov_write_uuid_tag_psp(AVIOContext *pb, MOVTrack *mov) |
|
|
|
|
{ |
|
|
|
|
avio_wb32(pb, 0x34); /* size ... reports as 28 in mp4box! */ |
|
|
|
|
put_tag(pb, "uuid"); |
|
|
|
|
put_tag(pb, "USMT"); |
|
|
|
|
ffio_wfourcc(pb, "uuid"); |
|
|
|
|
ffio_wfourcc(pb, "USMT"); |
|
|
|
|
avio_wb32(pb, 0x21d24fce); |
|
|
|
|
avio_wb32(pb, 0xbb88695c); |
|
|
|
|
avio_wb32(pb, 0xfac9c740); |
|
|
|
|
avio_wb32(pb, 0x1c); // another size here!
|
|
|
|
|
put_tag(pb, "MTDT"); |
|
|
|
|
ffio_wfourcc(pb, "MTDT"); |
|
|
|
|
avio_wb32(pb, 0x00010012); |
|
|
|
|
avio_wb32(pb, 0x0a); |
|
|
|
|
avio_wb32(pb, 0x55c40000); |
|
|
|
@ -1286,11 +1287,11 @@ static int mov_write_udta_sdp(AVIOContext *pb, AVCodecContext *ctx, int index) |
|
|
|
|
len = strlen(buf); |
|
|
|
|
|
|
|
|
|
avio_wb32(pb, len + 24); |
|
|
|
|
put_tag (pb, "udta"); |
|
|
|
|
ffio_wfourcc(pb, "udta"); |
|
|
|
|
avio_wb32(pb, len + 16); |
|
|
|
|
put_tag (pb, "hnti"); |
|
|
|
|
ffio_wfourcc(pb, "hnti"); |
|
|
|
|
avio_wb32(pb, len + 8); |
|
|
|
|
put_tag (pb, "sdp "); |
|
|
|
|
ffio_wfourcc(pb, "sdp "); |
|
|
|
|
avio_write(pb, buf, len); |
|
|
|
|
return len + 24; |
|
|
|
|
} |
|
|
|
@ -1299,7 +1300,7 @@ static int mov_write_trak_tag(AVIOContext *pb, MOVTrack *track, AVStream *st) |
|
|
|
|
{ |
|
|
|
|
int64_t pos = url_ftell(pb); |
|
|
|
|
avio_wb32(pb, 0); /* size */ |
|
|
|
|
put_tag(pb, "trak"); |
|
|
|
|
ffio_wfourcc(pb, "trak"); |
|
|
|
|
mov_write_tkhd_tag(pb, track, st); |
|
|
|
|
if (track->mode == MODE_PSP || track->flags & MOV_TRACK_CTTS) |
|
|
|
|
mov_write_edts_tag(pb, track); // PSP Movies require edts box
|
|
|
|
@ -1318,7 +1319,7 @@ static int mov_write_trak_tag(AVIOContext *pb, MOVTrack *track, AVStream *st) |
|
|
|
|
static int mov_write_iods_tag(AVIOContext *pb, MOVMuxContext *mov) |
|
|
|
|
{ |
|
|
|
|
avio_wb32(pb, 0x15); /* size */ |
|
|
|
|
put_tag(pb, "iods"); |
|
|
|
|
ffio_wfourcc(pb, "iods"); |
|
|
|
|
avio_wb32(pb, 0); /* version & flags */ |
|
|
|
|
avio_wb16(pb, 0x1007); |
|
|
|
|
avio_w8(pb, 0); |
|
|
|
@ -1350,7 +1351,7 @@ static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov) |
|
|
|
|
|
|
|
|
|
version = maxTrackLen < UINT32_MAX ? 0 : 1; |
|
|
|
|
(version == 1) ? avio_wb32(pb, 120) : avio_wb32(pb, 108); /* size */ |
|
|
|
|
put_tag(pb, "mvhd"); |
|
|
|
|
ffio_wfourcc(pb, "mvhd"); |
|
|
|
|
avio_w8(pb, version); |
|
|
|
|
avio_wb24(pb, 0); /* flags */ |
|
|
|
|
if (version == 1) { |
|
|
|
@ -1394,11 +1395,11 @@ static int mov_write_itunes_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov, |
|
|
|
|
AVFormatContext *s) |
|
|
|
|
{ |
|
|
|
|
avio_wb32(pb, 33); /* size */ |
|
|
|
|
put_tag(pb, "hdlr"); |
|
|
|
|
ffio_wfourcc(pb, "hdlr"); |
|
|
|
|
avio_wb32(pb, 0); |
|
|
|
|
avio_wb32(pb, 0); |
|
|
|
|
put_tag(pb, "mdir"); |
|
|
|
|
put_tag(pb, "appl"); |
|
|
|
|
ffio_wfourcc(pb, "mdir"); |
|
|
|
|
ffio_wfourcc(pb, "appl"); |
|
|
|
|
avio_wb32(pb, 0); |
|
|
|
|
avio_wb32(pb, 0); |
|
|
|
|
avio_w8(pb, 0); |
|
|
|
@ -1411,7 +1412,7 @@ static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang |
|
|
|
|
if(long_style){ |
|
|
|
|
int size = 16 + strlen(data); |
|
|
|
|
avio_wb32(pb, size); /* size */ |
|
|
|
|
put_tag(pb, "data"); |
|
|
|
|
ffio_wfourcc(pb, "data"); |
|
|
|
|
avio_wb32(pb, 1); |
|
|
|
|
avio_wb32(pb, 0); |
|
|
|
|
avio_write(pb, data, strlen(data)); |
|
|
|
@ -1431,7 +1432,7 @@ static int mov_write_string_tag(AVIOContext *pb, const char *name, const char *v |
|
|
|
|
if (value && value[0]) { |
|
|
|
|
int64_t pos = url_ftell(pb); |
|
|
|
|
avio_wb32(pb, 0); /* size */ |
|
|
|
|
put_tag(pb, name); |
|
|
|
|
ffio_wfourcc(pb, name); |
|
|
|
|
mov_write_string_data_tag(pb, value, lang, long_style); |
|
|
|
|
size= updateSize(pb, pos); |
|
|
|
|
} |
|
|
|
@ -1470,9 +1471,9 @@ static int mov_write_trkn_tag(AVIOContext *pb, MOVMuxContext *mov, |
|
|
|
|
int size = 0, track = t ? atoi(t->value) : 0; |
|
|
|
|
if (track) { |
|
|
|
|
avio_wb32(pb, 32); /* size */ |
|
|
|
|
put_tag(pb, "trkn"); |
|
|
|
|
ffio_wfourcc(pb, "trkn"); |
|
|
|
|
avio_wb32(pb, 24); /* size */ |
|
|
|
|
put_tag(pb, "data"); |
|
|
|
|
ffio_wfourcc(pb, "data"); |
|
|
|
|
avio_wb32(pb, 0); // 8 bytes empty
|
|
|
|
|
avio_wb32(pb, 0); |
|
|
|
|
avio_wb16(pb, 0); // empty
|
|
|
|
@ -1490,7 +1491,7 @@ static int mov_write_ilst_tag(AVIOContext *pb, MOVMuxContext *mov, |
|
|
|
|
{ |
|
|
|
|
int64_t pos = url_ftell(pb); |
|
|
|
|
avio_wb32(pb, 0); /* size */ |
|
|
|
|
put_tag(pb, "ilst"); |
|
|
|
|
ffio_wfourcc(pb, "ilst"); |
|
|
|
|
mov_write_string_metadata(s, pb, "\251nam", "title" , 1); |
|
|
|
|
mov_write_string_metadata(s, pb, "\251ART", "artist" , 1); |
|
|
|
|
mov_write_string_metadata(s, pb, "aART", "album_artist", 1); |
|
|
|
@ -1519,7 +1520,7 @@ static int mov_write_meta_tag(AVIOContext *pb, MOVMuxContext *mov, |
|
|
|
|
int size = 0; |
|
|
|
|
int64_t pos = url_ftell(pb); |
|
|
|
|
avio_wb32(pb, 0); /* size */ |
|
|
|
|
put_tag(pb, "meta"); |
|
|
|
|
ffio_wfourcc(pb, "meta"); |
|
|
|
|
avio_wb32(pb, 0); |
|
|
|
|
mov_write_itunes_hdlr_tag(pb, mov, s); |
|
|
|
|
mov_write_ilst_tag(pb, mov, s); |
|
|
|
@ -1562,7 +1563,7 @@ static int mov_write_3gp_udta_tag(AVIOContext *pb, AVFormatContext *s, |
|
|
|
|
if (!t || !utf8len(t->value)) |
|
|
|
|
return 0; |
|
|
|
|
avio_wb32(pb, 0); /* size */ |
|
|
|
|
put_tag (pb, tag); /* type */ |
|
|
|
|
ffio_wfourcc(pb, tag); /* type */ |
|
|
|
|
avio_wb32(pb, 0); /* version + flags */ |
|
|
|
|
if (!strcmp(tag, "yrrc")) |
|
|
|
|
avio_wb16(pb, atoi(t->value)); |
|
|
|
@ -1582,7 +1583,7 @@ static int mov_write_chpl_tag(AVIOContext *pb, AVFormatContext *s) |
|
|
|
|
int i, nb_chapters = FFMIN(s->nb_chapters, 255); |
|
|
|
|
|
|
|
|
|
avio_wb32(pb, 0); // size
|
|
|
|
|
put_tag (pb, "chpl"); |
|
|
|
|
ffio_wfourcc(pb, "chpl"); |
|
|
|
|
avio_wb32(pb, 0x01000000); // version + flags
|
|
|
|
|
avio_wb32(pb, 0); // unknown
|
|
|
|
|
avio_w8(pb, nb_chapters); |
|
|
|
@ -1647,7 +1648,7 @@ static int mov_write_udta_tag(AVIOContext *pb, MOVMuxContext *mov, |
|
|
|
|
|
|
|
|
|
if ((size = url_close_dyn_buf(pb_buf, &buf)) > 0) { |
|
|
|
|
avio_wb32(pb, size+8); |
|
|
|
|
put_tag(pb, "udta"); |
|
|
|
|
ffio_wfourcc(pb, "udta"); |
|
|
|
|
avio_write(pb, buf, size); |
|
|
|
|
} |
|
|
|
|
av_free(buf); |
|
|
|
@ -1676,15 +1677,15 @@ static int mov_write_uuidusmt_tag(AVIOContext *pb, AVFormatContext *s) |
|
|
|
|
if (title) { |
|
|
|
|
pos = url_ftell(pb); |
|
|
|
|
avio_wb32(pb, 0); /* size placeholder*/ |
|
|
|
|
put_tag(pb, "uuid"); |
|
|
|
|
put_tag(pb, "USMT"); |
|
|
|
|
ffio_wfourcc(pb, "uuid"); |
|
|
|
|
ffio_wfourcc(pb, "USMT"); |
|
|
|
|
avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */ |
|
|
|
|
avio_wb32(pb, 0xbb88695c); |
|
|
|
|
avio_wb32(pb, 0xfac9c740); |
|
|
|
|
|
|
|
|
|
pos2 = url_ftell(pb); |
|
|
|
|
avio_wb32(pb, 0); /* size placeholder*/ |
|
|
|
|
put_tag(pb, "MTDT"); |
|
|
|
|
ffio_wfourcc(pb, "MTDT"); |
|
|
|
|
avio_wb16(pb, 4); |
|
|
|
|
|
|
|
|
|
// ?
|
|
|
|
@ -1712,7 +1713,7 @@ static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov, |
|
|
|
|
int i; |
|
|
|
|
int64_t pos = url_ftell(pb); |
|
|
|
|
avio_wb32(pb, 0); /* size placeholder*/ |
|
|
|
|
put_tag(pb, "moov"); |
|
|
|
|
ffio_wfourcc(pb, "moov"); |
|
|
|
|
|
|
|
|
|
for (i=0; i<mov->nb_streams; i++) { |
|
|
|
|
if(mov->tracks[i].entry <= 0) continue; |
|
|
|
@ -1753,11 +1754,11 @@ static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov, |
|
|
|
|
static int mov_write_mdat_tag(AVIOContext *pb, MOVMuxContext *mov) |
|
|
|
|
{ |
|
|
|
|
avio_wb32(pb, 8); // placeholder for extended size field (64 bit)
|
|
|
|
|
put_tag(pb, mov->mode == MODE_MOV ? "wide" : "free"); |
|
|
|
|
ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free"); |
|
|
|
|
|
|
|
|
|
mov->mdat_pos = url_ftell(pb); |
|
|
|
|
avio_wb32(pb, 0); /* size placeholder*/ |
|
|
|
|
put_tag(pb, "mdat"); |
|
|
|
|
ffio_wfourcc(pb, "mdat"); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1779,42 +1780,42 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
avio_wb32(pb, 0); /* size */ |
|
|
|
|
put_tag(pb, "ftyp"); |
|
|
|
|
ffio_wfourcc(pb, "ftyp"); |
|
|
|
|
|
|
|
|
|
if (mov->mode == MODE_3GP) { |
|
|
|
|
put_tag(pb, has_h264 ? "3gp6" : "3gp4"); |
|
|
|
|
ffio_wfourcc(pb, has_h264 ? "3gp6" : "3gp4"); |
|
|
|
|
minor = has_h264 ? 0x100 : 0x200; |
|
|
|
|
} else if (mov->mode & MODE_3G2) { |
|
|
|
|
put_tag(pb, has_h264 ? "3g2b" : "3g2a"); |
|
|
|
|
ffio_wfourcc(pb, has_h264 ? "3g2b" : "3g2a"); |
|
|
|
|
minor = has_h264 ? 0x20000 : 0x10000; |
|
|
|
|
}else if (mov->mode == MODE_PSP) |
|
|
|
|
put_tag(pb, "MSNV"); |
|
|
|
|
ffio_wfourcc(pb, "MSNV"); |
|
|
|
|
else if (mov->mode == MODE_MP4) |
|
|
|
|
put_tag(pb, "isom"); |
|
|
|
|
ffio_wfourcc(pb, "isom"); |
|
|
|
|
else if (mov->mode == MODE_IPOD) |
|
|
|
|
put_tag(pb, has_video ? "M4V ":"M4A "); |
|
|
|
|
ffio_wfourcc(pb, has_video ? "M4V ":"M4A "); |
|
|
|
|
else |
|
|
|
|
put_tag(pb, "qt "); |
|
|
|
|
ffio_wfourcc(pb, "qt "); |
|
|
|
|
|
|
|
|
|
avio_wb32(pb, minor); |
|
|
|
|
|
|
|
|
|
if(mov->mode == MODE_MOV) |
|
|
|
|
put_tag(pb, "qt "); |
|
|
|
|
ffio_wfourcc(pb, "qt "); |
|
|
|
|
else{ |
|
|
|
|
put_tag(pb, "isom"); |
|
|
|
|
put_tag(pb, "iso2"); |
|
|
|
|
ffio_wfourcc(pb, "isom"); |
|
|
|
|
ffio_wfourcc(pb, "iso2"); |
|
|
|
|
if(has_h264) |
|
|
|
|
put_tag(pb, "avc1"); |
|
|
|
|
ffio_wfourcc(pb, "avc1"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (mov->mode == MODE_3GP) |
|
|
|
|
put_tag(pb, has_h264 ? "3gp6":"3gp4"); |
|
|
|
|
ffio_wfourcc(pb, has_h264 ? "3gp6":"3gp4"); |
|
|
|
|
else if (mov->mode & MODE_3G2) |
|
|
|
|
put_tag(pb, has_h264 ? "3g2b":"3g2a"); |
|
|
|
|
ffio_wfourcc(pb, has_h264 ? "3g2b":"3g2a"); |
|
|
|
|
else if (mov->mode == MODE_PSP) |
|
|
|
|
put_tag(pb, "MSNV"); |
|
|
|
|
ffio_wfourcc(pb, "MSNV"); |
|
|
|
|
else if (mov->mode == MODE_MP4) |
|
|
|
|
put_tag(pb, "mp41"); |
|
|
|
|
ffio_wfourcc(pb, "mp41"); |
|
|
|
|
return updateSize(pb, pos); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1828,8 +1829,8 @@ static void mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s) |
|
|
|
|
int video_kbitrate= FFMIN(VideoCodec->bit_rate / 1000, 800 - audio_kbitrate); |
|
|
|
|
|
|
|
|
|
avio_wb32(pb, 0x94); /* size */ |
|
|
|
|
put_tag(pb, "uuid"); |
|
|
|
|
put_tag(pb, "PROF"); |
|
|
|
|
ffio_wfourcc(pb, "uuid"); |
|
|
|
|
ffio_wfourcc(pb, "PROF"); |
|
|
|
|
|
|
|
|
|
avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */ |
|
|
|
|
avio_wb32(pb, 0xbb88695c); |
|
|
|
@ -1839,16 +1840,16 @@ static void mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s) |
|
|
|
|
avio_wb32(pb, 0x3); /* 3 sections ? */ |
|
|
|
|
|
|
|
|
|
avio_wb32(pb, 0x14); /* size */ |
|
|
|
|
put_tag(pb, "FPRF"); |
|
|
|
|
ffio_wfourcc(pb, "FPRF"); |
|
|
|
|
avio_wb32(pb, 0x0); /* ? */ |
|
|
|
|
avio_wb32(pb, 0x0); /* ? */ |
|
|
|
|
avio_wb32(pb, 0x0); /* ? */ |
|
|
|
|
|
|
|
|
|
avio_wb32(pb, 0x2c); /* size */ |
|
|
|
|
put_tag(pb, "APRF"); /* audio */ |
|
|
|
|
ffio_wfourcc(pb, "APRF");/* audio */ |
|
|
|
|
avio_wb32(pb, 0x0); |
|
|
|
|
avio_wb32(pb, 0x2); /* TrackID */ |
|
|
|
|
put_tag(pb, "mp4a"); |
|
|
|
|
ffio_wfourcc(pb, "mp4a"); |
|
|
|
|
avio_wb32(pb, 0x20f); |
|
|
|
|
avio_wb32(pb, 0x0); |
|
|
|
|
avio_wb32(pb, audio_kbitrate); |
|
|
|
@ -1857,15 +1858,15 @@ static void mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s) |
|
|
|
|
avio_wb32(pb, AudioCodec->channels); |
|
|
|
|
|
|
|
|
|
avio_wb32(pb, 0x34); /* size */ |
|
|
|
|
put_tag(pb, "VPRF"); /* video */ |
|
|
|
|
ffio_wfourcc(pb, "VPRF"); /* video */ |
|
|
|
|
avio_wb32(pb, 0x0); |
|
|
|
|
avio_wb32(pb, 0x1); /* TrackID */ |
|
|
|
|
if (VideoCodec->codec_id == CODEC_ID_H264) { |
|
|
|
|
put_tag(pb, "avc1"); |
|
|
|
|
ffio_wfourcc(pb, "avc1"); |
|
|
|
|
avio_wb16(pb, 0x014D); |
|
|
|
|
avio_wb16(pb, 0x0015); |
|
|
|
|
} else { |
|
|
|
|
put_tag(pb, "mp4v"); |
|
|
|
|
ffio_wfourcc(pb, "mp4v"); |
|
|
|
|
avio_wb16(pb, 0x0000); |
|
|
|
|
avio_wb16(pb, 0x0103); |
|
|
|
|
} |
|
|
|
@ -2206,7 +2207,7 @@ static int mov_write_trailer(AVFormatContext *s) |
|
|
|
|
/* overwrite 'wide' placeholder atom */ |
|
|
|
|
url_fseek(pb, mov->mdat_pos - 8, SEEK_SET); |
|
|
|
|
avio_wb32(pb, 1); /* special value: real atom size will be 64 bit value after tag field */ |
|
|
|
|
put_tag(pb, "mdat"); |
|
|
|
|
ffio_wfourcc(pb, "mdat"); |
|
|
|
|
avio_wb64(pb, mov->mdat_size+16); |
|
|
|
|
} |
|
|
|
|
url_fseek(pb, moov_pos, SEEK_SET); |
|
|
|
|