From patchwork Mon Apr 15 21:17:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 12757 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 20BD84492F7 for ; Tue, 16 Apr 2019 00:17:56 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 009C8689C61; Tue, 16 Apr 2019 00:17:55 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-qt1-f174.google.com (mail-qt1-f174.google.com [209.85.160.174]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id B2C63689C61 for ; Tue, 16 Apr 2019 00:17:48 +0300 (EEST) Received: by mail-qt1-f174.google.com with SMTP id v32so20906376qtc.10 for ; Mon, 15 Apr 2019 14:17:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=gTw0qBhTlwjWjcfv1I/IJFUv4chzFJk5LQg9nlcPUlE=; b=lrcVT+NRcUZ/1WPydjd6pW4CzhOmOk/ZE/U+MioEsOn5fa3hrYN9bAI/+KqAwymo0i T8inTbQgRJNpJbRST2eZIpaYtxA0aBf1K56sCV4AXBPH8ejHX3b83JOhTi8khU/8hb7w N7M8ARAwaLCWS1kZgcyPyUGM37+6NPpW6NPPizFDcQ/gmPHfU/GmYiPz4/kuP5+LbXab ovZjjOyyubekDaMEOHxYE8FFFCMYfGFAf2QSdNh7rAlhk8ZPq87h+tIefGjP05W0GHmQ or6SY8+5LQkgaczIIRjsqKYj77O2jwqq2PMxGmHAfTdJaK9oSGcU6tb4b2BKwcqOMNuU 8FVw== 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:mime-version :content-transfer-encoding; bh=gTw0qBhTlwjWjcfv1I/IJFUv4chzFJk5LQg9nlcPUlE=; b=JOTZ8oDUW5+DlChUfKQclvIfS3Du3jW8yUfqhS3GIsNkQ2kcehjSNLINzQaSHCQYXx FOcDCNxm5CG1bGtDJfWDzTmy1jNLuHpVfePfgJGe/q4Sbhi2F4JYRiwS6CEj80WczyfE lbypf/GxqAodl99XAoMM+bp7dTClg0Uy0OIuXVzmcPqtQ2JYfKIf1GgZGJZoSVECw3ff 2JGhF34zhPTCVSjzb2oiGWOLp+oVJLFN/9cJEwAgfRnpgyciMhhLnF//mK9YVynSw7sK 5bBUT/Hfg3txlG0euHFk/RFih4b0VhCo9J8JjJg7nzEwvXMr/6tjH/odzgPl+XmM6GNk sEcQ== X-Gm-Message-State: APjAAAWc05MBz4mAzBuIUp+GLFDYvGi5jmoKVQpY0x0qpdZAK53yS4YY pyjlG4V4eu9a5ubEKOieaVGxXImS X-Google-Smtp-Source: APXvYqxhM/fU06A5nBT9ja2Ej0krZkjO8ihsq0/VY17ym+b9L6bmgmiTKt4aoyfNGSO0+LfatgVQTw== X-Received: by 2002:aed:3a44:: with SMTP id n62mr17816126qte.147.1555363067272; Mon, 15 Apr 2019 14:17:47 -0700 (PDT) Received: from localhost.localdomain ([181.23.87.223]) by smtp.gmail.com with ESMTPSA id g12sm28478315qkk.85.2019.04.15.14.17.46 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 15 Apr 2019 14:17:46 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Mon, 15 Apr 2019 18:17:30 -0300 Message-Id: <20190415211734.3968-1-jamrial@gmail.com> X-Mailer: git-send-email 2.21.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/5] avcodec/cbs: add helper functions and macros to read and write signed values 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" Signed-off-by: James Almer --- libavcodec/cbs.c | 79 +++++++++++++++++++++++++++++++++++++++ libavcodec/cbs_internal.h | 20 +++++++++- 2 files changed, 98 insertions(+), 1 deletion(-) diff --git a/libavcodec/cbs.c b/libavcodec/cbs.c index c388be896b..726bd582f5 100644 --- a/libavcodec/cbs.c +++ b/libavcodec/cbs.c @@ -504,6 +504,85 @@ int ff_cbs_write_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc, return 0; } +int ff_cbs_read_signed(CodedBitstreamContext *ctx, GetBitContext *gbc, + int width, const char *name, + const int *subscripts, int32_t *write_to, + int32_t range_min, int32_t range_max) +{ + int32_t value; + int position; + + av_assert0(width > 0 && width <= 32); + + if (get_bits_left(gbc) < width) { + av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid value at " + "%s: bitstream ended.\n", name); + return AVERROR_INVALIDDATA; + } + + if (ctx->trace_enable) + position = get_bits_count(gbc); + + value = get_sbits_long(gbc, width); + + if (ctx->trace_enable) { + char bits[33]; + int i; + for (i = 0; i < width; i++) + bits[i] = value & (1 << (width - i - 1)) ? '1' : '0'; + bits[i] = 0; + + ff_cbs_trace_syntax_element(ctx, position, name, subscripts, + bits, value); + } + + if (value < range_min || value > range_max) { + av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " + "%"PRId32", but must be in [%"PRId32",%"PRId32"].\n", + name, value, range_min, range_max); + return AVERROR_INVALIDDATA; + } + + *write_to = value; + return 0; +} + +int ff_cbs_write_signed(CodedBitstreamContext *ctx, PutBitContext *pbc, + int width, const char *name, + const int *subscripts, int32_t value, + int32_t range_min, int32_t range_max) +{ + av_assert0(width > 0 && width <= 32); + + if (value < range_min || value > range_max) { + av_log(ctx->log_ctx, AV_LOG_ERROR, "%s out of range: " + "%"PRId32", but must be in [%"PRId32",%"PRId32"].\n", + name, value, range_min, range_max); + return AVERROR_INVALIDDATA; + } + + if (put_bits_left(pbc) < width) + return AVERROR(ENOSPC); + + if (ctx->trace_enable) { + char bits[33]; + int i; + for (i = 0; i < width; i++) + bits[i] = value & (1 << (width - i - 1)) ? '1' : '0'; + bits[i] = 0; + + ff_cbs_trace_syntax_element(ctx, put_bits_count(pbc), + name, subscripts, bits, value); + } + + if (width < 32) + put_sbits(pbc, width, value); + else + put_bits32(pbc, value); + + return 0; +} + int ff_cbs_alloc_unit_content(CodedBitstreamContext *ctx, CodedBitstreamUnit *unit, diff --git a/libavcodec/cbs_internal.h b/libavcodec/cbs_internal.h index 53f2e5d187..6ab85679dd 100644 --- a/libavcodec/cbs_internal.h +++ b/libavcodec/cbs_internal.h @@ -81,10 +81,28 @@ int ff_cbs_write_unsigned(CodedBitstreamContext *ctx, PutBitContext *pbc, const int *subscripts, uint32_t value, uint32_t range_min, uint32_t range_max); -// The largest value representable in N bits, suitable for use as +int ff_cbs_read_signed(CodedBitstreamContext *ctx, GetBitContext *gbc, + int width, const char *name, + const int *subscripts, int32_t *write_to, + int32_t range_min, int32_t range_max); + +int ff_cbs_write_signed(CodedBitstreamContext *ctx, PutBitContext *pbc, + int width, const char *name, + const int *subscripts, int32_t value, + int32_t range_min, int32_t range_max); + +// The largest unsigned value representable in N bits, suitable for use as // range_max in the above functions. #define MAX_UINT_BITS(length) ((UINT64_C(1) << (length)) - 1) +// The largest signed value representable in N bits, suitable for use as +// range_max in the above functions. +#define MAX_INT_BITS(length) ((INT64_C(1) << (length - 1)) - 1) + +// The smallest signed value representable in N bits, suitable for use as +// range_min in the above functions. +#define MIN_INT_BITS(length) (-(INT64_C(1) << (length - 1))) + extern const CodedBitstreamType ff_cbs_type_av1; extern const CodedBitstreamType ff_cbs_type_h264;