From patchwork Sun Jan 21 14:18:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jianfeng Zheng X-Patchwork-Id: 45691 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:a402:b0:199:de12:6fa6 with SMTP id z2csp943909pzk; Sun, 21 Jan 2024 06:19:59 -0800 (PST) X-Google-Smtp-Source: AGHT+IHnzPj0hkCgw7F8FPxuH7y/nqzKMIO9wkj5JK+QiDFreR8u5noliCJGnS014b5wKDZGTKgF X-Received: by 2002:ac2:4e0f:0:b0:50e:4509:ef76 with SMTP id e15-20020ac24e0f000000b0050e4509ef76mr1280047lfr.83.1705846799344; Sun, 21 Jan 2024 06:19:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1705846799; cv=none; d=google.com; s=arc-20160816; b=rmKXLJeS+3+LBPBWK+f7mWzUf3SCrcWTRDfDqOQyCemuQSAt8AEzkvFY3S8fTPMo9Y n18Rwtre2P+9KqyuXTSNaC2eDjTB3ixSwz1UlPglACy505YSwLjffJqhMrjBfcCMl5r1 3xxVUoSUT6eHOG3iQjX9R02+M2rw4BdqyfAsqCXQ9YmgCisnIwAOICqRLxARLxauRNta UZvLhdumJlcdOV6uVM2YmskCctrp3J3ISjgMGfWF4XNbv+c0YP/CpgnvwD1TqwxooL+J Fuz+tBvDFWDlELdT0dHIa6rZBjRCglxj1mS6YGAals0tP0FE72D7TKAj/o6uJfibHQUT 7rPA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc: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 :dkim-signature:delivered-to; bh=lZ2vIiD5yOxSyYW57YeLfh2twGUPgaY0/l+krDn47eY=; fh=iiAW4vjlCGdXV3Yszi/eNCPr6t9/oDQbs1mdNL59KvI=; b=crQcmCCH5lwLRj+xRcr9IuS8XE2HaEJd+w76/ztjIMUN6eC0ScSJbYpD6wtigKH0n8 Q2ZdgBrxsskAdSGNqXOz/lwV0IXiRh6A8ZLPb5OPrbwExjLFK1K5gEX1GXFiwioY1tDR m4Fi2V5L/U1Kn5igsyvI9TOWxtI14v1AvQRJ95e1B2ElzeCqmTW7hLxDtZTA7tmNM9jx /RIB+oSCy8OfW/cFNjIWcnu5pJrAEvZXkl41o4FYCFdZuhmDHl75MXOt0jnPb18uM42G 7Hr7PpLuQ9PhZSvhV7Sh26A6hF+AiB7OFJjketeO1hLbccIvKVJ1VoZCutmX2tlU0d7Z Gfug== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20230601 header.b=fqPKlCWl; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id z23-20020a170906241700b00a2d3b4b794fsi8258792eja.185.2024.01.21.06.19.58; Sun, 21 Jan 2024 06:19:59 -0800 (PST) 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=@gmail.com header.s=20230601 header.b=fqPKlCWl; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B043C68D0C8; Sun, 21 Jan 2024 16:19:27 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-pj1-f46.google.com (mail-pj1-f46.google.com [209.85.216.46]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A6B2968D0A5 for ; Sun, 21 Jan 2024 16:19:25 +0200 (EET) Received: by mail-pj1-f46.google.com with SMTP id 98e67ed59e1d1-2907a17fa34so528819a91.1 for ; Sun, 21 Jan 2024 06:19:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1705846763; x=1706451563; darn=ffmpeg.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=hF6iqGARoFgQUGMtyT/wzKgen42Ko2SWZNAbUx8gmmk=; b=fqPKlCWl1aMfkHAdKt5CVLEnjgBkq86jFHdmLOeZHwWkmAvrb+9bffie/92/NvfyPL 5KvdoLCAXimzF1WlKJtWuwPvXquonPyM2evF3suOu7NqVFRzHU5wOWiTsQ7I/B8571fl n5KO1UCViv/yF2wVNwS7KSKMNGYYGfgRYkFaiUzeCNRVpYsIOgeFZJt1enHkMOs1Flx6 eCkek1PtUZJkjZyqgtyZmChFwKPx9loxJsbNq7lfQmvlHAJfoIkixHMeAV3PbLouhqT6 5fDudlJlaIqRpnceOoPKa78q9NytoI6n+xmgJrQ9bS1ferYMWpMAbuug9MvPCCZW/3X7 H2CQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1705846763; x=1706451563; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=hF6iqGARoFgQUGMtyT/wzKgen42Ko2SWZNAbUx8gmmk=; b=rdcArd+Q1iaxM4eEJDa5LreeOSU8m2jU0vuWbG5hg/WMhBnr7I2r4Q/wetDjkNPp0E 4/y0mHfi4mI+zRUV0rGnGLVGXtWunvhSNLkUULkhzTMnE6aDoiIe/1i/Swp73kwtj4YL b9CR7fyJhCFfItLSmf/nNdQZ3+dLu/o4apeVo2xAgcw/goQdJaxLMwECJP7mZtmW2nTB AAU//Uo+M7JHuuFnfPBhEuBzJyQUw17SU78m3TZ1wFqqgD1a5oytxFp4PUIEd4to++p8 tOn28Dwp5f/ayACPHA9FxYZ4PanIVDAX+ovcgR9CEc+K8CwE7oxhJcEZaYx1hiBQquGo zfLg== X-Gm-Message-State: AOJu0YyVY4ALIZh5y2ecNgWarOiKqqV17MGhcp7WCKbGi0BskIOv/fwu wBIeDXGZxdIccpPwWGiB3/GagSrFtDplBe8WCxaNZftyoUAaIQ/9JutVhefF514= X-Received: by 2002:a17:90a:bc84:b0:28c:90e:1b4c with SMTP id x4-20020a17090abc8400b0028c090e1b4cmr947032pjr.5.1705846763125; Sun, 21 Jan 2024 06:19:23 -0800 (PST) Received: from localhost.localdomain ([183.242.63.6]) by smtp.gmail.com with ESMTPSA id bg4-20020a1709028e8400b001d4b73f60e4sm5840726plb.149.2024.01.21.06.19.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 21 Jan 2024 06:19:22 -0800 (PST) From: "jianfeng.zheng" X-Google-Original-From: "jianfeng.zheng" To: ffmpeg-devel@ffmpeg.org Date: Sun, 21 Jan 2024 22:18:46 +0800 Message-Id: <20240121141846.4077778-7-jianfeng.zheng@mthreads.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240121141846.4077778-1-jianfeng.zheng@mthreads.com> References: <20240121141846.4077778-1-jianfeng.zheng@mthreads.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [vaapi-cavs 7/7] cavs: support vaapi hwaccel decoding X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: "jianfeng.zheng" Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: bRgs8BhcJ8K3 see https://github.com/intel/libva/pull/738 Signed-off-by: jianfeng.zheng --- configure | 14 ++++ libavcodec/Makefile | 1 + libavcodec/cavs.h | 4 + libavcodec/cavsdec.c | 101 +++++++++++++++++++++-- libavcodec/hwaccels.h | 1 + libavcodec/vaapi_cavs.c | 164 ++++++++++++++++++++++++++++++++++++++ libavcodec/vaapi_decode.c | 4 + 7 files changed, 284 insertions(+), 5 deletions(-) create mode 100644 libavcodec/vaapi_cavs.c diff --git a/configure b/configure index c8ae0a061d..89759eda5d 100755 --- a/configure +++ b/configure @@ -2463,6 +2463,7 @@ HAVE_LIST=" xmllint zlib_gzip openvino2 + va_profile_avs " # options emitted with CONFIG_ prefix but not available on the command line @@ -3202,6 +3203,7 @@ wmv3_dxva2_hwaccel_select="vc1_dxva2_hwaccel" wmv3_nvdec_hwaccel_select="vc1_nvdec_hwaccel" wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel" wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel" +cavs_vaapi_hwaccel_deps="vaapi va_profile_avs VAPictureParameterBufferAVS" # hardware-accelerated codecs mediafoundation_deps="mftransform_h MFCreateAlignedMemoryBuffer" @@ -7175,6 +7177,18 @@ if enabled vaapi; then check_type "va/va.h va/va_enc_vp8.h" "VAEncPictureParameterBufferVP8" check_type "va/va.h va/va_enc_vp9.h" "VAEncPictureParameterBufferVP9" check_type "va/va.h va/va_enc_av1.h" "VAEncPictureParameterBufferAV1" + + # + # Using 'VA_CHECK_VERSION' in source codes make things easy. But we have to wait + # until newly added VAProfile being distributed by VAAPI released version. + # + # Before or after that, we can use auto-detection to keep version compatibility. + # It always works. + # + disable va_profile_avs && + test_code cc va/va.h "VAProfile p1 = VAProfileAVSJizhun, p2 = VAProfileAVSGuangdian;" && + enable va_profile_avs + enabled va_profile_avs && check_type "va/va.h va/va_dec_avs.h" "VAPictureParameterBufferAVS" fi if enabled_all opencl libdrm ; then diff --git a/libavcodec/Makefile b/libavcodec/Makefile index bb42095165..7d92375fed 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -1055,6 +1055,7 @@ OBJS-$(CONFIG_VP9_VAAPI_HWACCEL) += vaapi_vp9.o OBJS-$(CONFIG_VP9_VDPAU_HWACCEL) += vdpau_vp9.o OBJS-$(CONFIG_VP9_VIDEOTOOLBOX_HWACCEL) += videotoolbox_vp9.o OBJS-$(CONFIG_VP8_QSV_HWACCEL) += qsvdec.o +OBJS-$(CONFIG_CAVS_VAAPI_HWACCEL) += vaapi_cavs.o # Objects duplicated from other libraries for shared builds SHLIBOBJS += log2_tab.o reverse.o diff --git a/libavcodec/cavs.h b/libavcodec/cavs.h index 33ef10e850..4a0918da5a 100644 --- a/libavcodec/cavs.h +++ b/libavcodec/cavs.h @@ -167,10 +167,14 @@ typedef struct AVSFrame { AVFrame *f; int poc; int outputed; + + AVBufferRef *hwaccel_priv_buf; + void *hwaccel_picture_private; } AVSFrame; typedef struct AVSContext { AVCodecContext *avctx; + int got_pix_fmt; BlockDSPContext bdsp; H264ChromaContext h264chroma; VideoDSPContext vdsp; diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index 5036ef50f7..5ca021c098 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -25,11 +25,14 @@ * @author Stefan Gehrer */ +#include "config_components.h" #include "libavutil/avassert.h" #include "libavutil/emms.h" #include "avcodec.h" #include "get_bits.h" #include "golomb.h" +#include "hwaccel_internal.h" +#include "hwconfig.h" #include "profiles.h" #include "cavs.h" #include "codec_internal.h" @@ -1002,9 +1005,9 @@ static inline int decode_slice_header(AVSContext *h, GetBitContext *gb) } h->mb_weight_pred_flag = get_bits1(gb); if (!h->avctx->hwaccel) { - av_log(h->avctx, AV_LOG_ERROR, - "weighted prediction not yet supported\n"); - } + av_log(h->avctx, AV_LOG_ERROR, + "weighted prediction not yet supported\n"); + } } } if (h->aec_flag) { @@ -1115,6 +1118,46 @@ static inline int check_for_slice(AVSContext *h) * frame level * ****************************************************************************/ +static int hwaccel_pic(AVSContext *h) +{ + int ret = 0; + int stc = -1; + const uint8_t *frm_start = align_get_bits(&h->gb); + const uint8_t *frm_end = h->gb.buffer_end; + const uint8_t *slc_start = frm_start; + const uint8_t *slc_end = frm_end; + GetBitContext gb = h->gb; + const FFHWAccel *hwaccel = ffhwaccel(h->avctx->hwaccel); + + ret = hwaccel->start_frame(h->avctx, NULL, 0); + if (ret < 0) + return ret; + + for (slc_start = frm_start; slc_start + 4 < frm_end; slc_start = slc_end) { + slc_end = avpriv_find_start_code(slc_start + 4, frm_end, &stc); + if (slc_end < frm_end) { + slc_end -= 4; + } + + init_get_bits(&h->gb, slc_start, (slc_end - slc_start) * 8); + if (!check_for_slice(h)) { + break; + } + + ret = hwaccel->decode_slice(h->avctx, slc_start, slc_end - slc_start); + if (ret < 0) { + break; + } + } + + h->gb = gb; + skip_bits(&h->gb, (slc_start - frm_start) * 8); + + if (ret < 0) + return ret; + + return hwaccel->end_frame(h->avctx); +} /** * @brief remove frame out of dpb @@ -1125,6 +1168,9 @@ static void cavs_frame_unref(AVSFrame *frame) if (!frame->f || !frame->f->buf[0]) return; + av_buffer_unref(&frame->hwaccel_priv_buf); + frame->hwaccel_picture_private = NULL; + av_frame_unref(frame->f); } @@ -1219,6 +1265,17 @@ static int decode_pic(AVSContext *h) if (ret < 0) return ret; + if (h->avctx->hwaccel) { + const FFHWAccel *hwaccel = ffhwaccel(h->avctx->hwaccel); + av_assert0(!h->cur.hwaccel_picture_private); + if (hwaccel->frame_priv_data_size) { + h->cur.hwaccel_priv_buf = av_buffer_allocz(hwaccel->frame_priv_data_size); + if (!h->cur.hwaccel_priv_buf) + return AVERROR(ENOMEM); + h->cur.hwaccel_picture_private = h->cur.hwaccel_priv_buf->data; + } + } + if (!h->edge_emu_buffer) { int alloc_size = FFALIGN(FFABS(h->cur.f->linesize[0]) + 32, 32); h->edge_emu_buffer = av_mallocz(alloc_size * 2 * 24); @@ -1247,7 +1304,9 @@ static int decode_pic(AVSContext *h) av_log(h->avctx, AV_LOG_ERROR, "poc=%d/%d/%d, dist=%d/%d\n", h->DPB[1].poc, h->DPB[0].poc, h->cur.poc, h->dist[0], h->dist[1]); av_log(h->avctx, AV_LOG_ERROR, "sym_factor %d too large\n", h->sym_factor); - return AVERROR_INVALIDDATA; + + if (!h->avctx->hwaccel) + return AVERROR_INVALIDDATA; } } else { h->direct_den[0] = h->dist[0] ? 16384 / h->dist[0] : 0; @@ -1332,7 +1391,9 @@ static int decode_pic(AVSContext *h) } ret = 0; - if (h->cur.f->pict_type == AV_PICTURE_TYPE_I) { + if (h->avctx->hwaccel) { + ret = hwaccel_pic(h); + } else if (h->cur.f->pict_type == AV_PICTURE_TYPE_I) { do { check_for_slice(h); ret = decode_mb_i(h, 0); @@ -1503,6 +1564,20 @@ static int cavs_decode_frame(AVCodecContext *avctx, AVFrame *rframe, return ret; avctx->profile = h->profile; avctx->level = h->level; + if (!h->got_pix_fmt) { + h->got_pix_fmt = 1; + ret = ff_get_format(avctx, avctx->codec->pix_fmts); + if (ret < 0) + return ret; + + avctx->pix_fmt = ret; + + if (h->profile == AV_PROFILE_CAVS_GUANGDIAN && !avctx->hwaccel) { + av_log(avctx, AV_LOG_ERROR, "Your platform doesn't suppport hardware" + " accelerated for CAVS Guangdian Profile decoding.\n"); + return AVERROR(ENOTSUP); + } + } break; case PIC_I_START_CODE: if (!h->got_keyframe) { @@ -1577,6 +1652,14 @@ static int cavs_decode_frame(AVCodecContext *avctx, AVFrame *rframe, return (buf_ptr - avpkt->data); } +static const enum AVPixelFormat cavs_hwaccel_pixfmt_list_420[] = { +#if CONFIG_CAVS_VAAPI_HWACCEL + AV_PIX_FMT_VAAPI, +#endif + AV_PIX_FMT_YUV420P, + AV_PIX_FMT_NONE +}; + const FFCodec ff_cavs_decoder = { .p.name = "cavs", CODEC_LONG_NAME("Chinese AVS (Audio Video Standard) (AVS1-P2, JiZhun profile)"), @@ -1589,4 +1672,12 @@ const FFCodec ff_cavs_decoder = { .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, .flush = cavs_flush, .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, + .p.pix_fmts = cavs_hwaccel_pixfmt_list_420, + .hw_configs = (const AVCodecHWConfigInternal *const []) { +#if CONFIG_CAVS_VAAPI_HWACCEL + HWACCEL_VAAPI(cavs), +#endif + NULL + }, + .p.profiles = NULL_IF_CONFIG_SMALL(ff_cavs_profiles), }; diff --git a/libavcodec/hwaccels.h b/libavcodec/hwaccels.h index 5171e4c7d7..a1a973b460 100644 --- a/libavcodec/hwaccels.h +++ b/libavcodec/hwaccels.h @@ -89,5 +89,6 @@ extern const struct FFHWAccel ff_wmv3_dxva2_hwaccel; extern const struct FFHWAccel ff_wmv3_nvdec_hwaccel; extern const struct FFHWAccel ff_wmv3_vaapi_hwaccel; extern const struct FFHWAccel ff_wmv3_vdpau_hwaccel; +extern const struct FFHWAccel ff_cavs_vaapi_hwaccel; #endif /* AVCODEC_HWACCELS_H */ diff --git a/libavcodec/vaapi_cavs.c b/libavcodec/vaapi_cavs.c new file mode 100644 index 0000000000..4a7a9b95ad --- /dev/null +++ b/libavcodec/vaapi_cavs.c @@ -0,0 +1,164 @@ +/* + * AVS (Chinese GY/T 257.1—2012) HW decode acceleration through VA-API + * Copyright (c) 2022 JianfengZheng + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "hwconfig.h" +#include "hwaccel_internal.h" +#include "vaapi_decode.h" +#include "cavs.h" + +/** + * @file + * This file implements the glue code between FFmpeg's and VA-API's + * structures for AVS (Chinese GY/T 257.1—2012) decoding. + */ + +static int vaapi_avs_pic_type_cvt(int pict_type) +{ + switch (pict_type) + { + case AV_PICTURE_TYPE_I: return VA_AVS_I_IMG; + case AV_PICTURE_TYPE_P: return VA_AVS_P_IMG; + case AV_PICTURE_TYPE_B: return VA_AVS_B_IMG; + default: return VA_AVS_I_IMG; + } +} + +static void vaapi_avs_fill_pic(VAPictureAVS *va_pic, const AVSFrame *frame) +{ + va_pic->surface_id = ff_vaapi_get_surface_id(frame->f); + va_pic->poc = frame->poc / 2; +} + +/** Initialize and start decoding a frame with VA API. */ +static int vaapi_avs_start_frame(AVCodecContext *avctx, + av_unused const uint8_t *buffer, + av_unused uint32_t size) +{ + int i, err; + AVSContext *h = avctx->priv_data; + VAPictureParameterBufferAVS pic_param = {}; + VAAPIDecodePicture *vapic = h->cur.hwaccel_picture_private; + vapic->output_surface = ff_vaapi_get_surface_id(h->cur.f); + + pic_param = (VAPictureParameterBufferAVS) { + .width = h->width, + .height = h->height, + .picture_type = vaapi_avs_pic_type_cvt(h->cur.f->pict_type), + .progressive_seq_flag = h->progressive_seq, + .progressive_frame_flag = h->progressive_frame, + .picture_structure_flag = h->pic_structure, + .fixed_pic_qp_flag = h->qp_fixed, + .picture_qp = h->qp, + .loop_filter_disable_flag = h->loop_filter_disable, + .alpha_c_offset = h->alpha_offset, + .beta_offset = h->beta_offset, + .skip_mode_flag_flag = h->skip_mode_flag, + .picture_reference_flag = h->ref_flag, + }; + + if (h->profile == 0x48) { + pic_param.guangdian_fields.guangdian_flag = 1; + pic_param.guangdian_fields.aec_flag = h->aec_flag; + pic_param.guangdian_fields.weight_quant_flag = h->weight_quant_flag; + pic_param.guangdian_fields.chroma_quant_param_delta_cb = h->chroma_quant_param_delta_cb; + pic_param.guangdian_fields.chroma_quant_param_delta_cr = h->chroma_quant_param_delta_cr; + memcpy(pic_param.guangdian_fields.wqm_8x8, h->wqm_8x8, 64); + } + + vaapi_avs_fill_pic(&pic_param.curr_pic, &h->cur); + for (i = 0; i < 2; i++) { + vaapi_avs_fill_pic(&pic_param.ref_list[i], &h->DPB[i]); + } + + err = ff_vaapi_decode_make_param_buffer(avctx, vapic, + VAPictureParameterBufferType, + &pic_param, sizeof(pic_param)); + if (err < 0) + goto fail; + + return 0; +fail: + ff_vaapi_decode_cancel(avctx, vapic); + return err; +} + +/** End a hardware decoding based frame. */ +static int vaapi_avs_end_frame(AVCodecContext *avctx) +{ + AVSContext *h = avctx->priv_data; + VAAPIDecodePicture *vapic = h->cur.hwaccel_picture_private; + return ff_vaapi_decode_issue(avctx, vapic); +} + +/** Decode the given H.264 slice with VA API. */ +static int vaapi_avs_decode_slice(AVCodecContext *avctx, + const uint8_t *buffer, + uint32_t size) +{ + int err; + AVSContext *h = avctx->priv_data; + VAAPIDecodePicture *vapic = h->cur.hwaccel_picture_private; + VASliceParameterBufferAVS slice_param; + slice_param = (VASliceParameterBufferAVS) { + .slice_data_size = size, + .slice_data_offset = 0, + .slice_data_flag = VA_SLICE_DATA_FLAG_ALL, + .mb_data_bit_offset = get_bits_count(&h->gb), + .slice_vertical_pos = h->stc, + .fixed_slice_qp_flag = h->qp_fixed, + .slice_qp = h->qp, + .slice_weight_pred_flag = h->slice_weight_pred_flag, + .mb_weight_pred_flag = h->mb_weight_pred_flag, + }; + + *((uint32_t *)slice_param.luma_scale) = *((uint32_t *)h->luma_scale); + *((uint32_t *)slice_param.luma_shift) = *((uint32_t *)h->luma_shift); + *((uint32_t *)slice_param.chroma_scale) = *((uint32_t *)h->chroma_scale); + *((uint32_t *)slice_param.chroma_shift) = *((uint32_t *)h->chroma_shift); + + err = ff_vaapi_decode_make_slice_buffer(avctx, vapic, + &slice_param, sizeof(slice_param), + buffer, size); + if (err < 0) + goto fail; + + return 0; + +fail: + ff_vaapi_decode_cancel(avctx, vapic); + return err; +} + +const FFHWAccel ff_cavs_vaapi_hwaccel = { + .p.name = "cavs_vaapi", + .p.type = AVMEDIA_TYPE_VIDEO, + .p.id = AV_CODEC_ID_CAVS, + .p.pix_fmt = AV_PIX_FMT_VAAPI, + .start_frame = &vaapi_avs_start_frame, + .end_frame = &vaapi_avs_end_frame, + .decode_slice = &vaapi_avs_decode_slice, + .frame_priv_data_size = sizeof(VAAPIDecodePicture), + .init = &ff_vaapi_decode_init, + .uninit = &ff_vaapi_decode_uninit, + .frame_params = &ff_vaapi_common_frame_params, + .priv_data_size = sizeof(VAAPIDecodeContext), + .caps_internal = HWACCEL_CAP_ASYNC_SAFE, +}; diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c index ceac769c52..13a3f6aa42 100644 --- a/libavcodec/vaapi_decode.c +++ b/libavcodec/vaapi_decode.c @@ -408,6 +408,10 @@ static const struct { H264ConstrainedBaseline), MAP(H264, H264_MAIN, H264Main ), MAP(H264, H264_HIGH, H264High ), +#if HAVE_VA_PROFILE_AVS + MAP(CAVS, CAVS_JIZHUN, AVSJizhun ), + MAP(CAVS, CAVS_GUANGDIAN, AVSGuangdian), +#endif #if VA_CHECK_VERSION(0, 37, 0) MAP(HEVC, HEVC_MAIN, HEVCMain ), MAP(HEVC, HEVC_MAIN_10, HEVCMain10 ),