You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-04 22:03:09 +02:00
avformat/movenc: allow storing more than one extradata buffer per track
This is in preparation for a following change Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
@ -654,8 +654,8 @@ static int mov_write_eac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra
|
|||||||
*/
|
*/
|
||||||
static int mov_write_extradata_tag(AVIOContext *pb, MOVTrack *track)
|
static int mov_write_extradata_tag(AVIOContext *pb, MOVTrack *track)
|
||||||
{
|
{
|
||||||
avio_write(pb, track->par->extradata, track->par->extradata_size);
|
avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]);
|
||||||
return track->par->extradata_size;
|
return track->extradata_size[track->last_stsd_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mov_write_enda_tag(AVIOContext *pb)
|
static int mov_write_enda_tag(AVIOContext *pb)
|
||||||
@ -749,7 +749,8 @@ static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
|
|||||||
{
|
{
|
||||||
struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
|
struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
|
||||||
int64_t pos = avio_tell(pb);
|
int64_t pos = avio_tell(pb);
|
||||||
int decoder_specific_info_len = track->vos_len ? 5 + track->vos_len : 0;
|
int decoder_specific_info_len = track->extradata_size[track->last_stsd_index] ?
|
||||||
|
5 + track->extradata_size[track->last_stsd_index] : 0;
|
||||||
|
|
||||||
avio_wb32(pb, 0); // size
|
avio_wb32(pb, 0); // size
|
||||||
ffio_wfourcc(pb, "esds");
|
ffio_wfourcc(pb, "esds");
|
||||||
@ -784,10 +785,11 @@ static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic
|
|||||||
avio_wb32(pb, bit_rates.max_bit_rate); // maxbitrate
|
avio_wb32(pb, bit_rates.max_bit_rate); // maxbitrate
|
||||||
avio_wb32(pb, bit_rates.avg_bit_rate);
|
avio_wb32(pb, bit_rates.avg_bit_rate);
|
||||||
|
|
||||||
if (track->vos_len) {
|
if (track->extradata_size[track->last_stsd_index]) {
|
||||||
// DecoderSpecific info descriptor
|
// DecoderSpecific info descriptor
|
||||||
put_descr(pb, 0x05, track->vos_len);
|
put_descr(pb, 0x05, track->extradata_size[track->last_stsd_index]);
|
||||||
avio_write(pb, track->vos_data, track->vos_len);
|
avio_write(pb, track->extradata[track->last_stsd_index],
|
||||||
|
track->extradata_size[track->last_stsd_index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// SL descriptor
|
// SL descriptor
|
||||||
@ -844,13 +846,13 @@ static int mov_write_dfla_tag(AVIOContext *pb, MOVTrack *track)
|
|||||||
avio_wb24(pb, 0); /* flags */
|
avio_wb24(pb, 0); /* flags */
|
||||||
|
|
||||||
/* Expect the encoder to pass a METADATA_BLOCK_TYPE_STREAMINFO. */
|
/* Expect the encoder to pass a METADATA_BLOCK_TYPE_STREAMINFO. */
|
||||||
if (track->par->extradata_size != FLAC_STREAMINFO_SIZE)
|
if (track->extradata_size[track->last_stsd_index] != FLAC_STREAMINFO_SIZE)
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
/* TODO: Write other METADATA_BLOCK_TYPEs if the encoder makes them available. */
|
/* TODO: Write other METADATA_BLOCK_TYPEs if the encoder makes them available. */
|
||||||
avio_w8(pb, 1 << 7 | FLAC_METADATA_TYPE_STREAMINFO); /* LastMetadataBlockFlag << 7 | BlockType */
|
avio_w8(pb, 1 << 7 | FLAC_METADATA_TYPE_STREAMINFO); /* LastMetadataBlockFlag << 7 | BlockType */
|
||||||
avio_wb24(pb, track->par->extradata_size); /* Length */
|
avio_wb24(pb, track->extradata_size[track->last_stsd_index]); /* Length */
|
||||||
avio_write(pb, track->par->extradata, track->par->extradata_size); /* BlockData[Length] */
|
avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]); /* BlockData[Length] */
|
||||||
|
|
||||||
return update_size(pb, pos);
|
return update_size(pb, pos);
|
||||||
}
|
}
|
||||||
@ -862,28 +864,28 @@ static int mov_write_dops_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra
|
|||||||
avio_wb32(pb, 0);
|
avio_wb32(pb, 0);
|
||||||
ffio_wfourcc(pb, "dOps");
|
ffio_wfourcc(pb, "dOps");
|
||||||
avio_w8(pb, 0); /* Version */
|
avio_w8(pb, 0); /* Version */
|
||||||
if (track->par->extradata_size < 19) {
|
if (track->extradata_size[track->last_stsd_index] < 19) {
|
||||||
av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
|
av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
/* extradata contains an Ogg OpusHead, other than byte-ordering and
|
/* extradata contains an Ogg OpusHead, other than byte-ordering and
|
||||||
OpusHead's preceeding magic/version, OpusSpecificBox is currently
|
OpusHead's preceeding magic/version, OpusSpecificBox is currently
|
||||||
identical. */
|
identical. */
|
||||||
channels = AV_RB8(track->par->extradata + 9);
|
channels = AV_RB8(track->extradata[track->last_stsd_index] + 9);
|
||||||
channel_map = AV_RB8(track->par->extradata + 18);
|
channel_map = AV_RB8(track->extradata[track->last_stsd_index] + 18);
|
||||||
|
|
||||||
avio_w8(pb, channels); /* OuputChannelCount */
|
avio_w8(pb, channels); /* OuputChannelCount */
|
||||||
avio_wb16(pb, AV_RL16(track->par->extradata + 10)); /* PreSkip */
|
avio_wb16(pb, AV_RL16(track->extradata[track->last_stsd_index] + 10)); /* PreSkip */
|
||||||
avio_wb32(pb, AV_RL32(track->par->extradata + 12)); /* InputSampleRate */
|
avio_wb32(pb, AV_RL32(track->extradata[track->last_stsd_index] + 12)); /* InputSampleRate */
|
||||||
avio_wb16(pb, AV_RL16(track->par->extradata + 16)); /* OutputGain */
|
avio_wb16(pb, AV_RL16(track->extradata[track->last_stsd_index] + 16)); /* OutputGain */
|
||||||
avio_w8(pb, channel_map); /* ChannelMappingFamily */
|
avio_w8(pb, channel_map); /* ChannelMappingFamily */
|
||||||
/* Write the rest of the header out without byte-swapping. */
|
/* Write the rest of the header out without byte-swapping. */
|
||||||
if (channel_map) {
|
if (channel_map) {
|
||||||
if (track->par->extradata_size < 21 + channels) {
|
if (track->extradata_size[track->last_stsd_index] < 21 + channels) {
|
||||||
av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
|
av_log(s, AV_LOG_ERROR, "invalid extradata size\n");
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
}
|
}
|
||||||
avio_write(pb, track->par->extradata + 19, 2 + channels); /* ChannelMappingTable */
|
avio_write(pb, track->extradata[track->last_stsd_index] + 19, 2 + channels); /* ChannelMappingTable */
|
||||||
}
|
}
|
||||||
|
|
||||||
return update_size(pb, pos);
|
return update_size(pb, pos);
|
||||||
@ -896,23 +898,23 @@ static int mov_write_dmlp_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra
|
|||||||
avio_wb32(pb, 0);
|
avio_wb32(pb, 0);
|
||||||
ffio_wfourcc(pb, "dmlp");
|
ffio_wfourcc(pb, "dmlp");
|
||||||
|
|
||||||
if (track->vos_len < 20) {
|
if (track->extradata_size[track->last_stsd_index] < 20) {
|
||||||
av_log(s, AV_LOG_ERROR,
|
av_log(s, AV_LOG_ERROR,
|
||||||
"Cannot write moov atom before TrueHD packets."
|
"Cannot write moov atom before TrueHD packets."
|
||||||
" Set the delay_moov flag to fix this.\n");
|
" Set the delay_moov flag to fix this.\n");
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
length = (AV_RB16(track->vos_data) & 0xFFF) * 2;
|
length = (AV_RB16(track->extradata[track->last_stsd_index]) & 0xFFF) * 2;
|
||||||
if (length < 20 || length > track->vos_len)
|
if (length < 20 || length > track->extradata_size[track->last_stsd_index])
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
// Only TrueHD is supported
|
// Only TrueHD is supported
|
||||||
if (AV_RB32(track->vos_data + 4) != 0xF8726FBA)
|
if (AV_RB32(track->extradata[track->last_stsd_index] + 4) != 0xF8726FBA)
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
avio_wb32(pb, AV_RB32(track->vos_data + 8)); /* format_info */
|
avio_wb32(pb, AV_RB32(track->extradata[track->last_stsd_index] + 8)); /* format_info */
|
||||||
avio_wb16(pb, AV_RB16(track->vos_data + 18) << 1); /* peak_data_rate */
|
avio_wb16(pb, AV_RB16(track->extradata[track->last_stsd_index] + 18) << 1); /* peak_data_rate */
|
||||||
avio_wb32(pb, 0); /* reserved */
|
avio_wb32(pb, 0); /* reserved */
|
||||||
|
|
||||||
return update_size(pb, pos);
|
return update_size(pb, pos);
|
||||||
@ -1078,7 +1080,8 @@ static int mov_write_wave_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra
|
|||||||
static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
|
static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
|
||||||
{
|
{
|
||||||
uint8_t *unescaped;
|
uint8_t *unescaped;
|
||||||
const uint8_t *start, *next, *end = track->vos_data + track->vos_len;
|
const uint8_t *start, *next, *end = track->extradata[track->last_stsd_index] +
|
||||||
|
track->extradata_size[track->last_stsd_index];
|
||||||
int unescaped_size, seq_found = 0;
|
int unescaped_size, seq_found = 0;
|
||||||
int level = 0, interlace = 0;
|
int level = 0, interlace = 0;
|
||||||
int packet_seq = track->vc1_info.packet_seq;
|
int packet_seq = track->vc1_info.packet_seq;
|
||||||
@ -1095,10 +1098,10 @@ static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
|
|||||||
"dvc1 atom. Set the delay_moov flag to fix this.\n");
|
"dvc1 atom. Set the delay_moov flag to fix this.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
unescaped = av_mallocz(track->vos_len + AV_INPUT_BUFFER_PADDING_SIZE);
|
unescaped = av_mallocz(track->extradata_size[track->last_stsd_index] + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||||
if (!unescaped)
|
if (!unescaped)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
start = find_next_marker(track->vos_data, end);
|
start = find_next_marker(track->extradata[track->last_stsd_index], end);
|
||||||
for (next = start; next < end; start = next) {
|
for (next = start; next < end; start = next) {
|
||||||
GetBitContext gb;
|
GetBitContext gb;
|
||||||
int size;
|
int size;
|
||||||
@ -1166,20 +1169,22 @@ static int mov_write_dvc1_tag(AVIOContext *pb, MOVTrack *track)
|
|||||||
if ((ret = mov_write_dvc1_structs(track, buf)) < 0)
|
if ((ret = mov_write_dvc1_structs(track, buf)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
avio_wb32(pb, track->vos_len + 8 + sizeof(buf));
|
avio_wb32(pb, track->extradata_size[track->last_stsd_index] + 8 + sizeof(buf));
|
||||||
ffio_wfourcc(pb, "dvc1");
|
ffio_wfourcc(pb, "dvc1");
|
||||||
avio_write(pb, buf, sizeof(buf));
|
avio_write(pb, buf, sizeof(buf));
|
||||||
avio_write(pb, track->vos_data, track->vos_len);
|
avio_write(pb, track->extradata[track->last_stsd_index],
|
||||||
|
track->extradata_size[track->last_stsd_index]);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mov_write_glbl_tag(AVIOContext *pb, MOVTrack *track)
|
static int mov_write_glbl_tag(AVIOContext *pb, MOVTrack *track)
|
||||||
{
|
{
|
||||||
avio_wb32(pb, track->vos_len + 8);
|
avio_wb32(pb, track->extradata_size[track->last_stsd_index] + 8);
|
||||||
ffio_wfourcc(pb, "glbl");
|
ffio_wfourcc(pb, "glbl");
|
||||||
avio_write(pb, track->vos_data, track->vos_len);
|
avio_write(pb, track->extradata[track->last_stsd_index],
|
||||||
return 8 + track->vos_len;
|
track->extradata_size[track->last_stsd_index]);
|
||||||
|
return 8 + track->extradata_size[track->last_stsd_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1476,7 +1481,7 @@ static int mov_write_audio_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
ret = mov_write_pcmc_tag(s, pb, track);
|
ret = mov_write_pcmc_tag(s, pb, track);
|
||||||
} else if (track->vos_len > 0)
|
} else if (track->extradata_size[track->last_stsd_index] > 0)
|
||||||
ret = mov_write_glbl_tag(pb, track);
|
ret = mov_write_glbl_tag(pb, track);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
@ -1523,7 +1528,8 @@ static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack *track)
|
|||||||
|
|
||||||
avio_wb32(pb, 0);
|
avio_wb32(pb, 0);
|
||||||
ffio_wfourcc(pb, "av1C");
|
ffio_wfourcc(pb, "av1C");
|
||||||
ff_isom_write_av1c(pb, track->vos_data, track->vos_len, track->mode != MODE_AVIF);
|
ff_isom_write_av1c(pb, track->extradata[track->last_stsd_index],
|
||||||
|
track->extradata_size[track->last_stsd_index], track->mode != MODE_AVIF);
|
||||||
return update_size(pb, pos);
|
return update_size(pb, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1533,7 +1539,8 @@ static int mov_write_avcc_tag(AVIOContext *pb, MOVTrack *track)
|
|||||||
|
|
||||||
avio_wb32(pb, 0);
|
avio_wb32(pb, 0);
|
||||||
ffio_wfourcc(pb, "avcC");
|
ffio_wfourcc(pb, "avcC");
|
||||||
ff_isom_write_avcc(pb, track->vos_data, track->vos_len);
|
ff_isom_write_avcc(pb, track->extradata[track->last_stsd_index],
|
||||||
|
track->extradata_size[track->last_stsd_index]);
|
||||||
return update_size(pb, pos);
|
return update_size(pb, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1565,7 +1572,8 @@ static int mov_write_av3c_tag(AVIOContext *pb, MOVTrack *track)
|
|||||||
int64_t pos = avio_tell(pb);
|
int64_t pos = avio_tell(pb);
|
||||||
avio_wb32(pb, 0);
|
avio_wb32(pb, 0);
|
||||||
ffio_wfourcc(pb, "av3c");
|
ffio_wfourcc(pb, "av3c");
|
||||||
mov_write_av3c(pb, track->vos_data, track->vos_len);
|
mov_write_av3c(pb, track->extradata[track->last_stsd_index],
|
||||||
|
track->extradata_size[track->last_stsd_index]);
|
||||||
return update_size(pb, pos);
|
return update_size(pb, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1575,7 +1583,8 @@ static int mov_write_vpcc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra
|
|||||||
|
|
||||||
avio_wb32(pb, 0);
|
avio_wb32(pb, 0);
|
||||||
ffio_wfourcc(pb, "vpcC");
|
ffio_wfourcc(pb, "vpcC");
|
||||||
ff_isom_write_vpcc(s, pb, track->vos_data, track->vos_len, track->par);
|
ff_isom_write_vpcc(s, pb, track->extradata[track->last_stsd_index],
|
||||||
|
track->extradata_size[track->last_stsd_index], track->par);
|
||||||
return update_size(pb, pos);
|
return update_size(pb, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1586,9 +1595,11 @@ static int mov_write_hvcc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra
|
|||||||
avio_wb32(pb, 0);
|
avio_wb32(pb, 0);
|
||||||
ffio_wfourcc(pb, "hvcC");
|
ffio_wfourcc(pb, "hvcC");
|
||||||
if (track->tag == MKTAG('h','v','c','1'))
|
if (track->tag == MKTAG('h','v','c','1'))
|
||||||
ff_isom_write_hvcc(pb, track->vos_data, track->vos_len, 1, s);
|
ff_isom_write_hvcc(pb, track->extradata[track->last_stsd_index],
|
||||||
|
track->extradata_size[track->last_stsd_index], 1, s);
|
||||||
else
|
else
|
||||||
ff_isom_write_hvcc(pb, track->vos_data, track->vos_len, 0, s);
|
ff_isom_write_hvcc(pb, track->extradata[track->last_stsd_index],
|
||||||
|
track->extradata_size[track->last_stsd_index], 0, s);
|
||||||
return update_size(pb, pos);
|
return update_size(pb, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1600,9 +1611,11 @@ static int mov_write_lhvc_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra
|
|||||||
avio_wb32(pb, 0);
|
avio_wb32(pb, 0);
|
||||||
ffio_wfourcc(pb, "lhvC");
|
ffio_wfourcc(pb, "lhvC");
|
||||||
if (track->tag == MKTAG('h','v','c','1'))
|
if (track->tag == MKTAG('h','v','c','1'))
|
||||||
ret = ff_isom_write_lhvc(pb, track->vos_data, track->vos_len, 1, s);
|
ret = ff_isom_write_lhvc(pb, track->extradata[track->last_stsd_index],
|
||||||
|
track->extradata_size[track->last_stsd_index], 1, s);
|
||||||
else
|
else
|
||||||
ret = ff_isom_write_lhvc(pb, track->vos_data, track->vos_len, 0, s);
|
ret = ff_isom_write_lhvc(pb, track->extradata[track->last_stsd_index],
|
||||||
|
track->extradata_size[track->last_stsd_index], 0, s);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
avio_seek(pb, pos, SEEK_SET);
|
avio_seek(pb, pos, SEEK_SET);
|
||||||
@ -1620,9 +1633,11 @@ static int mov_write_evcc_tag(AVIOContext *pb, MOVTrack *track)
|
|||||||
ffio_wfourcc(pb, "evcC");
|
ffio_wfourcc(pb, "evcC");
|
||||||
|
|
||||||
if (track->tag == MKTAG('e','v','c','1'))
|
if (track->tag == MKTAG('e','v','c','1'))
|
||||||
ff_isom_write_evcc(pb, track->vos_data, track->vos_len, 1);
|
ff_isom_write_evcc(pb, track->extradata[track->last_stsd_index],
|
||||||
|
track->extradata_size[track->last_stsd_index], 1);
|
||||||
else
|
else
|
||||||
ff_isom_write_evcc(pb, track->vos_data, track->vos_len, 0);
|
ff_isom_write_evcc(pb, track->extradata[track->last_stsd_index],
|
||||||
|
track->extradata_size[track->last_stsd_index], 0);
|
||||||
|
|
||||||
return update_size(pb, pos);
|
return update_size(pb, pos);
|
||||||
}
|
}
|
||||||
@ -1638,9 +1653,11 @@ static int mov_write_vvcc_tag(AVIOContext *pb, MOVTrack *track)
|
|||||||
avio_wb24(pb, 0); /* flags */
|
avio_wb24(pb, 0); /* flags */
|
||||||
|
|
||||||
if (track->tag == MKTAG('v','v','c','1'))
|
if (track->tag == MKTAG('v','v','c','1'))
|
||||||
ff_isom_write_vvcc(pb, track->vos_data, track->vos_len, 1);
|
ff_isom_write_vvcc(pb, track->extradata[track->last_stsd_index],
|
||||||
|
track->extradata_size[track->last_stsd_index], 1);
|
||||||
else
|
else
|
||||||
ff_isom_write_vvcc(pb, track->vos_data, track->vos_len, 0);
|
ff_isom_write_vvcc(pb, track->extradata[track->last_stsd_index],
|
||||||
|
track->extradata_size[track->last_stsd_index], 0);
|
||||||
return update_size(pb, pos);
|
return update_size(pb, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1666,11 +1683,11 @@ static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
|
|||||||
int cid;
|
int cid;
|
||||||
int display_width = track->par->width;
|
int display_width = track->par->width;
|
||||||
|
|
||||||
if (track->vos_data && track->vos_len > 0x29) {
|
if (track->extradata[track->last_stsd_index] && track->extradata_size[track->last_stsd_index] > 0x29) {
|
||||||
if (ff_dnxhd_parse_header_prefix(track->vos_data) != 0) {
|
if (ff_dnxhd_parse_header_prefix(track->extradata[track->last_stsd_index]) != 0) {
|
||||||
/* looks like a DNxHD bit stream */
|
/* looks like a DNxHD bit stream */
|
||||||
interlaced = (track->vos_data[5] & 2);
|
interlaced = (track->extradata[track->last_stsd_index][5] & 2);
|
||||||
cid = AV_RB32(track->vos_data + 0x28);
|
cid = AV_RB32(track->extradata[track->last_stsd_index] + 0x28);
|
||||||
} else {
|
} else {
|
||||||
av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream in vos_data\n");
|
av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream in vos_data\n");
|
||||||
return 0;
|
return 0;
|
||||||
@ -1745,9 +1762,9 @@ static int mov_write_dpxe_tag(AVIOContext *pb, MOVTrack *track)
|
|||||||
{
|
{
|
||||||
avio_wb32(pb, 12);
|
avio_wb32(pb, 12);
|
||||||
ffio_wfourcc(pb, "DpxE");
|
ffio_wfourcc(pb, "DpxE");
|
||||||
if (track->par->extradata_size >= 12 &&
|
if (track->extradata_size[track->last_stsd_index] >= 12 &&
|
||||||
!memcmp(&track->par->extradata[4], "DpxE", 4)) {
|
!memcmp(&track->extradata[track->last_stsd_index][4], "DpxE", 4)) {
|
||||||
avio_wb32(pb, track->par->extradata[11]);
|
avio_wb32(pb, track->extradata[track->last_stsd_index][11]);
|
||||||
} else {
|
} else {
|
||||||
avio_wb32(pb, 1);
|
avio_wb32(pb, 1);
|
||||||
}
|
}
|
||||||
@ -2158,8 +2175,8 @@ static int mov_write_subtitle_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack
|
|||||||
track->track_id);
|
track->track_id);
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
}
|
}
|
||||||
} else if (track->par->extradata_size)
|
} else if (track->extradata_size[track->last_stsd_index])
|
||||||
avio_write(pb, track->par->extradata, track->par->extradata_size);
|
avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]);
|
||||||
|
|
||||||
if (mov->write_btrt &&
|
if (mov->write_btrt &&
|
||||||
((ret = mov_write_btrt_tag(pb, track)) < 0))
|
((ret = mov_write_btrt_tag(pb, track)) < 0))
|
||||||
@ -2788,7 +2805,7 @@ static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex
|
|||||||
mov_write_vpcc_tag(mov->fc, pb, track);
|
mov_write_vpcc_tag(mov->fc, pb, track);
|
||||||
} else if (track->par->codec_id == AV_CODEC_ID_AV1) {
|
} else if (track->par->codec_id == AV_CODEC_ID_AV1) {
|
||||||
mov_write_av1c_tag(pb, track);
|
mov_write_av1c_tag(pb, track);
|
||||||
} else if (track->par->codec_id == AV_CODEC_ID_VC1 && track->vos_len > 0)
|
} else if (track->par->codec_id == AV_CODEC_ID_VC1 && track->extradata_size[track->last_stsd_index] > 0)
|
||||||
mov_write_dvc1_tag(pb, track);
|
mov_write_dvc1_tag(pb, track);
|
||||||
else if (track->par->codec_id == AV_CODEC_ID_VP6F ||
|
else if (track->par->codec_id == AV_CODEC_ID_VP6F ||
|
||||||
track->par->codec_id == AV_CODEC_ID_VP6A) {
|
track->par->codec_id == AV_CODEC_ID_VP6A) {
|
||||||
@ -2799,7 +2816,7 @@ static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex
|
|||||||
mov_write_dpxe_tag(pb, track);
|
mov_write_dpxe_tag(pb, track);
|
||||||
} else if (track->par->codec_id == AV_CODEC_ID_AVS3) {
|
} else if (track->par->codec_id == AV_CODEC_ID_AVS3) {
|
||||||
mov_write_av3c_tag(pb, track);
|
mov_write_av3c_tag(pb, track);
|
||||||
} else if (track->vos_len > 0)
|
} else if (track->extradata_size[track->last_stsd_index] > 0)
|
||||||
mov_write_glbl_tag(pb, track);
|
mov_write_glbl_tag(pb, track);
|
||||||
|
|
||||||
if (track->par->codec_id != AV_CODEC_ID_H264 &&
|
if (track->par->codec_id != AV_CODEC_ID_H264 &&
|
||||||
@ -3037,6 +3054,7 @@ static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContext
|
|||||||
ffio_wfourcc(pb, "stsd");
|
ffio_wfourcc(pb, "stsd");
|
||||||
avio_wb32(pb, 0); /* version & flags */
|
avio_wb32(pb, 0); /* version & flags */
|
||||||
avio_wb32(pb, 1); /* entry count */
|
avio_wb32(pb, 1); /* entry count */
|
||||||
|
|
||||||
if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
|
if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||||
ret = mov_write_video_tag(s, pb, mov, track);
|
ret = mov_write_video_tag(s, pb, mov, track);
|
||||||
else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
|
else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
|
||||||
@ -5253,19 +5271,19 @@ static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov, AVFormat
|
|||||||
if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
|
if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||||
if (track->par->codec_id == AV_CODEC_ID_H264) {
|
if (track->par->codec_id == AV_CODEC_ID_H264) {
|
||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
int size = track->par->extradata_size;
|
int size = track->extradata_size[track->last_stsd_index];
|
||||||
if (!ff_avc_write_annexb_extradata(track->par->extradata, &ptr,
|
if (!ff_avc_write_annexb_extradata(track->extradata[track->last_stsd_index], &ptr,
|
||||||
&size)) {
|
&size)) {
|
||||||
param_write_hex(pb, "CodecPrivateData",
|
param_write_hex(pb, "CodecPrivateData",
|
||||||
ptr ? ptr : track->par->extradata,
|
ptr ? ptr : track->extradata[track->last_stsd_index],
|
||||||
size);
|
size);
|
||||||
av_free(ptr);
|
av_free(ptr);
|
||||||
}
|
}
|
||||||
param_write_string(pb, "FourCC", "H264");
|
param_write_string(pb, "FourCC", "H264");
|
||||||
} else if (track->par->codec_id == AV_CODEC_ID_VC1) {
|
} else if (track->par->codec_id == AV_CODEC_ID_VC1) {
|
||||||
param_write_string(pb, "FourCC", "WVC1");
|
param_write_string(pb, "FourCC", "WVC1");
|
||||||
param_write_hex(pb, "CodecPrivateData", track->par->extradata,
|
param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
|
||||||
track->par->extradata_size);
|
track->extradata_size[track->last_stsd_index]);
|
||||||
}
|
}
|
||||||
param_write_int(pb, "MaxWidth", track->par->width);
|
param_write_int(pb, "MaxWidth", track->par->width);
|
||||||
param_write_int(pb, "MaxHeight", track->par->height);
|
param_write_int(pb, "MaxHeight", track->par->height);
|
||||||
@ -5286,8 +5304,8 @@ static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov, AVFormat
|
|||||||
} else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) {
|
} else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) {
|
||||||
param_write_string(pb, "FourCC", "WMAP");
|
param_write_string(pb, "FourCC", "WMAP");
|
||||||
}
|
}
|
||||||
param_write_hex(pb, "CodecPrivateData", track->par->extradata,
|
param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
|
||||||
track->par->extradata_size);
|
track->extradata_size[track->last_stsd_index]);
|
||||||
param_write_int(pb, "AudioTag", ff_codec_get_tag(ff_codec_wav_tags,
|
param_write_int(pb, "AudioTag", ff_codec_get_tag(ff_codec_wav_tags,
|
||||||
track->par->codec_id));
|
track->par->codec_id));
|
||||||
param_write_int(pb, "Channels", track->par->ch_layout.nb_channels);
|
param_write_int(pb, "Channels", track->par->ch_layout.nb_channels);
|
||||||
@ -6713,17 +6731,15 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* copy extradata if it exists */
|
/* copy extradata if it exists */
|
||||||
if (trk->vos_len == 0 && par->extradata_size > 0 &&
|
if (trk->extradata_size[0] == 0 && par->extradata_size > 0 &&
|
||||||
!TAG_IS_AVCI(trk->tag) &&
|
!TAG_IS_AVCI(trk->tag) &&
|
||||||
(par->codec_id != AV_CODEC_ID_DNXHD)) {
|
(par->codec_id != AV_CODEC_ID_DNXHD)) {
|
||||||
trk->vos_len = par->extradata_size;
|
trk->extradata[0] = av_memdup(par->extradata, par->extradata_size);
|
||||||
trk->vos_data = av_malloc(trk->vos_len + AV_INPUT_BUFFER_PADDING_SIZE);
|
if (!trk->extradata[0]) {
|
||||||
if (!trk->vos_data) {
|
|
||||||
ret = AVERROR(ENOMEM);
|
ret = AVERROR(ENOMEM);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
memcpy(trk->vos_data, par->extradata, trk->vos_len);
|
trk->extradata_size[0] = par->extradata_size;
|
||||||
memset(trk->vos_data + trk->vos_len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((par->codec_id == AV_CODEC_ID_DNXHD ||
|
if ((par->codec_id == AV_CODEC_ID_DNXHD ||
|
||||||
@ -6732,17 +6748,17 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
par->codec_id == AV_CODEC_ID_VVC ||
|
par->codec_id == AV_CODEC_ID_VVC ||
|
||||||
par->codec_id == AV_CODEC_ID_VP9 ||
|
par->codec_id == AV_CODEC_ID_VP9 ||
|
||||||
par->codec_id == AV_CODEC_ID_EVC ||
|
par->codec_id == AV_CODEC_ID_EVC ||
|
||||||
par->codec_id == AV_CODEC_ID_TRUEHD) && !trk->vos_len &&
|
par->codec_id == AV_CODEC_ID_TRUEHD) && !trk->extradata_size[0] &&
|
||||||
!TAG_IS_AVCI(trk->tag)) {
|
!TAG_IS_AVCI(trk->tag)) {
|
||||||
/* copy frame to create needed atoms */
|
/* copy frame to create needed atoms */
|
||||||
trk->vos_len = size;
|
trk->extradata_size[0] = size;
|
||||||
trk->vos_data = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
|
trk->extradata[0] = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||||
if (!trk->vos_data) {
|
if (!trk->extradata[0]) {
|
||||||
ret = AVERROR(ENOMEM);
|
ret = AVERROR(ENOMEM);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
memcpy(trk->vos_data, pkt->data, size);
|
memcpy(trk->extradata[0], pkt->data, size);
|
||||||
memset(trk->vos_data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
memset(trk->extradata[0] + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
|
if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
|
||||||
@ -6755,7 +6771,8 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
}
|
}
|
||||||
av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
|
av_log(s, AV_LOG_WARNING, "aac bitstream error\n");
|
||||||
}
|
}
|
||||||
if (par->codec_id == AV_CODEC_ID_H264 && trk->vos_len > 0 && *(uint8_t *)trk->vos_data != 1 && !TAG_IS_AVCI(trk->tag)) {
|
if (par->codec_id == AV_CODEC_ID_H264 && trk->extradata_size[trk->last_stsd_index] > 0 &&
|
||||||
|
*(uint8_t *)trk->extradata[trk->last_stsd_index] != 1 && !TAG_IS_AVCI(trk->tag)) {
|
||||||
/* from x264 or from bytestream H.264 */
|
/* from x264 or from bytestream H.264 */
|
||||||
/* NAL reformatting needed */
|
/* NAL reformatting needed */
|
||||||
if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
|
if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
|
||||||
@ -6775,8 +6792,8 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
size = ff_nal_parse_units(pb, pkt->data, pkt->size);
|
size = ff_nal_parse_units(pb, pkt->data, pkt->size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (par->codec_id == AV_CODEC_ID_HEVC && trk->vos_len > 6 &&
|
} else if (par->codec_id == AV_CODEC_ID_HEVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
|
||||||
(AV_RB24(trk->vos_data) == 1 || AV_RB32(trk->vos_data) == 1)) {
|
(AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
|
||||||
/* extradata is Annex B, assume the bitstream is too and convert it */
|
/* extradata is Annex B, assume the bitstream is too and convert it */
|
||||||
int filter_ps = (trk->tag == MKTAG('h','v','c','1'));
|
int filter_ps = (trk->tag == MKTAG('h','v','c','1'));
|
||||||
if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
|
if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
|
||||||
@ -6796,8 +6813,8 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, filter_ps, NULL);
|
size = ff_hevc_annexb2mp4(pb, pkt->data, pkt->size, filter_ps, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (par->codec_id == AV_CODEC_ID_VVC && trk->vos_len > 6 &&
|
} else if (par->codec_id == AV_CODEC_ID_VVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
|
||||||
(AV_RB24(trk->vos_data) == 1 || AV_RB32(trk->vos_data) == 1)) {
|
(AV_RB24(trk->extradata[trk->last_stsd_index]) == 1 || AV_RB32(trk->extradata[trk->last_stsd_index]) == 1)) {
|
||||||
/* extradata is Annex B, assume the bitstream is too and convert it */
|
/* extradata is Annex B, assume the bitstream is too and convert it */
|
||||||
if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
|
if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
|
||||||
ret = ff_vvc_annexb2mp4_buf(pkt->data, &reformatted_data,
|
ret = ff_vvc_annexb2mp4_buf(pkt->data, &reformatted_data,
|
||||||
@ -6854,11 +6871,13 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
avio_write(s->pb, pkt->data, pkt->size);
|
avio_write(s->pb, pkt->data, pkt->size);
|
||||||
} else {
|
} else {
|
||||||
if (trk->cenc.aes_ctr) {
|
if (trk->cenc.aes_ctr) {
|
||||||
if (par->codec_id == AV_CODEC_ID_H264 && par->extradata_size > 4) {
|
uint8_t *extradata = trk->extradata[trk->last_stsd_index];
|
||||||
int nal_size_length = (par->extradata[4] & 0x3) + 1;
|
int extradata_size = trk->extradata_size[trk->last_stsd_index];
|
||||||
|
if (par->codec_id == AV_CODEC_ID_H264 && extradata_size > 4) {
|
||||||
|
int nal_size_length = (extradata[4] & 0x3) + 1;
|
||||||
ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
|
ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
|
||||||
} else if(par->codec_id == AV_CODEC_ID_HEVC && par->extradata_size > 21) {
|
} else if(par->codec_id == AV_CODEC_ID_HEVC && extradata_size > 21) {
|
||||||
int nal_size_length = (par->extradata[21] & 0x3) + 1;
|
int nal_size_length = (extradata[21] & 0x3) + 1;
|
||||||
ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
|
ret = ff_mov_cenc_avc_write_nal_units(s, &trk->cenc, nal_size_length, pb, pkt->data, size);
|
||||||
} else if(par->codec_id == AV_CODEC_ID_VVC) {
|
} else if(par->codec_id == AV_CODEC_ID_VVC) {
|
||||||
ret = AVERROR_PATCHWELCOME;
|
ret = AVERROR_PATCHWELCOME;
|
||||||
@ -7050,16 +7069,14 @@ static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
trk->par->codec_id == AV_CODEC_ID_FLAC) {
|
trk->par->codec_id == AV_CODEC_ID_FLAC) {
|
||||||
size_t side_size;
|
size_t side_size;
|
||||||
uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
|
uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
|
||||||
if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
|
/* Overwrite extradata only on flush packets or when no extradata was available during init */
|
||||||
void *newextra = av_mallocz(side_size + AV_INPUT_BUFFER_PADDING_SIZE);
|
if (side_size > 0 && (!pkt->size || !trk->extradata_size[trk->last_stsd_index])) {
|
||||||
|
void *newextra = av_memdup(side, side_size);
|
||||||
if (!newextra)
|
if (!newextra)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
av_free(par->extradata);
|
av_free(trk->extradata[trk->last_stsd_index]);
|
||||||
par->extradata = newextra;
|
trk->extradata[trk->last_stsd_index] = newextra;
|
||||||
memcpy(par->extradata, side, side_size);
|
trk->extradata_size[trk->last_stsd_index] = side_size;
|
||||||
par->extradata_size = side_size;
|
|
||||||
if (!pkt->size) // Flush packet
|
|
||||||
mov->need_rewrite_extradata = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7398,6 +7415,11 @@ static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
|
|||||||
return ret;
|
return ret;
|
||||||
memcpy(track->par->extradata, stub_header, sizeof(stub_header));
|
memcpy(track->par->extradata, stub_header, sizeof(stub_header));
|
||||||
|
|
||||||
|
track->extradata[0] = av_memdup(stub_header, sizeof(stub_header));
|
||||||
|
if (!track->extradata[0])
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
track->extradata_size[0] = sizeof(stub_header);
|
||||||
|
|
||||||
pkt->stream_index = tracknum;
|
pkt->stream_index = tracknum;
|
||||||
pkt->flags = AV_PKT_FLAG_KEY;
|
pkt->flags = AV_PKT_FLAG_KEY;
|
||||||
|
|
||||||
@ -7569,8 +7591,9 @@ static void mov_free(AVFormatContext *s)
|
|||||||
av_packet_free(&info->pkt);
|
av_packet_free(&info->pkt);
|
||||||
av_freep(&track->eac3_priv);
|
av_freep(&track->eac3_priv);
|
||||||
}
|
}
|
||||||
if (track->vos_len)
|
for (int j = 0; j < track->stsd_count; j++)
|
||||||
av_freep(&track->vos_data);
|
av_freep(&track->extradata[j]);
|
||||||
|
av_freep(&track->extradata);
|
||||||
|
|
||||||
ff_mov_cenc_free(&track->cenc);
|
ff_mov_cenc_free(&track->cenc);
|
||||||
ffio_free_dyn_buf(&track->mdat_buf);
|
ffio_free_dyn_buf(&track->mdat_buf);
|
||||||
@ -7612,7 +7635,7 @@ static int mov_create_dvd_sub_decoder_specific_info(MOVTrack *track,
|
|||||||
int i, width = 720, height = 480;
|
int i, width = 720, height = 480;
|
||||||
int have_palette = 0, have_size = 0;
|
int have_palette = 0, have_size = 0;
|
||||||
uint32_t palette[16];
|
uint32_t palette[16];
|
||||||
char *cur = st->codecpar->extradata;
|
char *cur = track->extradata[track->last_stsd_index];
|
||||||
|
|
||||||
while (cur && *cur) {
|
while (cur && *cur) {
|
||||||
if (strncmp("palette:", cur, 8) == 0) {
|
if (strncmp("palette:", cur, 8) == 0) {
|
||||||
@ -7641,14 +7664,14 @@ static int mov_create_dvd_sub_decoder_specific_info(MOVTrack *track,
|
|||||||
cur += strspn(cur, "\n\r");
|
cur += strspn(cur, "\n\r");
|
||||||
}
|
}
|
||||||
if (have_palette) {
|
if (have_palette) {
|
||||||
track->vos_data = av_malloc(16*4 + AV_INPUT_BUFFER_PADDING_SIZE);
|
track->extradata[track->last_stsd_index] = av_malloc(16*4 + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||||
if (!track->vos_data)
|
if (!track->extradata[track->last_stsd_index])
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
for (i = 0; i < 16; i++) {
|
for (i = 0; i < 16; i++) {
|
||||||
AV_WB32(track->vos_data + i * 4, palette[i]);
|
AV_WB32(track->extradata[track->last_stsd_index] + i * 4, palette[i]);
|
||||||
}
|
}
|
||||||
memset(track->vos_data + 16*4, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
memset(track->extradata[track->last_stsd_index] + 16*4, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||||
track->vos_len = 16 * 4;
|
track->extradata_size[track->last_stsd_index] = 16 * 4;
|
||||||
}
|
}
|
||||||
st->codecpar->width = width;
|
st->codecpar->width = width;
|
||||||
st->codecpar->height = track->height = height;
|
st->codecpar->height = track->height = height;
|
||||||
@ -7963,6 +7986,16 @@ static int mov_init(AVFormatContext *s)
|
|||||||
if (!mov->tracks)
|
if (!mov->tracks)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
for (i = 0; i < mov->nb_tracks; i++) {
|
||||||
|
MOVTrack *track = &mov->tracks[i];
|
||||||
|
|
||||||
|
track->stsd_count = 1;
|
||||||
|
track->extradata = av_calloc(track->stsd_count, sizeof(*track->extradata));
|
||||||
|
track->extradata_size = av_calloc(track->stsd_count, sizeof(*track->extradata_size));
|
||||||
|
if (!track->extradata || !track->extradata_size)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
}
|
||||||
|
|
||||||
if (mov->encryption_scheme_str != NULL && strcmp(mov->encryption_scheme_str, "none") != 0) {
|
if (mov->encryption_scheme_str != NULL && strcmp(mov->encryption_scheme_str, "none") != 0) {
|
||||||
if (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) {
|
if (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) {
|
||||||
mov->encryption_scheme = MOV_ENC_CENC_AES_CTR;
|
mov->encryption_scheme = MOV_ENC_CENC_AES_CTR;
|
||||||
@ -8240,13 +8273,16 @@ static int mov_write_header(AVFormatContext *s)
|
|||||||
if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
|
if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
|
||||||
mov_create_dvd_sub_decoder_specific_info(track, st);
|
mov_create_dvd_sub_decoder_specific_info(track, st);
|
||||||
else if (!TAG_IS_AVCI(track->tag) && st->codecpar->codec_id != AV_CODEC_ID_DNXHD) {
|
else if (!TAG_IS_AVCI(track->tag) && st->codecpar->codec_id != AV_CODEC_ID_DNXHD) {
|
||||||
track->vos_len = st->codecpar->extradata_size;
|
track->extradata_size[track->last_stsd_index] = st->codecpar->extradata_size;
|
||||||
track->vos_data = av_malloc(track->vos_len + AV_INPUT_BUFFER_PADDING_SIZE);
|
track->extradata[track->last_stsd_index] =
|
||||||
if (!track->vos_data) {
|
av_malloc(track->extradata_size[track->last_stsd_index] + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||||
|
if (!track->extradata[track->last_stsd_index]) {
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
}
|
}
|
||||||
memcpy(track->vos_data, st->codecpar->extradata, track->vos_len);
|
memcpy(track->extradata[track->last_stsd_index],
|
||||||
memset(track->vos_data + track->vos_len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
st->codecpar->extradata, track->extradata_size[track->last_stsd_index]);
|
||||||
|
memset(track->extradata[track->last_stsd_index] + track->extradata_size[track->last_stsd_index],
|
||||||
|
0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8467,22 +8503,6 @@ static int mov_write_trailer(AVFormatContext *s)
|
|||||||
int i;
|
int i;
|
||||||
int64_t moov_pos;
|
int64_t moov_pos;
|
||||||
|
|
||||||
if (mov->need_rewrite_extradata) {
|
|
||||||
for (i = 0; i < mov->nb_streams; i++) {
|
|
||||||
MOVTrack *track = &mov->tracks[i];
|
|
||||||
AVCodecParameters *par = track->par;
|
|
||||||
|
|
||||||
track->vos_len = par->extradata_size;
|
|
||||||
av_freep(&track->vos_data);
|
|
||||||
track->vos_data = av_malloc(track->vos_len + AV_INPUT_BUFFER_PADDING_SIZE);
|
|
||||||
if (!track->vos_data)
|
|
||||||
return AVERROR(ENOMEM);
|
|
||||||
memcpy(track->vos_data, par->extradata, track->vos_len);
|
|
||||||
memset(track->vos_data + track->vos_len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
|
||||||
}
|
|
||||||
mov->need_rewrite_extradata = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Before actually writing the trailer, make sure that there are no
|
* Before actually writing the trailer, make sure that there are no
|
||||||
* dangling subtitles, that need a terminating sample.
|
* dangling subtitles, that need a terminating sample.
|
||||||
|
@ -90,6 +90,13 @@ typedef struct MOVTrack {
|
|||||||
uint64_t time;
|
uint64_t time;
|
||||||
int64_t track_duration;
|
int64_t track_duration;
|
||||||
int last_sample_is_subtitle_end;
|
int last_sample_is_subtitle_end;
|
||||||
|
|
||||||
|
/* multiple stsd */
|
||||||
|
int stsd_count;
|
||||||
|
int last_stsd_index;
|
||||||
|
uint8_t **extradata;
|
||||||
|
int *extradata_size;
|
||||||
|
|
||||||
long sample_count;
|
long sample_count;
|
||||||
long sample_size;
|
long sample_size;
|
||||||
long chunkCount;
|
long chunkCount;
|
||||||
@ -111,8 +118,6 @@ typedef struct MOVTrack {
|
|||||||
int mono_as_fc;
|
int mono_as_fc;
|
||||||
int multichannel_as_mono;
|
int multichannel_as_mono;
|
||||||
|
|
||||||
int vos_len;
|
|
||||||
uint8_t *vos_data;
|
|
||||||
MOVIentry *cluster;
|
MOVIentry *cluster;
|
||||||
MOVIentry *cluster_written;
|
MOVIentry *cluster_written;
|
||||||
unsigned cluster_capacity;
|
unsigned cluster_capacity;
|
||||||
@ -245,8 +250,6 @@ typedef struct MOVMuxContext {
|
|||||||
uint8_t *encryption_kid;
|
uint8_t *encryption_kid;
|
||||||
int encryption_kid_len;
|
int encryption_kid_len;
|
||||||
|
|
||||||
int need_rewrite_extradata;
|
|
||||||
|
|
||||||
int use_stream_ids_as_track_ids;
|
int use_stream_ids_as_track_ids;
|
||||||
int track_ids_ok;
|
int track_ids_ok;
|
||||||
int write_btrt;
|
int write_btrt;
|
||||||
|
Reference in New Issue
Block a user