From patchwork Sun Feb 28 18:45:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 26027 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 3698544A922 for ; Sun, 28 Feb 2021 20:45:26 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 08CC768AA98; Sun, 28 Feb 2021 20:45:26 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ej1-f46.google.com (mail-ej1-f46.google.com [209.85.218.46]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id CF20268A97D for ; Sun, 28 Feb 2021 20:45:19 +0200 (EET) Received: by mail-ej1-f46.google.com with SMTP id k13so24114762ejs.10 for ; Sun, 28 Feb 2021 10:45:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=laLu2Q88TWzvyHpIMkxOnbiiUHxxJC6NBpTiF2MRVsE=; b=Tao3B+6onRSYnIGOhT2CLGs75and7+6kk69kzzme/WdzT/rjT6W8IF2RRJxGMO4UNJ 4gvo/fqrZ3ItTzpW6oUAiACGqZIC6jCD5PQQWlRrZuHaknMS3IjE2P/bqBekjB2vhu2I hz9VnJD7YfimX4CJMRHPTjbb+ZXtoYnJyqNp/f6nL1LzXVSTIQXzoMjNu7GKw99Gr9gh KhanMaU1TNsDcSx9wA6rCVkP1oklMJ06wtYcgxg5BJV/Kkjfh/Ta/z23roRn7LB+CNKh rfBrDM7cK8Du3AhqORxFmCbof70rZ8NlstyLtd1kB0Pq9mWdxgLbYIqndPBoA3tdd3hU +EkA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=laLu2Q88TWzvyHpIMkxOnbiiUHxxJC6NBpTiF2MRVsE=; b=SxoPH3VhEvU03hRuX3rPJVl7gglOmyJx64tVzQDabEBCWntHiUJwztoRysDBYXGn3s /bBTh4lfQ6owgBwix/vO23N+y/vahGI6+KDHlCui69bo8aOPyqJGi/dTHcPCOrSC10hx gcllUgzPxaBcijbJTlFetcLaI871gLNHcnnprJPvB3sbfSFVQ0qSpZiUDxz/j3LcNUAi M6J+7RorAlXnGLj+TL5ujmCI47QIbUYBKS/e6v67Lr9s+1DHp/+Gi10pc5d5PpCTIwHz +F1dBmmTf3ZXuDpzwQwxY4QwdACOwOMnN7ejo9W+k+2C5GMq+i0tBNPDl/qzeJ/nh3WM 4sVA== X-Gm-Message-State: AOAM53367YfTCqLxk7lYI8yoUi0R41dMJnbCHgrp8kJpS7mjWUmrZgoW YGT7+x2yemi1twzZmmSyYnkCIJv5/RU= X-Google-Smtp-Source: ABdhPJw4acYq7CDx4WDqZoy3UKQqUSZdkPb8wy4LWdZsrQX6X8yKuZgaJbu31pfMdiFlxfvsNFxNPA== X-Received: by 2002:a17:906:6096:: with SMTP id t22mr12946188ejj.34.1614537918898; Sun, 28 Feb 2021 10:45:18 -0800 (PST) Received: from sblaptop.fritz.box (ipbcc1aa4b.dynamic.kabel-deutschland.de. [188.193.170.75]) by smtp.gmail.com with ESMTPSA id d14sm13126675edk.81.2021.02.28.10.45.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Feb 2021 10:45:18 -0800 (PST) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Sun, 28 Feb 2021 19:45:06 +0100 Message-Id: <20210228184510.247073-1-andreas.rheinhardt@gmail.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 1/5] tests/fate: Don't keep unnecessary temp files 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: Andreas Rheinhardt Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Some FATE tests use files created by other FATE tests as input files; this mostly affects the seek tests which use files from vsynth_lena as well as acodec-pcm as input files. In order to make this possible the temporary files of all the vsynth* and all acodec-pcm tests are kept. Yet only a fraction of these files are actually used. This commit changes this to only keep the files that are actually needed for other tests. This reduces the size of the tests/data/fate folder after a full FATE run from 2024727441B to 138739312B. Signed-off-by: Andreas Rheinhardt --- tests/fate/acodec.mak | 2 +- tests/fate/filter-video.mak | 1 + tests/fate/seek.mak | 1 + tests/fate/vcodec.mak | 4 ++-- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/fate/acodec.mak b/tests/fate/acodec.mak index 35b597859c..1b8c32b163 100644 --- a/tests/fate/acodec.mak +++ b/tests/fate/acodec.mak @@ -1,6 +1,6 @@ fate-acodec-%: CODEC = $(@:fate-acodec-%=%) fate-acodec-%: SRC = tests/data/asynth-44100-2.wav -fate-acodec-%: CMD = enc_dec wav $(SRC) $(FMT) "-b:a 128k -c $(CODEC) $(ENCOPTS)" wav "-c pcm_s16le $(DECOPTS)" -keep +fate-acodec-%: CMD = enc_dec wav $(SRC) $(FMT) "-b:a 128k -c $(CODEC) $(ENCOPTS)" wav "-c pcm_s16le $(DECOPTS)" "$(KEEP_OVERRIDE)" fate-acodec-%: CMP_UNIT = 2 fate-acodec-%: REF = $(SRC_PATH)/tests/ref/acodec/$(@:fate-acodec-%=%) diff --git a/tests/fate/filter-video.mak b/tests/fate/filter-video.mak index 9c7e3489f4..a0d645cc4a 100644 --- a/tests/fate/filter-video.mak +++ b/tests/fate/filter-video.mak @@ -564,6 +564,7 @@ fate-filter-pad: CMD = video_filter "pad=iw*1.5:ih*1.5:iw*0.3:ih*0.2" FATE_FILTER_PP = fate-filter-pp fate-filter-pp1 fate-filter-pp2 fate-filter-pp3 fate-filter-pp4 fate-filter-pp5 fate-filter-pp6 FATE_FILTER_VSYNTH-$(CONFIG_PP_FILTER) += $(FATE_FILTER_PP) $(FATE_FILTER_PP): fate-vsynth1-mpeg4-qprd +fate-vsynth1-mpeg4-qprd: KEEP_OVERRIDE= -keep fate-filter-pp: CMD = framecrc -flags bitexact -export_side_data venc_params -idct simple -i $(TARGET_PATH)/tests/data/fate/vsynth1-mpeg4-qprd.avi -frames:v 5 -flags +bitexact -vf "pp=be/hb/vb/tn/l5/al" fate-filter-pp1: CMD = video_filter "pp=fq|4/be/hb/vb/tn/l5/al" diff --git a/tests/fate/seek.mak b/tests/fate/seek.mak index 98d2b54674..5efec32702 100644 --- a/tests/fate/seek.mak +++ b/tests/fate/seek.mak @@ -270,6 +270,7 @@ FATE_SEEK_EXTRA += $(FATE_SEEK_EXTRA-yes) $(FATE_SEEK) $(FATE_SAMPLES_SEEK) $(FATE_SEEK_EXTRA): libavformat/tests/seek$(EXESUF) $(FATE_SEEK) $(FATE_SAMPLES_SEEK): CMD = run libavformat/tests/seek$(EXESUF) $(TARGET_PATH)/tests/data/$(SRC) $(FATE_SEEK) $(FATE_SAMPLES_SEEK): fate-seek-%: fate-% +$(subst fate-seek-,fate-,$(FATE_SAMPLES_SEEK) $(FATE_SEEK)): KEEP_OVERRIDE = -keep fate-seek-%: REF = $(SRC_PATH)/tests/ref/seek/$(@:fate-seek-%=%) FATE_AVCONV += $(FATE_SEEK) diff --git a/tests/fate/vcodec.mak b/tests/fate/vcodec.mak index 1e9c0d5647..ef892366eb 100644 --- a/tests/fate/vcodec.mak +++ b/tests/fate/vcodec.mak @@ -4,8 +4,8 @@ fate-vsynth_lena-%: SRC = tests/data/vsynth_lena.yuv fate-vsynth3-%: SRC = tests/data/vsynth3.yuv fate-vsynth%: CODEC = $(word 3, $(subst -, ,$(@))) fate-vsynth%: FMT = avi -fate-vsynth%: CMD = enc_dec "rawvideo -s 352x288 -pix_fmt yuv420p $(RAWDECOPTS)" $(SRC) $(FMT) "-c $(CODEC) $(ENCOPTS)" rawvideo "-s 352x288 -pix_fmt yuv420p -vsync 0 $(DECOPTS)" -keep "$(DECINOPTS)" -fate-vsynth3-%: CMD = enc_dec "rawvideo -s $(FATEW)x$(FATEH) -pix_fmt yuv420p $(RAWDECOPTS)" $(SRC) $(FMT) "-c $(CODEC) $(ENCOPTS)" rawvideo "-s $(FATEW)x$(FATEH) -pix_fmt yuv420p -vsync 0 $(DECOPTS)" -keep "$(DECINOPTS)" +fate-vsynth%: CMD = enc_dec "rawvideo -s 352x288 -pix_fmt yuv420p $(RAWDECOPTS)" $(SRC) $(FMT) "-c $(CODEC) $(ENCOPTS)" rawvideo "-s 352x288 -pix_fmt yuv420p -vsync 0 $(DECOPTS)" "$(KEEP_OVERRIDE)" "$(DECINOPTS)" +fate-vsynth3-%: CMD = enc_dec "rawvideo -s $(FATEW)x$(FATEH) -pix_fmt yuv420p $(RAWDECOPTS)" $(SRC) $(FMT) "-c $(CODEC) $(ENCOPTS)" rawvideo "-s $(FATEW)x$(FATEH) -pix_fmt yuv420p -vsync 0 $(DECOPTS)" "" "$(DECINOPTS)" fate-vsynth%: CMP_UNIT = 1 fate-vsynth%: REF = $(SRC_PATH)/tests/ref/vsynth/$(@:fate-%=%) From patchwork Sun Feb 28 18:45:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 26028 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 9B7D1449D4F for ; Sun, 28 Feb 2021 20:45:56 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 7656768AB0A; Sun, 28 Feb 2021 20:45:56 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ej1-f54.google.com (mail-ej1-f54.google.com [209.85.218.54]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2BB8B68807B for ; Sun, 28 Feb 2021 20:45:49 +0200 (EET) Received: by mail-ej1-f54.google.com with SMTP id g5so24141219ejt.2 for ; Sun, 28 Feb 2021 10:45:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=q0Me9sFS0EMWKu17JXffJgs35aFMwyN3y2biRAeMEPA=; b=aLm0FYBbUODNNXTO7PjRjleUhDB3fwCSBXSlQ6BQvDmdh0EVRE+BxuaqXaEstDH2ck SgjA3ncwgb4kLMYMtENrezR/JXJPAXm9r/MEuFNkopnmgdlk2Ik4r98Bk2gGsLvTZJhg OwRxSd1NE3IJwCa+vruetzVvW7DztfUK5BXJ2X0VyVJMez84HjEShTcFg+PTVlDgMd4I qz2iR6mh6o/WIDkgv+xrLB/loHR6x1Y82RsPa6hrfGcR1pG9pXVCPBW0jcXzMDQJ47NN Ot2THAo6di5te0TR2rczYW/pb3Y7mhNa2vGYX70kYIRHPpLyjrJ2g5zjgLtH92JfBkmi 0tbA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=q0Me9sFS0EMWKu17JXffJgs35aFMwyN3y2biRAeMEPA=; b=rUWCm8jq9RPgzMnnxWVLMhFtCA6uE1Pl8HkNWILQNGx+Pp+bSN13OJTnGRbSBJvRhe OfxAyTJuHxqnkc6vC3zsGwL3ukJjmnnseleLKOzcprFtTMrRXGFmXQnS/V7m5ko5uvju jcQhtq/lgnsrUrDG8V/0WjmE4bxuIy2qe2zZAX+0GiYRuiQjCCjZChLSENfd30jJGN5j Hj+xIf6v7KmzgS28JUyf3YzP+OKCa3LAt8SJqfRLQ/YTPp7Xcul0iaegFwhXyyBGh+7H +KX7sUqSIcOi2hV5LDUE1bE1AU8Dp3cfTg4pQ0lGafDT0/jfgC12nez/j6j/kkb5H4jC rU3Q== X-Gm-Message-State: AOAM5337uzAtb/MPsyxgrstQuGIm9M49sHOV0MSoirO+oohyqYQpKinj Etm1BuYfbrGvFeSiXdplB5JAkFmNGEw= X-Google-Smtp-Source: ABdhPJy3qNE2n3tyv4kdmMVnioZtrPZEyBXep3NVBcJdhtPEbqqryqRZzhan9yWqhxDryEvV4mScfg== X-Received: by 2002:a17:906:4349:: with SMTP id z9mr12744652ejm.471.1614537948068; Sun, 28 Feb 2021 10:45:48 -0800 (PST) Received: from sblaptop.fritz.box (ipbcc1aa4b.dynamic.kabel-deutschland.de. [188.193.170.75]) by smtp.gmail.com with ESMTPSA id d14sm13126675edk.81.2021.02.28.10.45.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Feb 2021 10:45:47 -0800 (PST) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Sun, 28 Feb 2021 19:45:07 +0100 Message-Id: <20210228184510.247073-2-andreas.rheinhardt@gmail.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210228184510.247073-1-andreas.rheinhardt@gmail.com> References: <20210228184510.247073-1-andreas.rheinhardt@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/5] avcodec/roqvideo: Use dedicated context for encoder 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: Andreas Rheinhardt Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Up until now, the RoQ video decoder and encoder used the same context; and said context contained several fields that are only used by the encoder. This commit changes this and uses a dedicated context for the encoder; it contains the common context as first element in order to use functions common to the de- and encoder. Signed-off-by: Andreas Rheinhardt --- libavcodec/roqvideo.h | 28 +---- libavcodec/roqvideoenc.c | 218 ++++++++++++++++++++++----------------- 2 files changed, 127 insertions(+), 119 deletions(-) diff --git a/libavcodec/roqvideo.h b/libavcodec/roqvideo.h index f47b2c8e6f..8318b6e5a0 100644 --- a/libavcodec/roqvideo.h +++ b/libavcodec/roqvideo.h @@ -22,9 +22,7 @@ #ifndef AVCODEC_ROQVIDEO_H #define AVCODEC_ROQVIDEO_H -#include "libavutil/lfg.h" #include "avcodec.h" -#include "bytestream.h" typedef struct roq_cell { unsigned char y[4]; @@ -39,39 +37,15 @@ typedef struct motion_vect { int d[2]; } motion_vect; -struct RoqTempData; - typedef struct RoqContext { - const AVClass *class; AVCodecContext *avctx; AVFrame *last_frame; AVFrame *current_frame; - int first_frame; + int width, height; roq_cell cb2x2[256]; roq_qcell cb4x4[256]; - - int width, height; - - /* Encoder only data */ - AVLFG randctx; - uint64_t lambda; - - motion_vect *this_motion4; - motion_vect *last_motion4; - - motion_vect *this_motion8; - motion_vect *last_motion8; - - unsigned int framesSinceKeyframe; - - const AVFrame *frame_to_enc; - uint8_t *out_buf; - struct RoqTempData *tmpData; - - int quake3_compat; // Quake 3 compatibility option - } RoqContext; #define RoQ_INFO 0x1001 diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c index dc6a63099d..f52c1f5454 100644 --- a/libavcodec/roqvideoenc.c +++ b/libavcodec/roqvideoenc.c @@ -57,6 +57,7 @@ #include #include "libavutil/attributes.h" +#include "libavutil/lfg.h" #include "libavutil/opt.h" #include "roqvideo.h" #include "bytestream.h" @@ -77,6 +78,27 @@ /* The cast is useful when multiplying it by INT_MAX */ #define ROQ_LAMBDA_SCALE ((uint64_t) FF_LAMBDA_SCALE) +typedef struct RoqEncContext { + RoqContext common; + AVLFG randctx; + uint64_t lambda; + + motion_vect *this_motion4; + motion_vect *last_motion4; + + motion_vect *this_motion8; + motion_vect *last_motion8; + + unsigned int framesSinceKeyframe; + + const AVFrame *frame_to_enc; + uint8_t *out_buf; + struct RoqTempData *tmpData; + + int first_frame; + int quake3_compat; // Quake 3 compatibility option +} RoqEncContext; + /* Macroblock support functions */ static void unpack_roq_cell(roq_cell *cell, uint8_t u[4*3]) { @@ -143,9 +165,10 @@ static int block_sse(uint8_t * const *buf1, uint8_t * const *buf2, int x1, int y return sse; } -static int eval_motion_dist(RoqContext *enc, int x, int y, motion_vect vect, +static int eval_motion_dist(RoqEncContext *enc, int x, int y, motion_vect vect, int size) { + RoqContext *const roq = &enc->common; int mx=vect.d[0]; int my=vect.d[1]; @@ -158,12 +181,12 @@ static int eval_motion_dist(RoqContext *enc, int x, int y, motion_vect vect, mx += x; my += y; - if ((unsigned) mx > enc->width-size || (unsigned) my > enc->height-size) + if ((unsigned) mx > roq->width-size || (unsigned) my > roq->height-size) return INT_MAX; - return block_sse(enc->frame_to_enc->data, enc->last_frame->data, x, y, + return block_sse(enc->frame_to_enc->data, roq->last_frame->data, x, y, mx, my, - enc->frame_to_enc->linesize, enc->last_frame->linesize, + enc->frame_to_enc->linesize, roq->last_frame->linesize, size); } @@ -307,7 +330,7 @@ static int index_mb(uint8_t cluster[], uint8_t cb[], int numCB, } \ } while(0) -static void motion_search(RoqContext *enc, int blocksize) +static void motion_search(RoqEncContext *enc, int blocksize) { static const motion_vect offsets[8] = { {{ 0,-1}}, @@ -320,6 +343,7 @@ static void motion_search(RoqContext *enc, int blocksize) {{ 1, 1}}, }; + RoqContext *const roq = &enc->common; int diff, lowestdiff, oldbest; int off[3]; motion_vect bestpick = {{0,0}}; @@ -328,8 +352,7 @@ static void motion_search(RoqContext *enc, int blocksize) motion_vect *last_motion; motion_vect *this_motion; motion_vect vect, vect2; - - int max=(enc->width/blocksize)*enc->height/blocksize; + const int max = (roq->width / blocksize) * roq->height / blocksize; if (blocksize == 4) { last_motion = enc->last_motion4; @@ -339,17 +362,17 @@ static void motion_search(RoqContext *enc, int blocksize) this_motion = enc->this_motion8; } - for (i=0; iheight; i+=blocksize) - for (j=0; jwidth; j+=blocksize) { + for (i = 0; i< roq->height; i += blocksize) + for (j = 0; j < roq->width; j += blocksize) { lowestdiff = eval_motion_dist(enc, j, i, (motion_vect) {{0,0}}, blocksize); bestpick.d[0] = 0; bestpick.d[1] = 0; if (blocksize == 4) - EVAL_MOTION(enc->this_motion8[(i/8)*(enc->width/8) + j/8]); + EVAL_MOTION(enc->this_motion8[(i/8) * (roq->width/8) + j/8]); - offset = (i/blocksize)*enc->width/blocksize + j/blocksize; + offset = (i/blocksize) * roq->width / blocksize + j / blocksize; if (offset < max && offset >= 0) EVAL_MOTION(last_motion[offset]); @@ -357,12 +380,12 @@ static void motion_search(RoqContext *enc, int blocksize) if (offset < max && offset >= 0) EVAL_MOTION(last_motion[offset]); - offset = (i/blocksize + 1)*enc->width/blocksize + j/blocksize; + offset = (i/blocksize + 1) * roq->width / blocksize + j / blocksize; if (offset < max && offset >= 0) EVAL_MOTION(last_motion[offset]); - off[0]= (i/blocksize)*enc->width/blocksize + j/blocksize - 1; - off[1]= off[0] - enc->width/blocksize + 1; + off[0]= (i/blocksize) * roq->width / blocksize + j/blocksize - 1; + off[1]= off[0] - roq->width / blocksize + 1; off[2]= off[1] + 1; if (i) { @@ -391,7 +414,7 @@ static void motion_search(RoqContext *enc, int blocksize) } vect = bestpick; } - offset = (i/blocksize)*enc->width/blocksize + j/blocksize; + offset = (i/blocksize) * roq->width / blocksize + j/blocksize; this_motion[offset] = bestpick; } } @@ -400,8 +423,9 @@ static void motion_search(RoqContext *enc, int blocksize) * Get distortion for all options available to a subcel */ static void gather_data_for_subcel(SubcelEvaluation *subcel, int x, - int y, RoqContext *enc, RoqTempdata *tempData) + int y, RoqEncContext *enc, RoqTempdata *tempData) { + RoqContext *const roq = &enc->common; uint8_t mb4[4*4*3]; uint8_t mb2[2*2*3]; int cluster_index; @@ -410,25 +434,25 @@ static void gather_data_for_subcel(SubcelEvaluation *subcel, int x, static const int bitsUsed[4] = {2, 10, 10, 34}; if (enc->framesSinceKeyframe >= 1) { - subcel->motion = enc->this_motion4[y*enc->width/16 + x/4]; + subcel->motion = enc->this_motion4[y * roq->width / 16 + x / 4]; subcel->eval_dist[RoQ_ID_FCC] = eval_motion_dist(enc, x, y, - enc->this_motion4[y*enc->width/16 + x/4], 4); + enc->this_motion4[y * roq->width / 16 + x / 4], 4); } else subcel->eval_dist[RoQ_ID_FCC] = INT_MAX; if (enc->framesSinceKeyframe >= 2) subcel->eval_dist[RoQ_ID_MOT] = block_sse(enc->frame_to_enc->data, - enc->current_frame->data, x, + roq->current_frame->data, x, y, x, y, enc->frame_to_enc->linesize, - enc->current_frame->linesize, + roq->current_frame->linesize, 4); else subcel->eval_dist[RoQ_ID_MOT] = INT_MAX; - cluster_index = y*enc->width/16 + x/4; + cluster_index = y * roq->width / 16 + x / 4; get_frame_mb(enc->frame_to_enc, x, y, mb4, 4); @@ -463,11 +487,12 @@ static void gather_data_for_subcel(SubcelEvaluation *subcel, int x, /** * Get distortion for all options available to a cel */ -static void gather_data_for_cel(CelEvaluation *cel, RoqContext *enc, +static void gather_data_for_cel(CelEvaluation *cel, RoqEncContext *enc, RoqTempdata *tempData) { + RoqContext *const roq = &enc->common; uint8_t mb8[8*8*3]; - int index = cel->sourceY*enc->width/64 + cel->sourceX/8; + int index = cel->sourceY * roq->width / 64 + cel->sourceX/8; int i, j, best_dist, divide_bit_use; int bitsUsed[4] = {2, 10, 10, 0}; @@ -483,11 +508,11 @@ static void gather_data_for_cel(CelEvaluation *cel, RoqContext *enc, if (enc->framesSinceKeyframe >= 2) cel->eval_dist[RoQ_ID_MOT] = block_sse(enc->frame_to_enc->data, - enc->current_frame->data, + roq->current_frame->data, cel->sourceX, cel->sourceY, cel->sourceX, cel->sourceY, enc->frame_to_enc->linesize, - enc->current_frame->linesize,8); + roq->current_frame->linesize,8); else cel->eval_dist[RoQ_ID_MOT] = INT_MAX; @@ -537,8 +562,9 @@ static void gather_data_for_cel(CelEvaluation *cel, RoqContext *enc, } } -static void remap_codebooks(RoqContext *enc, RoqTempdata *tempData) +static void remap_codebooks(RoqEncContext *enc, RoqTempdata *tempData) { + RoqContext *const roq = &enc->common; int i, j, idx=0; /* Make remaps for the final codebook usage */ @@ -547,7 +573,7 @@ static void remap_codebooks(RoqContext *enc, RoqTempdata *tempData) tempData->i2f4[i] = idx; tempData->f2i4[idx] = i; for (j=0; j<4; j++) - tempData->codebooks.usedCB2[enc->cb4x4[i].idx[j]]++; + tempData->codebooks.usedCB2[roq->cb4x4[i].idx[j]]++; idx++; } } @@ -569,8 +595,9 @@ static void remap_codebooks(RoqContext *enc, RoqTempdata *tempData) /** * Write codebook chunk */ -static void write_codebooks(RoqContext *enc, RoqTempdata *tempData) +static void write_codebooks(RoqEncContext *enc, RoqTempdata *tempData) { + RoqContext *const roq = &enc->common; int i, j; uint8_t **outp= &enc->out_buf; @@ -581,14 +608,14 @@ static void write_codebooks(RoqContext *enc, RoqTempdata *tempData) bytestream_put_byte(outp, tempData->numCB2); for (i=0; inumCB2; i++) { - bytestream_put_buffer(outp, enc->cb2x2[tempData->f2i2[i]].y, 4); - bytestream_put_byte(outp, enc->cb2x2[tempData->f2i2[i]].u); - bytestream_put_byte(outp, enc->cb2x2[tempData->f2i2[i]].v); + bytestream_put_buffer(outp, roq->cb2x2[tempData->f2i2[i]].y, 4); + bytestream_put_byte(outp, roq->cb2x2[tempData->f2i2[i]].u); + bytestream_put_byte(outp, roq->cb2x2[tempData->f2i2[i]].v); } for (i=0; inumCB4; i++) for (j=0; j<4; j++) - bytestream_put_byte(outp, tempData->i2f2[enc->cb4x4[tempData->f2i4[i]].idx[j]]); + bytestream_put_byte(outp, tempData->i2f2[roq->cb4x4[tempData->f2i4[i]].idx[j]]); } } @@ -623,8 +650,11 @@ static void write_typecode(CodingSpool *s, uint8_t type) } } -static void reconstruct_and_encode_image(RoqContext *enc, RoqTempdata *tempData, int w, int h, int numBlocks) +static void reconstruct_and_encode_image(RoqEncContext *enc, + RoqTempdata *tempData, + int w, int h, int numBlocks) { + RoqContext *const roq = &enc->common; int i, j, k; int x, y; int subX, subY; @@ -665,7 +695,7 @@ static void reconstruct_and_encode_image(RoqContext *enc, RoqTempdata *tempData, bytestream_put_byte(&spool.args, motion_arg(eval->motion)); write_typecode(&spool, RoQ_ID_FCC); - ff_apply_motion_8x8(enc, x, y, + ff_apply_motion_8x8(roq, x, y, eval->motion.d[0], eval->motion.d[1]); break; @@ -673,11 +703,11 @@ static void reconstruct_and_encode_image(RoqContext *enc, RoqTempdata *tempData, bytestream_put_byte(&spool.args, tempData->i2f4[eval->cbEntry]); write_typecode(&spool, RoQ_ID_SLD); - qcell = enc->cb4x4 + eval->cbEntry; - ff_apply_vector_4x4(enc, x , y , enc->cb2x2 + qcell->idx[0]); - ff_apply_vector_4x4(enc, x+4, y , enc->cb2x2 + qcell->idx[1]); - ff_apply_vector_4x4(enc, x , y+4, enc->cb2x2 + qcell->idx[2]); - ff_apply_vector_4x4(enc, x+4, y+4, enc->cb2x2 + qcell->idx[3]); + qcell = roq->cb4x4 + eval->cbEntry; + ff_apply_vector_4x4(roq, x , y , roq->cb2x2 + qcell->idx[0]); + ff_apply_vector_4x4(roq, x+4, y , roq->cb2x2 + qcell->idx[1]); + ff_apply_vector_4x4(roq, x , y+4, roq->cb2x2 + qcell->idx[2]); + ff_apply_vector_4x4(roq, x+4, y+4, roq->cb2x2 + qcell->idx[3]); break; case RoQ_ID_CCC: @@ -695,7 +725,7 @@ static void reconstruct_and_encode_image(RoqContext *enc, RoqTempdata *tempData, bytestream_put_byte(&spool.args, motion_arg(eval->subCels[j].motion)); - ff_apply_motion_4x4(enc, subX, subY, + ff_apply_motion_4x4(roq, subX, subY, eval->subCels[j].motion.d[0], eval->subCels[j].motion.d[1]); break; @@ -704,16 +734,16 @@ static void reconstruct_and_encode_image(RoqContext *enc, RoqTempdata *tempData, bytestream_put_byte(&spool.args, tempData->i2f4[eval->subCels[j].cbEntry]); - qcell = enc->cb4x4 + eval->subCels[j].cbEntry; + qcell = roq->cb4x4 + eval->subCels[j].cbEntry; - ff_apply_vector_2x2(enc, subX , subY , - enc->cb2x2 + qcell->idx[0]); - ff_apply_vector_2x2(enc, subX+2, subY , - enc->cb2x2 + qcell->idx[1]); - ff_apply_vector_2x2(enc, subX , subY+2, - enc->cb2x2 + qcell->idx[2]); - ff_apply_vector_2x2(enc, subX+2, subY+2, - enc->cb2x2 + qcell->idx[3]); + ff_apply_vector_2x2(roq, subX , subY , + roq->cb2x2 + qcell->idx[0]); + ff_apply_vector_2x2(roq, subX+2, subY , + roq->cb2x2 + qcell->idx[1]); + ff_apply_vector_2x2(roq, subX , subY+2, + roq->cb2x2 + qcell->idx[2]); + ff_apply_vector_2x2(roq, subX+2, subY+2, + roq->cb2x2 + qcell->idx[3]); break; case RoQ_ID_CCC: @@ -722,8 +752,8 @@ static void reconstruct_and_encode_image(RoqContext *enc, RoqTempdata *tempData, bytestream_put_byte(&spool.args, tempData->i2f2[cb_idx]); - ff_apply_vector_2x2(enc, subX + 2*(k&1), subY + (k&2), - enc->cb2x2 + cb_idx); + ff_apply_vector_2x2(roq, subX + 2*(k&1), subY + (k&2), + roq->cb2x2 + cb_idx); } break; } @@ -777,7 +807,7 @@ static void create_clusters(const AVFrame *frame, int w, int h, uint8_t *yuvClus } } -static int generate_codebook(RoqContext *enc, RoqTempdata *tempdata, +static int generate_codebook(RoqEncContext *enc, RoqTempdata *tempdata, int *points, int inputCount, roq_cell *results, int size, int cbsize) { @@ -825,11 +855,12 @@ out: return ret; } -static int generate_new_codebooks(RoqContext *enc, RoqTempdata *tempData) +static int generate_new_codebooks(RoqEncContext *enc, RoqTempdata *tempData) { int i, j, ret = 0; RoqCodebooks *codebooks = &tempData->codebooks; - int max = enc->width*enc->height/16; + RoqContext *const roq = &enc->common; + int max = roq->width * roq->height / 16; uint8_t mb2[3*4]; roq_cell *results4 = av_malloc(sizeof(roq_cell)*MAX_CBS_4x4*4); uint8_t *yuvClusters=av_malloc_array(max, sizeof(int)*6*4); @@ -842,7 +873,7 @@ static int generate_new_codebooks(RoqContext *enc, RoqTempdata *tempData) } /* Subsample YUV data */ - create_clusters(enc->frame_to_enc, enc->width, enc->height, yuvClusters); + create_clusters(enc->frame_to_enc, roq->width, roq->height, yuvClusters); /* Cast to integer and apply chroma bias */ for (i=0; icb2x2, 2, MAX_CBS_2x2)) < 0) + roq->cb2x2, 2, MAX_CBS_2x2)) < 0) goto out; codebooks->numCB2 = MAX_CBS_2x2; /* Unpack 2x2 codebook clusters */ for (i=0; inumCB2; i++) - unpack_roq_cell(enc->cb2x2 + i, codebooks->unpacked_cb2 + i*2*2*3); + unpack_roq_cell(roq->cb2x2 + i, codebooks->unpacked_cb2 + i*2*2*3); /* Index all 4x4 entries to the 2x2 entries, unpack, and enlarge */ for (i=0; inumCB4; i++) { for (j=0; j<4; j++) { unpack_roq_cell(&results4[4*i + j], mb2); index_mb(mb2, codebooks->unpacked_cb2, codebooks->numCB2, - &enc->cb4x4[i].idx[j], 2); + &roq->cb4x4[i].idx[j], 2); } - unpack_roq_qcell(codebooks->unpacked_cb2, enc->cb4x4 + i, + unpack_roq_qcell(codebooks->unpacked_cb2, roq->cb4x4 + i, codebooks->unpacked_cb4 + i*4*4*3); enlarge_roq_mb4(codebooks->unpacked_cb4 + i*4*4*3, codebooks->unpacked_cb4_enlarged + i*8*8*3); @@ -893,14 +924,15 @@ out: return ret; } -static int roq_encode_video(RoqContext *enc) +static int roq_encode_video(RoqEncContext *enc) { RoqTempdata *tempData = enc->tmpData; - int i, ret; + RoqContext *const roq = &enc->common; + int ret; memset(tempData, 0, sizeof(*tempData)); - ret = create_cel_evals(enc, tempData); + ret = create_cel_evals(roq, tempData); if (ret < 0) return ret; @@ -914,16 +946,16 @@ static int roq_encode_video(RoqContext *enc) } retry_encode: - for (i=0; iwidth*enc->height/64; i++) + for (int i = 0; i < roq->width * roq->height / 64; i++) gather_data_for_cel(tempData->cel_evals + i, enc, tempData); /* Quake 3 can't handle chunks bigger than 65535 bytes */ if (tempData->mainChunkSize/8 > 65535 && enc->quake3_compat) { if (enc->lambda > 100000) { - av_log(enc->avctx, AV_LOG_ERROR, "Cannot encode video in Quake compatible form\n"); + av_log(roq->avctx, AV_LOG_ERROR, "Cannot encode video in Quake compatible form\n"); return AVERROR(EINVAL); } - av_log(enc->avctx, AV_LOG_ERROR, + av_log(roq->avctx, AV_LOG_ERROR, "Warning, generated a frame too big for Quake (%d > 65535), " "now switching to a bigger qscale value.\n", tempData->mainChunkSize/8); @@ -942,11 +974,11 @@ static int roq_encode_video(RoqContext *enc) write_codebooks(enc, tempData); - reconstruct_and_encode_image(enc, tempData, enc->width, enc->height, - enc->width*enc->height/64); + reconstruct_and_encode_image(enc, tempData, roq->width, roq->height, + roq->width * roq->height / 64); /* Rotate frame history */ - FFSWAP(AVFrame *, enc->current_frame, enc->last_frame); + FFSWAP(AVFrame *, roq->current_frame, roq->last_frame); FFSWAP(motion_vect *, enc->last_motion4, enc->this_motion4); FFSWAP(motion_vect *, enc->last_motion8, enc->this_motion8); @@ -960,10 +992,10 @@ static int roq_encode_video(RoqContext *enc) static av_cold int roq_encode_end(AVCodecContext *avctx) { - RoqContext *enc = avctx->priv_data; + RoqEncContext *const enc = avctx->priv_data; - av_frame_free(&enc->current_frame); - av_frame_free(&enc->last_frame); + av_frame_free(&enc->common.current_frame); + av_frame_free(&enc->common.last_frame); av_freep(&enc->tmpData); av_freep(&enc->this_motion4); @@ -976,11 +1008,12 @@ static av_cold int roq_encode_end(AVCodecContext *avctx) static av_cold int roq_encode_init(AVCodecContext *avctx) { - RoqContext *enc = avctx->priv_data; + RoqEncContext *const enc = avctx->priv_data; + RoqContext *const roq = &enc->common; av_lfg_init(&enc->randctx, 1); - enc->avctx = avctx; + roq->avctx = avctx; enc->framesSinceKeyframe = 0; if ((avctx->width & 0xf) || (avctx->height & 0xf)) { @@ -996,30 +1029,30 @@ static av_cold int roq_encode_init(AVCodecContext *avctx) if (((avctx->width)&(avctx->width-1))||((avctx->height)&(avctx->height-1))) av_log(avctx, AV_LOG_ERROR, "Warning: dimensions not power of two, this is not supported by quake\n"); - enc->width = avctx->width; - enc->height = avctx->height; + roq->width = avctx->width; + roq->height = avctx->height; enc->framesSinceKeyframe = 0; enc->first_frame = 1; - enc->last_frame = av_frame_alloc(); - enc->current_frame = av_frame_alloc(); - if (!enc->last_frame || !enc->current_frame) + roq->last_frame = av_frame_alloc(); + roq->current_frame = av_frame_alloc(); + if (!roq->last_frame || !roq->current_frame) return AVERROR(ENOMEM); enc->tmpData = av_malloc(sizeof(RoqTempdata)); enc->this_motion4 = - av_mallocz_array((enc->width*enc->height/16), sizeof(motion_vect)); + av_mallocz_array(roq->width * roq->height / 16, sizeof(motion_vect)); enc->last_motion4 = - av_malloc_array ((enc->width*enc->height/16), sizeof(motion_vect)); + av_malloc_array (roq->width * roq->height / 16, sizeof(motion_vect)); enc->this_motion8 = - av_mallocz_array((enc->width*enc->height/64), sizeof(motion_vect)); + av_mallocz_array(roq->width * roq->height / 64, sizeof(motion_vect)); enc->last_motion8 = - av_malloc_array ((enc->width*enc->height/64), sizeof(motion_vect)); + av_malloc_array (roq->width * roq->height / 64, sizeof(motion_vect)); if (!enc->tmpData || !enc->this_motion4 || !enc->last_motion4 || !enc->this_motion8 || !enc->last_motion8) @@ -1028,7 +1061,7 @@ static av_cold int roq_encode_init(AVCodecContext *avctx) return 0; } -static void roq_write_video_info_chunk(RoqContext *enc) +static void roq_write_video_info_chunk(RoqEncContext *enc) { /* ROQ info chunk */ bytestream_put_le16(&enc->out_buf, RoQ_INFO); @@ -1041,10 +1074,10 @@ static void roq_write_video_info_chunk(RoqContext *enc) bytestream_put_byte(&enc->out_buf, 0x00); /* Width */ - bytestream_put_le16(&enc->out_buf, enc->width); + bytestream_put_le16(&enc->out_buf, enc->common.width); /* Height */ - bytestream_put_le16(&enc->out_buf, enc->height); + bytestream_put_le16(&enc->out_buf, enc->common.height); /* Unused in Quake 3, mimics the output of the real encoder */ bytestream_put_byte(&enc->out_buf, 0x08); @@ -1056,10 +1089,11 @@ static void roq_write_video_info_chunk(RoqContext *enc) static int roq_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet) { - RoqContext *enc = avctx->priv_data; + RoqEncContext *const enc = avctx->priv_data; + RoqContext *const roq = &enc->common; int size, ret; - enc->avctx = avctx; + roq->avctx = avctx; enc->frame_to_enc = frame; @@ -1070,7 +1104,7 @@ static int roq_encode_frame(AVCodecContext *avctx, AVPacket *pkt, /* 138 bits max per 8x8 block + * 256 codebooks*(6 bytes 2x2 + 4 bytes 4x4) + 8 bytes frame header */ - size = ((enc->width * enc->height / 64) * 138 + 7) / 8 + 256 * (6 + 4) + 8; + size = ((roq->width * roq->height / 64) * 138 + 7) / 8 + 256 * (6 + 4) + 8; if ((ret = ff_alloc_packet2(avctx, pkt, size, 0)) < 0) return ret; enc->out_buf = pkt->data; @@ -1082,8 +1116,8 @@ static int roq_encode_frame(AVCodecContext *avctx, AVPacket *pkt, if (enc->first_frame) { /* Alloc memory for the reconstruction data (we must know the stride for that) */ - if ((ret = ff_get_buffer(avctx, enc->current_frame, 0)) < 0 || - (ret = ff_get_buffer(avctx, enc->last_frame, 0)) < 0) + if ((ret = ff_get_buffer(avctx, roq->current_frame, 0)) < 0 || + (ret = ff_get_buffer(avctx, roq->last_frame, 0)) < 0) return ret; /* Before the first video frame, write a "video info" chunk */ @@ -1105,7 +1139,7 @@ static int roq_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } -#define OFFSET(x) offsetof(RoqContext, x) +#define OFFSET(x) offsetof(RoqEncContext, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { { "quake3_compat", "Whether to respect known limitations in Quake 3 decoder", OFFSET(quake3_compat), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE }, @@ -1124,7 +1158,7 @@ AVCodec ff_roq_encoder = { .long_name = NULL_IF_CONFIG_SMALL("id RoQ video"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_ROQ, - .priv_data_size = sizeof(RoqContext), + .priv_data_size = sizeof(RoqEncContext), .init = roq_encode_init, .encode2 = roq_encode_frame, .close = roq_encode_end, From patchwork Sun Feb 28 18:45:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 26029 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 AF1C5449D4F for ; Sun, 28 Feb 2021 20:45:57 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 9472F68AAEB; Sun, 28 Feb 2021 20:45:57 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ej1-f50.google.com (mail-ej1-f50.google.com [209.85.218.50]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 81D6868807B for ; Sun, 28 Feb 2021 20:45:49 +0200 (EET) Received: by mail-ej1-f50.google.com with SMTP id do6so24120580ejc.3 for ; Sun, 28 Feb 2021 10:45:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XW49GcqOKakSFMC8cu5JBnNIW5UdumWcgY6lwlbVlr8=; b=HF9dWPKSI+r5L9Zef4Aate2s3l2ErM9E/IT/3qHFykidUCuptq57+mOpz/4YTqUGwF V9ZvD98GyyPSocOxVzyuv6dTWvsM/xgodinttLNCXRz/DRoqr6L9zQcjo98P6DN2No94 F31nos04YhYDzVxj9UNe72GKuwN06+vPGnxKLsl7QGoS1OVp2hiqM7OQuJt0JJDT01ml HpX13V8R5R9CLc3W84c/gI8KQidYz1sBxJg1wuB4ftn9V3CkWxPRRDZIxiF9ZIaL9kIM XJDT/K/mU9J2jmX3pQh1DfixgUStHTGKi63UuI7ulZ9/BpE/hq2MrCT9163Me+ubdVnb Thvg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XW49GcqOKakSFMC8cu5JBnNIW5UdumWcgY6lwlbVlr8=; b=BotsHMRQiYnl4bECHOlSqTVp+DzhedYFOyIhfmaSpXsGo3n1KaNB2dR4k6zQQTQmKR 9R4TElTDgZnf/WyjRkj+O1iHgmE63MdyQ/lX88fZt9kWYXEYAhkwEb4ZMi9YTXnrZNUr PtG4qNXaJ6eswymCmp0fMD2Ivp6ML8MgBLcthxvTSa87f2SOPgymwl2kdyJLslmlTpbV RYp251OSYiWxlkrYesOzsbi7VjjDtrcQSNcs/KyT1XduC9X96WxVdP5Gns/nWr6OSvmY wpXQppPH7wZDMmzhl008gDpSuo4b/xeAOq2H6bS22Sg4CYjlM0u0XOfhHj+oJ45T+nuZ P2Cg== X-Gm-Message-State: AOAM533HVVxjWB7yD9allcLnh+z/zoRZZekugNkrmiXgTHufQHiWG7i1 cWaLLnDWmzIxpuqHCZCRBYV9FNh6yJs= X-Google-Smtp-Source: ABdhPJxxl4kzvdL38Iiu+hyu5KUl00GymCPX7wLwMU1ACtiGZcfQ9uCmqB2JyBBRw9IXjjQzhkhDjw== X-Received: by 2002:a17:906:3801:: with SMTP id v1mr12790179ejc.353.1614537948730; Sun, 28 Feb 2021 10:45:48 -0800 (PST) Received: from sblaptop.fritz.box (ipbcc1aa4b.dynamic.kabel-deutschland.de. [188.193.170.75]) by smtp.gmail.com with ESMTPSA id d14sm13126675edk.81.2021.02.28.10.45.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Feb 2021 10:45:48 -0800 (PST) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Sun, 28 Feb 2021 19:45:08 +0100 Message-Id: <20210228184510.247073-3-andreas.rheinhardt@gmail.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210228184510.247073-1-andreas.rheinhardt@gmail.com> References: <20210228184510.247073-1-andreas.rheinhardt@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 3/5] avcodec/roqvideoenc: Reuse buffers instead of alloc+free for each frame 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: Andreas Rheinhardt Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" In case of the cel evaluators it even allows to perform the initialization of the source coordinates only once instead of for each frame. Signed-off-by: Andreas Rheinhardt --- libavcodec/roqvideoenc.c | 125 +++++++++++++++++---------------------- 1 file changed, 55 insertions(+), 70 deletions(-) diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c index f52c1f5454..7ce0332f5b 100644 --- a/libavcodec/roqvideoenc.c +++ b/libavcodec/roqvideoenc.c @@ -78,6 +78,28 @@ /* The cast is useful when multiplying it by INT_MAX */ #define ROQ_LAMBDA_SCALE ((uint64_t) FF_LAMBDA_SCALE) +typedef struct SubcelEvaluation { + int eval_dist[4]; + int best_bit_use; + int best_coding; + + int subCels[4]; + motion_vect motion; + int cbEntry; +} SubcelEvaluation; + +typedef struct CelEvaluation { + int eval_dist[4]; + int best_coding; + + SubcelEvaluation subCels[4]; + + motion_vect motion; + int cbEntry; + + int sourceX, sourceY; +} CelEvaluation; + typedef struct RoqEncContext { RoqContext common; AVLFG randctx; @@ -95,6 +117,10 @@ typedef struct RoqEncContext { uint8_t *out_buf; struct RoqTempData *tmpData; + CelEvaluation *cel_evals; + int *closest_cb; + int *points; // Allocated together with closest_cb + int first_frame; int quake3_compat; // Quake 3 compatibility option } RoqEncContext; @@ -207,28 +233,6 @@ static inline int squared_diff_macroblock(uint8_t a[], uint8_t b[], int size) return sdiff; } -typedef struct SubcelEvaluation { - int eval_dist[4]; - int best_bit_use; - int best_coding; - - int subCels[4]; - motion_vect motion; - int cbEntry; -} SubcelEvaluation; - -typedef struct CelEvaluation { - int eval_dist[4]; - int best_coding; - - SubcelEvaluation subCels[4]; - - motion_vect motion; - int cbEntry; - - int sourceX, sourceY; -} CelEvaluation; - typedef struct RoqCodebooks { int numCB4; int numCB2; @@ -244,8 +248,6 @@ typedef struct RoqCodebooks { */ typedef struct RoqTempData { - CelEvaluation *cel_evals; - int f2i4[MAX_CBS_4x4]; int i2f4[MAX_CBS_4x4]; int f2i2[MAX_CBS_2x2]; @@ -258,27 +260,26 @@ typedef struct RoqTempData RoqCodebooks codebooks; - int *closest_cb2; int used_option[4]; } RoqTempdata; /** * Initialize cel evaluators and set their source coordinates */ -static int create_cel_evals(RoqContext *enc, RoqTempdata *tempData) +static int create_cel_evals(RoqEncContext *enc) { - int n=0, x, y, i; + RoqContext *const roq = &enc->common; - tempData->cel_evals = av_malloc_array(enc->width*enc->height/64, sizeof(CelEvaluation)); - if (!tempData->cel_evals) + enc->cel_evals = av_malloc_array(roq->width * roq->height / 64, sizeof(CelEvaluation)); + if (!enc->cel_evals) return AVERROR(ENOMEM); /* Map to the ROQ quadtree order */ - for (y=0; yheight; y+=16) - for (x=0; xwidth; x+=16) - for(i=0; i<4; i++) { - tempData->cel_evals[n ].sourceX = x + (i&1)*8; - tempData->cel_evals[n++].sourceY = y + (i&2)*4; + for (int y = 0, n = 0; y < roq->height; y += 16) + for (int x = 0; x < roq->width; x += 16) + for(int i = 0; i < 4; i++) { + enc->cel_evals[n ].sourceX = x + (i&1)*8; + enc->cel_evals[n++].sourceY = y + (i&2)*4; } return 0; @@ -464,7 +465,7 @@ static void gather_data_for_subcel(SubcelEvaluation *subcel, int x, subcel->eval_dist[RoQ_ID_CCC] = 0; for(i=0;i<4;i++) { - subcel->subCels[i] = tempData->closest_cb2[cluster_index*4+i]; + subcel->subCels[i] = enc->closest_cb[cluster_index*4+i]; get_frame_mb(enc->frame_to_enc, x+2*(i&1), y+(i&2), mb2, 2); @@ -680,7 +681,7 @@ static void reconstruct_and_encode_image(RoqEncContext *enc, bytestream_put_byte(&enc->out_buf, 0x0); for (i=0; icel_evals + i; + eval = enc->cel_evals + i; x = eval->sourceX; y = eval->sourceY; @@ -807,7 +808,7 @@ static void create_clusters(const AVFrame *frame, int w, int h, uint8_t *yuvClus } } -static int generate_codebook(RoqEncContext *enc, RoqTempdata *tempdata, +static int generate_codebook(RoqEncContext *enc, int *points, int inputCount, roq_cell *results, int size, int cbsize) { @@ -815,20 +816,11 @@ static int generate_codebook(RoqEncContext *enc, RoqTempdata *tempdata, int c_size = size*size/4; int *buf; int *codebook = av_malloc_array(6*c_size, cbsize*sizeof(int)); - int *closest_cb; + int *closest_cb = enc->closest_cb; if (!codebook) return AVERROR(ENOMEM); - if (size == 4) { - closest_cb = av_malloc_array(6*c_size, inputCount*sizeof(int)); - if (!closest_cb) { - ret = AVERROR(ENOMEM); - goto out; - } - } else - closest_cb = tempdata->closest_cb2; - ret = avpriv_init_elbg(points, 6 * c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->randctx); if (ret < 0) @@ -849,8 +841,6 @@ static int generate_codebook(RoqEncContext *enc, RoqTempdata *tempdata, results++; } out: - if (size == 4) - av_free(closest_cb); av_free(codebook); return ret; } @@ -864,10 +854,10 @@ static int generate_new_codebooks(RoqEncContext *enc, RoqTempdata *tempData) uint8_t mb2[3*4]; roq_cell *results4 = av_malloc(sizeof(roq_cell)*MAX_CBS_4x4*4); uint8_t *yuvClusters=av_malloc_array(max, sizeof(int)*6*4); - int *points = av_malloc_array(max, 6*4*sizeof(int)); + int *points = enc->points; int bias; - if (!results4 || !yuvClusters || !points) { + if (!results4 || !yuvClusters) { ret = AVERROR(ENOMEM); goto out; } @@ -882,20 +872,14 @@ static int generate_new_codebooks(RoqEncContext *enc, RoqTempdata *tempData) } /* Create 4x4 codebooks */ - if ((ret = generate_codebook(enc, tempData, points, max, + if ((ret = generate_codebook(enc, points, max, results4, 4, (enc->quake3_compat ? MAX_CBS_4x4-1 : MAX_CBS_4x4))) < 0) goto out; codebooks->numCB4 = (enc->quake3_compat ? MAX_CBS_4x4-1 : MAX_CBS_4x4); - tempData->closest_cb2 = av_malloc_array(max, 4*sizeof(int)); - if (!tempData->closest_cb2) { - ret = AVERROR(ENOMEM); - goto out; - } - /* Create 2x2 codebooks */ - if ((ret = generate_codebook(enc, tempData, points, max * 4, + if ((ret = generate_codebook(enc, points, max * 4, roq->cb2x2, 2, MAX_CBS_2x2)) < 0) goto out; @@ -919,7 +903,6 @@ static int generate_new_codebooks(RoqEncContext *enc, RoqTempdata *tempData) } out: av_free(yuvClusters); - av_free(points); av_free(results4); return ret; } @@ -932,10 +915,6 @@ static int roq_encode_video(RoqEncContext *enc) memset(tempData, 0, sizeof(*tempData)); - ret = create_cel_evals(roq, tempData); - if (ret < 0) - return ret; - ret = generate_new_codebooks(enc, tempData); if (ret < 0) return ret; @@ -947,7 +926,7 @@ static int roq_encode_video(RoqEncContext *enc) retry_encode: for (int i = 0; i < roq->width * roq->height / 64; i++) - gather_data_for_cel(tempData->cel_evals + i, enc, tempData); + gather_data_for_cel(enc->cel_evals + i, enc, tempData); /* Quake 3 can't handle chunks bigger than 65535 bytes */ if (tempData->mainChunkSize/8 > 65535 && enc->quake3_compat) { @@ -982,9 +961,6 @@ static int roq_encode_video(RoqEncContext *enc) FFSWAP(motion_vect *, enc->last_motion4, enc->this_motion4); FFSWAP(motion_vect *, enc->last_motion8, enc->this_motion8); - av_freep(&tempData->cel_evals); - av_freep(&tempData->closest_cb2); - enc->framesSinceKeyframe++; return 0; @@ -998,6 +974,8 @@ static av_cold int roq_encode_end(AVCodecContext *avctx) av_frame_free(&enc->common.last_frame); av_freep(&enc->tmpData); + av_freep(&enc->cel_evals); + av_freep(&enc->closest_cb); av_freep(&enc->this_motion4); av_freep(&enc->last_motion4); av_freep(&enc->this_motion8); @@ -1054,11 +1032,18 @@ static av_cold int roq_encode_init(AVCodecContext *avctx) enc->last_motion8 = av_malloc_array (roq->width * roq->height / 64, sizeof(motion_vect)); + /* 4x4 codebook needs 6 * 4 * 4 / 4 * width * height / 16 * sizeof(int); + * and so does the points buffer. */ + enc->closest_cb = + av_malloc_array(roq->width * roq->height, 3 * sizeof(int)); + if (!enc->tmpData || !enc->this_motion4 || !enc->last_motion4 || - !enc->this_motion8 || !enc->last_motion8) + !enc->this_motion8 || !enc->last_motion8 || !enc->closest_cb) return AVERROR(ENOMEM); - return 0; + enc->points = enc->closest_cb + roq->width * roq->height * 3 / 2; + + return create_cel_evals(enc); } static void roq_write_video_info_chunk(RoqEncContext *enc) From patchwork Sun Feb 28 18:45:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 26030 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 773BC449D4F for ; Sun, 28 Feb 2021 20:45:58 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 5CEC968A8F3; Sun, 28 Feb 2021 20:45:58 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ej1-f47.google.com (mail-ej1-f47.google.com [209.85.218.47]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2404A68807B for ; Sun, 28 Feb 2021 20:45:50 +0200 (EET) Received: by mail-ej1-f47.google.com with SMTP id bm21so5270136ejb.4 for ; Sun, 28 Feb 2021 10:45:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=KdKLxpY2JC2AaP1XXlEpMK+Ut4LyCJFYhwbmbsmIzx4=; b=SjyNsT5SjxUAoT+InjsePGeQuwZQYd79WAUFju7clYoQoI1ZTxIgXa2beT731vO+HJ +gmmanTrv77adhOOwEy5m38vvrqNbEvcXtXUNNXjS/Tn6PZvHnRdlcPWCxAIaamtm1Ja 8LvyBLLjzjuvw/GpxTjGd2WcOqjsZVnQAIVxO6o/g5o7zdi9JLxHhvoXU9KaYKbovgRC Eoh5gfXucJv+EGpBTV379u0CWWrEqhl8jao2TJoi7gJNy30caxJ07/Rlu4T+z5qMyxGL QopDyf+ujcylH3An4a5Y38MMlqQJRetTvHBJQBnSBL9mdolURAQly0fKEiyN/03aVYUt P0YQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=KdKLxpY2JC2AaP1XXlEpMK+Ut4LyCJFYhwbmbsmIzx4=; b=tzy/S+8gyb693Eg9QojDRY6VYhaEsm+Rj5heQzvfQYg3WtppixYEHskLRb0nu17Tod In8Wx5dm1V3mh73eJG6oF0oW4lCjPf8pNYEjM4pMGErc3NYTPB9LvC/arE5k9F/9e+vg gHk6Q5LuW47ZPqjNg4l43nsu6cqnUjtAljDj3VlK1Jc32xVBwDNNxB7/y07kJrqRSVZp juBsCpxIitAnoHbIznOHcDyvESDxeIadQhjW85p8pv69XH/Is+/ONQWnfiHPC6MRmE77 FR1JgpeRZzpZlq9bhLaTaWXFmqPtPc0i8w3LkofY8dBXpFRbzGF1AcUCfSt8VCkdCodA nNsQ== X-Gm-Message-State: AOAM533Plq6Lrj3G7zWifekeIJGsCa7bBnbMKHxjFwVpb3wh+zTlCvdG wdJGfVomYbLtrP83xwNrEwOOxwpPYlE= X-Google-Smtp-Source: ABdhPJztPceu9FgAekgn9C5WDbFJ7e82/JeR3jD0vCVc5KB+MDo4xvaE/dwGXw2ykXEyEirN8cKliQ== X-Received: by 2002:a17:906:304a:: with SMTP id d10mr12488308ejd.507.1614537949427; Sun, 28 Feb 2021 10:45:49 -0800 (PST) Received: from sblaptop.fritz.box (ipbcc1aa4b.dynamic.kabel-deutschland.de. [188.193.170.75]) by smtp.gmail.com with ESMTPSA id d14sm13126675edk.81.2021.02.28.10.45.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Feb 2021 10:45:49 -0800 (PST) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Sun, 28 Feb 2021 19:45:09 +0100 Message-Id: <20210228184510.247073-4-andreas.rheinhardt@gmail.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210228184510.247073-1-andreas.rheinhardt@gmail.com> References: <20210228184510.247073-1-andreas.rheinhardt@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 4/5] avcodec/roqvideoenc: Avoid intermediate buffer 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: Andreas Rheinhardt Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Signed-off-by: Andreas Rheinhardt --- libavcodec/roqvideoenc.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c index 7ce0332f5b..d65c740d5f 100644 --- a/libavcodec/roqvideoenc.c +++ b/libavcodec/roqvideoenc.c @@ -773,7 +773,7 @@ static void reconstruct_and_encode_image(RoqEncContext *enc, /** * Create a single YUV cell from a 2x2 section of the image */ -static inline void frame_block_to_cell(uint8_t *block, uint8_t * const *data, +static inline void frame_block_to_cell(int *block, uint8_t * const *data, int top, int left, const int *stride) { int i, j, u=0, v=0; @@ -787,14 +787,14 @@ static inline void frame_block_to_cell(uint8_t *block, uint8_t * const *data, v += data[2][x]; } - *block++ = (u+2)/4; - *block++ = (v+2)/4; + *block++ = (u + 2) / 4 * CHROMA_BIAS; + *block++ = (v + 2) / 4 * CHROMA_BIAS; } /** * Create YUV clusters for the entire image */ -static void create_clusters(const AVFrame *frame, int w, int h, uint8_t *yuvClusters) +static void create_clusters(const AVFrame *frame, int w, int h, int *points) { int i, j, k, l; @@ -802,9 +802,9 @@ static void create_clusters(const AVFrame *frame, int w, int h, uint8_t *yuvClus for (j=0; jdata, + frame_block_to_cell(points + (l + 2*k)*6, frame->data, i+2*k, j+2*l, frame->linesize); - yuvClusters += 24; + points += 24; } } @@ -853,23 +853,15 @@ static int generate_new_codebooks(RoqEncContext *enc, RoqTempdata *tempData) int max = roq->width * roq->height / 16; uint8_t mb2[3*4]; roq_cell *results4 = av_malloc(sizeof(roq_cell)*MAX_CBS_4x4*4); - uint8_t *yuvClusters=av_malloc_array(max, sizeof(int)*6*4); int *points = enc->points; - int bias; - if (!results4 || !yuvClusters) { + if (!results4) { ret = AVERROR(ENOMEM); goto out; } /* Subsample YUV data */ - create_clusters(enc->frame_to_enc, roq->width, roq->height, yuvClusters); - - /* Cast to integer and apply chroma bias */ - for (i=0; iframe_to_enc, roq->width, roq->height, points); /* Create 4x4 codebooks */ if ((ret = generate_codebook(enc, points, max, @@ -902,7 +894,6 @@ static int generate_new_codebooks(RoqEncContext *enc, RoqTempdata *tempData) codebooks->unpacked_cb4_enlarged + i*8*8*3); } out: - av_free(yuvClusters); av_free(results4); return ret; } From patchwork Sun Feb 28 18:45:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Rheinhardt X-Patchwork-Id: 26031 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 662EC449D4F for ; Sun, 28 Feb 2021 20:46:01 +0200 (EET) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 4846A68AAE8; Sun, 28 Feb 2021 20:46:01 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ed1-f52.google.com (mail-ed1-f52.google.com [209.85.208.52]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 2196868AAD5 for ; Sun, 28 Feb 2021 20:45:51 +0200 (EET) Received: by mail-ed1-f52.google.com with SMTP id s8so17793611edd.5 for ; Sun, 28 Feb 2021 10:45:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/Y76/XjZ3YQ2ooLV+HiGiN88xOeUYcI67hleoZi+PdQ=; b=THUV0sxMjVf1KXjNOnEKaSVPddlCCABzn7oYQxA0LN2yuWNFXtbN4g4D6EJoDmm5dm l+YfYTboYqzAs7Sqo+tEK4pMGQKqzVl99V0dTm/obWq1Omix1ku/6FEdKZN6dacGvRcq rQEYjcrwdbxV6wY/Qu3gdEo/7k43Q/LV/dEDuEViVgqrSZH9wvJHAuYHI202s3qmytR3 btuaVn3P5yZE30tAO21y3oGfZHj5zSc1Wtgu7cL1kizYPMKHqJ3u3TR7ABr+/jRKwc7h 1GhAiXFxKFL8qxdCsAN/6TGc8TYja+cQK9ipf8uJ7vKuYqVh4tzR8e5BWpyUGLlfT2m/ 4JQA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/Y76/XjZ3YQ2ooLV+HiGiN88xOeUYcI67hleoZi+PdQ=; b=fuqHAqvv4Ocb5z7j5mZf6QOXUmeUQXz7GZOE/sIk0sqGSx6FakqlKLFBSzShMRiZ3J JWsoVcUC5O7OSUhB+gm3/1AfYpKZCGe//KEV9EBmaWjzwOStuNmA3qGv8KEQCBedG3Mp BOmUQ08REWHvWDCmEh4rJ7RvMuA0oSZLbVfkz7gY5PgQtA6ylOxHG6r6pQdb66/t8sow cVHym8xZa/D8RNarwIDw2MxyX6XKiFlzMB8aDb2Hry+HYNjORINC3I3rvs3HGwxMsWSF LPsp2LGBgWhO2WYFwtp9nLIwwNuvg3Eky8EHSMRo6vU7y1Ou32I7KgOwEAvNHVyYnJro fLOw== X-Gm-Message-State: AOAM533xwI3se1wK1KQqbvhNJlQvvwea4SRbpzAQbpKcE2lQLupCuB6Y nmNnsaEelbsLO3rAz+FQVcLZ/6tCdG4= X-Google-Smtp-Source: ABdhPJz255MEyVZxqNBw0o5/SyMfMnKQsegpg9a998D1mVEbXQh3rasilT7MhNOY6dxtZHYuZGLs8A== X-Received: by 2002:aa7:d2d5:: with SMTP id k21mr7421325edr.216.1614537950273; Sun, 28 Feb 2021 10:45:50 -0800 (PST) Received: from sblaptop.fritz.box (ipbcc1aa4b.dynamic.kabel-deutschland.de. [188.193.170.75]) by smtp.gmail.com with ESMTPSA id d14sm13126675edk.81.2021.02.28.10.45.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 28 Feb 2021 10:45:49 -0800 (PST) From: Andreas Rheinhardt To: ffmpeg-devel@ffmpeg.org Date: Sun, 28 Feb 2021 19:45:10 +0100 Message-Id: <20210228184510.247073-5-andreas.rheinhardt@gmail.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20210228184510.247073-1-andreas.rheinhardt@gmail.com> References: <20210228184510.247073-1-andreas.rheinhardt@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 5/5] avcodec/roqvideoenc: Avoid allocating buffers separately 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: Andreas Rheinhardt Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" This is possible because their size is known at compile-time; so they can be put directly into the context and don't need to be allocated for every frame. Signed-off-by: Andreas Rheinhardt --- libavcodec/roqvideoenc.c | 146 ++++++++++++++++++--------------------- 1 file changed, 68 insertions(+), 78 deletions(-) diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c index d65c740d5f..1ab0de0abb 100644 --- a/libavcodec/roqvideoenc.c +++ b/libavcodec/roqvideoenc.c @@ -78,6 +78,36 @@ /* The cast is useful when multiplying it by INT_MAX */ #define ROQ_LAMBDA_SCALE ((uint64_t) FF_LAMBDA_SCALE) +typedef struct RoqCodebooks { + int numCB4; + int numCB2; + int usedCB2[MAX_CBS_2x2]; + int usedCB4[MAX_CBS_4x4]; + uint8_t unpacked_cb2[MAX_CBS_2x2*2*2*3]; + uint8_t unpacked_cb4[MAX_CBS_4x4*4*4*3]; + uint8_t unpacked_cb4_enlarged[MAX_CBS_4x4*8*8*3]; +} RoqCodebooks; + +/** + * Temporary vars + */ +typedef struct RoqTempData +{ + int f2i4[MAX_CBS_4x4]; + int i2f4[MAX_CBS_4x4]; + int f2i2[MAX_CBS_2x2]; + int i2f2[MAX_CBS_2x2]; + + int mainChunkSize; + + int numCB4; + int numCB2; + + RoqCodebooks codebooks; + + int used_option[4]; +} RoqTempData; + typedef struct SubcelEvaluation { int eval_dist[4]; int best_bit_use; @@ -115,7 +145,9 @@ typedef struct RoqEncContext { const AVFrame *frame_to_enc; uint8_t *out_buf; - struct RoqTempData *tmpData; + RoqTempData tmp_data; + roq_cell results4[4 * MAX_CBS_4x4]; + int tmp_codebook_buf[FFMAX(24 * MAX_CBS_4x4, 6 * MAX_CBS_2x2)]; CelEvaluation *cel_evals; int *closest_cb; @@ -233,36 +265,6 @@ static inline int squared_diff_macroblock(uint8_t a[], uint8_t b[], int size) return sdiff; } -typedef struct RoqCodebooks { - int numCB4; - int numCB2; - int usedCB2[MAX_CBS_2x2]; - int usedCB4[MAX_CBS_4x4]; - uint8_t unpacked_cb2[MAX_CBS_2x2*2*2*3]; - uint8_t unpacked_cb4[MAX_CBS_4x4*4*4*3]; - uint8_t unpacked_cb4_enlarged[MAX_CBS_4x4*8*8*3]; -} RoqCodebooks; - -/** - * Temporary vars - */ -typedef struct RoqTempData -{ - int f2i4[MAX_CBS_4x4]; - int i2f4[MAX_CBS_4x4]; - int f2i2[MAX_CBS_2x2]; - int i2f2[MAX_CBS_2x2]; - - int mainChunkSize; - - int numCB4; - int numCB2; - - RoqCodebooks codebooks; - - int used_option[4]; -} RoqTempdata; - /** * Initialize cel evaluators and set their source coordinates */ @@ -424,9 +426,10 @@ static void motion_search(RoqEncContext *enc, int blocksize) * Get distortion for all options available to a subcel */ static void gather_data_for_subcel(SubcelEvaluation *subcel, int x, - int y, RoqEncContext *enc, RoqTempdata *tempData) + int y, RoqEncContext *enc) { RoqContext *const roq = &enc->common; + RoqTempData *const tempData = &enc->tmp_data; uint8_t mb4[4*4*3]; uint8_t mb2[2*2*3]; int cluster_index; @@ -488,10 +491,10 @@ static void gather_data_for_subcel(SubcelEvaluation *subcel, int x, /** * Get distortion for all options available to a cel */ -static void gather_data_for_cel(CelEvaluation *cel, RoqEncContext *enc, - RoqTempdata *tempData) +static void gather_data_for_cel(CelEvaluation *cel, RoqEncContext *enc) { RoqContext *const roq = &enc->common; + RoqTempData *const tempData = &enc->tmp_data; uint8_t mb8[8*8*3]; int index = cel->sourceY * roq->width / 64 + cel->sourceX/8; int i, j, best_dist, divide_bit_use; @@ -523,10 +526,10 @@ static void gather_data_for_cel(CelEvaluation *cel, RoqEncContext *enc, index_mb(mb8, tempData->codebooks.unpacked_cb4_enlarged, tempData->codebooks.numCB4, &cel->cbEntry, 8); - gather_data_for_subcel(cel->subCels + 0, cel->sourceX+0, cel->sourceY+0, enc, tempData); - gather_data_for_subcel(cel->subCels + 1, cel->sourceX+4, cel->sourceY+0, enc, tempData); - gather_data_for_subcel(cel->subCels + 2, cel->sourceX+0, cel->sourceY+4, enc, tempData); - gather_data_for_subcel(cel->subCels + 3, cel->sourceX+4, cel->sourceY+4, enc, tempData); + gather_data_for_subcel(cel->subCels + 0, cel->sourceX+0, cel->sourceY+0, enc); + gather_data_for_subcel(cel->subCels + 1, cel->sourceX+4, cel->sourceY+0, enc); + gather_data_for_subcel(cel->subCels + 2, cel->sourceX+0, cel->sourceY+4, enc); + gather_data_for_subcel(cel->subCels + 3, cel->sourceX+4, cel->sourceY+4, enc); cel->eval_dist[RoQ_ID_CCC] = 0; divide_bit_use = 0; @@ -563,9 +566,10 @@ static void gather_data_for_cel(CelEvaluation *cel, RoqEncContext *enc, } } -static void remap_codebooks(RoqEncContext *enc, RoqTempdata *tempData) +static void remap_codebooks(RoqEncContext *enc) { RoqContext *const roq = &enc->common; + RoqTempData *const tempData = &enc->tmp_data; int i, j, idx=0; /* Make remaps for the final codebook usage */ @@ -596,9 +600,10 @@ static void remap_codebooks(RoqEncContext *enc, RoqTempdata *tempData) /** * Write codebook chunk */ -static void write_codebooks(RoqEncContext *enc, RoqTempdata *tempData) +static void write_codebooks(RoqEncContext *enc) { RoqContext *const roq = &enc->common; + RoqTempData *const tempData = &enc->tmp_data; int i, j; uint8_t **outp= &enc->out_buf; @@ -652,10 +657,10 @@ static void write_typecode(CodingSpool *s, uint8_t type) } static void reconstruct_and_encode_image(RoqEncContext *enc, - RoqTempdata *tempData, int w, int h, int numBlocks) { RoqContext *const roq = &enc->common; + RoqTempData *const tempData = &enc->tmp_data; int i, j, k; int x, y; int subX, subY; @@ -815,20 +820,17 @@ static int generate_codebook(RoqEncContext *enc, int i, j, k, ret = 0; int c_size = size*size/4; int *buf; - int *codebook = av_malloc_array(6*c_size, cbsize*sizeof(int)); + int *codebook = enc->tmp_codebook_buf; int *closest_cb = enc->closest_cb; - if (!codebook) - return AVERROR(ENOMEM); - ret = avpriv_init_elbg(points, 6 * c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->randctx); if (ret < 0) - goto out; + return ret; ret = avpriv_do_elbg(points, 6 * c_size, inputCount, codebook, cbsize, 1, closest_cb, &enc->randctx); if (ret < 0) - goto out; + return ret; buf = codebook; for (i=0; iv = (*buf++ + CHROMA_BIAS/2)/CHROMA_BIAS; results++; } -out: - av_free(codebook); - return ret; + return 0; } -static int generate_new_codebooks(RoqEncContext *enc, RoqTempdata *tempData) +static int generate_new_codebooks(RoqEncContext *enc) { int i, j, ret = 0; - RoqCodebooks *codebooks = &tempData->codebooks; + RoqCodebooks *codebooks = &enc->tmp_data.codebooks; RoqContext *const roq = &enc->common; int max = roq->width * roq->height / 16; uint8_t mb2[3*4]; - roq_cell *results4 = av_malloc(sizeof(roq_cell)*MAX_CBS_4x4*4); int *points = enc->points; - if (!results4) { - ret = AVERROR(ENOMEM); - goto out; - } - /* Subsample YUV data */ create_clusters(enc->frame_to_enc, roq->width, roq->height, points); - /* Create 4x4 codebooks */ - if ((ret = generate_codebook(enc, points, max, - results4, 4, (enc->quake3_compat ? MAX_CBS_4x4-1 : MAX_CBS_4x4))) < 0) - goto out; - codebooks->numCB4 = (enc->quake3_compat ? MAX_CBS_4x4-1 : MAX_CBS_4x4); + /* Create 4x4 codebooks */ + if ((ret = generate_codebook(enc, points, max, enc->results4, + 4, codebooks->numCB4)) < 0) + return ret; + /* Create 2x2 codebooks */ if ((ret = generate_codebook(enc, points, max * 4, roq->cb2x2, 2, MAX_CBS_2x2)) < 0) - goto out; + return ret; codebooks->numCB2 = MAX_CBS_2x2; @@ -884,7 +878,7 @@ static int generate_new_codebooks(RoqEncContext *enc, RoqTempdata *tempData) /* Index all 4x4 entries to the 2x2 entries, unpack, and enlarge */ for (i=0; inumCB4; i++) { for (j=0; j<4; j++) { - unpack_roq_cell(&results4[4*i + j], mb2); + unpack_roq_cell(&enc->results4[4*i + j], mb2); index_mb(mb2, codebooks->unpacked_cb2, codebooks->numCB2, &roq->cb4x4[i].idx[j], 2); } @@ -893,20 +887,19 @@ static int generate_new_codebooks(RoqEncContext *enc, RoqTempdata *tempData) enlarge_roq_mb4(codebooks->unpacked_cb4 + i*4*4*3, codebooks->unpacked_cb4_enlarged + i*8*8*3); } -out: - av_free(results4); - return ret; + + return 0; } static int roq_encode_video(RoqEncContext *enc) { - RoqTempdata *tempData = enc->tmpData; + RoqTempData *const tempData = &enc->tmp_data; RoqContext *const roq = &enc->common; int ret; memset(tempData, 0, sizeof(*tempData)); - ret = generate_new_codebooks(enc, tempData); + ret = generate_new_codebooks(enc); if (ret < 0) return ret; @@ -917,7 +910,7 @@ static int roq_encode_video(RoqEncContext *enc) retry_encode: for (int i = 0; i < roq->width * roq->height / 64; i++) - gather_data_for_cel(enc->cel_evals + i, enc, tempData); + gather_data_for_cel(enc->cel_evals + i, enc); /* Quake 3 can't handle chunks bigger than 65535 bytes */ if (tempData->mainChunkSize/8 > 65535 && enc->quake3_compat) { @@ -940,11 +933,11 @@ static int roq_encode_video(RoqEncContext *enc) goto retry_encode; } - remap_codebooks(enc, tempData); + remap_codebooks(enc); - write_codebooks(enc, tempData); + write_codebooks(enc); - reconstruct_and_encode_image(enc, tempData, roq->width, roq->height, + reconstruct_and_encode_image(enc, roq->width, roq->height, roq->width * roq->height / 64); /* Rotate frame history */ @@ -964,7 +957,6 @@ static av_cold int roq_encode_end(AVCodecContext *avctx) av_frame_free(&enc->common.current_frame); av_frame_free(&enc->common.last_frame); - av_freep(&enc->tmpData); av_freep(&enc->cel_evals); av_freep(&enc->closest_cb); av_freep(&enc->this_motion4); @@ -1009,8 +1001,6 @@ static av_cold int roq_encode_init(AVCodecContext *avctx) if (!roq->last_frame || !roq->current_frame) return AVERROR(ENOMEM); - enc->tmpData = av_malloc(sizeof(RoqTempdata)); - enc->this_motion4 = av_mallocz_array(roq->width * roq->height / 16, sizeof(motion_vect)); @@ -1028,7 +1018,7 @@ static av_cold int roq_encode_init(AVCodecContext *avctx) enc->closest_cb = av_malloc_array(roq->width * roq->height, 3 * sizeof(int)); - if (!enc->tmpData || !enc->this_motion4 || !enc->last_motion4 || + if (!enc->this_motion4 || !enc->last_motion4 || !enc->this_motion8 || !enc->last_motion8 || !enc->closest_cb) return AVERROR(ENOMEM);