From patchwork Sun Nov 19 20:46:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stebbins X-Patchwork-Id: 6206 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.161.94 with SMTP id m30csp3148186jah; Sun, 19 Nov 2017 12:47:32 -0800 (PST) X-Google-Smtp-Source: AGs4zMZ7l6nE/W1exUO0VKt/UC27W0BZDHLYXWqbBYnhy0Cb5XfTrsjrztfVkEKug1D0Yj+/tQS9 X-Received: by 10.223.160.230 with SMTP id n35mr10461935wrn.116.1511124452891; Sun, 19 Nov 2017 12:47:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511124452; cv=none; d=google.com; s=arc-20160816; b=P5IlYnV447d+3/L2uFzG7f2Wa26tmG3qaKAPdN0NzsPOx/2mpXvA5OkyvJzjlJrG0D 7Yh2jkgs1zyVrs9B8jeSQfkmIrdzGqUA2zOFIMEtOBoG6gyE7J/HBQtUQgqBmufnhGR/ PiHy7gRD27uJekMb4S+xhaoUKEdMKacsAPmgnc/fHCqNkijAH/wx11jYh7Lu2v5nxU5Q kSW7FJh2OOXYz82LSwrcWdC3TfNeFaSgTvnZovhjOJVyRjasUgWuEZRMdUvFLu/Kyzqt rjPk+Pat6hd2ztC0OevSY806AeUGONeJ44uts+zVD5kmEkDRY9bNYLE4/13wcac5fwx/ FC6g== 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:delivered-to:arc-authentication-results; bh=5ghjNNggxE1EwY4aRgaAFeHswqdXzQVPCnC1zMwO4QM=; b=DgQOTR3KWhiGgHYt5ZTXWPehkciJ6Ll3Oo7FB//aJtCQdN4B8bBeXa5I1mKfafWUte 2sSEUmG80fbVDjHmHxxXoKuRLPCNEg39MvyWwp9WfVSQ4kA0P+xFmduayNy9VdLtVDFx ya7wBKOa1AS+ipwHzo5NpYYouIC58ihUV9Mki1Paxik0jGxUH9mPdpYP3p5kURo1ePme bRYyqz/wpyKvhv3eHgzBKDUU5+TxXnoOUMFKV6oH5r0O5JfMveJdPJhlKeE77571xVDK 7dS76ZeGw77IGLqe9f8xgot8snhviOJY3eqtjjRyCLPo4EzGop/0t69C45Zq4EXa8jix NV0A== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id w187si6340062wmb.119.2017.11.19.12.47.32; Sun, 19 Nov 2017 12:47:32 -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; 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 Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 52FC6689C8C; Sun, 19 Nov 2017 22:47:11 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail.jetheaddev.com (mail.jetheaddev.com [70.164.99.34]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 0DF5E6891EE for ; Sun, 19 Nov 2017 22:47:10 +0200 (EET) Received: from dionysus.jetheaddev.com (10.13.12.63) by cas.jetheaddev.com (192.168.13.27) with Microsoft SMTP Server (TLS) id 14.3.351.0; Sun, 19 Nov 2017 12:47:25 -0800 Received: from dionysus.jetheaddev.com (localhost [127.0.0.1]) by dionysus.jetheaddev.com (8.15.2/8.14.7) with ESMTP id vAJKlPkW004690 for ; Sun, 19 Nov 2017 12:47:25 -0800 Received: (from jstebbins@localhost) by dionysus.jetheaddev.com (8.15.2/8.15.2/Submit) id vAJKlPVs004689 for ffmpeg-devel@ffmpeg.org; Sun, 19 Nov 2017 12:47:25 -0800 From: John Stebbins To: Date: Sun, 19 Nov 2017 12:46:33 -0800 Message-ID: <20171119204635.4593-5-jstebbins@jetheaddev.com> X-Mailer: git-send-email 2.13.6 In-Reply-To: <20171119204635.4593-1-jstebbins@jetheaddev.com> References: <20171119204635.4593-1-jstebbins@jetheaddev.com> MIME-Version: 1.0 X-Originating-IP: [10.13.12.63] Subject: [FFmpeg-devel] [PATCH 4/6] lavf/mov: set AV_PKT_FLAG_DISPOSABLE from sdtp box X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 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" --- libavformat/isom.h | 10 ++++++ libavformat/mov.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++--- libavformat/utils.c | 3 +- 3 files changed, 99 insertions(+), 6 deletions(-) diff --git a/libavformat/isom.h b/libavformat/isom.h index 65676fb0f5..646b31ccc7 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -137,11 +137,19 @@ typedef struct MOVIndexRange { int64_t end; } MOVIndexRange; +typedef struct MOVIndexEntry { +#define MOVINDEX_DISPOSABLE 0x01 + int8_t flags; +} MOVIndexEntry; + typedef struct MOVStreamContext { AVIOContext *pb; int pb_is_copied; int ffindex; ///< AVStream index int next_chunk; + MOVIndexEntry * mov_index_entries; + int nb_mov_index_entries; + unsigned int mov_index_allocated_size; unsigned int chunk_count; int64_t *chunk_offsets; unsigned int stts_count; @@ -166,6 +174,8 @@ typedef struct MOVStreamContext { int keyframe_absent; unsigned int keyframe_count; int *keyframes; + unsigned int frame_deps_count; + int *frame_deps; int time_scale; int64_t time_offset; ///< time offset of the edit list entries int current_sample; diff --git a/libavformat/mov.c b/libavformat/mov.c index 5c9f926bce..b064708ced 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -2680,6 +2680,43 @@ static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; } +static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom) +{ + AVStream *st; + MOVStreamContext *sc; + unsigned int i, entries; + + if (c->fc->nb_streams < 1) + return 0; + st = c->fc->streams[c->fc->nb_streams-1]; + sc = st->priv_data; + + if (atom.size < 8) + return 0; + + avio_r8(pb); /* version */ + avio_rb24(pb); /* flags */ + + entries = atom.size - 4; + sc->frame_deps_count = 0; + sc->frame_deps = av_malloc_array(entries, sizeof(*sc->frame_deps)); + + if (!sc->frame_deps) + return AVERROR(ENOMEM); + + for (i = 0; i < entries && !pb->eof_reached; i++) { + sc->frame_deps[i] = avio_r8(pb); + } + + sc->frame_deps_count = i; + + if (pb->eof_reached) + return AVERROR_EOF; + + + return 0; +} + static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; @@ -3635,15 +3672,40 @@ static void mov_build_index(MOVContext *mov, AVStream *st) if (!sc->sample_count || st->nb_index_entries) return; - if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries) + if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries)) return; - if (av_reallocp_array(&st->index_entries, - st->nb_index_entries + sc->sample_count, + if (av_reallocp_array(&st->index_entries, sc->sample_count, sizeof(*st->index_entries)) < 0) { st->nb_index_entries = 0; return; } - st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries); + st->index_entries_allocated_size = sc->sample_count * + sizeof(*st->index_entries); + + // realloc mov_index_entries if needed for frame dependencies + // or if it already exists for ctts + if (sc->frame_deps || sc->mov_index_entries) { + // make mov_index_entries the same number of entries as + // index_entries + if (av_reallocp_array(&sc->mov_index_entries, + sc->sample_count, + sizeof(*sc->mov_index_entries)) < 0) { + sc->nb_mov_index_entries = 0; + return; + } + sc->mov_index_allocated_size = sc->sample_count * + sizeof(*sc->mov_index_entries); + + if (sc->sample_count > sc->nb_mov_index_entries) + // In case there were samples without ctts entries, ensure they + // get zero valued entries. This ensures clips which mix boxes + // with and without ctts entries don't pickup uninitialized + // data. + memset(sc->mov_index_entries + sc->nb_mov_index_entries, 0, + (sc->sample_count - sc->nb_mov_index_entries) * + sizeof(*sc->mov_index_entries)); + sc->nb_mov_index_entries = sc->sample_count; + } for (i = 0; i < sc->chunk_count; i++) { int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX; @@ -3664,10 +3726,14 @@ static void mov_build_index(MOVContext *mov, AVStream *st) for (j = 0; j < sc->stsc_data[stsc_index].count; j++) { int keyframe = 0; + int disposable = 0; if (current_sample >= sc->sample_count) { av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n"); return; } + if (sc->frame_deps && current_sample < sc->frame_deps_count) + disposable = ((sc->frame_deps[current_sample] >> 2) & 3) == + MOV_SAMPLE_DEPENDENCY_NO; if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) { keyframe = 1; @@ -3697,16 +3763,22 @@ static void mov_build_index(MOVContext *mov, AVStream *st) if (sc->pseudo_stream_id == -1 || sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) { AVIndexEntry *e; + MOVIndexEntry *me; if (sample_size > 0x3FFFFFFF) { av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size); return; } - e = &st->index_entries[st->nb_index_entries++]; + e = &st->index_entries[st->nb_index_entries]; e->pos = current_offset; e->timestamp = current_dts; e->size = sample_size; e->min_distance = distance; e->flags = keyframe ? AVINDEX_KEYFRAME : 0; + if (sc->mov_index_entries) { + me = &sc->mov_index_entries[st->nb_index_entries]; + me->flags = disposable ? MOVINDEX_DISPOSABLE : 0; + } + st->nb_index_entries++; av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", " "size %u, distance %u, keyframe %d\n", st->index, current_sample, current_offset, current_dts, sample_size, distance, keyframe); @@ -4073,6 +4145,7 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_freep(&sc->chunk_offsets); av_freep(&sc->sample_sizes); av_freep(&sc->keyframes); + av_freep(&sc->frame_deps); av_freep(&sc->stts_data); av_freep(&sc->stps_data); av_freep(&sc->elst_data); @@ -5878,6 +5951,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { { MKTAG('s','t','s','c'), mov_read_stsc }, { MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */ { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */ +{ MKTAG('s','d','t','p'), mov_read_sdtp }, /* sample dependencies */ { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */ { MKTAG('s','t','t','s'), mov_read_stts }, { MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */ @@ -6308,6 +6382,7 @@ static int mov_read_close(AVFormatContext *s) continue; av_freep(&sc->ctts_data); + av_freep(&sc->mov_index_entries); for (j = 0; j < sc->drefs_count; j++) { av_freep(&sc->drefs[j].path); av_freep(&sc->drefs[j].dir); @@ -6324,6 +6399,7 @@ static int mov_read_close(AVFormatContext *s) av_freep(&sc->stsc_data); av_freep(&sc->sample_sizes); av_freep(&sc->keyframes); + av_freep(&sc->frame_deps); av_freep(&sc->stts_data); av_freep(&sc->stps_data); av_freep(&sc->elst_data); @@ -6810,6 +6886,7 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) MOVContext *mov = s->priv_data; MOVStreamContext *sc; AVIndexEntry *sample; + MOVIndexEntry *movsample = NULL; AVStream *st = NULL; int64_t current_index; int ret; @@ -6824,6 +6901,8 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) goto retry; } sc = st->priv_data; + if (sc->current_sample < sc->nb_mov_index_entries) + movsample = &sc->mov_index_entries[sc->current_sample]; /* must be done just before reading, to avoid infinite loop on sample */ current_index = sc->current_index; mov_current_sample_inc(sc); @@ -6906,6 +6985,9 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) if (st->discard == AVDISCARD_ALL) goto retry; pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0; + if (movsample) + pkt->flags |= movsample->flags & MOVINDEX_DISPOSABLE ? + AV_PKT_FLAG_DISPOSABLE : 0; pkt->pos = sample->pos; /* Multiple stsd handling. */ diff --git a/libavformat/utils.c b/libavformat/utils.c index ff5e14df6c..a1aa8ac6a7 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -1458,7 +1458,8 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index) out_pkt.pts = st->parser->pts; out_pkt.dts = st->parser->dts; out_pkt.pos = st->parser->pos; - out_pkt.flags |= pkt->flags & AV_PKT_FLAG_DISCARD; + out_pkt.flags |= pkt->flags & (AV_PKT_FLAG_DISCARD | + AV_PKT_FLAG_DISPOSABLE); if (st->need_parsing == AVSTREAM_PARSE_FULL_RAW) out_pkt.pos = st->parser->frame_offset;