From patchwork Fri Dec 1 00:25:01 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Stebbins X-Patchwork-Id: 6485 Delivered-To: ffmpegpatchwork@gmail.com Received: by 10.2.161.94 with SMTP id m30csp526868jah; Thu, 30 Nov 2017 16:25:21 -0800 (PST) X-Google-Smtp-Source: AGs4zMY58pH9DtzZ6JJz0L8Zks8XORzAROqZBSG2g6RIdgdiX1MCTFlLVmDydLwe1GSevp0xZOoj X-Received: by 10.28.36.194 with SMTP id k185mr3033180wmk.26.1512087921409; Thu, 30 Nov 2017 16:25:21 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1512087921; cv=none; d=google.com; s=arc-20160816; b=H/1tb34mYywfOeplMT5NEc2V3QmSTEDpb02Xv4D2bnAm3Bd53YvVo/VamqtvGH6YIn OSB12ggr9s7gFv5KgjC+OKwSszXUl4cqHy/uAwWG4hOsPJF31vyOLvMNmP8qSvTA3tDH C5iSr1MXSHuOc4QhesgUdA3PPOKz6PLzZhuOoAOL448wBREh+QPy6XBwu79WomkKAaev 1j/PZjLHrzxYqc/wn5e+U99kfK3JahjXUevvXrJYrWao3S+NPwlZQ0x2WdJi5Zgv+t8U tpnZxEMThoyfu2t9Kj3znlMlz0QXXmx+/2xU/KjMsTpGY4SHeV/qg67I4PVwr5EiOGi1 sNpA== 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=J+e0G6SlFy0hO0QbpSmFNv0OWKOaKuJNCgCRJDxh0w8=; b=iC7ovVzYpu+l06nLnxWh4cOV7/hpNctz0ixJyBxADUTvY4iZ47fNtSueaO7tS1LBmm m3f6kjd2EoJnJ6xtNzhNOSoAKdfydD98I9yfua+i4DBPyNsiwQimcgcVeO9t25EotdSH hnFLFOb5fMp1CgQ7G0ro5o/7jHDkxecYbnPeM9nfJjZkONA2Zfv3zGwqatpPL80UACgh ax/OlezHIb/C1FzLz8+Uhe+s/5UyZ5zvlAG5JnuPfzNUkHzonOIP6dxXBfUpLO4bjIsN EZKgGxV7DopUIt9WKoxjVlCIq047qAJ5B0dBSg8qM7atG7GfA9Viia2k591hWXedA5ko x4vw== 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 a131si3971437wme.217.2017.11.30.16.25.21; Thu, 30 Nov 2017 16:25:21 -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 DC4B9689D30; Fri, 1 Dec 2017 02:25:13 +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 B7D466807BF for ; Fri, 1 Dec 2017 02:25:07 +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; Thu, 30 Nov 2017 16:25:05 -0800 Received: from dionysus.jetheaddev.com (localhost [127.0.0.1]) by dionysus.jetheaddev.com (8.15.2/8.14.7) with ESMTP id vB10P5fo024496 for ; Thu, 30 Nov 2017 16:25:05 -0800 Received: (from jstebbins@localhost) by dionysus.jetheaddev.com (8.15.2/8.15.2/Submit) id vB10P5Rf024495 for ffmpeg-devel@ffmpeg.org; Thu, 30 Nov 2017 16:25:05 -0800 From: John Stebbins To: Date: Thu, 30 Nov 2017 16:25:01 -0800 Message-ID: <20171201002502.24432-2-jstebbins@jetheaddev.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20171201002502.24432-1-jstebbins@jetheaddev.com> References: <20171201002502.24432-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 f7fab98dd8..2bb81d8f01 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -2682,6 +2682,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; @@ -3638,15 +3675,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; + } if (ctts_data_old) { // Expand ctts entries such that we have a 1-1 mapping with samples @@ -3689,10 +3751,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; @@ -3722,16 +3788,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); @@ -4098,6 +4170,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); @@ -5975,6 +6048,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 */ @@ -6407,6 +6481,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); @@ -6423,6 +6498,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); @@ -6912,6 +6988,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; @@ -6926,6 +7003,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); @@ -7008,6 +7087,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 84e49208b8..816f963b5f 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;