From patchwork Mon Mar 30 11:45:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 18517 Delivered-To: andriy.gelman@gmail.com Received: by 2002:a0c:ab15:0:0:0:0:0 with SMTP id h21csp2134925qvb; Mon, 30 Mar 2020 04:46:43 -0700 (PDT) X-Google-Smtp-Source: ADFU+vug4ufxHrsNzTHTHazvkGB4LxYCcJRxH9uF1QJO1Q4lo/WIhdk3PVMfgqLPscb9ZrSU1MDM X-Received: by 2002:a17:906:3008:: with SMTP id 8mr4905642ejz.162.1585568802939; Mon, 30 Mar 2020 04:46:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1585568802; cv=none; d=google.com; s=arc-20160816; b=E6rXILkTn738kHwkURNB1jrLiq2fQFR/JZgYIV53igOayJ1NvllVV8smwtLRu9BWAo quSrTOUBv4v04QtCE/urMC/CD4QV7KcWypyxhk09uCpMFmdPht7JiLk3kukfhFoLCs8V q27IGt4aEu+309nxZo4TL8kxGN05k1C7w6x0fCOj22srooFxs5SwO3vPX5ERTFWbvDFy Hsvd2kT65CDhB9Numc8PZEQzB9hN+lwLc6W1gonYSRQSBRobXSuTVtiKu8KUTt7lsioj PY6rbrXvnGkXgd7Gp+hOAXm9YMb0xFpycPnZnAz4UKw0t3YJtm+BFf6MTX67q8ut+E8B ByHg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:reply-to:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:subject:mime-version:references:in-reply-to:message-id :date:to:from:delivered-to; bh=pKdVmXXRqH3pg+YHS5x7tD5MA7dcjYKokMEStauxNfk=; b=xS/r9nD8VxMA+JsPZ32OiC6SfxgO+kccumYnj53o9RwAZy6AQ13oeoRgUAmATH4f6F 09C7c4oR6kZ8Vu1q7yxu9H880h9bSv4Zy8ut1vznrfQYfwYvGTZEJtAP7lNgtfCoyMLZ LrejcQER02fhlJYRjyrRE3fjBHhsgaoLKeDpx68hWcztiMfvnrqThuDvrHlDMy6XyuoR jZcZc8wUrbsjtCOHYoShRsqUDu2q9DHzIieM5wBlXOIbXr9okKxV2XdP+SrO2OMdQHRM thtQN0zK4I7yKYyOVNof7MMhPxBzlg9yLs1tCcjGcGvXOpI5UVgHslboHOyeKHdp53og KqOw== ARC-Authentication-Results: i=1; mx.google.com; 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 i3si8382747ejy.255.2020.03.30.04.46.42; Mon, 30 Mar 2020 04:46:42 -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; 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 6742668B051; Mon, 30 Mar 2020 14:46:03 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail.red.khirnov.net (red.khirnov.net [176.97.15.12]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 9201968AEB0 for ; Mon, 30 Mar 2020 14:45:55 +0300 (EEST) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id 4782D28661B for ; Mon, 30 Mar 2020 13:45:55 +0200 (CEST) Received: from mail.red.khirnov.net ([IPv6:::1]) by localhost (mail.red.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id EQ5Eoia1jmoy for ; Mon, 30 Mar 2020 13:45:54 +0200 (CEST) Received: from quelana.khirnov.net (unknown [IPv6:2a00:c500:61:23b::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) client-signature RSA-PSS (2048 bits)) (Client CN "quelana.khirnov.net", Issuer "smtp.khirnov.net SMTP CA" (verified OK)) by mail.red.khirnov.net (Postfix) with ESMTPS id B9C9C284F05 for ; Mon, 30 Mar 2020 13:45:54 +0200 (CEST) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id 4321A21249 for ; Mon, 30 Mar 2020 13:45:54 +0200 (CEST) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id 6-2CpocCTGTf for ; Mon, 30 Mar 2020 13:45:52 +0200 (CEST) Received: from libav.daenerys.khirnov.net (libav.daenerys.khirnov.net [IPv6:2a00:c500:561:201::7]) by quelana.khirnov.net (Postfix) with ESMTP id CCE0521256 for ; Mon, 30 Mar 2020 13:45:37 +0200 (CEST) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id BADA820E0041; Mon, 30 Mar 2020 13:45:37 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Mon, 30 Mar 2020 13:45:26 +0200 Message-Id: <20200330114526.11086-7-anton@khirnov.net> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200330114526.11086-1-anton@khirnov.net> References: <20200330114526.11086-1-anton@khirnov.net> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 7/7] vp9dec: support exporting QP tables through the AVVideoEncParams API X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: 9tn3LsXPzJfU Content-Length: 9654 --- libavcodec/vp9.c | 74 ++++++++++++++++++++++++++++++++++++ libavcodec/vp9block.c | 8 ++++ libavcodec/vp9dec.h | 8 ++++ libavutil/video_enc_params.h | 1 + 4 files changed, 91 insertions(+) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index e03891887b..8baf337f1b 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -34,6 +34,7 @@ #include "vp9dec.h" #include "libavutil/avassert.h" #include "libavutil/pixdesc.h" +#include "libavutil/video_enc_params.h" #define VP9_SYNCCODE 0x498342 @@ -97,6 +98,7 @@ static void vp9_tile_data_free(VP9TileData *td) { av_freep(&td->b_base); av_freep(&td->block_base); + av_freep(&td->block_structure); } static void vp9_frame_unref(AVCodecContext *avctx, VP9Frame *f) @@ -326,6 +328,12 @@ static int update_block_buffers(AVCodecContext *avctx) td->eob_base = (uint8_t *) (td->uvblock_base[1] + sbs * chroma_blocks * bytesperpixel); td->uveob_base[0] = td->eob_base + 16 * 16 * sbs; td->uveob_base[1] = td->uveob_base[0] + chroma_eobs * sbs; + + if (avctx->export_side_data & AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS) { + td->block_structure = av_malloc_array(s->cols * s->rows, sizeof(*td->block_structure)); + if (!td->block_structure) + return AVERROR(ENOMEM); + } } else { for (i = 1; i < s->active_tile_cols; i++) vp9_tile_data_free(&s->td[i]); @@ -341,6 +349,12 @@ static int update_block_buffers(AVCodecContext *avctx) s->td[i].eob_base = (uint8_t *) (s->td[i].uvblock_base[1] + chroma_blocks * bytesperpixel); s->td[i].uveob_base[0] = s->td[i].eob_base + 16 * 16; s->td[i].uveob_base[1] = s->td[i].uveob_base[0] + chroma_eobs; + + if (avctx->export_side_data & AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS) { + s->td[i].block_structure = av_malloc_array(s->cols * s->rows, sizeof(*td->block_structure)); + if (!s->td[i].block_structure) + return AVERROR(ENOMEM); + } } } s->block_alloc_using_2pass = s->s.frames[CUR_FRAME].uses_2pass; @@ -1475,6 +1489,59 @@ int loopfilter_proc(AVCodecContext *avctx) } #endif +static int vp9_export_enc_params(VP9Context *s, VP9Frame *frame) +{ + AVVideoEncParams *par; + unsigned int tile, nb_blocks = 0; + + if (s->s.h.segmentation.enabled) { + for (tile = 0; tile < s->active_tile_cols; tile++) + nb_blocks += s->td[tile].nb_block_structure; + } + + par = av_video_enc_params_create_side_data(frame->tf.f, nb_blocks); + if (!par) + return AVERROR(ENOMEM); + + par->type = AV_VIDEO_ENC_PARAMS_VP9; + + par->qp = s->s.h.yac_qi; + par->delta_qp[0][0] = s->s.h.ydc_qdelta; + par->delta_qp[1][0] = s->s.h.uvdc_qdelta; + par->delta_qp[2][0] = s->s.h.uvdc_qdelta; + par->delta_qp[1][1] = s->s.h.uvac_qdelta; + par->delta_qp[2][1] = s->s.h.uvac_qdelta; + + if (nb_blocks) { + unsigned int block = 0; + unsigned int tile, block_tile; + + for (tile = 0; tile < s->active_tile_cols; tile++) { + VP9TileData *td = &s->td[tile]; + + for (block_tile = 0; block_tile < td->nb_block_structure; block_tile++) { + AVVideoBlockParams *b = av_video_enc_params_block(par, block++); + unsigned int row = td->block_structure[block_tile].row; + unsigned int col = td->block_structure[block_tile].col; + uint8_t seg_id = frame->segmentation_map[row * 8 * s->sb_cols + col]; + + b->src_x = col * 8; + b->src_y = row * 8; + b->w = 1 << (3 + td->block_structure[block_tile].block_size_idx_x); + b->h = 1 << (3 + td->block_structure[block_tile].block_size_idx_y); + + if (s->s.h.segmentation.feat[seg_id].q_enabled) { + b->delta_qp = s->s.h.segmentation.feat[seg_id].q_val; + if (s->s.h.segmentation.absolute_vals) + b->delta_qp -= par->qp; + } + } + } + } + + return 0; +} + static int vp9_decode_frame(AVCodecContext *avctx, void *frame, int *got_frame, AVPacket *pkt) { @@ -1621,6 +1688,7 @@ FF_ENABLE_DEPRECATION_WARNINGS s->td[i].eob = s->td[i].eob_base; s->td[i].uveob[0] = s->td[i].uveob_base[0]; s->td[i].uveob[1] = s->td[i].uveob_base[1]; + s->td[i].nb_block_structure = 0; } #if HAVE_THREADS @@ -1677,6 +1745,12 @@ FF_ENABLE_DEPRECATION_WARNINGS } while (s->pass++ == 1); ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); + if (avctx->export_side_data & AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS) { + ret = vp9_export_enc_params(s, &s->s.frames[CUR_FRAME]); + if (ret < 0) + return ret; + } + finish: // ref frame setup for (i = 0; i < 8; i++) { diff --git a/libavcodec/vp9block.c b/libavcodec/vp9block.c index 1c3f7a7225..ec16e26c69 100644 --- a/libavcodec/vp9block.c +++ b/libavcodec/vp9block.c @@ -1290,6 +1290,14 @@ void ff_vp9_decode_block(VP9TileData *td, int row, int col, b->uvtx = b->tx - ((s->ss_h && w4 * 2 == (1 << b->tx)) || (s->ss_v && h4 * 2 == (1 << b->tx))); + if (td->block_structure) { + td->block_structure[td->nb_block_structure].row = row; + td->block_structure[td->nb_block_structure].col = col; + td->block_structure[td->nb_block_structure].block_size_idx_x = av_log2(w4); + td->block_structure[td->nb_block_structure].block_size_idx_y = av_log2(h4); + td->nb_block_structure++; + } + if (!b->skip) { int has_coeffs; diff --git a/libavcodec/vp9dec.h b/libavcodec/vp9dec.h index de02b146f0..65a8d2fc51 100644 --- a/libavcodec/vp9dec.h +++ b/libavcodec/vp9dec.h @@ -221,6 +221,14 @@ struct VP9TileData { struct { int x, y; } min_mv, max_mv; int16_t *block_base, *block, *uvblock_base[2], *uvblock[2]; uint8_t *eob_base, *uveob_base[2], *eob, *uveob[2]; + + struct { + unsigned int row:14; + unsigned int col:14; + unsigned int block_size_idx_x:2; + unsigned int block_size_idx_y:2; + } *block_structure; + unsigned int nb_block_structure; }; void ff_vp9_fill_mv(VP9TileData *td, VP56mv *mv, int mode, int sb); diff --git a/libavutil/video_enc_params.h b/libavutil/video_enc_params.h index b19c7a5925..e38f1312fb 100644 --- a/libavutil/video_enc_params.h +++ b/libavutil/video_enc_params.h @@ -30,6 +30,7 @@ enum AVVideoEncParamsType { AV_VIDEO_ENC_PARAMS_MPEG2, AV_VIDEO_ENC_PARAMS_H263, AV_VIDEO_ENC_PARAMS_H264, + AV_VIDEO_ENC_PARAMS_VP9, }; /**