From patchwork Sun May 31 06:24:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Zhang, Guiyong" X-Patchwork-Id: 20032 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 0C1A644992B for ; Sun, 31 May 2020 09:24:40 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id DB31B68803D; Sun, 31 May 2020 09:24:39 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from shasxm03.verisilicon.com (unknown [101.89.135.45]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E4D4C6809FF for ; Sun, 31 May 2020 09:24:31 +0300 (EEST) Content-Language: en-US DKIM-Signature: v=1; a=rsa-sha256; d=Verisilicon.com; s=default; c=simple/simple; t=1590906253; h=from:subject:to:date:message-id; bh=Dzll/Uax/Mtx8LRPyKEESCEbrvn62MLT6Y6DetEGbMQ=; b=SK3j2vTXXs5aCr2Q6kZwFq+nX1uDij/JVlgTR6pEuBBwWnwxETLjta8jEZVaqjgrJKqfM5CAlwX BlXN9EWCY6FSt645Qg3dl9d0P9djeriSdKMh+j80VfdzLxL98rwD2BSy14W22JSy2Z5y1Y0coih4X XRPZiN2uX3xFCAqzXLk= Received: from SHASXM03.verisilicon.com ([fe80::938:4dda:a2f9:38aa]) by SHASXM06.verisilicon.com ([fe80::59a8:ce34:dc14:ddda%16]) with mapi id 14.03.0123.003; Sun, 31 May 2020 14:24:11 +0800 From: "Zhang, Guiyong" To: "ffmpeg-devel@ffmpeg.org" Thread-Topic: [PATCH v2 1/8] avutil/hwcontext: Add VPE implementation Thread-Index: AdY3FBjV1FwU3QSySbOxhoNIlZqxxw== Date: Sun, 31 May 2020 06:24:10 +0000 Message-ID: <8847CE4FAA78C048A83C2AE8AA751D2770A5370D@SHASXM03.verisilicon.com> Accept-Language: en-US, zh-CN X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.10.25.45] x-tm-as-product-ver: SMEX-11.0.0.4179-8.100.1062-25452.001 x-tm-as-result: No--9.334600-0.000000-31 x-tm-as-user-approved-sender: Yes x-tm-as-user-blocked-sender: No MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 1/8] avutil/hwcontext: Add VPE implementation 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" VPE(VeriSilicon Paltform Engine) is VeriSilicon's hardware engine for multi formats video encoding and decoding. It is used with the VPE hwaccel codec API and library to initialize and use a VPE device which is within the hwcontext libavutil framework. Signed-off-by: Qin.Wang --- configure | 3 + libavutil/Makefile | 3 + libavutil/hwcontext.c | 4 + libavutil/hwcontext.h | 1 + libavutil/hwcontext_internal.h | 1 + libavutil/hwcontext_vpe.c | 402 +++++++++++++++++++++++++++++++++++++++++ libavutil/hwcontext_vpe.h | 52 ++++++ libavutil/pixdesc.c | 4 + libavutil/pixfmt.h | 7 + libavutil/version.h | 2 +- 10 files changed, 478 insertions(+), 1 deletion(-) create mode 100644 libavutil/hwcontext_vpe.c create mode 100644 libavutil/hwcontext_vpe.h diff --git a/configure b/configure index 8569a60..7f0f843 100755 --- a/configure +++ b/configure @@ -322,6 +322,7 @@ External library support: --enable-vulkan enable Vulkan code [no] --disable-xlib disable xlib [autodetect] --disable-zlib disable zlib [autodetect] + --enable-vpe enable vpe codec [no] The following libraries provide various hardware acceleration features: --disable-amf disable AMF video encoding code [autodetect] @@ -1822,6 +1823,7 @@ EXTERNAL_LIBRARY_LIST=" opengl pocketsphinx vapoursynth + vpe " HWACCEL_AUTODETECT_LIBRARY_LIST=" @@ -6476,6 +6478,7 @@ enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/r die "ERROR: rkmpp requires --enable-libdrm"; } } enabled vapoursynth && require_pkg_config vapoursynth "vapoursynth-script >= 42" VSScript.h vsscript_init +enabled vpe && require_pkg_config libvpi libvpi "vpe/vpi_types.h vpe/vpi_api.h" vpi_create if enabled gcrypt; then diff --git a/libavutil/Makefile b/libavutil/Makefile index 9b08372..5809b38 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -46,6 +46,7 @@ HEADERS = adler32.h \ hwcontext_videotoolbox.h \ hwcontext_vdpau.h \ hwcontext_vulkan.h \ + hwcontext_vpe.h \ imgutils.h \ intfloat.h \ intreadwrite.h \ @@ -184,6 +185,7 @@ OBJS-$(CONFIG_VAAPI) += hwcontext_vaapi.o OBJS-$(CONFIG_VIDEOTOOLBOX) += hwcontext_videotoolbox.o OBJS-$(CONFIG_VDPAU) += hwcontext_vdpau.o OBJS-$(CONFIG_VULKAN) += hwcontext_vulkan.o +OBJS-$(CONFIG_VPE) += hwcontext_vpe.o OBJS += $(COMPAT_OBJS:%=../compat/%) @@ -201,6 +203,7 @@ SKIPHEADERS-$(CONFIG_VAAPI) += hwcontext_vaapi.h SKIPHEADERS-$(CONFIG_VIDEOTOOLBOX) += hwcontext_videotoolbox.h SKIPHEADERS-$(CONFIG_VDPAU) += hwcontext_vdpau.h SKIPHEADERS-$(CONFIG_VULKAN) += hwcontext_vulkan.h +SKIPHEADERS-$(CONFIG_VPE) += hwcontext_vpe.h TESTPROGS = adler32 \ aes \ diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c index d13d0f7..5b12013 100644 --- a/libavutil/hwcontext.c +++ b/libavutil/hwcontext.c @@ -62,6 +62,9 @@ static const HWContextType * const hw_table[] = { #if CONFIG_VULKAN &ff_hwcontext_type_vulkan, #endif +#if CONFIG_VPE + &ff_hwcontext_type_vpe, +#endif NULL, }; @@ -77,6 +80,7 @@ static const char *const hw_type_names[] = { [AV_HWDEVICE_TYPE_VIDEOTOOLBOX] = "videotoolbox", [AV_HWDEVICE_TYPE_MEDIACODEC] = "mediacodec", [AV_HWDEVICE_TYPE_VULKAN] = "vulkan", + [AV_HWDEVICE_TYPE_VPE] = "vpe", }; enum AVHWDeviceType av_hwdevice_find_type_by_name(const char *name) diff --git a/libavutil/hwcontext.h b/libavutil/hwcontext.h index 04d19d8..62d948e 100644 --- a/libavutil/hwcontext.h +++ b/libavutil/hwcontext.h @@ -37,6 +37,7 @@ enum AVHWDeviceType { AV_HWDEVICE_TYPE_OPENCL, AV_HWDEVICE_TYPE_MEDIACODEC, AV_HWDEVICE_TYPE_VULKAN, + AV_HWDEVICE_TYPE_VPE, }; typedef struct AVHWDeviceInternal AVHWDeviceInternal; diff --git a/libavutil/hwcontext_internal.h b/libavutil/hwcontext_internal.h index e626649..3190a3a 100644 --- a/libavutil/hwcontext_internal.h +++ b/libavutil/hwcontext_internal.h @@ -174,5 +174,6 @@ extern const HWContextType ff_hwcontext_type_vdpau; extern const HWContextType ff_hwcontext_type_videotoolbox; extern const HWContextType ff_hwcontext_type_mediacodec; extern const HWContextType ff_hwcontext_type_vulkan; +extern const HWContextType ff_hwcontext_type_vpe; #endif /* AVUTIL_HWCONTEXT_INTERNAL_H */ diff --git a/libavutil/hwcontext_vpe.c b/libavutil/hwcontext_vpe.c new file mode 100644 index 0000000..7b218e3 --- /dev/null +++ b/libavutil/hwcontext_vpe.c @@ -0,0 +1,402 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +#include "buffer.h" +#include "pixfmt.h" +#include "pixdesc.h" +#include "hwcontext.h" +#include "hwcontext_internal.h" +#include "hwcontext_vpe.h" +#include "libavutil/opt.h" + +typedef struct VpeDevicePriv { + VpiSysInfo *sys_info; +} VpeDevicePriv; + +typedef struct VpeDeviceContext { + VpiMediaProc *media_proc; +} VpeDeviceContext; + +static const enum AVPixelFormat supported_sw_formats[] = { + AV_PIX_FMT_NV12, + AV_PIX_FMT_P010LE, + AV_PIX_FMT_YUV420P, + AV_PIX_FMT_YUV422P, + AV_PIX_FMT_NV21, + AV_PIX_FMT_YUV420P10LE, + AV_PIX_FMT_YUV420P10BE, + AV_PIX_FMT_YUV422P10LE, + AV_PIX_FMT_YUV422P10BE, + AV_PIX_FMT_P010BE, + AV_PIX_FMT_YUV444P, + AV_PIX_FMT_RGB24, + AV_PIX_FMT_BGR24, + AV_PIX_FMT_ARGB, + AV_PIX_FMT_RGBA, + AV_PIX_FMT_ABGR, + AV_PIX_FMT_BGRA, +}; + +static const enum AVPixelFormat supported_hw_formats[] = { + AV_PIX_FMT_VPE, +}; + +static int vpe_frames_get_constraints(AVHWDeviceContext *ctx, + const void *hwconfig, + AVHWFramesConstraints *constraints) +{ + int i; + + constraints->valid_sw_formats = + av_malloc_array(FF_ARRAY_ELEMS(supported_sw_formats) + 1, + sizeof(*constraints->valid_sw_formats)); + if (!constraints->valid_sw_formats) + return AVERROR(ENOMEM); + + for (i = 0; i < FF_ARRAY_ELEMS(supported_sw_formats); i++) + constraints->valid_sw_formats[i] = supported_sw_formats[i]; + constraints->valid_sw_formats[FF_ARRAY_ELEMS(supported_sw_formats)] = + AV_PIX_FMT_NONE; + + constraints->valid_hw_formats = + av_malloc_array(2, sizeof(*constraints->valid_hw_formats)); + if (!constraints->valid_hw_formats) { + return AVERROR(ENOMEM); + } + + constraints->valid_hw_formats[0] = AV_PIX_FMT_VPE; + constraints->valid_hw_formats[1] = AV_PIX_FMT_NONE; + + constraints->min_width = 144; + constraints->min_height = 144; + constraints->max_width = 4096; + constraints->max_height = 4096; + + return 0; +} + +static int vpe_transfer_get_formats(AVHWFramesContext *ctx, + enum AVHWFrameTransferDirection dir, + enum AVPixelFormat **formats) +{ + enum AVPixelFormat *fmts; + + fmts = av_malloc_array(2, sizeof(*fmts)); + if (!fmts) + return AVERROR(ENOMEM); + + fmts[0] = ctx->sw_format; + fmts[1] = AV_PIX_FMT_NONE; + + *formats = fmts; + + return 0; +} + +static int vpe_transfer_data_from(AVHWFramesContext *ctx, AVFrame *dst, + const AVFrame *src) +{ + VpeDeviceContext *priv = ctx->device_ctx->internal->priv; + VpiFrame *in_frame; + VpiFrame out_frame; + VpiCtrlCmdParam cmd_param; + + VpiPicInfo *pic_info; + int pp_index; + int i, ret; + + in_frame = (VpiFrame *)src->data[0]; + for (i = 1; i < PIC_INDEX_MAX_NUMBER; i++) { + pic_info = (VpiPicInfo *)src->buf[i]->data; + if (pic_info->enabled == 1) { + pp_index = i; + break; + } + } + if (i == PIC_INDEX_MAX_NUMBER) { + return AVERROR_EXTERNAL; + } + + cmd_param.cmd = VPI_CMD_HWDW_SET_INDEX; + cmd_param.data = (void *)&pp_index; + priv->media_proc->vpi->control(priv->media_proc->ctx, + (void *)&cmd_param, NULL); + + out_frame.data[0] = dst->data[0]; + out_frame.data[1] = dst->data[1]; + out_frame.data[2] = dst->data[2]; + out_frame.linesize[0] = dst->linesize[0]; + out_frame.linesize[1] = dst->linesize[1]; + out_frame.linesize[2] = dst->linesize[2]; + ret = priv->media_proc->vpi->process(priv->media_proc->ctx, + in_frame, &out_frame); + + return ret; +} + +static void vpe_buffer_free(void *opaque, uint8_t *data) +{ + AVHWFramesContext *ctx = opaque; + AVVpeDeviceContext *device_hwctx = ctx->device_ctx->hwctx; + VpiCtrlCmdParam cmd_param; + + cmd_param.cmd = VPI_CMD_FREE_FRAME_BUFFER; + cmd_param.data = (void *)data; + device_hwctx->func->control(&device_hwctx->device, &cmd_param, NULL); +} + +static AVBufferRef *vpe_pool_alloc(void *opaque, int size) +{ + AVHWFramesContext *ctx = opaque; + AVVpeDeviceContext *device_hwctx = ctx->device_ctx->hwctx; + VpiFrame *v_frame = NULL; + VpiCtrlCmdParam cmd_param; + AVBufferRef *ret; + + cmd_param.cmd = VPI_CMD_GET_FRAME_BUFFER; + device_hwctx->func->control(&device_hwctx->device, &cmd_param, (void *)&v_frame); + if (!v_frame) { + return NULL; + } + ret = av_buffer_create((uint8_t*)v_frame, size, + vpe_buffer_free, ctx, 0); + + return ret; +} + +static int vpe_frames_init(AVHWFramesContext *hwfc) +{ + AVVpeDeviceContext *device_hwctx = hwfc->device_ctx->hwctx; + AVVpeFramesContext *frame_hwctx = hwfc->hwctx; + VpiCtrlCmdParam cmd_param; + int size = 0; + int picinfo_size = 0; + int i; + + for (i = 0; i < FF_ARRAY_ELEMS(supported_sw_formats); i++) { + if (hwfc->sw_format == supported_sw_formats[i]) { + break; + } + } + if (i == FF_ARRAY_ELEMS(supported_sw_formats)) { + av_log(hwfc, AV_LOG_ERROR, "Pixel format '%s' is not supported\n", + av_get_pix_fmt_name(hwfc->sw_format)); + return AVERROR(ENOSYS); + } + + if (!hwfc->pool) { + cmd_param.cmd = VPI_CMD_GET_VPEFRAME_SIZE; + device_hwctx->func->control(&device_hwctx->device, &cmd_param, (void *)&size); + if (size == 0) { + return AVERROR_EXTERNAL; + } + frame_hwctx->frame = (VpiFrame *)av_mallocz(size); + if (!frame_hwctx->frame) { + return AVERROR(ENOMEM); + } + frame_hwctx->frame_size = size; + + cmd_param.cmd = VPI_CMD_GET_PICINFO_SIZE; + device_hwctx->func->control(&device_hwctx->device, &cmd_param, (void *)&picinfo_size); + if (picinfo_size == 0) { + return AVERROR_EXTERNAL; + } + frame_hwctx->pic_info_size = picinfo_size; + + hwfc->internal->pool_internal = + av_buffer_pool_init2(size, hwfc, vpe_pool_alloc, NULL); + if (!hwfc->internal->pool_internal) + return AVERROR(ENOMEM); + } + return 0; +} + +static int vpe_get_buffer(AVHWFramesContext *hwfc, AVFrame *frame) +{ + AVVpeFramesContext *vpeframe_ctx = hwfc->hwctx; + VpiPicInfo *pic_info; + int i; + + frame->buf[0] = av_buffer_pool_get(hwfc->pool); + if (!frame->buf[0]) + return AVERROR(ENOMEM); + + frame->data[0] = frame->buf[0]->data; + memset(frame->data[0], 0, vpeframe_ctx->frame_size); + + /* suppor max 4 channel low res buffer */ + for (i = 1; i < PIC_INDEX_MAX_NUMBER; i++) { + frame->buf[i] = av_buffer_alloc(vpeframe_ctx->pic_info_size); + if (frame->buf[i] == 0) { + return AVERROR(ENOMEM); + } + } + /* always enable the first channel */ + pic_info = (VpiPicInfo *)frame->buf[1]->data; + pic_info->enabled = 1; + + frame->format = AV_PIX_FMT_VPE; + frame->width = hwfc->width; + frame->height = hwfc->height; + return 0; +} + +static void vpe_device_uninit(AVHWDeviceContext *device_ctx) +{ + VpeDeviceContext *priv = device_ctx->internal->priv; + + if (priv->media_proc) { + if (priv->media_proc->ctx) { + priv->media_proc->vpi->close(priv->media_proc->ctx); + vpi_destroy(priv->media_proc->ctx); + priv->media_proc->ctx = NULL; + } + vpi_freep(&priv->media_proc); + } +} + +static int vpe_device_init(AVHWDeviceContext *device_ctx) +{ + VpeDeviceContext *priv = device_ctx->internal->priv; + int ret = 0; + + ret = vpi_get_media_proc_struct(&priv->media_proc); + if (ret || !priv->media_proc) { + return AVERROR(ENOMEM); + } + + ret = vpi_create(&priv->media_proc->ctx, &priv->media_proc->vpi, + HWDOWNLOAD_VPE); + if (ret != 0) + return AVERROR_EXTERNAL; + + ret = priv->media_proc->vpi->init(priv->media_proc->ctx, NULL); + if (ret != 0) + return AVERROR_EXTERNAL; + + return 0; +} + +static void vpe_device_free(AVHWDeviceContext *device_ctx) +{ + AVVpeDeviceContext *hwctx = device_ctx->hwctx; + VpeDevicePriv *priv = (VpeDevicePriv *)device_ctx->user_opaque; + + vpi_destroy(priv->sys_info); + + vpi_freep(&priv->sys_info); + av_freep(&priv); + + if (hwctx->device >= 0) { + close(hwctx->device); + } +} + +static int vpe_device_create(AVHWDeviceContext *device_ctx, const char *device, + AVDictionary *opts, int flags) +{ + AVVpeDeviceContext *hwctx = device_ctx->hwctx; + AVDictionaryEntry *opt; + VpeDevicePriv *priv; + const char *path; + int ret; + + priv = av_mallocz(sizeof(*priv)); + if (!priv) + return AVERROR(ENOMEM); + ret = vpi_get_sys_info_struct(&priv->sys_info); + if (ret || !priv->sys_info) { + av_freep(&priv); + return AVERROR(ENOMEM); + } + + device_ctx->user_opaque = priv; + device_ctx->free = vpe_device_free; + + // Try to open the device as a transcode path. + // Default to using the first node if the user did not + // supply a path. + path = device ? device : "/dev/transcoder0"; + hwctx->device = open(path, O_RDWR); + if (hwctx->device == -1) { + av_log(device_ctx, AV_LOG_ERROR, "failed to open hw device\n"); + return AVERROR(errno); + } + + priv->sys_info->device = hwctx->device; + priv->sys_info->device_name = av_strdup(path); + if (!priv->sys_info->device_name) { + return AVERROR(ENOMEM); + } + priv->sys_info->priority = VPE_TASK_VOD; + priv->sys_info->sys_log_level = 0; + + if (opts) { + opt = av_dict_get(opts, "priority", NULL, 0); + if (opt) { + if (!strcmp(opt->value, "live")) { + priv->sys_info->priority = VPE_TASK_LIVE; + } else if (!strcmp(opt->value, "vod")) { + priv->sys_info->priority = VPE_TASK_VOD; + } else { + av_log(device_ctx, AV_LOG_ERROR, "Unknow priority : %s\n", + opt->value); + return AVERROR_INVALIDDATA; + } + } + + opt = av_dict_get(opts, "fbloglevel", NULL, 0); + if (opt) { + priv->sys_info->sys_log_level = atoi(opt->value); + } + } + + if (vpi_create(&priv->sys_info, &hwctx->func, HWCONTEXT_VPE) != 0) { + return AVERROR_EXTERNAL; + } + + return 0; +} + +const HWContextType ff_hwcontext_type_vpe = { + .type = AV_HWDEVICE_TYPE_VPE, + .name = "VPE", + + .device_hwctx_size = sizeof(AVVpeDeviceContext), + .device_priv_size = sizeof(VpeDeviceContext), + .frames_hwctx_size = sizeof(AVVpeFramesContext), + + .device_create = vpe_device_create, + .device_init = vpe_device_init, + .device_uninit = vpe_device_uninit, + .frames_get_constraints = vpe_frames_get_constraints, + .frames_init = vpe_frames_init, + .frames_get_buffer = vpe_get_buffer, + .transfer_get_formats = vpe_transfer_get_formats, + .transfer_data_from = vpe_transfer_data_from, + + .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_VPE, AV_PIX_FMT_NONE }, +}; diff --git a/libavutil/hwcontext_vpe.h b/libavutil/hwcontext_vpe.h new file mode 100644 index 0000000..6fd5291 --- /dev/null +++ b/libavutil/hwcontext_vpe.h @@ -0,0 +1,52 @@ +/* + * Verisilicon VPI Video codec + * Copyright (c) 2019 VeriSilicon, Inc. + * + * 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 + */ + +#ifndef AVUTIL_HWCONTEXT_VPE_H +#define AVUTIL_HWCONTEXT_VPE_H + +#include +#include + +/** + * @file + * An API-specific header for AV_HWDEVICE_TYPE_VPE. + */ + +/** + * This struct is allocated as AVHWDeviceContext.hwctx + * It will save some device level info + */ + +typedef struct AVVpeDeviceContext { + int device; + VpiApi *func; +} AVVpeDeviceContext; + +/** + * This struct is allocated as AVHWFramesContext.hwctx + * It will save some frame level info + */ +typedef struct AVVpeFramesContext { + VpiFrame *frame; + int frame_size; + int pic_info_size; +} AVVpeFramesContext; +#endif /* AVUTIL_HWCONTEXT_VPE_H */ diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 9d61c52..f2dc9fa 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -2371,6 +2371,10 @@ static const AVPixFmtDescriptor av_pix_fmt_descriptors[AV_PIX_FMT_NB] = { .name = "vulkan", .flags = AV_PIX_FMT_FLAG_HWACCEL, }, + [AV_PIX_FMT_VPE] = { + .name = "vpe", + .flags = AV_PIX_FMT_FLAG_HWACCEL, + }, }; #if FF_API_PLUS1_MINUS1 FF_ENABLE_DEPRECATION_WARNINGS diff --git a/libavutil/pixfmt.h b/libavutil/pixfmt.h index 1c625cf..252261e 100644 --- a/libavutil/pixfmt.h +++ b/libavutil/pixfmt.h @@ -358,6 +358,13 @@ enum AVPixelFormat { AV_PIX_FMT_Y210BE, ///< packed YUV 4:2:2 like YUYV422, 20bpp, data in the high bits, big-endian AV_PIX_FMT_Y210LE, ///< packed YUV 4:2:2 like YUYV422, 20bpp, data in the high bits, little-endian + /** + * VPE hardware images. + * + * data[0] points to a VpiFrame + */ + AV_PIX_FMT_VPE, + AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions }; diff --git a/libavutil/version.h b/libavutil/version.h index 7acecf5..5d5cec6 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 56 -#define LIBAVUTIL_VERSION_MINOR 49 +#define LIBAVUTIL_VERSION_MINOR 50 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \