From patchwork Thu Jun 7 23:43:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Thompson X-Patchwork-Id: 9296 Delivered-To: ffmpegpatchwork@gmail.com Received: by 2002:a02:11c:0:0:0:0:0 with SMTP id c28-v6csp193853jad; Thu, 7 Jun 2018 16:46:10 -0700 (PDT) X-Google-Smtp-Source: ADUXVKIl+PSSQ2b2ASbTFq/G7AO/KaF478JTVjrWiNVRnSqfipojQULxpDc0ISrSAIbFBeqoJpUU X-Received: by 2002:adf:fe4c:: with SMTP id m12-v6mr3060298wrs.171.1528415170335; Thu, 07 Jun 2018 16:46:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1528415170; cv=none; d=google.com; s=arc-20160816; b=cQdlgkTqeOWzLBn08Hn8oYxqRVDFkE7GsSJ7wH3LwwAoOg63o8xLfhQVkJcoZtTUKb E1VBGVV4pSLek2XIZqaAFc28xQM4EOaqfKcAl4jPEDvAW7E36MbOBRyMd5mTnl2HZk0h 8kbAcQEkIN5ij0O4BK934kGQOW4r/MQszCRk3qmyqofmI+GDxOYVCT2RON02St2lublL 67WTRHwE0iPOTyqfIqbDFKgCHb3JvX5XDuzLj7I6h5HTJJoVxTLiX9ATn8D0J/awwMGC 0GOyEQsS3KAlof1GSlNjsEaWYwwyogAFOBi7XMZjpHYzMNsmSfQ8kwcyhCf76m0I9m8U rFzg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:references:in-reply-to:message-id:date :to:from:dkim-signature:delivered-to:arc-authentication-results; bh=Eur19buWSyhT5/ViVdpijttwgt7GhMkUHW+rIb+bj+s=; b=ka4CylIdPpBB8kHx1RVRuad3TIs8I4Ym4knRlfyK2Kn5Y/KuwkgKULePp5IV+GKGgq fYzOb5BvCKrMuQF7u28Arub4wfnNfbpw7XTAFwzrpWF3vM+XwguIhlHSPQB2S/+TLVom vYBOSxdTYLqjP3EG7rrg1oViPdb71tS9FEI1Gd3ffDF03/qx/AV3quS/c4yRfYUmgI+f MO+1pZHftKhiyUDDL/Ui9CJqJuUnHeeTY5HztvZwHEocl/OpApEaeprx/Sf5TL98o9xz QoamDglV3yFDGxameBTDBAt3kgLDS1ww7un0rvVzwhViBT5aenv3TFDhrEDgRfwbO6m9 NQgw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@jkqxz-net.20150623.gappssmtp.com header.s=20150623 header.b=c3vQ1cLv; 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 l18-v6si76432wmd.113.2018.06.07.16.46.09; Thu, 07 Jun 2018 16:46:10 -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=@jkqxz-net.20150623.gappssmtp.com header.s=20150623 header.b=c3vQ1cLv; 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 194F768A7F3; Fri, 8 Jun 2018 02:43:14 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr0-f173.google.com (mail-wr0-f173.google.com [209.85.128.173]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4740668A7E1 for ; Fri, 8 Jun 2018 02:43:11 +0300 (EEST) Received: by mail-wr0-f173.google.com with SMTP id l10-v6so11537182wrn.2 for ; Thu, 07 Jun 2018 16:43:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=jkqxz-net.20150623.gappssmtp.com; s=20150623; h=from:to:subject:date:message-id:in-reply-to:references; bh=PXIg8ME62/S4B8OK5PSHeFA0D8qrBiB1FlnJuMLtzt0=; b=c3vQ1cLv8sAAFUr7freRViJzrmKHadZrMeHJZdYSQ5lsxcGREhhhQhSIRy175eyRbQ /ySBjD0HbjtJjUuLFJeyfYgGRIi5fOm9K98EqfvksZwKObge1BPawfmmo0HnOr674ssx eCFk7p/MzRAPKtQHc1Cy/H9yLh/j65ft0D2DAUy11UelxlD6k0zEQ5Ig9QSSjAca14QE pZQiRVecetQxplwmpXiTv2D3SItpdpMtw3ep9LxkLzk0vwx6TxJxS7gN5WpdVOVE6sW5 h5kXZZ+Bq4SbAN9urajLbzqDFKdW9RyMZvxANfH+sEigWifSesyA/vImMB0w/QxYCrko NE/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=PXIg8ME62/S4B8OK5PSHeFA0D8qrBiB1FlnJuMLtzt0=; b=bEpnDHrtjlLC8n7eNd6HCL0aJdK1pjRXaWkMbBT2/1Z/cE0mqfoKxKts0UyrdSXhMS NJQAKQGCuPfv2Z/RvjFnrqXJ9YswdImVFlP/JgXE3UGu7TF9PUexQ7VbLtFD4nkZYeG4 bVh7XjyrTlIkq/rqCrLFqse47qXp4m6x6P38PHC8R7lT+Cf1FJDOZWfybk2kll9B5bHo AeUGjv/qrFZL4KPgwiRTu8s00pNlFjWzBmjD3H9S0nm4RQRufsv+0MCaT6jSPu8RAyRd cqLRm0/LFWMvYNH9NPPF0GEqTxxFUvmASOzIAPCzQoxeGecz0Xs7jQQA0dWXWAhNwx+Q uEBg== X-Gm-Message-State: APt69E0d608MjOx0uT1ZFVLR8nrfkt48IngBq/Ebf4hRghxrZacGk48f fhtlAv4ICv8Nd9Lts5jLzpk0TOA7 X-Received: by 2002:adf:9441:: with SMTP id 59-v6mr3016052wrq.274.1528415038126; Thu, 07 Jun 2018 16:43:58 -0700 (PDT) Received: from rywe.jkqxz.net (cpc91242-cmbg18-2-0-cust650.5-4.cable.virginm.net. [82.8.130.139]) by smtp.gmail.com with ESMTPSA id r2-v6sm18640545wrq.55.2018.06.07.16.43.56 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 07 Jun 2018 16:43:57 -0700 (PDT) From: Mark Thompson To: ffmpeg-devel@ffmpeg.org Date: Fri, 8 Jun 2018 00:43:13 +0100 Message-Id: <20180607234331.32139-19-sw@jkqxz.net> X-Mailer: git-send-email 2.16.3 In-Reply-To: <20180607234331.32139-1-sw@jkqxz.net> References: <20180607234331.32139-1-sw@jkqxz.net> Subject: [FFmpeg-devel] [PATCH v2 18/36] vaapi_encode: Clean up the GOP structure configuration 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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Choose what types of reference frames will be used based on what types are available, and make the intra-only mode explicit (GOP size one, which must be used for MJPEG). --- libavcodec/vaapi_encode.c | 83 +++++++++++++++++++++++++++-------------- libavcodec/vaapi_encode.h | 1 + libavcodec/vaapi_encode_h264.c | 4 +- libavcodec/vaapi_encode_h265.c | 4 +- libavcodec/vaapi_encode_mjpeg.c | 1 + libavcodec/vaapi_encode_mpeg2.c | 2 +- libavcodec/vaapi_encode_vp8.c | 7 +--- libavcodec/vaapi_encode_vp9.c | 7 ++-- 8 files changed, 68 insertions(+), 41 deletions(-) diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index 0e806a29e3..af9224c98f 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -680,7 +680,7 @@ static int vaapi_encode_get_next(AVCodecContext *avctx, return AVERROR(ENOMEM); if (ctx->input_order == 0 || ctx->force_idr || - ctx->gop_counter >= avctx->gop_size) { + ctx->gop_counter >= ctx->gop_size) { pic->type = PICTURE_TYPE_IDR; ctx->force_idr = 0; ctx->gop_counter = 1; @@ -703,7 +703,7 @@ static int vaapi_encode_get_next(AVCodecContext *avctx, // encode-after it, but not exceeding the GOP size. for (i = 0; i < ctx->b_per_p && - ctx->gop_counter < avctx->gop_size; i++) { + ctx->gop_counter < ctx->gop_size; i++) { pic = vaapi_encode_alloc(avctx); if (!pic) goto fail; @@ -1217,7 +1217,6 @@ static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx) int i; VAConfigAttrib attr[] = { - { VAConfigAttribEncMaxRefFrames }, { VAConfigAttribEncPackedHeaders }, }; @@ -1240,24 +1239,6 @@ static av_cold int vaapi_encode_config_attributes(AVCodecContext *avctx) continue; } switch (attr[i].type) { - case VAConfigAttribEncMaxRefFrames: - { - unsigned int ref_l0 = attr[i].value & 0xffff; - unsigned int ref_l1 = (attr[i].value >> 16) & 0xffff; - - if (avctx->gop_size > 1 && ref_l0 < 1) { - av_log(avctx, AV_LOG_ERROR, "P frames are not " - "supported (%#x).\n", attr[i].value); - return AVERROR(EINVAL); - } - if (avctx->max_b_frames > 0 && ref_l1 < 1) { - av_log(avctx, AV_LOG_WARNING, "B frames are not " - "supported (%#x) by the underlying driver.\n", - attr[i].value); - avctx->max_b_frames = 0; - } - } - break; case VAConfigAttribEncPackedHeaders: if (ctx->va_packed_headers & ~attr[i].value) { // This isn't fatal, but packed headers are always @@ -1465,6 +1446,54 @@ static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx) return 0; } +static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) +{ + VAAPIEncodeContext *ctx = avctx->priv_data; + VAStatus vas; + VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames }; + uint32_t ref_l0, ref_l1; + + vas = vaGetConfigAttributes(ctx->hwctx->display, + ctx->va_profile, + ctx->va_entrypoint, + &attr, 1); + if (vas != VA_STATUS_SUCCESS) { + av_log(avctx, AV_LOG_ERROR, "Failed to query reference frames " + "attribute: %d (%s).\n", vas, vaErrorStr(vas)); + return AVERROR_EXTERNAL; + } + + if (attr.value == VA_ATTRIB_NOT_SUPPORTED) { + ref_l0 = ref_l1 = 0; + } else { + ref_l0 = attr.value & 0xffff; + ref_l1 = attr.value >> 16 & 0xffff; + } + + if (avctx->gop_size <= 1) { + av_log(avctx, AV_LOG_VERBOSE, "Using intra frames only.\n"); + ctx->gop_size = 1; + } else if (ref_l0 < 1) { + av_log(avctx, AV_LOG_ERROR, "Driver does not support any " + "reference frames.\n"); + return AVERROR(EINVAL); + } else if (ref_l1 < 1 || avctx->max_b_frames < 1) { + av_log(avctx, AV_LOG_VERBOSE, "Using intra and P-frames " + "(supported references: %d / %d).\n", ref_l0, ref_l1); + ctx->gop_size = avctx->gop_size; + ctx->p_per_i = INT_MAX; + ctx->b_per_p = 0; + } else { + av_log(avctx, AV_LOG_VERBOSE, "Using intra, P- and B-frames " + "(supported references: %d / %d).\n", ref_l0, ref_l1); + ctx->gop_size = avctx->gop_size; + ctx->p_per_i = INT_MAX; + ctx->b_per_p = avctx->max_b_frames; + } + + return 0; +} + static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx) { #if VA_CHECK_VERSION(0, 36, 0) @@ -1636,7 +1665,7 @@ static av_cold int vaapi_encode_create_recon_frames(AVCodecContext *avctx) ctx->recon_frames->height = ctx->surface_height; // At most three IDR/I/P frames and two runs of B frames can be in // flight at any one time. - ctx->recon_frames->initial_pool_size = 3 + 2 * avctx->max_b_frames; + ctx->recon_frames->initial_pool_size = 3 + 2 * ctx->b_per_p; err = av_hwframe_ctx_init(ctx->recon_frames_ref); if (err < 0) { @@ -1691,6 +1720,10 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) if (err < 0) goto fail; + err = vaapi_encode_init_gop_structure(avctx); + if (err < 0) + goto fail; + err = vaapi_encode_config_attributes(avctx); if (err < 0) goto fail; @@ -1745,14 +1778,10 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) } ctx->input_order = 0; - ctx->output_delay = avctx->max_b_frames; + ctx->output_delay = ctx->b_per_p; ctx->decode_delay = 1; ctx->output_order = - ctx->output_delay - 1; - // Currently we never generate I frames, only IDR. - ctx->p_per_i = INT_MAX; - ctx->b_per_p = avctx->max_b_frames; - if (ctx->codec->sequence_params_size > 0) { ctx->codec_sequence_params = av_mallocz(ctx->codec->sequence_params_size); diff --git a/libavcodec/vaapi_encode.h b/libavcodec/vaapi_encode.h index 6fac4781c3..bbec721bca 100644 --- a/libavcodec/vaapi_encode.h +++ b/libavcodec/vaapi_encode.h @@ -224,6 +224,7 @@ typedef struct VAAPIEncodeContext { int64_t ts_ring[MAX_REORDER_DELAY * 3]; // Frame type decision. + int gop_size; int p_per_i; int b_per_p; int force_idr; diff --git a/libavcodec/vaapi_encode_h264.c b/libavcodec/vaapi_encode_h264.c index 87c0d9acf3..717be024ca 100644 --- a/libavcodec/vaapi_encode_h264.c +++ b/libavcodec/vaapi_encode_h264.c @@ -493,8 +493,8 @@ static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx) *vseq = (VAEncSequenceParameterBufferH264) { .seq_parameter_set_id = sps->seq_parameter_set_id, .level_idc = sps->level_idc, - .intra_period = avctx->gop_size, - .intra_idr_period = avctx->gop_size, + .intra_period = ctx->gop_size, + .intra_idr_period = ctx->gop_size, .ip_period = ctx->b_per_p + 1, .bits_per_second = ctx->va_bit_rate, diff --git a/libavcodec/vaapi_encode_h265.c b/libavcodec/vaapi_encode_h265.c index 13ddad79ae..b2d6b8d24d 100644 --- a/libavcodec/vaapi_encode_h265.c +++ b/libavcodec/vaapi_encode_h265.c @@ -509,8 +509,8 @@ static int vaapi_encode_h265_init_sequence_params(AVCodecContext *avctx) .general_level_idc = vps->profile_tier_level.general_level_idc, .general_tier_flag = vps->profile_tier_level.general_tier_flag, - .intra_period = avctx->gop_size, - .intra_idr_period = avctx->gop_size, + .intra_period = ctx->gop_size, + .intra_idr_period = ctx->gop_size, .ip_period = ctx->b_per_p + 1, .bits_per_second = ctx->va_bit_rate, diff --git a/libavcodec/vaapi_encode_mjpeg.c b/libavcodec/vaapi_encode_mjpeg.c index 67ac2fba96..4982cd166f 100644 --- a/libavcodec/vaapi_encode_mjpeg.c +++ b/libavcodec/vaapi_encode_mjpeg.c @@ -401,6 +401,7 @@ static av_cold int vaapi_encode_mjpeg_init(AVCodecContext *avctx) static const AVCodecDefault vaapi_encode_mjpeg_defaults[] = { { "global_quality", "80" }, { "b", "0" }, + { "g", "1" }, { NULL }, }; diff --git a/libavcodec/vaapi_encode_mpeg2.c b/libavcodec/vaapi_encode_mpeg2.c index db72516187..b6edca9158 100644 --- a/libavcodec/vaapi_encode_mpeg2.c +++ b/libavcodec/vaapi_encode_mpeg2.c @@ -355,7 +355,7 @@ static int vaapi_encode_mpeg2_init_sequence_params(AVCodecContext *avctx) *vseq = (VAEncSequenceParameterBufferMPEG2) { - .intra_period = avctx->gop_size, + .intra_period = ctx->gop_size, .ip_period = ctx->b_per_p + 1, .picture_width = avctx->width, diff --git a/libavcodec/vaapi_encode_vp8.c b/libavcodec/vaapi_encode_vp8.c index db67136556..4512609a19 100644 --- a/libavcodec/vaapi_encode_vp8.c +++ b/libavcodec/vaapi_encode_vp8.c @@ -66,7 +66,7 @@ static int vaapi_encode_vp8_init_sequence_params(AVCodecContext *avctx) if (!(ctx->va_rc_mode & VA_RC_CQP)) { vseq->bits_per_second = ctx->va_bit_rate; - vseq->intra_period = avctx->gop_size; + vseq->intra_period = ctx->gop_size; } return 0; @@ -198,11 +198,6 @@ static av_cold int vaapi_encode_vp8_init(AVCodecContext *avctx) { VAAPIEncodeContext *ctx = avctx->priv_data; - if (avctx->max_b_frames > 0) { - av_log(avctx, AV_LOG_ERROR, "B-frames are not supported.\n"); - return AVERROR_PATCHWELCOME; - } - ctx->codec = &vaapi_encode_type_vp8; // Packed headers are not currently supported. diff --git a/libavcodec/vaapi_encode_vp9.c b/libavcodec/vaapi_encode_vp9.c index 2b0658ec1f..d4069ec850 100644 --- a/libavcodec/vaapi_encode_vp9.c +++ b/libavcodec/vaapi_encode_vp9.c @@ -72,7 +72,7 @@ static int vaapi_encode_vp9_init_sequence_params(AVCodecContext *avctx) if (!(ctx->va_rc_mode & VA_RC_CQP)) { vseq->bits_per_second = ctx->va_bit_rate; - vseq->intra_period = avctx->gop_size; + vseq->intra_period = ctx->gop_size; } vpic->frame_width_src = avctx->width; @@ -86,6 +86,7 @@ static int vaapi_encode_vp9_init_sequence_params(AVCodecContext *avctx) static int vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx, VAAPIEncodePicture *pic) { + VAAPIEncodeContext *ctx = avctx->priv_data; VAAPIEncodeVP9Context *priv = avctx->priv_data; VAEncPictureParameterBufferVP9 *vpic = pic->codec_picture_params; int i; @@ -102,7 +103,7 @@ static int vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx, break; case PICTURE_TYPE_P: av_assert0(pic->nb_refs == 1); - if (avctx->max_b_frames > 0) { + if (ctx->b_per_p > 0) { if (priv->last_ref_dir) { vpic->ref_flags.bits.ref_frame_ctrl_l0 = 2; vpic->ref_flags.bits.ref_gf_idx = 1; @@ -174,7 +175,7 @@ static int vaapi_encode_vp9_init_picture_params(AVCodecContext *avctx, vpic->filter_level = priv->loop_filter_level; vpic->sharpness_level = priv->loop_filter_sharpness; - if (avctx->max_b_frames > 0 && pic->type == PICTURE_TYPE_P) + if (ctx->b_per_p > 0 && pic->type == PICTURE_TYPE_P) priv->last_ref_dir = !priv->last_ref_dir; return 0;