title_str[title_size] = 0;
if (title_str[0]) {
int off = (!c->isom && title_str[0] == title_size - 1);
- av_dict_set(&st->metadata, "handler_name", title_str + off, 0);
+ // flag added so as to not set stream handler name if already set from mdia->hdlr
+ av_dict_set(&st->metadata, "handler_name", title_str + off, AV_DICT_DONT_OVERWRITE);
}
av_freep(&title_str);
}
ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size);
if (ret < 0)
return ret;
+ if (atom.type == MKTAG('h','v','c','C') && st->codecpar->codec_tag == MKTAG('d','v','h','1'))
+ st->codecpar->codec_id = AV_CODEC_ID_HEVC;
return 0;
}
avio_rb24(pb); /* flags */
entries = avio_rb32(pb);
- if (entries <= 0) {
+ /* Each entry contains a size (4 bytes) and format (4 bytes). */
+ if (entries <= 0 || entries > atom.size / 8) {
av_log(c->fc, AV_LOG_ERROR, "invalid STSD entries %d\n", entries);
return AVERROR_INVALIDDATA;
}
int ctts_sample = 0;
int64_t pts_buf[MAX_REORDER_DELAY + 1]; // Circular buffer to sort pts.
int buf_start = 0;
- int buf_size = 0;
int j, r, num_swaps;
+ for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
+ pts_buf[j] = INT64_MIN;
+
if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
st->codecpar->codec_id == AV_CODEC_ID_H264) {
st->codecpar->video_delay = 0;
for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
- if (buf_size == (MAX_REORDER_DELAY + 1)) {
- // If circular buffer is full, then move the first element forward.
- buf_start = (buf_start + 1) % buf_size;
- } else {
- ++buf_size;
- }
-
// Point j to the last elem of the buffer and insert the current pts there.
- j = (buf_start + buf_size - 1) % buf_size;
+ j = buf_start;
+ buf_start = (buf_start + 1);
+ if (buf_start == MAX_REORDER_DELAY + 1)
+ buf_start = 0;
+
pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration;
// The timestamps that are already in the sorted buffer, and are greater than the
// go through, to keep this buffer in sorted order.
num_swaps = 0;
while (j != buf_start) {
- r = (j - 1 + buf_size) % buf_size;
+ r = j - 1;
+ if (r < 0) r = MAX_REORDER_DELAY;
if (pts_buf[j] < pts_buf[r]) {
FFSWAP(int64_t, pts_buf[j], pts_buf[r]);
++num_swaps;
+ } else {
+ break;
}
j = r;
}
st->index_entries[i].timestamp -= msc->min_corrected_pts;
}
}
- // Start time should be equal to zero or the duration of any empty edits.
- st->start_time = empty_edits_sum_duration;
}
+ // Start time should be equal to zero or the duration of any empty edits.
+ st->start_time = empty_edits_sum_duration;
// Update av stream length, if it ends up shorter than the track's media duration
st->duration = FFMIN(st->duration, edit_list_dts_entry_end - start_dts);
return 0;
}
+static int mov_read_av1c(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ AVStream *st;
+ int ret;
+
+ if (c->fc->nb_streams < 1)
+ return 0;
+ st = c->fc->streams[c->fc->nb_streams - 1];
+
+ if (atom.size < 4) {
+ av_log(c->fc, AV_LOG_ERROR, "Empty AV1 Codec Configuration Box\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* For now, propagate only the OBUs, if any. Once libavcodec is
+ updated to handle isobmff style extradata this can be removed. */
+ avio_skip(pb, 4);
+
+ if (atom.size == 4)
+ return 0;
+
+ ret = ff_get_extradata(c->fc, st->codecpar, pb, atom.size - 4);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
static int mov_read_vpcc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
AVStream *st;
*sc = st->priv_data;
if (!frag_stream_info->encryption_index) {
+ // If this stream isn't encrypted, don't create the index.
+ if (!(*sc)->cenc.default_encrypted_sample)
+ return 0;
frag_stream_info->encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
if (!frag_stream_info->encryption_index)
return AVERROR(ENOMEM);
*sc = st->priv_data;
if (!(*sc)->cenc.encryption_index) {
+ // If this stream isn't encrypted, don't create the index.
+ if (!(*sc)->cenc.default_encrypted_sample)
+ return 0;
(*sc)->cenc.encryption_index = av_mallocz(sizeof(*frag_stream_info->encryption_index));
if (!(*sc)->cenc.encryption_index)
return AVERROR(ENOMEM);
unsigned int subsample_count;
AVSubsampleEncryptionInfo *subsamples;
+ if (!sc->cenc.default_encrypted_sample) {
+ av_log(c->fc, AV_LOG_ERROR, "Missing schm or tenc\n");
+ return AVERROR_INVALIDDATA;
+ }
+
*sample = av_encryption_info_clone(sc->cenc.default_encrypted_sample);
if (!*sample)
return AVERROR(ENOMEM);
const int OPUS_SEEK_PREROLL_MS = 80;
AVStream *st;
size_t size;
- int16_t pre_skip;
+ uint16_t pre_skip;
if (c->fc->nb_streams < 1)
return 0;
{ MKTAG('A','A','L','P'), mov_read_avid },
{ MKTAG('A','R','E','S'), mov_read_ares },
{ MKTAG('a','v','s','s'), mov_read_avss },
+{ MKTAG('a','v','1','C'), mov_read_av1c },
{ MKTAG('c','h','p','l'), mov_read_chpl },
{ MKTAG('c','o','6','4'), mov_read_stco },
{ MKTAG('c','o','l','r'), mov_read_colr },