From patchwork Sun Jun 10 10:36:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marton Balint X-Patchwork-Id: 9345 Delivered-To: ffmpegpatchwork@gmail.com Received: by 2002:a02:11c:0:0:0:0:0 with SMTP id c28-v6csp2902605jad; Sun, 10 Jun 2018 03:37:33 -0700 (PDT) X-Google-Smtp-Source: ADUXVKKb9YcEsHoBrwjzFK7mqu4cWF1tbGvSCDClXeZLBmGJW/SqbEYduKPU293aPwEXRmyoHOFL X-Received: by 2002:a1c:da4e:: with SMTP id r75-v6mr5517412wmg.64.1528627053353; Sun, 10 Jun 2018 03:37:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1528627053; cv=none; d=google.com; s=arc-20160816; b=y6lE70ab1eq0a9FORH6wv42Kx/i6yp60IHdK2BKCxx7liXYPV3Qo6CUPqzcbbGrqQv XkRhUD0f1wirJ/eOMpNDZ06QJUu27PsGNnOoy0NJhsgUXt1NWBgEXUW9dsHUJRFU+ioC azuBeV8m/kSVrcazqknYYRsuc0ImZBbcRjritA7EJD6PnE2bqz7GsWPIVO/As/irWKOC Gll1BXen063XdsDVaXgDxhW/l15xAGEGPjGT3eFLg8ecqhJW4O7+EJDFzNObifvPnt8R XbYdi5Uf6BsfuayWSPocFRpQi2UbmofB0YnZ6Azlf4I/xkXAiUe4gJb7e28AUQnqHGrd rugw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:delivered-to:arc-authentication-results; bh=zmhfAtfj5TEKRAwNNE5ZQbGoPmi0qKeSoxVgJiXfzGE=; b=r8tVxtWa0g1B/JPm+iSXmBtNB++UcGTxwk/2I8KcO8lAphsXzdcuUncJ1AX0t+w8ns uhmoPzqbtb2sL+J/jrQfkk5lWhyxlbPMJCl9HBULevaw69g10KSepySn34AyDf79CoQW o+epY5QIFy7+86CdYixdhIKVUGzxdohmkjbeQRjMD/yy5lpRN600eRZlGsK69muja3uK Rgl5cxI4zHNaJ2saKsOkuDOzgyUyp1XRMV2ijdSweBEKx6QhNVfttu4Ujfp7yozg9Vob TLoJtAK+xmxtK1c/y8ia1pvxca8utzvOkQn2s6fMdQBdbYL/xR5E39OHwt44Tpe5OMYX xMcg== 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 v8-v6si32307680wrm.205.2018.06.10.03.37.33; Sun, 10 Jun 2018 03:37:33 -0700 (PDT) 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 A031D68AB76; Sun, 10 Jun 2018 13:36:19 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from iq.passwd.hu (iq.passwd.hu [217.27.212.140]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 9BE3968AAEE for ; Sun, 10 Jun 2018 13:36:13 +0300 (EEST) Received: from localhost (localhost [127.0.0.1]) by iq.passwd.hu (Postfix) with ESMTP id 5142DE1055; Sun, 10 Jun 2018 12:37:02 +0200 (CEST) X-Virus-Scanned: amavisd-new at passwd.hu Received: from iq.passwd.hu ([127.0.0.1]) by localhost (iq.passwd.hu [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id cmkbs3u3X39X; Sun, 10 Jun 2018 12:37:01 +0200 (CEST) Received: from bluegene.passwd.hu (localhost [127.0.0.1]) by iq.passwd.hu (Postfix) with ESMTP id 4038EE102D; Sun, 10 Jun 2018 12:37:01 +0200 (CEST) From: Marton Balint To: ffmpeg-devel@ffmpeg.org Date: Sun, 10 Jun 2018 12:36:42 +0200 Message-Id: <20180610103650.10155-4-cus@passwd.hu> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20180610103650.10155-1-cus@passwd.hu> References: <20180610103650.10155-1-cus@passwd.hu> Subject: [FFmpeg-devel] [PATCH 04/12] avformat/mxfdec: compute both essence_offset and essence_length in mxf_compute_essence_containers 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 Cc: Marton Balint MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Also compute the correct essence_offset and essence_length for all clip wrapped essences. Signed-off-by: Marton Balint --- libavformat/mxfdec.c | 108 +++++++++++++++++++++++++++------------------------ 1 file changed, 57 insertions(+), 51 deletions(-) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 1ab34f4873..67b0028e88 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -98,6 +98,7 @@ typedef struct MXFPartition { int pack_length; int64_t pack_ofs; ///< absolute offset of pack in file, including run-in int64_t body_offset; + KLVPacket first_essence_klv; } MXFPartition; typedef struct MXFCryptoContext { @@ -2782,47 +2783,76 @@ static int mxf_parse_handle_partition_or_eof(MXFContext *mxf) return mxf->parsing_backward ? mxf_seek_to_previous_partition(mxf) : 1; } +static int64_t round_to_kag(int64_t position, int kag_size) +{ + /* TODO: account for run-in? the spec isn't clear whether KAG should account for it */ + /* NOTE: kag_size may be any integer between 1 - 2^10 */ + int64_t ret = (position / kag_size) * kag_size; + return ret == position ? ret : ret + kag_size; +} + +static MXFWrappingScheme mxf_get_wrapping_by_body_sid(AVFormatContext *s, int body_sid) +{ + for (int i = 0; i < s->nb_streams; i++) { + MXFTrack *track = s->streams[i]->priv_data; + if (track && track->body_sid == body_sid && track->wrapping != UnknownWrapped) + return track->wrapping; + } + return UnknownWrapped; +} + /** * Figures out the proper offset and length of the essence container in each partition */ -static void mxf_compute_essence_containers(MXFContext *mxf) +static void mxf_compute_essence_containers(AVFormatContext *s) { + MXFContext *mxf = s->priv_data; int x; - /* everything is already correct */ - if (mxf->op == OPAtom) - return; - for (x = 0; x < mxf->partitions_count; x++) { MXFPartition *p = &mxf->partitions[x]; + MXFWrappingScheme wrapping; if (!p->body_sid) continue; /* BodySID == 0 -> no essence */ - if (x >= mxf->partitions_count - 1) - break; /* FooterPartition - can't compute length (and we don't need to) */ + /* for non clip-wrapped essences we compute essence_offset + * for clip wrapped essences we point essence_offset after the KL (usually klv.offset + 20 or 25) + */ - /* essence container spans to the next partition */ - p->essence_length = mxf->partitions[x+1].this_partition - p->essence_offset; + wrapping = (mxf->op == OPAtom) ? ClipWrapped : mxf_get_wrapping_by_body_sid(s, p->body_sid); - if (p->essence_length < 0) { - /* next ThisPartition < essence_offset */ - p->essence_length = 0; - av_log(mxf->fc, AV_LOG_ERROR, - "partition %i: bad ThisPartition = %"PRIX64"\n", - x+1, mxf->partitions[x+1].this_partition); + if (wrapping == ClipWrapped) { + p->essence_offset = p->first_essence_klv.next_klv - p->first_essence_klv.length; + p->essence_length = p->first_essence_klv.length; + } else { + int64_t op1a_essence_offset = + p->this_partition + + round_to_kag(p->pack_length, p->kag_size) + + round_to_kag(p->header_byte_count, p->kag_size) + + round_to_kag(p->index_byte_count, p->kag_size); + + /* NOTE: op1a_essence_offset may be less than to klv.offset (C0023S01.mxf) */ + if (IS_KLV_KEY(p->first_essence_klv.key, mxf_system_item_key_cp) || IS_KLV_KEY(p->first_essence_klv.key, mxf_system_item_key_gc)) + p->essence_offset = p->first_essence_klv.offset; + else + p->essence_offset = op1a_essence_offset; + + /* essence container spans to the next partition */ + if (x < mxf->partitions_count - 1) + p->essence_length = mxf->partitions[x+1].this_partition - p->essence_offset; + + if (p->essence_length < 0) { + /* next ThisPartition < essence_offset */ + p->essence_length = 0; + av_log(mxf->fc, AV_LOG_ERROR, + "partition %i: bad ThisPartition = %"PRIX64"\n", + x+1, mxf->partitions[x+1].this_partition); + } } } } -static int64_t round_to_kag(int64_t position, int kag_size) -{ - /* TODO: account for run-in? the spec isn't clear whether KAG should account for it */ - /* NOTE: kag_size may be any integer between 1 - 2^10 */ - int64_t ret = (position / kag_size) * kag_size; - return ret == position ? ret : ret + kag_size; -} - static int is_pcm(enum AVCodecID codec_id) { /* we only care about "normal" PCM codecs until we get samples */ @@ -3034,32 +3064,8 @@ static int mxf_read_header(AVFormatContext *s) return AVERROR_INVALIDDATA; } - if (!mxf->current_partition->essence_offset) { - /* for OP1a we compute essence_offset - * for OPAtom we point essence_offset after the KL (usually op1a_essence_offset + 20 or 25) - * TODO: for OP1a we could eliminate this entire if statement, always stopping parsing at op1a_essence_offset - * for OPAtom we still need the actual essence_offset though (the KL's length can vary) - */ - int64_t op1a_essence_offset = - mxf->current_partition->this_partition + - round_to_kag(mxf->current_partition->pack_length, mxf->current_partition->kag_size) + - round_to_kag(mxf->current_partition->header_byte_count, mxf->current_partition->kag_size) + - round_to_kag(mxf->current_partition->index_byte_count, mxf->current_partition->kag_size); - - if (mxf->op == OPAtom) { - /* point essence_offset to the actual data - * OPAtom has all the essence in one big KLV - */ - mxf->current_partition->essence_offset = avio_tell(s->pb); - mxf->current_partition->essence_length = klv.length; - } else { - /* NOTE: op1a_essence_offset may be less than to klv.offset (C0023S01.mxf) */ - if (IS_KLV_KEY(klv.key, mxf_system_item_key_cp) || IS_KLV_KEY(klv.key, mxf_system_item_key_gc)) - mxf->current_partition->essence_offset = klv.offset; - else - mxf->current_partition->essence_offset = op1a_essence_offset; - } - } + if (!mxf->current_partition->first_essence_klv.offset) + mxf->current_partition->first_essence_klv = klv; if (!essence_offset) essence_offset = klv.offset; @@ -3098,8 +3104,6 @@ static int mxf_read_header(AVFormatContext *s) } avio_seek(s->pb, essence_offset, SEEK_SET); - mxf_compute_essence_containers(mxf); - /* we need to do this before computing the index tables * to be able to fill in zero IndexDurations with st->duration */ if ((ret = mxf_parse_structural_metadata(mxf)) < 0) @@ -3121,6 +3125,8 @@ static int mxf_read_header(AVFormatContext *s) goto fail; } + mxf_compute_essence_containers(s); + mxf_handle_small_eubc(s); return 0;