@@ -31,6 +31,7 @@
#include "libavutil/attributes.h"
#include "libavutil/bprint.h"
+#include "libavutil/buffer.h"
#include "libavutil/channel_layout.h"
#include "libavutil/dict_internal.h"
#include "libavutil/internal.h"
@@ -184,10 +185,20 @@ static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
return p - dst;
}
+static void mov_free_stream_context(void *opaque, uint8_t *data);
+
+static inline MOVStreamContext *mov_get_stream_context(const AVStream *st)
+{
+ AVBufferRef *buf = st->priv_data;
+
+ return (MOVStreamContext *)buf->data;
+}
+
static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
{
AVStream *st;
- MOVStreamContext *sc;
+ AVBufferRef *buf;
+ uint8_t *data;
enum AVCodecID id;
int ret;
@@ -201,16 +212,22 @@ static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
return 0;
}
- sc = av_mallocz(sizeof(*sc));
- if (!sc)
+ data = av_mallocz(sizeof(MOVStreamContext));
+ if (!data)
+ return AVERROR(ENOMEM);
+ buf = av_buffer_create(data, sizeof(MOVStreamContext), mov_free_stream_context, c->fc, 0);
+ if (!buf) {
+ av_free(data);
return AVERROR(ENOMEM);
+ }
+
ret = ff_add_attached_pic(c->fc, NULL, pb, NULL, len);
if (ret < 0) {
- av_free(sc);
+ av_buffer_unref(&buf);
return ret;
}
st = c->fc->streams[c->fc->nb_streams - 1];
- st->priv_data = sc;
+ st->priv_data = buf;
if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
@@ -590,7 +607,7 @@ static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
avio_rb32(pb); // version + flags
entries = avio_rb32(pb);
@@ -1369,7 +1386,7 @@ static int64_t get_frag_time(AVFormatContext *s, AVStream *dst_st,
MOVFragmentIndex *frag_index, int index)
{
MOVFragmentStreamInfo * frag_stream_info;
- MOVStreamContext *sc = dst_st->priv_data;
+ MOVStreamContext *sc = mov_get_stream_context(dst_st);
int64_t timestamp;
int i, j;
@@ -1567,7 +1584,7 @@ static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
if (sc->time_scale) {
av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
@@ -1710,7 +1727,7 @@ static int mov_read_pcmc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return AVERROR_INVALIDDATA;
st = fc->streams[fc->nb_streams - 1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
if (sc->format == MOV_MP4_FPCM_TAG) {
switch (pcm_sample_size) {
@@ -2213,7 +2230,7 @@ static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
avio_r8(pb); /* version */
avio_rb24(pb); /* flags */
@@ -2546,7 +2563,7 @@ static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
if (ret < 0)
return ret;
if (size > 16) {
- MOVStreamContext *tmcd_ctx = st->priv_data;
+ MOVStreamContext *tmcd_ctx = mov_get_stream_context(st);
int val;
val = AV_RB32(st->codecpar->extradata + 4);
tmcd_ctx->tmcd_flags = val;
@@ -2712,7 +2729,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
av_assert0 (c->fc->nb_streams >= 1);
st = c->fc->streams[c->fc->nb_streams-1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
for (pseudo_stream_id = 0;
pseudo_stream_id < entries && !pb->eof_reached;
@@ -2810,7 +2827,7 @@ static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams - 1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
sc->stsd_version = avio_r8(pb);
avio_rb24(pb); /* flags */
@@ -2875,7 +2892,7 @@ static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
avio_r8(pb); /* version */
avio_rb24(pb); /* flags */
@@ -2971,7 +2988,7 @@ static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
avio_rb32(pb); // version + flags
@@ -3009,7 +3026,7 @@ static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
sti = ffstream(st);
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
avio_r8(pb); /* version */
avio_rb24(pb); /* flags */
@@ -3060,7 +3077,7 @@ static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
avio_r8(pb); /* version */
avio_rb24(pb); /* flags */
@@ -3149,7 +3166,7 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
avio_r8(pb); /* version */
avio_rb24(pb); /* flags */
@@ -3260,7 +3277,7 @@ static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams - 1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
avio_r8(pb); /* version */
avio_rb24(pb); /* flags */
@@ -3305,7 +3322,7 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
avio_r8(pb); /* version */
avio_rb24(pb); /* flags */
@@ -3375,7 +3392,7 @@ static int mov_read_sgpd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams - 1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
version = avio_r8(pb); /* version */
avio_rb24(pb); /* flags */
@@ -3431,7 +3448,7 @@ static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
version = avio_r8(pb); /* version */
avio_rb24(pb); /* flags */
@@ -3532,7 +3549,7 @@ static int find_prev_closest_index(AVStream *st,
int64_t* ctts_index,
int64_t* ctts_sample)
{
- MOVStreamContext *msc = st->priv_data;
+ MOVStreamContext *msc = mov_get_stream_context(st);
FFStream *const sti = ffstream(st);
AVIndexEntry *e_keep = sti->index_entries;
int nb_keep = sti->nb_index_entries;
@@ -3705,7 +3722,7 @@ static int64_t add_ctts_entry(MOVCtts** ctts_data, unsigned int* ctts_count, uns
#define MAX_REORDER_DELAY 16
static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
{
- MOVStreamContext *msc = st->priv_data;
+ MOVStreamContext *msc = mov_get_stream_context(st);
FFStream *const sti = ffstream(st);
int ctts_ind = 0;
int ctts_sample = 0;
@@ -3813,7 +3830,7 @@ static void mov_current_sample_set(MOVStreamContext *sc, int current_sample)
*/
static void mov_fix_index(MOVContext *mov, AVStream *st)
{
- MOVStreamContext *msc = st->priv_data;
+ MOVStreamContext *msc = mov_get_stream_context(st);
FFStream *const sti = ffstream(st);
AVIndexEntry *e_old = sti->index_entries;
int nb_old = sti->nb_index_entries;
@@ -4127,7 +4144,7 @@ static int build_open_gop_key_points(AVStream *st)
int k;
int sample_id = 0;
uint32_t cra_index;
- MOVStreamContext *sc = st->priv_data;
+ MOVStreamContext *sc = mov_get_stream_context(st);
if (st->codecpar->codec_id != AV_CODEC_ID_HEVC || !sc->sync_group_count)
return 0;
@@ -4187,7 +4204,7 @@ static int build_open_gop_key_points(AVStream *st)
static void mov_build_index(MOVContext *mov, AVStream *st)
{
- MOVStreamContext *sc = st->priv_data;
+ MOVStreamContext *sc = mov_get_stream_context(st);
FFStream *const sti = ffstream(st);
int64_t current_offset;
int64_t current_dts = 0;
@@ -4627,7 +4644,9 @@ static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
AVStream *st;
+ AVBufferRef *buf;
MOVStreamContext *sc;
+ uint8_t *data;
int ret;
if (c->is_still_picture_avif) {
@@ -4637,10 +4656,16 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
st = avformat_new_stream(c->fc, NULL);
if (!st) return AVERROR(ENOMEM);
st->id = -1;
- sc = av_mallocz(sizeof(MOVStreamContext));
- if (!sc) return AVERROR(ENOMEM);
+ data = av_mallocz(sizeof(MOVStreamContext));
+ if (!data) return AVERROR(ENOMEM);
+ buf = av_buffer_create(data, sizeof(MOVStreamContext), mov_free_stream_context, c->fc, 0);
+ if (!buf) {
+ av_free(data);
+ return AVERROR(ENOMEM);
+ }
- st->priv_data = sc;
+ st->priv_data = buf;
+ sc = mov_get_stream_context(st);
st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
sc->ffindex = st->index;
c->trak_index = st->index;
@@ -4836,7 +4861,7 @@ static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
for (i = 0; i < 3; i++) {
uint8_t **p;
@@ -4936,7 +4961,7 @@ static int avif_add_stream(MOVContext *c, int item_id)
st->time_base.num = st->time_base.den = 1;
st->nb_frames = 1;
sc->time_scale = 1;
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
sc->pb = c->fc->pb;
sc->pb_is_copied = 1;
@@ -5025,7 +5050,7 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
// Each stream (trak) should have exactly 1 tkhd. This catches bad files and
// avoids corrupting AVStreams mapped to an earlier tkhd.
@@ -5227,7 +5252,7 @@ static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
return 0;
}
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
if (sc->pseudo_stream_id + 1 != frag->stsd_id && sc->pseudo_stream_id != -1)
return 0;
version = avio_r8(pb);
@@ -5281,7 +5306,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
av_log(c->fc, AV_LOG_WARNING, "could not find corresponding track id %u\n", frag->track_id);
return 0;
}
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
return 0;
@@ -5584,7 +5609,7 @@ static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
}
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
timescale = av_make_q(1, avio_rb32(pb));
@@ -5667,14 +5692,14 @@ static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom)
si = &item->stream_info[j];
if (si->sidx_pts != AV_NOPTS_VALUE) {
ref_st = c->fc->streams[j];
- ref_sc = ref_st->priv_data;
+ ref_sc = mov_get_stream_context(ref_st);
break;
}
}
}
if (ref_st) for (i = 0; i < c->fc->nb_streams; i++) {
st = c->fc->streams[i];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
if (!sc->has_sidx) {
st->duration = sc->track_end = av_rescale(ref_st->duration, sc->time_scale, ref_sc->time_scale);
}
@@ -5770,7 +5795,7 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1 || c->ignore_editlist)
return 0;
- sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
+ sc = mov_get_stream_context(c->fc->streams[c->fc->nb_streams-1]);
version = avio_r8(pb); /* version */
avio_rb24(pb); /* flags */
@@ -5837,7 +5862,7 @@ static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return AVERROR_INVALIDDATA;
- sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
+ sc = mov_get_stream_context(c->fc->streams[c->fc->nb_streams - 1]);
sc->timecode_track = avio_rb32(pb);
return 0;
}
@@ -5894,7 +5919,7 @@ static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return AVERROR_INVALIDDATA;
- sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
+ sc = mov_get_stream_context(c->fc->streams[c->fc->nb_streams - 1]);
if (atom.size < 5) {
av_log(c->fc, AV_LOG_ERROR, "Empty Mastering Display Metadata box\n");
@@ -5942,7 +5967,7 @@ static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return AVERROR_INVALIDDATA;
- sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
+ sc = mov_get_stream_context(c->fc->streams[c->fc->nb_streams - 1]);
if (atom.size < 24 || sc->mastering) {
av_log(c->fc, AV_LOG_ERROR, "Invalid Mastering Display Color Volume box\n");
@@ -5978,7 +6003,7 @@ static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return AVERROR_INVALIDDATA;
- sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
+ sc = mov_get_stream_context(c->fc->streams[c->fc->nb_streams - 1]);
if (atom.size < 5) {
av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level box\n");
@@ -6014,7 +6039,7 @@ static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return AVERROR_INVALIDDATA;
- sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
+ sc = mov_get_stream_context(c->fc->streams[c->fc->nb_streams - 1]);
if (atom.size < 4) {
av_log(c->fc, AV_LOG_ERROR, "Empty Content Light Level Info box\n");
@@ -6047,7 +6072,7 @@ static int mov_read_st3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
st = c->fc->streams[c->fc->nb_streams - 1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
if (atom.size < 5) {
av_log(c->fc, AV_LOG_ERROR, "Empty stereoscopic video box\n");
@@ -6097,7 +6122,7 @@ static int mov_read_sv3d(MOVContext *c, AVIOContext *pb, MOVAtom atom)
return 0;
st = c->fc->streams[c->fc->nb_streams - 1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
if (atom.size < 8) {
av_log(c->fc, AV_LOG_ERROR, "Empty spherical video box\n");
@@ -6308,7 +6333,7 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams - 1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
ret = ffio_read_size(pb, uuid, AV_UUID_LEN);
if (ret < 0)
@@ -6420,7 +6445,7 @@ static int mov_read_frma(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams - 1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
switch (sc->format)
{
@@ -6473,7 +6498,7 @@ static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encry
}
if (i == c->fc->nb_streams)
return 0;
- *sc = st->priv_data;
+ *sc = mov_get_stream_context(st);
if (!frag_stream_info->encryption_index) {
// If this stream isn't encrypted, don't create the index.
@@ -6491,7 +6516,7 @@ static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encry
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams - 1];
- *sc = st->priv_data;
+ *sc = mov_get_stream_context(st);
if (!(*sc)->cenc.encryption_index) {
// If this stream isn't encrypted, don't create the index.
@@ -6984,7 +7009,7 @@ static int mov_read_schm(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
if (sc->pseudo_stream_id != 0) {
av_log(c->fc, AV_LOG_ERROR, "schm boxes are only supported in first sample descriptor\n");
@@ -7016,7 +7041,7 @@ static int mov_read_tenc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
if (c->fc->nb_streams < 1)
return 0;
st = c->fc->streams[c->fc->nb_streams-1];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
if (sc->pseudo_stream_id != 0) {
av_log(c->fc, AV_LOG_ERROR, "tenc atom are only supported in first sample descriptor\n");
@@ -8198,7 +8223,7 @@ static void mov_read_chapters(AVFormatContext *s)
}
sti = ffstream(st);
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
cur_pos = avio_tell(sc->pb);
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
@@ -8288,7 +8313,7 @@ static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
{
- MOVStreamContext *sc = st->priv_data;
+ MOVStreamContext *sc = mov_get_stream_context(st);
FFStream *const sti = ffstream(st);
char buf[AV_TIMECODE_STR_SIZE];
int64_t cur_pos = avio_tell(sc->pb);
@@ -8314,7 +8339,7 @@ static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st)
static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
{
- MOVStreamContext *sc = st->priv_data;
+ MOVStreamContext *sc = mov_get_stream_context(st);
FFStream *const sti = ffstream(st);
int flags = 0;
int64_t cur_pos = avio_tell(sc->pb);
@@ -8371,6 +8396,56 @@ static void mov_free_encryption_index(MOVEncryptionIndex **index) {
av_freep(index);
}
+static void mov_free_stream_context(void *opaque, uint8_t *data)
+{
+ AVFormatContext *s = opaque;
+ MOVStreamContext *sc = (MOVStreamContext *)data;
+
+ av_freep(&sc->ctts_data);
+ for (int i = 0; i < sc->drefs_count; i++) {
+ av_freep(&sc->drefs[i].path);
+ av_freep(&sc->drefs[i].dir);
+ }
+ av_freep(&sc->drefs);
+
+ sc->drefs_count = 0;
+
+ if (!sc->pb_is_copied)
+ ff_format_io_close(s, &sc->pb);
+
+ sc->pb = NULL;
+ av_freep(&sc->chunk_offsets);
+ av_freep(&sc->stsc_data);
+ av_freep(&sc->sample_sizes);
+ av_freep(&sc->keyframes);
+ av_freep(&sc->stts_data);
+ av_freep(&sc->sdtp_data);
+ av_freep(&sc->stps_data);
+ av_freep(&sc->elst_data);
+ av_freep(&sc->rap_group);
+ av_freep(&sc->sync_group);
+ av_freep(&sc->sgpd_sync);
+ av_freep(&sc->sample_offsets);
+ av_freep(&sc->open_key_samples);
+ av_freep(&sc->display_matrix);
+ av_freep(&sc->index_ranges);
+
+ if (sc->extradata)
+ for (int i = 0; i < sc->stsd_count; i++)
+ av_free(sc->extradata[i]);
+ av_freep(&sc->extradata);
+ av_freep(&sc->extradata_size);
+
+ mov_free_encryption_index(&sc->cenc.encryption_index);
+ av_encryption_info_free(sc->cenc.default_encrypted_sample);
+ av_aes_ctr_free(sc->cenc.aes_ctr);
+
+ av_freep(&sc->stereo3d);
+ av_freep(&sc->spherical);
+ av_freep(&sc->mastering);
+ av_freep(&sc->coll);
+}
+
static int mov_read_close(AVFormatContext *s)
{
MOVContext *mov = s->priv_data;
@@ -8378,54 +8453,12 @@ static int mov_read_close(AVFormatContext *s)
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
- MOVStreamContext *sc = st->priv_data;
+ MOVStreamContext *sc = mov_get_stream_context(st);
if (!sc)
continue;
- av_freep(&sc->ctts_data);
- for (j = 0; j < sc->drefs_count; j++) {
- av_freep(&sc->drefs[j].path);
- av_freep(&sc->drefs[j].dir);
- }
- av_freep(&sc->drefs);
-
- sc->drefs_count = 0;
-
- if (!sc->pb_is_copied)
- ff_format_io_close(s, &sc->pb);
-
- sc->pb = NULL;
- av_freep(&sc->chunk_offsets);
- av_freep(&sc->stsc_data);
- av_freep(&sc->sample_sizes);
- av_freep(&sc->keyframes);
- av_freep(&sc->stts_data);
- av_freep(&sc->sdtp_data);
- av_freep(&sc->stps_data);
- av_freep(&sc->elst_data);
- av_freep(&sc->rap_group);
- av_freep(&sc->sync_group);
- av_freep(&sc->sgpd_sync);
- av_freep(&sc->sample_offsets);
- av_freep(&sc->open_key_samples);
- av_freep(&sc->display_matrix);
- av_freep(&sc->index_ranges);
-
- if (sc->extradata)
- for (j = 0; j < sc->stsd_count; j++)
- av_free(sc->extradata[j]);
- av_freep(&sc->extradata);
- av_freep(&sc->extradata_size);
-
- mov_free_encryption_index(&sc->cenc.encryption_index);
- av_encryption_info_free(sc->cenc.default_encrypted_sample);
- av_aes_ctr_free(sc->cenc.aes_ctr);
-
- av_freep(&sc->stereo3d);
- av_freep(&sc->spherical);
- av_freep(&sc->mastering);
- av_freep(&sc->coll);
+ av_buffer_unref((AVBufferRef **)&st->priv_data);
}
av_freep(&mov->dv_demux);
@@ -8464,7 +8497,7 @@ static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
- MOVStreamContext *sc = st->priv_data;
+ MOVStreamContext *sc = mov_get_stream_context(st);
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&
sc->timecode_track == tmcd_id)
@@ -8644,7 +8677,7 @@ static int mov_read_header(AVFormatContext *s)
/* copy timecode metadata from tmcd tracks to the related video streams */
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
- MOVStreamContext *sc = st->priv_data;
+ MOVStreamContext *sc = mov_get_stream_context(st);
if (sc->timecode_track > 0) {
AVDictionaryEntry *tcr;
int tmcd_st_id = -1;
@@ -8665,7 +8698,7 @@ static int mov_read_header(AVFormatContext *s)
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
FFStream *const sti = ffstream(st);
- MOVStreamContext *sc = st->priv_data;
+ MOVStreamContext *sc = mov_get_stream_context(st);
fix_timescale(mov, sc);
if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
st->codecpar->codec_id == AV_CODEC_ID_AAC) {
@@ -8695,7 +8728,7 @@ static int mov_read_header(AVFormatContext *s)
if (mov->trex_data) {
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
- MOVStreamContext *sc = st->priv_data;
+ MOVStreamContext *sc = mov_get_stream_context(st);
if (st->duration > 0) {
/* Akin to sc->data_size * 8 * sc->time_scale / st->duration but accounting for overflows. */
st->codecpar->bit_rate = av_rescale(sc->data_size, ((int64_t) sc->time_scale) * 8, st->duration);
@@ -8713,7 +8746,7 @@ static int mov_read_header(AVFormatContext *s)
if (mov->use_mfra_for > 0) {
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
- MOVStreamContext *sc = st->priv_data;
+ MOVStreamContext *sc = mov_get_stream_context(st);
if (sc->duration_for_fps > 0) {
/* Akin to sc->data_size * 8 * sc->time_scale / sc->duration_for_fps but accounting for overflows. */
st->codecpar->bit_rate = av_rescale(sc->data_size, ((int64_t) sc->time_scale) * 8, sc->duration_for_fps);
@@ -8738,7 +8771,7 @@ static int mov_read_header(AVFormatContext *s)
for (i = 0; i < s->nb_streams; i++) {
AVStream *st = s->streams[i];
- MOVStreamContext *sc = st->priv_data;
+ MOVStreamContext *sc = mov_get_stream_context(st);
switch (st->codecpar->codec_type) {
case AVMEDIA_TYPE_AUDIO:
@@ -8809,7 +8842,7 @@ static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
for (i = 0; i < s->nb_streams; i++) {
AVStream *avst = s->streams[i];
FFStream *const avsti = ffstream(avst);
- MOVStreamContext *msc = avst->priv_data;
+ MOVStreamContext *msc = mov_get_stream_context(avst);
if (msc->pb && msc->current_sample < avsti->nb_index_entries) {
AVIndexEntry *current_sample = &avsti->index_entries[msc->current_sample];
int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
@@ -8934,7 +8967,7 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
return ret;
goto retry;
}
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
/* must be done just before reading, to avoid infinite loop on sample */
current_index = sc->current_index;
mov_current_sample_inc(sc);
@@ -9100,7 +9133,7 @@ static int is_open_key_sample(const MOVStreamContext *sc, int sample)
*/
static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pts)
{
- MOVStreamContext *sc = st->priv_data;
+ MOVStreamContext *sc = mov_get_stream_context(st);
FFStream *const sti = ffstream(st);
int64_t key_sample_dts, key_sample_pts;
@@ -9126,7 +9159,7 @@ static int can_seek_to_key_sample(AVStream *st, int sample, int64_t requested_pt
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
{
- MOVStreamContext *sc = st->priv_data;
+ MOVStreamContext *sc = mov_get_stream_context(st);
FFStream *const sti = ffstream(st);
int sample, time_sample, ret;
unsigned int i;
@@ -9188,7 +9221,7 @@ static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp,
static int64_t mov_get_skip_samples(AVStream *st, int sample)
{
- MOVStreamContext *sc = st->priv_data;
+ MOVStreamContext *sc = mov_get_stream_context(st);
FFStream *const sti = ffstream(st);
int64_t first_ts = sti->index_entries[0].timestamp;
int64_t ts = sti->index_entries[sample].timestamp;
@@ -9242,7 +9275,7 @@ static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
for (i = 0; i < s->nb_streams; i++) {
MOVStreamContext *sc;
st = s->streams[i];
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
mov_current_sample_set(sc, 0);
}
while (1) {
@@ -9250,7 +9283,7 @@ static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
AVIndexEntry *entry = mov_find_next_sample(s, &st);
if (!entry)
return AVERROR_INVALIDDATA;
- sc = st->priv_data;
+ sc = mov_get_stream_context(st);
if (sc->ffindex == stream_index && sc->current_sample == sample)
break;
mov_current_sample_inc(sc);
Signed-off-by: James Almer <jamrial@gmail.com> --- libavformat/mov.c | 257 ++++++++++++++++++++++++++-------------------- 1 file changed, 145 insertions(+), 112 deletions(-)