mirror of https://github.com/FFmpeg/FFmpeg.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
259 lines
11 KiB
259 lines
11 KiB
/* |
|
* 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 AVCODEC_VULKAN_ENCODE_H |
|
#define AVCODEC_VULKAN_ENCODE_H |
|
|
|
#include "codec_id.h" |
|
#include "internal.h" |
|
|
|
#include "encode.h" |
|
#include "hwconfig.h" |
|
|
|
#include "vulkan_video.h" |
|
#include "hw_base_encode.h" |
|
|
|
typedef struct FFVulkanEncodeDescriptor { |
|
enum AVCodecID codec_id; |
|
FFVulkanExtensions encode_extension; |
|
VkVideoCodecOperationFlagBitsKHR encode_op; |
|
|
|
VkExtensionProperties ext_props; |
|
} FFVulkanEncodeDescriptor; |
|
|
|
typedef struct FFVulkanEncodePicture { |
|
FFHWBaseEncodePicture base; |
|
VkVideoPictureResourceInfoKHR dpb_res; |
|
VkVideoReferenceSlotInfoKHR dpb_slot; |
|
|
|
struct { |
|
VkImageView view; |
|
VkImageAspectFlags aspect; |
|
} in; |
|
|
|
struct { |
|
VkImageView view; |
|
VkImageAspectFlags aspect; |
|
} dpb; |
|
|
|
void *codec_layer; |
|
void *codec_rc_layer; |
|
|
|
FFVkExecContext *exec; |
|
AVBufferRef *pkt_buf; |
|
int slices_offset; |
|
} FFVulkanEncodePicture; |
|
|
|
/** |
|
* Callback for writing stream-level headers. |
|
*/ |
|
typedef int (*vkenc_cb_write_stream_headers)(AVCodecContext *avctx, |
|
uint8_t *data, size_t *data_len); |
|
|
|
/** |
|
* Callback for initializing codec-specific picture headers. |
|
*/ |
|
typedef int (*vkenc_cb_init_pic_headers)(AVCodecContext *avctx, |
|
FFVulkanEncodePicture *pic); |
|
|
|
/** |
|
* Callback for writing alignment data. |
|
* Align is the value to align offset to. |
|
*/ |
|
typedef int (*vkenc_cb_write_filler)(AVCodecContext *avctx, uint32_t filler, |
|
uint8_t *data, size_t *data_len); |
|
|
|
/** |
|
* Callback for writing any extra units requested. data_len must be set |
|
* to the available size, and its value will be overwritten by the #bytes written |
|
* to the output buffer. |
|
*/ |
|
typedef int (*vkenc_cb_write_extra_headers)(AVCodecContext *avctx, |
|
FFVulkanEncodePicture *pic, |
|
uint8_t *data, size_t *data_len); |
|
|
|
typedef struct FFVulkanCodec { |
|
/** |
|
* Codec feature flags. |
|
*/ |
|
int flags; |
|
/* Codec output packet without timestamp delay, which means the |
|
* output packet has same PTS and DTS. For AV1. */ |
|
#define VK_ENC_FLAG_NO_DELAY 1 << 6 |
|
|
|
/** |
|
* Size of the codec-specific picture struct. |
|
*/ |
|
size_t picture_priv_data_size; |
|
|
|
/** |
|
* Size of the filler header. |
|
*/ |
|
size_t filler_header_size; |
|
|
|
/** |
|
* Initialize codec-specific structs in a Vulkan profile. |
|
*/ |
|
int (*init_profile)(AVCodecContext *avctx, VkVideoProfileInfoKHR *profile, |
|
void *pnext); |
|
|
|
/** |
|
* Initialize codec-specific rate control structures for a picture. |
|
*/ |
|
int (*init_pic_rc)(AVCodecContext *avctx, FFHWBaseEncodePicture *pic, |
|
VkVideoEncodeRateControlInfoKHR *rc_info, |
|
VkVideoEncodeRateControlLayerInfoKHR *rc_layer); |
|
|
|
/** |
|
* Initialize codec-specific picture parameters. |
|
*/ |
|
int (*init_pic_params)(AVCodecContext *avctx, FFHWBaseEncodePicture *pic, |
|
VkVideoEncodeInfoKHR *encode_info); |
|
|
|
/** |
|
* Callback for writing stream headers. |
|
*/ |
|
int (*write_sequence_headers)(AVCodecContext *avctx, |
|
FFHWBaseEncodePicture *base_pic, |
|
uint8_t *data, size_t *data_len); |
|
|
|
/** |
|
* Callback for writing alignment data. |
|
*/ |
|
int (*write_filler)(AVCodecContext *avctx, uint32_t filler, |
|
uint8_t *data, size_t *data_len); |
|
|
|
/** |
|
* Callback for writing any extra units requested. data_len must be set |
|
* to the available size, and its value will be overwritten by the #bytes written |
|
* to the output buffer. |
|
*/ |
|
int (*write_extra_headers)(AVCodecContext *avctx, FFHWBaseEncodePicture *pic, |
|
uint8_t *data, size_t *data_len); |
|
} FFVulkanCodec; |
|
|
|
typedef struct FFVkEncodeCommonOptions { |
|
int qp; |
|
int quality; |
|
int profile; |
|
int level; |
|
int tier; |
|
int async_depth; |
|
VkVideoEncodeUsageFlagBitsKHR usage; |
|
VkVideoEncodeContentFlagBitsKHR content; |
|
VkVideoEncodeTuningModeKHR tune; |
|
|
|
VkVideoEncodeRateControlModeFlagBitsKHR rc_mode; |
|
#define FF_VK_RC_MODE_AUTO 0xFFFFFFFF |
|
} FFVkEncodeCommonOptions; |
|
|
|
typedef struct FFVulkanEncodeContext { |
|
FFVulkanContext s; |
|
FFVkVideoCommon common; |
|
FFHWBaseEncodeContext base; |
|
const FFVulkanCodec *codec; |
|
|
|
int explicit_qp; |
|
int session_reset; |
|
|
|
/* Session parameters object, initialized by each codec independently |
|
* and set here. */ |
|
VkVideoSessionParametersKHR session_params; |
|
|
|
AVBufferPool *buf_pool; |
|
|
|
VkFormat pic_format; |
|
|
|
FFVkEncodeCommonOptions opts; |
|
|
|
VkVideoProfileInfoKHR profile; |
|
VkVideoProfileListInfoKHR profile_list; |
|
VkVideoCapabilitiesKHR caps; |
|
VkVideoEncodeQualityLevelPropertiesKHR quality_props; |
|
VkVideoEncodeCapabilitiesKHR enc_caps; |
|
VkVideoEncodeUsageInfoKHR usage_info; |
|
|
|
FFVkQueueFamilyCtx qf_enc; |
|
FFVkExecPool enc_pool; |
|
|
|
FFHWBaseEncodePicture *slots[32]; |
|
} FFVulkanEncodeContext; |
|
|
|
#define VULKAN_ENCODE_COMMON_OPTIONS \ |
|
{ "qp", "Use an explicit constant quantizer for the whole stream", OFFSET(common.opts.qp), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 255, FLAGS }, \ |
|
{ "quality", "Set encode quality (trades off against speed, higher is faster)", OFFSET(common.opts.quality), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS }, \ |
|
{ "rc_mode", "Select rate control type", OFFSET(common.opts.rc_mode), AV_OPT_TYPE_INT, { .i64 = FF_VK_RC_MODE_AUTO }, 0, FF_VK_RC_MODE_AUTO, FLAGS, "rc_mode" }, \ |
|
{ "auto", "Choose mode automatically based on parameters", 0, AV_OPT_TYPE_CONST, { .i64 = FF_VK_RC_MODE_AUTO }, INT_MIN, INT_MAX, FLAGS, "rc_mode" }, \ |
|
{ "driver", "Driver-specific rate control", 0, AV_OPT_TYPE_CONST, { .i64 = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DEFAULT_KHR }, INT_MIN, INT_MAX, FLAGS, "rc_mode" }, \ |
|
{ "cqp", "Constant quantizer mode", 0, AV_OPT_TYPE_CONST, { .i64 = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_DISABLED_BIT_KHR }, INT_MIN, INT_MAX, FLAGS, "rc_mode" }, \ |
|
{ "cbr", "Constant bitrate mode", 0, AV_OPT_TYPE_CONST, { .i64 = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_CBR_BIT_KHR }, INT_MIN, INT_MAX, FLAGS, "rc_mode" }, \ |
|
{ "vbr", "Variable bitrate mode", 0, AV_OPT_TYPE_CONST, { .i64 = VK_VIDEO_ENCODE_RATE_CONTROL_MODE_VBR_BIT_KHR }, INT_MIN, INT_MAX, FLAGS, "rc_mode" }, \ |
|
{ "tune", "Select tuning type", OFFSET(common.opts.tune), AV_OPT_TYPE_INT, { .i64 = VK_VIDEO_ENCODE_TUNING_MODE_DEFAULT_KHR }, 0, INT_MAX, FLAGS, "tune" }, \ |
|
{ "default", "Default tuning", 0, AV_OPT_TYPE_CONST, { .i64 = VK_VIDEO_ENCODE_TUNING_MODE_DEFAULT_KHR }, INT_MIN, INT_MAX, FLAGS, "tune" }, \ |
|
{ "hq", "High quality tuning", 0, AV_OPT_TYPE_CONST, { .i64 = VK_VIDEO_ENCODE_TUNING_MODE_HIGH_QUALITY_KHR }, INT_MIN, INT_MAX, FLAGS, "tune" }, \ |
|
{ "ll", "Low-latency tuning", 0, AV_OPT_TYPE_CONST, { .i64 = VK_VIDEO_ENCODE_TUNING_MODE_LOW_LATENCY_KHR }, INT_MIN, INT_MAX, FLAGS, "tune" }, \ |
|
{ "ull", "Ultra low-latency tuning", 0, AV_OPT_TYPE_CONST, { .i64 = VK_VIDEO_ENCODE_TUNING_MODE_ULTRA_LOW_LATENCY_KHR }, INT_MIN, INT_MAX, FLAGS, "tune" }, \ |
|
{ "lossless", "Lossless mode tuning", 0, AV_OPT_TYPE_CONST, { .i64 = VK_VIDEO_ENCODE_TUNING_MODE_LOSSLESS_KHR }, INT_MIN, INT_MAX, FLAGS, "tune" }, \ |
|
{ "usage", "Select usage type", OFFSET(common.opts.usage), AV_OPT_TYPE_FLAGS, { .i64 = VK_VIDEO_ENCODE_USAGE_DEFAULT_KHR }, 0, INT_MAX, FLAGS, "usage" }, \ |
|
{ "default", "Default optimizations", 0, AV_OPT_TYPE_CONST, { .i64 = VK_VIDEO_ENCODE_USAGE_DEFAULT_KHR }, INT_MIN, INT_MAX, FLAGS, "usage" }, \ |
|
{ "transcode", "Optimize for transcoding", 0, AV_OPT_TYPE_CONST, { .i64 = VK_VIDEO_ENCODE_USAGE_TRANSCODING_BIT_KHR }, INT_MIN, INT_MAX, FLAGS, "usage" }, \ |
|
{ "stream", "Optimize for streaming", 0, AV_OPT_TYPE_CONST, { .i64 = VK_VIDEO_ENCODE_USAGE_STREAMING_BIT_KHR }, INT_MIN, INT_MAX, FLAGS, "usage" }, \ |
|
{ "record", "Optimize for offline recording", 0, AV_OPT_TYPE_CONST, { .i64 = VK_VIDEO_ENCODE_USAGE_RECORDING_BIT_KHR }, INT_MIN, INT_MAX, FLAGS, "usage" }, \ |
|
{ "conference", "Optimize for teleconferencing", 0, AV_OPT_TYPE_CONST, { .i64 = VK_VIDEO_ENCODE_USAGE_CONFERENCING_BIT_KHR }, INT_MIN, INT_MAX, FLAGS, "usage" }, \ |
|
{ "content", "Select content type", OFFSET(common.opts.content), AV_OPT_TYPE_FLAGS, { .i64 = VK_VIDEO_ENCODE_CONTENT_DEFAULT_KHR }, 0, INT_MAX, FLAGS, "content" }, \ |
|
{ "default", "Default content", 0, AV_OPT_TYPE_CONST, { .i64 = VK_VIDEO_ENCODE_CONTENT_DEFAULT_KHR }, INT_MIN, INT_MAX, FLAGS, "content" }, \ |
|
{ "camera", "Camera footage", 0, AV_OPT_TYPE_CONST, { .i64 = VK_VIDEO_ENCODE_CONTENT_CAMERA_BIT_KHR }, INT_MIN, INT_MAX, FLAGS, "content" }, \ |
|
{ "desktop", "Screen recording", 0, AV_OPT_TYPE_CONST, { .i64 = VK_VIDEO_ENCODE_CONTENT_DESKTOP_BIT_KHR }, INT_MIN, INT_MAX, FLAGS, "content" }, \ |
|
{ "rendered", "Game or 3D content", 0, AV_OPT_TYPE_CONST, { .i64 = VK_VIDEO_ENCODE_CONTENT_RENDERED_BIT_KHR }, INT_MIN, INT_MAX, FLAGS, "content" } |
|
|
|
/** |
|
* Initialize encoder. |
|
*/ |
|
av_cold int ff_vulkan_encode_init(AVCodecContext *avctx, FFVulkanEncodeContext *ctx, |
|
const FFVulkanEncodeDescriptor *vk_desc, |
|
const FFVulkanCodec *codec, |
|
void *codec_caps, void *quality_pnext); |
|
|
|
/** |
|
* Write out the extradata in case its needed. |
|
*/ |
|
av_cold int ff_vulkan_write_global_header(AVCodecContext *avctx, |
|
FFVulkanEncodeContext *ctx); |
|
|
|
/** |
|
* Encode. |
|
*/ |
|
int ff_vulkan_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt); |
|
|
|
/** |
|
* Uninitialize encoder. |
|
*/ |
|
void ff_vulkan_encode_uninit(FFVulkanEncodeContext *ctx); |
|
|
|
/** |
|
* Create session parameters. |
|
*/ |
|
int ff_vulkan_encode_create_session_params(AVCodecContext *avctx, FFVulkanEncodeContext *ctx, |
|
void *codec_params_pnext); |
|
|
|
/** |
|
* Paperwork. |
|
*/ |
|
extern const AVCodecHWConfigInternal *const ff_vulkan_encode_hw_configs[]; |
|
|
|
#endif /* AVCODEC_VULKAN_ENCODE_H */
|
|
|