From patchwork Tue Jan 30 17:32:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 45911 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a21:8786:b0:199:de12:6fa6 with SMTP id ph6csp2315041pzb; Tue, 30 Jan 2024 09:32:43 -0800 (PST) X-Google-Smtp-Source: AGHT+IHpNH9OFw0+TX1JSvSoyWhw8GwfrUweVl5F1T9fRaRATS+Pjtpnd3yZHMMPje40U086OWlr X-Received: by 2002:a17:906:a85a:b0:a35:eab4:84c7 with SMTP id dx26-20020a170906a85a00b00a35eab484c7mr2046157ejb.27.1706635963018; Tue, 30 Jan 2024 09:32:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1706635963; cv=none; d=google.com; s=arc-20160816; b=Vqxzg7v2d7IoBLMfi5e0JXy54hMw7dREkKFAtdNsvaMTjg6lyEzQdqENJjj6aVmwT6 RmIhOemzo6Mx0QYnXhYDMzAYDJ+Z0ZSBKQ71cxuGs6yZJxQd3bJ5TB/08Xl84UdqX6TP tdzCjdqvpLGp7HdxZ+Ju+kx4KRMC90s7CXK8h2Ri8LDmSxNK2/t3p6/tA/zQm+AZMFs2 14di+T0LLYzj1AmWtPjakG4yd5YW/0O/V2GzO1p3AftYhF2Uc9wfBOGbeG+pBw925dML AdTNLGnx+py6+9x7tqiA76zRQqYFMNo9ah5E3YIfNg+y7HdLqLWbF+rgbTvzjZIR0cPr xGuw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:dkim-signature:delivered-to; bh=Aq21cWDn1MZ7CJU2E5clzgieiShQIZ418uXPR1Z0hI4=; fh=YOA8vD9MJZuwZ71F/05pj6KdCjf6jQRmzLS+CATXUQk=; b=zwo9ugsSi0p+JXV1VcOiO6Zqap4qjphUf7w0SmA1lZyoGS+abLCSBWm7ZvRc49YFeP tTbjkWD+msz66VxWrPbgfhFHknFMZV6unr1JND7vx1akM4w+U78wjnOpyvLBJQO7cQxd n6q9+7CWGUBqQEwcuBVOC6TM7sy4XRqZEvTPM63ycFb9vJTUktmJ6t9ADyWpKXuxi50Q wacUUAs27eQIntEAWzTKA5/3H7qZjwh/FjQxZDxv7R5sFvIbcxcltGfyVaI4iPIpl+31 LuIgg1ZNo08OTb54jSYJDtIAumc/yUTL7ZuNXJdY8+eQpTCnIY/kimZ+5EKvwb69gIkB /Ymg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b=d5i2BPWJ; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id l19-20020a1709067d5300b00a35c1f2ea3esi2038090ejp.992.2024.01.30.09.32.42; Tue, 30 Jan 2024 09:32:43 -0800 (PST) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b=d5i2BPWJ; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 9457568CE19; Tue, 30 Jan 2024 19:32:20 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pj1-f43.google.com (mail-pj1-f43.google.com [209.85.216.43]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C18FD68BD2C for ; Tue, 30 Jan 2024 19:32:12 +0200 (EET) Received: by mail-pj1-f43.google.com with SMTP id 98e67ed59e1d1-2906bcae4feso1864032a91.3 for ; Tue, 30 Jan 2024 09:32:12 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1706635931; x=1707240731; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=/VsaZSoNKxZqNxXHjSF+paFAph4jg7mHF3YziQCgWQM=; b=d5i2BPWJze2Xvbjhc3UAYBpv8LzW/VQL75F5+DZPlDRJLIhgf6960m9fSWaUqu34Ui /JaGcMnSfJzYAL6pT6HaZK+idjMbTLLGRWILN2+2JCxn2dLaAbJ3NqFWvbGHZkiku8Nd phAIxXA8UTHbQF1WBlSJEgj/AQ87MRdw9m2MJK0o5eI4xiBteJeOk1lKgtkSyqwAPhHz KJGqLHDqakvLrYRZwsOUGlYIGRkBFQFX+17w+OESb2cHg3pG8ZlPtDXX8zHsUXNts6K1 oFLMWZhNh3jIkZduvo4mI1Yum2uhZdRkmY22GLa3eB7LBE04YPUl/42f+SY3VPK5UgvF l6Bg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706635931; x=1707240731; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/VsaZSoNKxZqNxXHjSF+paFAph4jg7mHF3YziQCgWQM=; b=orX3N6VYd0gucpd0V1dgOnCorm5JCZkXRGoxKGaLJ3wgaqhLpLUuZJoa7TV9VxQd+1 oFzLnTAX93LJksK7Tn8I1+I1Tmh9R3o+QIDMHorb8YXiSKYLAuGdlRmUtH1J39NXUUxv hVoUPQ9ddFSzClJ2D9MKkXc07Lt0pJyTrPgRJs2W0rhyT6HvLbDj8Nuipl2tD1XUWvI2 E67gylpetoFc9t3o/hVcABK1DPMxXzXP6OfqI2iqLjZ5xC9VxT+3OhHQLT9AVL6dKOvZ whEi7+znjQ4CKCw8h6ltn/SxNr7eMxpeRZZCPRdu98PeG4MDSX/rViTI0HmVtsXgBf3w Segw== X-Gm-Message-State: AOJu0YzPS+WtCaVPgfutnDEX3ynswVefSd06wDj3wm5hwjaXeMgDEC1t 311XjjCqsZ93zZhhr6acT2Jro/g3StZQpVI5STDFJJ+szRzbdfkWpMyQPHJn X-Received: by 2002:a17:90b:d91:b0:295:bb92:a02 with SMTP id bg17-20020a17090b0d9100b00295bb920a02mr1463143pjb.34.1706635930267; Tue, 30 Jan 2024 09:32:10 -0800 (PST) Received: from localhost.localdomain (host197.190-225-105.telecom.net.ar. [190.225.105.197]) by smtp.gmail.com with ESMTPSA id k12-20020a170902f28c00b001d73702e0b7sm4107415plc.212.2024.01.30.09.32.09 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Jan 2024 09:32:09 -0800 (PST) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Tue, 30 Jan 2024 14:32:14 -0300 Message-ID: <20240130173218.63297-3-jamrial@gmail.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240130173218.63297-1-jamrial@gmail.com> References: <20240130173218.63297-1-jamrial@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 3/7 v2] avformat/mov: make MOVStreamContext refcounted X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: O8Xv+LFlR+iL This will be needed by the following commit. Signed-off-by: James Almer --- libavformat/mov.c | 257 ++++++++++++++++++++++++++-------------------- 1 file changed, 145 insertions(+), 112 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 3e71252e46..a0dfa22598 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -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); @@ -1372,7 +1389,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; @@ -1571,7 +1588,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"); @@ -1714,7 +1731,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) { @@ -2217,7 +2234,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 */ @@ -2555,7 +2572,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; @@ -2721,7 +2738,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; @@ -2819,7 +2836,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 */ @@ -2884,7 +2901,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 */ @@ -2980,7 +2997,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 @@ -3018,7 +3035,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 */ @@ -3069,7 +3086,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 */ @@ -3158,7 +3175,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 */ @@ -3269,7 +3286,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 */ @@ -3314,7 +3331,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 */ @@ -3384,7 +3401,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 */ @@ -3440,7 +3457,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 */ @@ -3541,7 +3558,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; @@ -3714,7 +3731,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; @@ -3822,7 +3839,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; @@ -4136,7 +4153,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; @@ -4196,7 +4213,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; @@ -4636,16 +4653,24 @@ 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; 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; @@ -4841,7 +4866,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; @@ -4941,7 +4966,7 @@ static int heif_add_stream(MOVContext *c, HEIFItem *item) 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; @@ -5013,7 +5038,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. @@ -5215,7 +5240,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); @@ -5269,7 +5294,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; @@ -5572,7 +5597,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)); @@ -5655,14 +5680,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); } @@ -5758,7 +5783,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 */ @@ -5825,7 +5850,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; } @@ -5882,7 +5907,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"); @@ -5930,7 +5955,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"); @@ -5966,7 +5991,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"); @@ -6002,7 +6027,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"); @@ -6035,7 +6060,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"); @@ -6085,7 +6110,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"); @@ -6296,7 +6321,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) @@ -6408,7 +6433,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) { @@ -6461,7 +6486,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. @@ -6479,7 +6504,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. @@ -6972,7 +6997,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"); @@ -7004,7 +7029,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"); @@ -8416,7 +8441,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) { @@ -8506,7 +8531,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); @@ -8532,7 +8557,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); @@ -8589,6 +8614,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; @@ -8596,54 +8671,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); @@ -8682,7 +8715,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) @@ -8882,7 +8915,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; @@ -8903,7 +8936,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) { @@ -8933,7 +8966,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); @@ -8951,7 +8984,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); @@ -8976,7 +9009,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: @@ -9047,7 +9080,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); @@ -9172,7 +9205,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); @@ -9338,7 +9371,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; @@ -9364,7 +9397,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; @@ -9426,7 +9459,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; @@ -9480,7 +9513,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) { @@ -9488,7 +9521,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);