From patchwork Fri Oct 25 01:57:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Niedermayer X-Patchwork-Id: 52484 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a59:be6b:0:b0:48e:c0f8:d0de with SMTP id bd11csp39164vqb; Thu, 24 Oct 2024 18:57:34 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCVRelVmK2hBp7kb1ljbRXFc9ZIlscYTpbdY4V3qId5XMvFNDMN63JeqVtzsmK2T4+eVsC9fJeCNEDdFPZYwlp1K@gmail.com X-Google-Smtp-Source: AGHT+IFqHgvDa55GGD82XTaMFb1qIASMNiKLGF0CKm3O2K1BcA7SNVeBqNqh/CqFrBXW4FRKoROk X-Received: by 2002:a05:6512:3195:b0:539:e333:1822 with SMTP id 2adb3069b0e04-53b23dde3e4mr2445839e87.4.1729821453828; Thu, 24 Oct 2024 18:57:33 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1729821453; cv=none; d=google.com; s=arc-20240605; b=F0d7fQcEJrwpCDqbqQZRYGfg3BDWjh8cb2lvZTTou9fvhmC1qETHW4Z7G82Qaf/ftI Dz/S7Zcg4w8PU/mf4Ym1BRGXWKy3zv48+CcBR38n0PJYYQjDu7JTY7efEBCK/cU+MTpG ND1sNXLahEb7zq1L5o5nuw7O/RFsA55nQ/BU8i98zBFU++pc7RFa88kcyX9cxtaCZnK5 2RH5+GJBFZbwCXuDw8A994gQJ3XnHGxl5OsjjP9yXuGiO57Eqj9+qkgQGWKoJYnrNXD/ gOC+TAXb9LyDo4We7q2Kt8XYefquUi8jDDa0+1A31tJ8orja6G4MK3+JWfFYvf6KXZ8K /Jrg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; 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:message-id:date:to:from :dkim-signature:delivered-to; bh=AhY8t2bzmih2QQeDFbTQx0i9avoAnPG6lOCGYs4wxfE=; fh=e5zN9xSzcxLA6bGo3lF+CqTbY/oLwzApV03EO/RBfgQ=; b=RlcfMRpK7qQnAx/NSko7vI/ySMSx6sp8j61jurwlCr2K546LIzhP+TWVcCWSgwdTSS BAu7aVTBCS1NiZgOEfCBaTjjA97H/QYGREonK2rf8WgTBgeFwPvWY/ARf6hDOR5vt2Nd iDf0pLxGWxy/9pHcwI5MwvApyCSwNENlkSDMp/SfB8UagwkwR+0JWLFTB75BdoQ5Mvb0 P2mq176qvzIOLOy62Yi5j8xunODSX1JCXzCfLB09JfFZisY2oB+HnpbyNUdt7ocYJ/TP tguqxd3cHtiZFBOikm/t7aYaASx5e1VmPceb4BUGs5UnWChX3WxkTbAM6M4xvD+2lu27 kMXg==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@niedermayer.cc header.s=gm1 header.b=A24nsKDS; 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 2adb3069b0e04-53b2e12cf43si64792e87.191.2024.10.24.18.57.33; Thu, 24 Oct 2024 18:57: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; dkim=neutral (body hash did not verify) header.i=@niedermayer.cc header.s=gm1 header.b=A24nsKDS; 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 0483C68DD17; Fri, 25 Oct 2024 04:57:30 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from relay2-d.mail.gandi.net (relay2-d.mail.gandi.net [217.70.183.194]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 0543D68DA2C for ; Fri, 25 Oct 2024 04:57:22 +0300 (EEST) Received: by mail.gandi.net (Postfix) with ESMTPSA id 4EA7740002 for ; Fri, 25 Oct 2024 01:57:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=niedermayer.cc; s=gm1; t=1729821442; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=3+FcGofvfIFbPRLpNTOBzQD9M2y+Lt6lKY1nSvNrACY=; b=A24nsKDS3eke0i4xFO7LXfXrRDnruhL3Vzw7QgtgsgOfGzHDbWoBsbCFMoUYyReqi/N47B 2QN52o0EjUuJraDCNHkidqK4BY+KuvLq4PgMyT5mJG83PsSshrWARyGuL8CYfqGUs94VPk yuIJtLrcjVQakjQk4WT3daFuhT83hNp5y+7FTjk+Ev3FdvSRJnu/6+J7E99KuxMJP3UPeZ WUN1oC7av0/68L11wmIdo0WLC0kWcfJamzWfiJsJOmXLkOlry9nLDy1AKK1g1YlYM2a+eh Oo/czEjtXyrJjBEW0wrE7R8dEEWqwDBNhYWKXmIg2X6I7Cg3kKvTLTGas4Qmlg== From: Michael Niedermayer To: FFmpeg development discussions and patches Date: Fri, 25 Oct 2024 03:57:21 +0200 Message-ID: <20241025015721.2271894-1-michael@niedermayer.cc> X-Mailer: git-send-email 2.47.0 MIME-Version: 1.0 X-GND-Sasl: michael@niedermayer.cc Subject: [FFmpeg-devel] [PATCH] avcodec/ffv1: Support slice coding mode 1 with golomb rice 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: MYeJybWuyV8K Sponsored-by: Sovereign Tech Fund Signed-off-by: Michael Niedermayer --- libavcodec/ffv1dec.c | 20 ++++++++++---------- libavcodec/ffv1dec_template.c | 3 +++ libavcodec/ffv1enc.c | 23 ++++++++++++----------- 3 files changed, 25 insertions(+), 21 deletions(-) diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index ac8cc8a31dc..de5abfe9b41 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -120,9 +120,8 @@ static int is_input_end(RangeCoder *c, GetBitContext *gb, int ac) static int decode_plane(FFV1Context *f, FFV1SliceContext *sc, GetBitContext *gb, uint8_t *src, int w, int h, int stride, int plane_index, - int pixel_stride) + int pixel_stride, int ac) { - const int ac = f->ac; int x, y; int16_t *sample[2]; sample[0] = sc->sample_buffer + 3; @@ -273,6 +272,7 @@ static int decode_slice(AVCodecContext *c, void *arg) AVFrame * const p = f->picture.f; const int si = sc - f->slices; GetBitContext gb; + int ac = f->ac || sc->slice_coding_mode == 1; if (!(p->flags & AV_FRAME_FLAG_KEY) && f->last_picture.f) ff_progress_frame_await(&f->last_picture, si); @@ -305,7 +305,7 @@ static int decode_slice(AVCodecContext *c, void *arg) x = sc->slice_x; y = sc->slice_y; - if (f->ac == AC_GOLOMB_RICE) { + if (ac == AC_GOLOMB_RICE) { if (f->version == 3 && f->micro_version > 1 || f->version > 3) get_rac(&sc->c, (uint8_t[]) { 129 }); sc->ac_byte_count = f->version > 2 || (!x && !y) ? sc->c.bytestream - sc->c.bytestream_start - 1 : 0; @@ -320,17 +320,17 @@ static int decode_slice(AVCodecContext *c, void *arg) const int chroma_height = AV_CEIL_RSHIFT(height, f->chroma_v_shift); const int cx = x >> f->chroma_h_shift; const int cy = y >> f->chroma_v_shift; - decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0, 1); + decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0, 1, ac); if (f->chroma_planes) { - decode_plane(f, sc, &gb, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1, 1); - decode_plane(f, sc, &gb, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1, 1); + decode_plane(f, sc, &gb, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1, 1, ac); + decode_plane(f, sc, &gb, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1, 1, ac); } if (f->transparency) - decode_plane(f, sc, &gb, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], (f->version >= 4 && !f->chroma_planes) ? 1 : 2, 1); + decode_plane(f, sc, &gb, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], (f->version >= 4 && !f->chroma_planes) ? 1 : 2, 1, ac); } else if (f->colorspace == 0) { - decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0] , width, height, p->linesize[0], 0, 2); - decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0] + 1, width, height, p->linesize[0], 1, 2); + decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0] , width, height, p->linesize[0], 0, 2, ac); + decode_plane(f, sc, &gb, p->data[0] + ps*x + y*p->linesize[0] + 1, width, height, p->linesize[0], 1, 2, ac); } else if (f->use32bit) { uint8_t *planes[4] = { p->data[0] + ps * x + y * p->linesize[0], p->data[1] + ps * x + y * p->linesize[1], @@ -344,7 +344,7 @@ static int decode_slice(AVCodecContext *c, void *arg) p->data[3] + ps * x + y * p->linesize[3] }; decode_rgb_frame(f, sc, &gb, planes, width, height, p->linesize); } - if (f->ac != AC_GOLOMB_RICE && f->version > 2) { + if (ac != AC_GOLOMB_RICE && f->version > 2) { int v; get_rac(&sc->c, (uint8_t[]) { 129 }); v = sc->c.bytestream_end - sc->c.bytestream - 2 - 5*!!f->ec; diff --git a/libavcodec/ffv1dec_template.c b/libavcodec/ffv1dec_template.c index 2da6bd935dc..e983d1ba648 100644 --- a/libavcodec/ffv1dec_template.c +++ b/libavcodec/ffv1dec_template.c @@ -143,6 +143,9 @@ static int RENAME(decode_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc, int transparency = f->transparency; int ac = f->ac; + if (sc->slice_coding_mode == 1) + ac = 1; + for (x = 0; x < 4; x++) { sample[x][0] = RENAME(sc->sample_buffer) + x * 2 * (w + 6) + 3; sample[x][1] = RENAME(sc->sample_buffer) + (x * 2 + 1) * (w + 6) + 3; diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index a32059886c0..547fb598d6d 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -271,10 +271,9 @@ static inline void put_vlc_symbol(PutBitContext *pb, VlcState *const state, static int encode_plane(FFV1Context *f, FFV1SliceContext *sc, const uint8_t *src, int w, int h, - int stride, int plane_index, int pixel_stride) + int stride, int plane_index, int pixel_stride, int ac) { int x, y, i, ret; - const int ac = f->ac; const int pass1 = !!(f->avctx->flags & AV_CODEC_FLAG_PASS1); const int ring_size = f->context_model ? 3 : 2; int16_t *sample[3]; @@ -1068,6 +1067,7 @@ static int encode_slice(AVCodecContext *c, void *arg) p->data[1] ? p->data[1] + ps*x + y*p->linesize[1] : NULL, p->data[2] ? p->data[2] + ps*x + y*p->linesize[2] : NULL, p->data[3] ? p->data[3] + ps*x + y*p->linesize[3] : NULL}; + int ac = f->ac; sc->slice_coding_mode = 0; if (f->version > 3 && f->colorspace == 1) { @@ -1083,7 +1083,7 @@ retry: if (f->version > 2) { encode_slice_header(f, sc); } - if (f->ac == AC_GOLOMB_RICE) { + if (ac == AC_GOLOMB_RICE) { sc->ac_byte_count = f->version > 2 || (!x && !y) ? ff_rac_terminate(&sc->c, f->version > 2) : 0; init_put_bits(&sc->pb, sc->c.bytestream_start + sc->ac_byte_count, @@ -1096,24 +1096,24 @@ retry: const int cx = x >> f->chroma_h_shift; const int cy = y >> f->chroma_v_shift; - ret = encode_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0, 1); + ret = encode_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0, 1, ac); if (f->chroma_planes) { - ret |= encode_plane(f, sc, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1, 1); - ret |= encode_plane(f, sc, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1, 1); + ret |= encode_plane(f, sc, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1, 1, ac); + ret |= encode_plane(f, sc, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1, 1, ac); } if (f->transparency) - ret |= encode_plane(f, sc, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], 2, 1); + ret |= encode_plane(f, sc, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], 2, 1, ac); } else if (c->pix_fmt == AV_PIX_FMT_YA8) { - ret = encode_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0, 2); - ret |= encode_plane(f, sc, p->data[0] + 1 + ps*x + y*p->linesize[0], width, height, p->linesize[0], 1, 2); + ret = encode_plane(f, sc, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0, 2, ac); + ret |= encode_plane(f, sc, p->data[0] + 1 + ps*x + y*p->linesize[0], width, height, p->linesize[0], 1, 2, ac); } else if (f->use32bit) { ret = encode_rgb_frame32(f, sc, planes, width, height, p->linesize); } else { ret = encode_rgb_frame(f, sc, planes, width, height, p->linesize); } - if (f->ac != AC_GOLOMB_RICE) { + if (ac != AC_GOLOMB_RICE) { sc->ac_byte_count = ff_rac_terminate(&sc->c, 1); } else { flush_put_bits(&sc->pb); // FIXME: nicer padding @@ -1122,11 +1122,12 @@ retry: if (ret < 0) { av_assert0(sc->slice_coding_mode == 0); - if (f->version < 4 || !f->ac) { + if (f->version < 4) { av_log(c, AV_LOG_ERROR, "Buffer too small\n"); return ret; } av_log(c, AV_LOG_DEBUG, "Coding slice as PCM\n"); + ac = 1; sc->slice_coding_mode = 1; sc->c = c_bak; goto retry;