From patchwork Mon Mar 30 11:45:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Khirnov X-Patchwork-Id: 18516 Delivered-To: andriy.gelman@gmail.com Received: by 2002:a0c:ab15:0:0:0:0:0 with SMTP id h21csp2134864qvb; Mon, 30 Mar 2020 04:46:37 -0700 (PDT) X-Google-Smtp-Source: ADFU+vvbK2C43ngbmSMutQ5V7k6B/FPtKG7wQSLFKS3Wie+abeeACJy/2mcpsnCfg8ftETMPQqQq X-Received: by 2002:a05:6402:504:: with SMTP id m4mr11219736edv.367.1585568797107; Mon, 30 Mar 2020 04:46:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1585568797; cv=none; d=google.com; s=arc-20160816; b=T1cvOU0fGtzv8wKPlWK7WDruCpMFcu+MSNAIDqfrI/fffjuS1NjA6vvTcTdSxBUjk7 EbaDTC3pKHeobfYOWBSKISDNM/5y71vLekx+ZY8Fd0Rk3sdwQS7S6ri220jzd/l7JTIB OLn1a+lj01hHrAiI7wM/6tXhj8IYufkiud1rmvdloXMLMVQX7X4FFvFv+sJVAGcEoq23 0h/P+T2xMHnDES0Cmpbp3Do6ytQAuZbbquhySGwgytL27r/7hufrCAXYKs6i56enXRIT WF2hEOrz5dZvsd4EwHX4etRpMlhd73r+lZwsxp97vgDjtco14mVWzbnCUeWlY6TUEaSL ZIEA== 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=V9geHt87nOtrkVZXfitiIdPUrG9u8vWIzPLshgMNYs8=; b=mJ25xKhwcQ0p+Z1rlODBSTpkGzmc4XqAJWSsukBHURjakPFSV4w3APGJTRl4Lmz3j/ /CRdBj0KzfFeA21UrHDFBB1xvZm1MecH1w6At9qUHat/I4mAyDG5J1qVPSjOZtBvLKtn TYGfRzTlitmvOIgiMpesaG4Q2ulLCvRrXDCKtInmWlyJ6zmmuqmjMKyT905rZFDowc0G R+zeps/TutTI1b0tClCEkBEnR+WSpw2OIhQLdzSTCztTDK0kLE5fMzwH4KVXqNSJOdQk nqUPJ1I5wLMo7WGDfhUkQ4MByoR2k+/s2QAgaenVEofEvtxT8utl1v2wYTbHAvXUg1JU W6Aw== 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 w28si8539327edl.601.2020.03.30.04.46.36; Mon, 30 Mar 2020 04:46:37 -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 0809068A659; 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 BC06868AA3D for ; Mon, 30 Mar 2020 14:45:53 +0300 (EEST) Received: from localhost (localhost [IPv6:::1]) by mail.red.khirnov.net (Postfix) with ESMTP id 75323286595 for ; Mon, 30 Mar 2020 13:45:53 +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 7lFTVqD-OFOC for ; Mon, 30 Mar 2020 13:45:53 +0200 (CEST) Received: from quelana.khirnov.net (unknown [IPv6:2002:b061:f0a:201:5e:e696:5100:0]) (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 06B35284F05 for ; Mon, 30 Mar 2020 13:45:53 +0200 (CEST) Received: from localhost (quelana.khirnov.net [IPv6:::1]) by quelana.khirnov.net (Postfix) with ESMTP id B830221249 for ; Mon, 30 Mar 2020 13:45:52 +0200 (CEST) Received: from quelana.khirnov.net ([IPv6:::1]) by localhost (quelana.khirnov.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id EMoRbpu0RzYH for ; Mon, 30 Mar 2020 13:45:51 +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 BC15421255 for ; Mon, 30 Mar 2020 13:45:37 +0200 (CEST) Received: by libav.daenerys.khirnov.net (Postfix, from userid 1000) id A786220E003B; Mon, 30 Mar 2020 13:45:37 +0200 (CEST) From: Anton Khirnov To: ffmpeg-devel@ffmpeg.org Date: Mon, 30 Mar 2020 13:45:24 +0200 Message-Id: <20200330114526.11086-5-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 5/7] h264dec: 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: B/F9MiTZEb/E Content-Length: 7830 --- libavcodec/h264_picture.c | 8 +++++- libavcodec/h264_slice.c | 9 +++++++ libavcodec/h264dec.c | 48 ++++++++++++++++++++++++++++++++++++ libavcodec/h264dec.h | 6 +++++ libavutil/video_enc_params.h | 1 + 5 files changed, 71 insertions(+), 1 deletion(-) diff --git a/libavcodec/h264_picture.c b/libavcodec/h264_picture.c index 2113947d1d..eec5e9fb9a 100644 --- a/libavcodec/h264_picture.c +++ b/libavcodec/h264_picture.c @@ -54,6 +54,7 @@ void ff_h264_unref_picture(H264Context *h, H264Picture *pic) av_buffer_unref(&pic->qscale_table_buf); av_buffer_unref(&pic->mb_type_buf); + av_buffer_unref(&pic->pps_buf); for (i = 0; i < 2; i++) { av_buffer_unref(&pic->motion_val_buf[i]); av_buffer_unref(&pic->ref_index_buf[i]); @@ -77,12 +78,14 @@ int ff_h264_ref_picture(H264Context *h, H264Picture *dst, H264Picture *src) dst->qscale_table_buf = av_buffer_ref(src->qscale_table_buf); dst->mb_type_buf = av_buffer_ref(src->mb_type_buf); - if (!dst->qscale_table_buf || !dst->mb_type_buf) { + dst->pps_buf = av_buffer_ref(src->pps_buf); + if (!dst->qscale_table_buf || !dst->mb_type_buf || !dst->pps_buf) { ret = AVERROR(ENOMEM); goto fail; } dst->qscale_table = src->qscale_table; dst->mb_type = src->mb_type; + dst->pps = src->pps; for (i = 0; i < 2; i++) { dst->motion_val_buf[i] = av_buffer_ref(src->motion_val_buf[i]); @@ -120,6 +123,9 @@ int ff_h264_ref_picture(H264Context *h, H264Picture *dst, H264Picture *src) dst->recovered = src->recovered; dst->invalid_gap = src->invalid_gap; dst->sei_recovery_frame_cnt = src->sei_recovery_frame_cnt; + dst->mb_width = src->mb_width; + dst->mb_height = src->mb_height; + dst->mb_stride = src->mb_stride; return 0; fail: diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index af30f6267b..775bf94f2e 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -243,6 +243,15 @@ static int alloc_picture(H264Context *h, H264Picture *pic) pic->ref_index[i] = pic->ref_index_buf[i]->data; } + pic->pps_buf = av_buffer_ref(h->ps.pps_ref); + if (!pic->pps_buf) + goto fail; + pic->pps = (const PPS*)pic->pps_buf->data; + + pic->mb_width = h->mb_width; + pic->mb_height = h->mb_height; + pic->mb_stride = h->mb_stride; + return 0; fail: ff_h264_unref_picture(h, pic); diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index fec1adfeed..242eeb9677 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -32,6 +32,8 @@ #include "libavutil/imgutils.h" #include "libavutil/opt.h" #include "libavutil/stereo3d.h" +#include "libavutil/video_enc_params.h" + #include "internal.h" #include "bytestream.h" #include "cabac.h" @@ -831,6 +833,43 @@ static int get_consumed_bytes(int pos, int buf_size) return pos; } +static int h264_export_enc_params(AVFrame *f, H264Picture *p) +{ + AVVideoEncParams *par; + unsigned int nb_mb = p->mb_height * p->mb_width; + unsigned int x, y; + + par = av_video_enc_params_create_side_data(f, nb_mb); + if (!par) + return AVERROR(ENOMEM); + + par->type = AV_VIDEO_ENC_PARAMS_H264; + + par->qp = p->pps->init_qp; + + par->delta_qp[1][0] = p->pps->chroma_qp_index_offset[0]; + par->delta_qp[1][1] = p->pps->chroma_qp_index_offset[0]; + par->delta_qp[2][0] = p->pps->chroma_qp_index_offset[1]; + par->delta_qp[2][1] = p->pps->chroma_qp_index_offset[1]; + + for (y = 0; y < p->mb_height; y++) + for (x = 0; x < p->mb_width; x++) { + const unsigned int block_idx = y * p->mb_width + x; + const unsigned int mb_xy = y * p->mb_stride + x; + AVVideoBlockParams *b = av_video_enc_params_block(par, block_idx); + + b->src_x = x * 16; + b->src_y = y * 16; + b->w = 16; + b->h = 16; + + b->delta_qp = p->qscale_table[mb_xy] - par->qp; + } + + + return 0; +} + static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp) { AVFrame *src = srcp->f; @@ -845,7 +884,16 @@ static int output_frame(H264Context *h, AVFrame *dst, H264Picture *srcp) if (srcp->sei_recovery_frame_cnt == 0) dst->key_frame = 1; + if (h->avctx->export_side_data & AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS) { + ret = h264_export_enc_params(dst, srcp); + if (ret < 0) + goto fail; + } + return 0; +fail: + av_frame_unref(dst); + return ret; } static int is_extra(const uint8_t *buf, int buf_size) diff --git a/libavcodec/h264dec.h b/libavcodec/h264dec.h index 530e2d4071..29c4d4e42c 100644 --- a/libavcodec/h264dec.h +++ b/libavcodec/h264dec.h @@ -161,6 +161,12 @@ typedef struct H264Picture { int recovered; ///< picture at IDR or recovery point + recovery count int invalid_gap; int sei_recovery_frame_cnt; + + AVBufferRef *pps_buf; + const PPS *pps; + + int mb_width, mb_height; + int mb_stride; } H264Picture; typedef struct H264Ref { diff --git a/libavutil/video_enc_params.h b/libavutil/video_enc_params.h index c1afcb3a63..b19c7a5925 100644 --- a/libavutil/video_enc_params.h +++ b/libavutil/video_enc_params.h @@ -29,6 +29,7 @@ enum AVVideoEncParamsType { AV_VIDEO_ENC_PARAMS_NONE = -1, AV_VIDEO_ENC_PARAMS_MPEG2, AV_VIDEO_ENC_PARAMS_H263, + AV_VIDEO_ENC_PARAMS_H264, }; /**