From patchwork Sun May 3 22:05:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 19485 Delivered-To: andriy.gelman@gmail.com Received: by 2002:a25:3c87:0:0:0:0:0 with SMTP id j129csp3060562yba; Sun, 3 May 2020 15:06:21 -0700 (PDT) X-Google-Smtp-Source: APiQypIjmiSUUog972aGh8+PAwju0S0cwVjvZznRBziDjHvnjLYU2C9y2pI0VuY+UEFoYeBF8xR8 X-Received: by 2002:a5d:6a4e:: with SMTP id t14mr2362806wrw.353.1588543581746; Sun, 03 May 2020 15:06:21 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1588543581; cv=none; d=google.com; s=arc-20160816; b=h/Y3yxzz2Ow9+VmFrFudbkzXdcwLFR3ovxd6z9AQXuhHwArAP3A/tu+34k0UGr4dQ3 NO6m9UZRen7o+T4RN6uVBgU71roT+5yZkASVCztY1utpMO0UhFDWs2zPXIqp+e5V0lK2 Irk9UBmqY6yX72m61m5ptEyqJOvR+eUUw4JLn7mxsOzXMejHyTL1VzSP7Lnulmr6j44U /XE87Hcc+XkydnJWJ1sTxWDIv5mt5BmCAeNN+2GtjiWM8tFupvZXG6dWvPAvWIBmws+g DdbsICAbEfnoyGgxLkNnFjDZ7jLI5RXVv/jxUmIP/1TB64y7JQYdJPGFcjfnEm8DM7lb SdLA== 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=blx7s3p9xNsVaTnvQe0esrhbmOFwhuinGt8FX31+0q8=; b=skKJbtI6y+4MoTx1Tf4NX1IWjCG1UtMtLEAlMBGYLB0WoPjJqPx9T7wqiN19YnycBe DoDWeVHSs8WqcYWv9xOrVREn46gl3FhdcXmCN3EG4xVMFH/G2DOfbRfqZd++vIBYLYqy KVrr+29psmNS7dDo2Vzqr3p/oJ9Wh80TLac1sAALXVvedrX4M4K/znfFMBKIU1zpGUpj 2mKvTxU9a7KagDpwQR0KGhJckm5hh4tPGeircae92YbAR/1W+bGjGXWEPovByT6UTf/m gNZZVbvUvPUZhTWYyrrpqhJjGYeu4g0cI1zBFUBChgXHNZ0Z+lA1/Y5du89pWwfndKb5 GDvw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@jkqxz-net.20150623.gappssmtp.com header.s=20150623 header.b=RsEgPXa9; 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 g10si9755654wrb.99.2020.05.03.15.06.21; Sun, 03 May 2020 15:06:21 -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; dkim=neutral (body hash did not verify) header.i=@jkqxz-net.20150623.gappssmtp.com header.s=20150623 header.b=RsEgPXa9; 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 1AC0D68C099; Mon, 4 May 2020 01:06:02 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f67.google.com (mail-wm1-f67.google.com [209.85.128.67]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 015CF68BECC for ; Mon, 4 May 2020 01:05:54 +0300 (EEST) Received: by mail-wm1-f67.google.com with SMTP id h4so6225260wmb.4 for ; Sun, 03 May 2020 15:05:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=pVYvLDSOR14rXDzwVYS1gJuTRadWAbcfQSkZdRObVJY=; b=RsEgPXa93XphB534z7iMHwEIArg/KFaMGfs2VtxIxYEGHMhTCKIWEHIneKyLYqSkVA dfvnzwBhsU3EUfVPimUsSizH/FNfpIWJfmLhbRMdDyDJ0FiP8J2Kb41rkkUwGKpvN9zJ ucXKnGY75sEHH0nAOXopJiwlC2ZyX9HAz6ovuuv6AhUH3JieOedMuuH8y8wq4Xx5JK5H 3fETxZiutDI/m5KV9xaKu7Lg6k3gmGPMFRyYW8LOZlZiLc3DP1mWujXyAMLtLg8YbKn1 AHSc6qI/Y2I9qb9kjYUfRCkF2DqbyPK20jtkpt0YcJ+JqcQDocdrfg9lpJarONgrzhbw U6RQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=pVYvLDSOR14rXDzwVYS1gJuTRadWAbcfQSkZdRObVJY=; b=n60Mi9T6R8tbMrWuZC82J5v9zpjLssb5K9Skl7xnmPATGrIPqndcNA6LJE1cX8IcZk 6wQAiOqjvLs7EzczWLtE2gjJWUWd6aO9pCrryas/DFazQoi7bmBIBUvywUtG3LL0K0FR VLMeo2MsxiGdAr3xY9lESn5ksTyBy1uhXv4IqJL1Puwzo1NsPoCLjycKGFJKUDMkKFOO 7DzDXAhvGA5ziZFflzyla/gIuApAj7EsUTDqmZc5D/jeMcLwc3S2/tQO7EOrr5PPnASy BYAGVH5TtPOSe4CeKRODMs2PScnkHVpIA9MzBZ0THKcY6LgkiEz4EKe+3CvMBx41t4xn lYRg== X-Gm-Message-State: AGi0PuakgPlLIcAzuzXjaCFokCAOz7CugrRNF17a8CCuy3Qs9TvXHz0+ o3CVUW/YMvFSCZltnmy0x6RckpWhLLE= X-Received: by 2002:a1c:5448:: with SMTP id p8mr10778211wmi.173.1588543553943; Sun, 03 May 2020 15:05:53 -0700 (PDT) Received: from rywe.jkqxz.net (cpc91242-cmbg18-2-0-cust650.5-4.cable.virginm.net. [82.8.130.139]) by smtp.gmail.com with ESMTPSA id a24sm10307285wmb.24.2020.05.03.15.05.53 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 03 May 2020 15:05:53 -0700 (PDT) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Sun, 3 May 2020 23:05:29 +0100 Message-Id: <20200503220548.23543-3-sw@jkqxz.net> X-Mailer: git-send-email 2.26.2 In-Reply-To: <20200503220548.23543-1-sw@jkqxz.net> References: <20200503220548.23543-1-sw@jkqxz.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v5 03/22] cbs: Describe allocate/free methods in tabular form 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" X-TUID: 5sx8JAk8Q+DF Content-Length: 9832 Unit types are split into three categories, depending on how their content is managed: * POD structure - these require no special treatment. * Structure containing references to refcounted buffers - these can use a common free function when the offsets of all the internal references are known. * More complex structures - these still require ad-hoc treatment. For each codec we can then maintain a table of descriptors for each set of equivalent unit types, defining the mechanism needed to allocate/free that unit content. This is not required to be used immediately - a new alloc function supports this, but does not replace the old one which works without referring to these tables. --- libavcodec/cbs.c | 69 +++++++++++++++++++++++++++++++++++++++ libavcodec/cbs.h | 9 +++++ libavcodec/cbs_internal.h | 61 ++++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+) diff --git a/libavcodec/cbs.c b/libavcodec/cbs.c index 0bd5e1ac5d..6cc559e545 100644 --- a/libavcodec/cbs.c +++ b/libavcodec/cbs.c @@ -812,3 +812,72 @@ void ff_cbs_delete_unit(CodedBitstreamContext *ctx, frag->units + position + 1, (frag->nb_units - position) * sizeof(*frag->units)); } + +static void cbs_default_free_unit_content(void *opaque, uint8_t *data) +{ + const CodedBitstreamUnitTypeDescriptor *desc = opaque; + if (desc->content_type == CBS_CONTENT_TYPE_INTERNAL_REFS) { + int i; + for (i = 0; i < desc->nb_ref_offsets; i++) { + void **ptr = (void**)(data + desc->ref_offsets[i]); + av_buffer_unref((AVBufferRef**)(ptr + 1)); + } + } + av_free(data); +} + +static const CodedBitstreamUnitTypeDescriptor + *cbs_find_unit_type_desc(CodedBitstreamContext *ctx, + CodedBitstreamUnit *unit) +{ + const CodedBitstreamUnitTypeDescriptor *desc; + int i, j; + + if (!ctx->codec->unit_types) + return NULL; + + for (i = 0;; i++) { + desc = &ctx->codec->unit_types[i]; + if (desc->nb_unit_types == 0) + break; + if (desc->nb_unit_types == CBS_UNIT_TYPE_RANGE) { + if (unit->type >= desc->unit_type_range_start && + unit->type <= desc->unit_type_range_end) + return desc; + } else { + for (j = 0; j < desc->nb_unit_types; j++) { + if (desc->unit_types[j] == unit->type) + return desc; + } + } + } + return NULL; +} + +int ff_cbs_alloc_unit_content2(CodedBitstreamContext *ctx, + CodedBitstreamUnit *unit) +{ + const CodedBitstreamUnitTypeDescriptor *desc; + + av_assert0(!unit->content && !unit->content_ref); + + desc = cbs_find_unit_type_desc(ctx, unit); + if (!desc) + return AVERROR(ENOSYS); + + unit->content = av_mallocz(desc->content_size); + if (!unit->content) + return AVERROR(ENOMEM); + + unit->content_ref = + av_buffer_create(unit->content, desc->content_size, + desc->content_free ? desc->content_free + : cbs_default_free_unit_content, + (void*)desc, 0); + if (!unit->content_ref) { + av_freep(&unit->content); + return AVERROR(ENOMEM); + } + + return 0; +} diff --git a/libavcodec/cbs.h b/libavcodec/cbs.h index cb3081e2c6..2a5959a2b0 100644 --- a/libavcodec/cbs.h +++ b/libavcodec/cbs.h @@ -352,6 +352,15 @@ int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx, size_t size, void (*free)(void *opaque, uint8_t *content)); +/** + * Allocate a new internal content buffer matching the type of the unit. + * + * The content will be zeroed. + */ +int ff_cbs_alloc_unit_content2(CodedBitstreamContext *ctx, + CodedBitstreamUnit *unit); + + /** * Allocate a new internal data buffer of the given size in the unit. * diff --git a/libavcodec/cbs_internal.h b/libavcodec/cbs_internal.h index 4c5a535ca6..282492bc88 100644 --- a/libavcodec/cbs_internal.h +++ b/libavcodec/cbs_internal.h @@ -25,11 +25,72 @@ #include "put_bits.h" +enum CBSContentType { + // Unit content is a simple structure. + CBS_CONTENT_TYPE_POD, + // Unit content contains some references to other structures, but all + // managed via buffer reference counting. The descriptor defines the + // structure offsets of every buffer reference. + CBS_CONTENT_TYPE_INTERNAL_REFS, + // Unit content is something more complex. The descriptor defines + // special functions to manage the content. + CBS_CONTENT_TYPE_COMPLEX, +}; + +enum { + // Maximum number of unit types described by the same unit type + // descriptor. + CBS_MAX_UNIT_TYPES = 3, + // Maximum number of reference buffer offsets in any one unit. + CBS_MAX_REF_OFFSETS = 2, + // Special value used in a unit type descriptor to indicate that it + // applies to a large range of types rather than a set of discrete + // values. + CBS_UNIT_TYPE_RANGE = -1, +}; + +typedef const struct CodedBitstreamUnitTypeDescriptor { + // Number of entries in the unit_types array, or the special value + // CBS_UNIT_TYPE_RANGE to indicate that the range fields should be + // used instead. + int nb_unit_types; + + // Array of unit types that this entry describes. + const CodedBitstreamUnitType unit_types[CBS_MAX_UNIT_TYPES]; + + // Start and end of unit type range, used if nb_unit_types is + // CBS_UNIT_TYPE_RANGE. + const CodedBitstreamUnitType unit_type_range_start; + const CodedBitstreamUnitType unit_type_range_end; + + // The type of content described. + enum CBSContentType content_type; + // The size of the structure which should be allocated to contain + // the decomposed content of this type of unit. + size_t content_size; + + // Number of entries in the ref_offsets array. Only used if the + // content_type is CBS_CONTENT_TYPE_INTERNAL_REFS. + int nb_ref_offsets; + // The structure must contain two adjacent elements: + // type *field; + // AVBufferRef *field_ref; + // where field points to something in the buffer referred to by + // field_ref. This offset is then set to offsetof(struct, field). + size_t ref_offsets[CBS_MAX_REF_OFFSETS]; + + void (*content_free)(void *opaque, uint8_t *data); +} CodedBitstreamUnitTypeDescriptor; + typedef struct CodedBitstreamType { enum AVCodecID codec_id; size_t priv_data_size; + // List of unit type descriptors for this codec. + // Terminated by a descriptor with nb_unit_types equal to zero. + const CodedBitstreamUnitTypeDescriptor *unit_types; + // Split frag->data into coded bitstream units, creating the // frag->units array. Fill data but not content on each unit. // The header argument should be set if the fragment came from