*/
static int mov_write_extradata_tag(AVIOContext *pb, MOVTrack *track)
{
- avio_write(pb, track->par->extradata, track->par->extradata_size);
- return track->par->extradata_size;
+ avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]);
+ return track->extradata_size[track->last_stsd_index];
}
static int mov_write_enda_tag(AVIOContext *pb)
{
struct mpeg4_bit_rate_values bit_rates = calculate_mpeg4_bit_rates(track);
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
ffio_wfourcc(pb, "esds");
avio_wb32(pb, bit_rates.max_bit_rate); // maxbitrate
avio_wb32(pb, bit_rates.avg_bit_rate);
- if (track->vos_len) {
+ if (track->extradata_size[track->last_stsd_index]) {
// DecoderSpecific info descriptor
- put_descr(pb, 0x05, track->vos_len);
- avio_write(pb, track->vos_data, track->vos_len);
+ put_descr(pb, 0x05, track->extradata_size[track->last_stsd_index]);
+ avio_write(pb, track->extradata[track->last_stsd_index],
+ track->extradata_size[track->last_stsd_index]);
}
// SL descriptor
avio_wb24(pb, 0); /* flags */
/* 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;
/* 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_wb24(pb, track->par->extradata_size); /* Length */
- avio_write(pb, track->par->extradata, track->par->extradata_size); /* BlockData[Length] */
+ avio_wb24(pb, track->extradata_size[track->last_stsd_index]); /* Length */
+ avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]); /* BlockData[Length] */
return update_size(pb, pos);
}
avio_wb32(pb, 0);
ffio_wfourcc(pb, "dOps");
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");
return AVERROR_INVALIDDATA;
}
/* extradata contains an Ogg OpusHead, other than byte-ordering and
OpusHead's preceeding magic/version, OpusSpecificBox is currently
identical. */
- channels = AV_RB8(track->par->extradata + 9);
- channel_map = AV_RB8(track->par->extradata + 18);
+ channels = AV_RB8(track->extradata[track->last_stsd_index] + 9);
+ channel_map = AV_RB8(track->extradata[track->last_stsd_index] + 18);
avio_w8(pb, channels); /* OuputChannelCount */
- avio_wb16(pb, AV_RL16(track->par->extradata + 10)); /* PreSkip */
- avio_wb32(pb, AV_RL32(track->par->extradata + 12)); /* InputSampleRate */
- avio_wb16(pb, AV_RL16(track->par->extradata + 16)); /* OutputGain */
+ avio_wb16(pb, AV_RL16(track->extradata[track->last_stsd_index] + 10)); /* PreSkip */
+ avio_wb32(pb, AV_RL32(track->extradata[track->last_stsd_index] + 12)); /* InputSampleRate */
+ avio_wb16(pb, AV_RL16(track->extradata[track->last_stsd_index] + 16)); /* OutputGain */
avio_w8(pb, channel_map); /* ChannelMappingFamily */
/* Write the rest of the header out without byte-swapping. */
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");
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);
avio_wb32(pb, 0);
ffio_wfourcc(pb, "dmlp");
- if (track->vos_len < 20) {
+ if (track->extradata_size[track->last_stsd_index] < 20) {
av_log(s, AV_LOG_ERROR,
"Cannot write moov atom before TrueHD packets."
" Set the delay_moov flag to fix this.\n");
return AVERROR(EINVAL);
}
- length = (AV_RB16(track->vos_data) & 0xFFF) * 2;
- if (length < 20 || length > track->vos_len)
+ length = (AV_RB16(track->extradata[track->last_stsd_index]) & 0xFFF) * 2;
+ if (length < 20 || length > track->extradata_size[track->last_stsd_index])
return AVERROR_INVALIDDATA;
// 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;
- avio_wb32(pb, AV_RB32(track->vos_data + 8)); /* format_info */
- avio_wb16(pb, AV_RB16(track->vos_data + 18) << 1); /* peak_data_rate */
+ avio_wb32(pb, AV_RB32(track->extradata[track->last_stsd_index] + 8)); /* format_info */
+ avio_wb16(pb, AV_RB16(track->extradata[track->last_stsd_index] + 18) << 1); /* peak_data_rate */
avio_wb32(pb, 0); /* reserved */
return update_size(pb, pos);
static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf)
{
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 level = 0, interlace = 0;
int packet_seq = track->vc1_info.packet_seq;
"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)
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) {
GetBitContext gb;
int size;
if ((ret = mov_write_dvc1_structs(track, buf)) < 0)
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");
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;
}
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");
- avio_write(pb, track->vos_data, track->vos_len);
- return 8 + track->vos_len;
+ avio_write(pb, track->extradata[track->last_stsd_index],
+ track->extradata_size[track->last_stsd_index]);
+ return 8 + track->extradata_size[track->last_stsd_index];
}
/**
if (ret < 0)
return ret;
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);
if (ret < 0)
avio_wb32(pb, 0);
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);
}
avio_wb32(pb, 0);
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);
}
int64_t pos = avio_tell(pb);
avio_wb32(pb, 0);
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);
}
avio_wb32(pb, 0);
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);
}
avio_wb32(pb, 0);
ffio_wfourcc(pb, "hvcC");
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
- 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);
}
avio_wb32(pb, 0);
ffio_wfourcc(pb, "lhvC");
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
- 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) {
avio_seek(pb, pos, SEEK_SET);
ffio_wfourcc(pb, "evcC");
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
- 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);
}
avio_wb24(pb, 0); /* flags */
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
- 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);
}
int cid;
int display_width = track->par->width;
- if (track->vos_data && track->vos_len > 0x29) {
- if (ff_dnxhd_parse_header_prefix(track->vos_data) != 0) {
+ if (track->extradata[track->last_stsd_index] && track->extradata_size[track->last_stsd_index] > 0x29) {
+ if (ff_dnxhd_parse_header_prefix(track->extradata[track->last_stsd_index]) != 0) {
/* looks like a DNxHD bit stream */
- interlaced = (track->vos_data[5] & 2);
- cid = AV_RB32(track->vos_data + 0x28);
+ interlaced = (track->extradata[track->last_stsd_index][5] & 2);
+ cid = AV_RB32(track->extradata[track->last_stsd_index] + 0x28);
} else {
av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream in vos_data\n");
return 0;
{
avio_wb32(pb, 12);
ffio_wfourcc(pb, "DpxE");
- if (track->par->extradata_size >= 12 &&
- !memcmp(&track->par->extradata[4], "DpxE", 4)) {
- avio_wb32(pb, track->par->extradata[11]);
+ if (track->extradata_size[track->last_stsd_index] >= 12 &&
+ !memcmp(&track->extradata[track->last_stsd_index][4], "DpxE", 4)) {
+ avio_wb32(pb, track->extradata[track->last_stsd_index][11]);
} else {
avio_wb32(pb, 1);
}
track->track_id);
return AVERROR(EINVAL);
}
- } else if (track->par->extradata_size)
- avio_write(pb, track->par->extradata, track->par->extradata_size);
+ } else if (track->extradata_size[track->last_stsd_index])
+ avio_write(pb, track->extradata[track->last_stsd_index], track->extradata_size[track->last_stsd_index]);
if (mov->write_btrt &&
((ret = mov_write_btrt_tag(pb, track)) < 0))
mov_write_vpcc_tag(mov->fc, pb, track);
} else if (track->par->codec_id == AV_CODEC_ID_AV1) {
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);
else if (track->par->codec_id == AV_CODEC_ID_VP6F ||
track->par->codec_id == AV_CODEC_ID_VP6A) {
mov_write_dpxe_tag(pb, track);
} else if (track->par->codec_id == AV_CODEC_ID_AVS3) {
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);
if (track->par->codec_id != AV_CODEC_ID_H264 &&
ffio_wfourcc(pb, "stsd");
avio_wb32(pb, 0); /* version & flags */
avio_wb32(pb, 1); /* entry count */
+
if (track->par->codec_type == AVMEDIA_TYPE_VIDEO)
ret = mov_write_video_tag(s, pb, mov, track);
else if (track->par->codec_type == AVMEDIA_TYPE_AUDIO)
if (track->par->codec_type == AVMEDIA_TYPE_VIDEO) {
if (track->par->codec_id == AV_CODEC_ID_H264) {
uint8_t *ptr;
- int size = track->par->extradata_size;
- if (!ff_avc_write_annexb_extradata(track->par->extradata, &ptr,
+ int size = track->extradata_size[track->last_stsd_index];
+ if (!ff_avc_write_annexb_extradata(track->extradata[track->last_stsd_index], &ptr,
&size)) {
param_write_hex(pb, "CodecPrivateData",
- ptr ? ptr : track->par->extradata,
+ ptr ? ptr : track->extradata[track->last_stsd_index],
size);
av_free(ptr);
}
param_write_string(pb, "FourCC", "H264");
} else if (track->par->codec_id == AV_CODEC_ID_VC1) {
param_write_string(pb, "FourCC", "WVC1");
- param_write_hex(pb, "CodecPrivateData", track->par->extradata,
- track->par->extradata_size);
+ param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
+ track->extradata_size[track->last_stsd_index]);
}
param_write_int(pb, "MaxWidth", track->par->width);
param_write_int(pb, "MaxHeight", track->par->height);
} else if (track->par->codec_id == AV_CODEC_ID_WMAPRO) {
param_write_string(pb, "FourCC", "WMAP");
}
- param_write_hex(pb, "CodecPrivateData", track->par->extradata,
- track->par->extradata_size);
+ param_write_hex(pb, "CodecPrivateData", track->extradata[track->last_stsd_index],
+ track->extradata_size[track->last_stsd_index]);
param_write_int(pb, "AudioTag", ff_codec_get_tag(ff_codec_wav_tags,
track->par->codec_id));
param_write_int(pb, "Channels", track->par->ch_layout.nb_channels);
}
/* 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) &&
(par->codec_id != AV_CODEC_ID_DNXHD)) {
- trk->vos_len = par->extradata_size;
- trk->vos_data = av_malloc(trk->vos_len + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!trk->vos_data) {
+ trk->extradata[0] = av_memdup(par->extradata, par->extradata_size);
+ if (!trk->extradata[0]) {
ret = AVERROR(ENOMEM);
goto err;
}
- memcpy(trk->vos_data, par->extradata, trk->vos_len);
- memset(trk->vos_data + trk->vos_len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+ trk->extradata_size[0] = par->extradata_size;
}
if ((par->codec_id == AV_CODEC_ID_DNXHD ||
par->codec_id == AV_CODEC_ID_VVC ||
par->codec_id == AV_CODEC_ID_VP9 ||
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)) {
/* copy frame to create needed atoms */
- trk->vos_len = size;
- trk->vos_data = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!trk->vos_data) {
+ trk->extradata_size[0] = size;
+ trk->extradata[0] = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!trk->extradata[0]) {
ret = AVERROR(ENOMEM);
goto err;
}
- memcpy(trk->vos_data, pkt->data, size);
- memset(trk->vos_data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+ memcpy(trk->extradata[0], pkt->data, size);
+ memset(trk->extradata[0] + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
}
if (par->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 &&
}
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 */
/* NAL reformatting needed */
if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
size = ff_nal_parse_units(pb, pkt->data, pkt->size);
}
}
- } else if (par->codec_id == AV_CODEC_ID_HEVC && trk->vos_len > 6 &&
- (AV_RB24(trk->vos_data) == 1 || AV_RB32(trk->vos_data) == 1)) {
+ } else if (par->codec_id == AV_CODEC_ID_HEVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
+ (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 */
int filter_ps = (trk->tag == MKTAG('h','v','c','1'));
if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
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 &&
- (AV_RB24(trk->vos_data) == 1 || AV_RB32(trk->vos_data) == 1)) {
+ } else if (par->codec_id == AV_CODEC_ID_VVC && trk->extradata_size[trk->last_stsd_index] > 6 &&
+ (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 */
if (trk->hint_track >= 0 && trk->hint_track < mov->nb_tracks) {
ret = ff_vvc_annexb2mp4_buf(pkt->data, &reformatted_data,
avio_write(s->pb, pkt->data, pkt->size);
} else {
if (trk->cenc.aes_ctr) {
- if (par->codec_id == AV_CODEC_ID_H264 && par->extradata_size > 4) {
- int nal_size_length = (par->extradata[4] & 0x3) + 1;
+ uint8_t *extradata = trk->extradata[trk->last_stsd_index];
+ 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);
- } else if(par->codec_id == AV_CODEC_ID_HEVC && par->extradata_size > 21) {
- int nal_size_length = (par->extradata[21] & 0x3) + 1;
+ } else if(par->codec_id == AV_CODEC_ID_HEVC && extradata_size > 21) {
+ 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);
} else if(par->codec_id == AV_CODEC_ID_VVC) {
ret = AVERROR_PATCHWELCOME;
trk->par->codec_id == AV_CODEC_ID_FLAC) {
size_t 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))) {
- void *newextra = av_mallocz(side_size + AV_INPUT_BUFFER_PADDING_SIZE);
+ /* Overwrite extradata only on flush packets or when no extradata was available during init */
+ if (side_size > 0 && (!pkt->size || !trk->extradata_size[trk->last_stsd_index])) {
+ void *newextra = av_memdup(side, side_size);
if (!newextra)
return AVERROR(ENOMEM);
- av_free(par->extradata);
- par->extradata = newextra;
- memcpy(par->extradata, side, side_size);
- par->extradata_size = side_size;
- if (!pkt->size) // Flush packet
- mov->need_rewrite_extradata = 1;
+ av_free(trk->extradata[trk->last_stsd_index]);
+ trk->extradata[trk->last_stsd_index] = newextra;
+ trk->extradata_size[trk->last_stsd_index] = side_size;
}
}
return ret;
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->flags = AV_PKT_FLAG_KEY;
av_packet_free(&info->pkt);
av_freep(&track->eac3_priv);
}
- if (track->vos_len)
- av_freep(&track->vos_data);
+ for (int j = 0; j < track->stsd_count; j++)
+ av_freep(&track->extradata[j]);
+ av_freep(&track->extradata);
ff_mov_cenc_free(&track->cenc);
ffio_free_dyn_buf(&track->mdat_buf);
int i, width = 720, height = 480;
int have_palette = 0, have_size = 0;
uint32_t palette[16];
- char *cur = st->codecpar->extradata;
+ char *cur = track->extradata[track->last_stsd_index];
while (cur && *cur) {
if (strncmp("palette:", cur, 8) == 0) {
cur += strspn(cur, "\n\r");
}
if (have_palette) {
- track->vos_data = av_malloc(16*4 + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!track->vos_data)
+ track->extradata[track->last_stsd_index] = av_malloc(16*4 + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!track->extradata[track->last_stsd_index])
return AVERROR(ENOMEM);
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);
- track->vos_len = 16 * 4;
+ memset(track->extradata[track->last_stsd_index] + 16*4, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+ track->extradata_size[track->last_stsd_index] = 16 * 4;
}
st->codecpar->width = width;
st->codecpar->height = track->height = height;
if (!mov->tracks)
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 (strcmp(mov->encryption_scheme_str, "cenc-aes-ctr") == 0) {
mov->encryption_scheme = MOV_ENC_CENC_AES_CTR;
if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
mov_create_dvd_sub_decoder_specific_info(track, st);
else if (!TAG_IS_AVCI(track->tag) && st->codecpar->codec_id != AV_CODEC_ID_DNXHD) {
- track->vos_len = st->codecpar->extradata_size;
- track->vos_data = av_malloc(track->vos_len + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!track->vos_data) {
+ track->extradata_size[track->last_stsd_index] = st->codecpar->extradata_size;
+ track->extradata[track->last_stsd_index] =
+ av_malloc(track->extradata_size[track->last_stsd_index] + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!track->extradata[track->last_stsd_index]) {
return AVERROR(ENOMEM);
}
- memcpy(track->vos_data, st->codecpar->extradata, track->vos_len);
- memset(track->vos_data + track->vos_len, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+ memcpy(track->extradata[track->last_stsd_index],
+ 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);
}
}
int i;
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
* dangling subtitles, that need a terminating sample.