From patchwork Fri Jan 27 12:18:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leo Izen X-Patchwork-Id: 40132 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:3ca3:b0:b9:1511:ac2c with SMTP id b35csp1298445pzj; Fri, 27 Jan 2023 04:18:25 -0800 (PST) X-Google-Smtp-Source: AMrXdXvG26a1+rryvZTi0AwqGlzo1X5y9HHLwlAyQMO6n4S7ujSSlW9CL1X/KppQPfIWTpq2Pjg7 X-Received: by 2002:a05:6402:298d:b0:49d:d4be:fc24 with SMTP id eq13-20020a056402298d00b0049dd4befc24mr46855690edb.11.1674821905286; Fri, 27 Jan 2023 04:18:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1674821905; cv=none; d=google.com; s=arc-20160816; b=I9sGv8KtNlo2q/kH9T/9gFQEvXpDpMTJcqJtUKc1Hal0k01s3frfqOExu9+aEqwc0O I3LSZ9AqGs9ie6r1wOHN/R6R2vjeWSZhg71/fklfKBch8gHqTJKdykGuitsRHgZdmSfN diSyA2Oostc6aH87NqxdmYD6u2VepbMNGK9ei697sbaY1cKjxDajcghNgMCAknYtXZAf j8hbWPNjwKSNY24Aljhe8gPnau/myYOkYF7nTXw4bMA0l1PaCLDH9AeDYVey19M5wjbH GajWOkJ8tPtrebj5ooz6/O2ruUEUu5hbf3+/8xRUaWFuqhG3UnPWGuWC5p97horbJjXo 6PSA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:message-id:date:to:from :dkim-signature:delivered-to; bh=sY33khdBCqII5xCS+v0p0g7gaysv//IhPdrQujLwRaM=; b=hpWMLGWFSY8iKWwBYyGz39fPIyAIVyt20TFiHLeOl0cMeY0cXuSZi93Bky6YlP9JTg S4x63zkO5bmVjWgeLOI7IV/qtvMnDvi/O923NsSPpPSZH0pWKFMgjOwXt/TG/7e473IW iHDcvAASTfNn+dTRR1R0FKeRGXfjAOIZF2vbFF5T4EcTXUlSM9wxk7HUlt6stJR9WJON ysx3v3JpzVGszsGFiJjjm0jgSGbbHCzxyVq51tXIkVuvXFIRMW3zutOIvWNKBxcLoBu5 R9cDPHQgx3bDJ76S7h4jDcMU3KjWWWCVs7bs1CpWGM9w+YV8Ioe+P/e747VD8bXRadMP 3Wng== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=LzkBbNyi; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id n24-20020aa7d058000000b004a0b5ac4118si4885714edo.597.2023.01.27.04.18.24; Fri, 27 Jan 2023 04:18:25 -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; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=LzkBbNyi; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id C961C68BC12; Fri, 27 Jan 2023 14:18:21 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-il1-f170.google.com (mail-il1-f170.google.com [209.85.166.170]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4A3ED68AE2B for ; Fri, 27 Jan 2023 14:18:15 +0200 (EET) Received: by mail-il1-f170.google.com with SMTP id i17so2194215ila.9 for ; Fri, 27 Jan 2023 04:18:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=iIVlMzd35Gq0eGF78KLesdMZvtGvmV7zKZN1cyUI8mw=; b=LzkBbNyiVfmRE+JSA3oSU0NrHq0JDbo0hiWOjZu5udDZ7itKOH8c68gEmn30qndI1p jRoq+HllWYPTq1TaLOMK5LbIpL6u79PSZNTNRaxpWUr0OoOMUw4bZnWraKR4+ygLS5t6 Zjrgp1ncpxERx5epj27sMws60joP5PVs+nzoIIKFYQCwhi2cR829sBu8nDwoZ1zPjH5U p8GnwdWm8FDrVV+ESGqRjs8MKReYTsdtcPbXs0UnFkechJaD9nG6kjI/ZOFsC+bpWRPE qNP8m9x2K9anClgoNGnyItG01U6hLLqha+ppZ4KR6s8jwjVLyHlo6lSkZIw4Pv1HqHxG Y4Bg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=iIVlMzd35Gq0eGF78KLesdMZvtGvmV7zKZN1cyUI8mw=; b=7nqIqHE3WX/J2egzhm3n4E9aZgZ7YpU6LNxQr8nMnahwRPZx5L1R8hSvZDWplbH6Ue DLAJ+FGOVN5whI7VG1surgFXMd3W79XPhZzO1WGO+dmccKbL3WJi+4S0TFoysGjo+VJu heU5uOq1NNtTafkhFz0T+cJhpOS2Lg4g0YT/DPDcrWkJNl4MQbszclpFQJA/mptBNhCT a/vL58aX0CU5HMjJiRlta5bXgBYNhb7eMhakjlRdlTM1CuOrW1VrJJ4HCCMsEYBvs/5q /qYS2JewyatA0WuNK2fdf07vIPWp7eEM5lZxOS7UpL83XBhQge0oyod7U+qpw3iHEw20 bNSA== X-Gm-Message-State: AO0yUKXYmewYRciP+T4pXGl4hjqpeuu8VentWUfV4QyIdSwHG6cok2Ct qciaQcmDoFyek/tpjOdmh7WtIb5ASNJk+Q== X-Received: by 2002:a05:6e02:b29:b0:30f:8a2d:87c7 with SMTP id e9-20020a056e020b2900b0030f8a2d87c7mr11841231ilu.2.1674821893631; Fri, 27 Jan 2023 04:18:13 -0800 (PST) Received: from gauss.local (c-68-41-54-207.hsd1.mi.comcast.net. [68.41.54.207]) by smtp.gmail.com with ESMTPSA id a130-20020a021688000000b00388660ca27dsm1457872jaa.4.2023.01.27.04.18.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 27 Jan 2023 04:18:13 -0800 (PST) From: Leo Izen To: ffmpeg-devel@ffmpeg.org Date: Fri, 27 Jan 2023 07:18:10 -0500 Message-Id: <20230127121810.349150-1-leo.izen@gmail.com> X-Mailer: git-send-email 2.39.1 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH] avcodec/libjxl: respect AVCodecContext->bits_per_raw_sample X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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: Leo Izen Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: ssGIaZe6qyj9 libjxl only accepts 16-bit buffers with its API, but it can accept 9-bit to 15-bit input via a 16-bit buffer, provided the flag is set declaring the buffer to be of the respective significant depth. Likewise, it can only provide pixel data on decode as a 16-bit buffer (if higher than 8) but does provide the metadata tagging the actual bit depth. This commit causes libjxlenc.c and libjxldec.c to respect this metadata and tag/read it accordingly from AVCodecContext->bits_per_raw_sample. Signed-off-by: Leo Izen --- libavcodec/libjxldec.c | 17 +++++++++++++---- libavcodec/libjxlenc.c | 10 +++++++++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/libavcodec/libjxldec.c b/libavcodec/libjxldec.c index c85cfa3d69..abe08eb400 100644 --- a/libavcodec/libjxldec.c +++ b/libavcodec/libjxldec.c @@ -47,6 +47,7 @@ typedef struct LibJxlDecodeContext { JxlDecoder *decoder; JxlBasicInfo basic_info; JxlPixelFormat jxl_pixfmt; + JxlBitDepth jxl_bit_depth; JxlDecoderStatus events; AVBufferRef *iccp; } LibJxlDecodeContext; @@ -93,10 +94,14 @@ static av_cold int libjxl_decode_init(AVCodecContext *avctx) return libjxl_init_jxl_decoder(avctx); } -static enum AVPixelFormat libjxl_get_pix_fmt(void *avctx, const JxlBasicInfo *basic_info, JxlPixelFormat *format) +static enum AVPixelFormat libjxl_get_pix_fmt(AVCodecContext *avctx, const JxlBasicInfo *basic_info, + JxlPixelFormat *format, JxlBitDepth *depth) { format->endianness = JXL_NATIVE_ENDIAN; format->num_channels = basic_info->num_color_channels + (basic_info->alpha_bits > 0); + depth->bits_per_sample = avctx->bits_per_raw_sample = basic_info->bits_per_sample; + depth->type = JXL_BIT_DEPTH_FROM_PIXEL_FORMAT; + depth->exponent_bits_per_sample = basic_info->exponent_bits_per_sample; /* Gray */ if (basic_info->num_color_channels == 1) { if (basic_info->bits_per_sample <= 8) { @@ -119,10 +124,10 @@ static enum AVPixelFormat libjxl_get_pix_fmt(void *avctx, const JxlBasicInfo *ba format->data_type = JXL_TYPE_UINT8; return basic_info->alpha_bits ? AV_PIX_FMT_RGBA : AV_PIX_FMT_RGB24; } - if (basic_info->bits_per_sample > 16) - av_log(avctx, AV_LOG_WARNING, "Downsampling larger integer to 16-bit via libjxl\n"); if (basic_info->exponent_bits_per_sample) av_log(avctx, AV_LOG_WARNING, "Downsampling float to 16-bit integer via libjxl\n"); + else if (basic_info->bits_per_sample > 16) + av_log(avctx, AV_LOG_WARNING, "Downsampling larger integer to 16-bit via libjxl\n"); format->data_type = JXL_TYPE_UINT16; return basic_info->alpha_bits ? AV_PIX_FMT_RGBA64 : AV_PIX_FMT_RGB48; } @@ -367,7 +372,7 @@ static int libjxl_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_f av_log(avctx, AV_LOG_ERROR, "Bad libjxl basic info event\n"); return AVERROR_EXTERNAL; } - avctx->pix_fmt = libjxl_get_pix_fmt(avctx, &ctx->basic_info, &ctx->jxl_pixfmt); + avctx->pix_fmt = libjxl_get_pix_fmt(avctx, &ctx->basic_info, &ctx->jxl_pixfmt, &ctx->jxl_bit_depth); if (avctx->pix_fmt == AV_PIX_FMT_NONE) { av_log(avctx, AV_LOG_ERROR, "Bad libjxl pixel format\n"); return AVERROR_EXTERNAL; @@ -390,6 +395,10 @@ static int libjxl_decode_frame(AVCodecContext *avctx, AVFrame *frame, int *got_f av_log(avctx, AV_LOG_ERROR, "Bad libjxl dec need image out buffer event\n"); return AVERROR_EXTERNAL; } + if (JxlDecoderSetImageOutBitDepth(ctx->decoder, &ctx->jxl_bit_depth) != JXL_DEC_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Error setting output bit depth\n"); + return AVERROR_EXTERNAL; + } continue; case JXL_DEC_FULL_IMAGE: /* full image is one frame, even if animated */ diff --git a/libavcodec/libjxlenc.c b/libavcodec/libjxlenc.c index 0793ed251b..b380e2ff96 100644 --- a/libavcodec/libjxlenc.c +++ b/libavcodec/libjxlenc.c @@ -250,6 +250,7 @@ static int libjxl_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFra JxlBasicInfo info; JxlColorEncoding jxl_color; JxlPixelFormat jxl_fmt; + JxlBitDepth jxl_bit_depth; JxlEncoderStatus jret; int ret; size_t available = ctx->buffer_size; @@ -269,17 +270,22 @@ static int libjxl_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFra info.ysize = frame->height; info.num_extra_channels = (jxl_fmt.num_channels + 1) % 2; info.num_color_channels = jxl_fmt.num_channels - info.num_extra_channels; - info.bits_per_sample = av_get_bits_per_pixel(pix_desc) / jxl_fmt.num_channels; + jxl_bit_depth.bits_per_sample = av_get_bits_per_pixel(pix_desc) / jxl_fmt.num_channels; + info.bits_per_sample = avctx->bits_per_raw_sample > 0 && !(pix_desc->flags & AV_PIX_FMT_FLAG_FLOAT) + ? avctx->bits_per_raw_sample : jxl_bit_depth.bits_per_sample; info.alpha_bits = (info.num_extra_channels > 0) * info.bits_per_sample; if (pix_desc->flags & AV_PIX_FMT_FLAG_FLOAT) { info.exponent_bits_per_sample = info.bits_per_sample > 16 ? 8 : 5; info.alpha_exponent_bits = info.alpha_bits ? info.exponent_bits_per_sample : 0; jxl_fmt.data_type = info.bits_per_sample > 16 ? JXL_TYPE_FLOAT : JXL_TYPE_FLOAT16; + jxl_bit_depth.exponent_bits_per_sample = info.exponent_bits_per_sample; } else { info.exponent_bits_per_sample = 0; info.alpha_exponent_bits = 0; jxl_fmt.data_type = info.bits_per_sample <= 8 ? JXL_TYPE_UINT8 : JXL_TYPE_UINT16; + jxl_bit_depth.exponent_bits_per_sample = 0; } + jxl_bit_depth.type = JXL_BIT_DEPTH_FROM_PIXEL_FORMAT; /* JPEG XL format itself does not support limited range */ if (avctx->color_range == AVCOL_RANGE_MPEG || @@ -356,6 +362,8 @@ static int libjxl_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFra av_log(avctx, AV_LOG_WARNING, "Could not set ICC Profile\n"); if (JxlEncoderSetColorEncoding(ctx->encoder, &jxl_color) != JXL_ENC_SUCCESS) av_log(avctx, AV_LOG_WARNING, "Failed to set JxlColorEncoding\n"); + if (JxlEncoderSetFrameBitDepth(ctx->options, &jxl_bit_depth) != JXL_ENC_SUCCESS) + av_log(avctx, AV_LOG_WARNING, "Failed to set JxlBitDepth\n"); /* depending on basic info, level 10 might * be required instead of level 5 */