From 7aa16d59bfc537db69ffb08b9d5ec5f868cff56a Mon Sep 17 00:00:00 2001 From: Andrey Turkin Date: Wed, 25 May 2016 16:04:28 +0300 Subject: [PATCH] avcodec/nvenc: split H264/HEVC encoder definitions into separate files Signed-off-by: Timo Rothenpieler --- MAINTAINERS | 2 +- libavcodec/Makefile | 4 + libavcodec/nvenc.c | 247 +++------------------------------------- libavcodec/nvenc.h | 159 ++++++++++++++++++++++++++ libavcodec/nvenc_h264.c | 98 ++++++++++++++++ libavcodec/nvenc_hevc.c | 72 ++++++++++++ 6 files changed, 349 insertions(+), 233 deletions(-) create mode 100644 libavcodec/nvenc.h create mode 100644 libavcodec/nvenc_h264.c create mode 100644 libavcodec/nvenc_hevc.c diff --git a/MAINTAINERS b/MAINTAINERS index 52c30edba40..29d55c3b8c8 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -234,7 +234,7 @@ Codecs: msvideo1.c Mike Melanson nellymoserdec.c Benjamin Larsson nuv.c Reimar Doeffinger - nvenc.c Timo Rothenpieler + nvenc* Timo Rothenpieler paf.* Paul B Mahol pcx.c Ivo van Poorten pgssubdec.c Reimar Doeffinger diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 46dd9e14ad9..0645f216741 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -779,6 +779,9 @@ OBJS-$(CONFIG_MPEG2_MMAL_DECODER) += mmaldec.o OBJS-$(CONFIG_MPEG2_QSV_DECODER) += qsvdec_mpeg2.o OBJS-$(CONFIG_MPEG2_QSV_ENCODER) += qsvenc_mpeg2.o OBJS-$(CONFIG_MPEG4_OMX_ENCODER) += omx.o +OBJS-$(CONFIG_NVENC_ENCODER) += nvenc_h264.o +OBJS-$(CONFIG_NVENC_H264_ENCODER) += nvenc_h264.o +OBJS-$(CONFIG_NVENC_HEVC_ENCODER) += nvenc_hevc.o # libavformat dependencies OBJS-$(CONFIG_ISO_MEDIA) += mpeg4audio.o mpegaudiodata.o @@ -986,6 +989,7 @@ SKIPHEADERS-$(CONFIG_LIBUTVIDEO) += libutvideo.h SKIPHEADERS-$(CONFIG_LIBVPX) += libvpx.h SKIPHEADERS-$(CONFIG_LIBWEBP_ENCODER) += libwebpenc_common.h SKIPHEADERS-$(CONFIG_MEDIACODEC) += mediacodecdec.h mediacodec_wrapper.h mediacodec_sw_buffer.h +SKIPHEADERS-$(CONFIG_NVENC) += nvenc.h SKIPHEADERS-$(CONFIG_QSV) += qsv.h qsv_internal.h SKIPHEADERS-$(CONFIG_QSVDEC) += qsvdec.h SKIPHEADERS-$(CONFIG_QSVENC) += qsvenc.h diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 73d05841ae3..4e422028324 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -19,43 +19,25 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" + #if defined(_WIN32) #include #else #include #endif -#include - -#include "libavutil/fifo.h" -#include "libavutil/internal.h" #include "libavutil/imgutils.h" #include "libavutil/avassert.h" -#include "libavutil/opt.h" #include "libavutil/mem.h" #include "libavutil/hwcontext.h" -#include "avcodec.h" #include "internal.h" #include "thread.h" +#include "nvenc.h" #if CONFIG_CUDA -#include #include "libavutil/hwcontext_cuda.h" -#else - -#if defined(_WIN32) -#define CUDAAPI __stdcall -#else -#define CUDAAPI -#endif - -typedef enum cudaError_enum { - CUDA_SUCCESS = 0 -} CUresult; -typedef int CUdevice; -typedef void* CUcontext; -typedef void* CUdeviceptr; #endif #if defined(_WIN32) @@ -66,34 +48,15 @@ typedef void* CUdeviceptr; #define DL_CLOSE_FUNC(l) dlclose(l) #endif -typedef CUresult(CUDAAPI *PCUINIT)(unsigned int Flags); -typedef CUresult(CUDAAPI *PCUDEVICEGETCOUNT)(int *count); -typedef CUresult(CUDAAPI *PCUDEVICEGET)(CUdevice *device, int ordinal); -typedef CUresult(CUDAAPI *PCUDEVICEGETNAME)(char *name, int len, CUdevice dev); -typedef CUresult(CUDAAPI *PCUDEVICECOMPUTECAPABILITY)(int *major, int *minor, CUdevice dev); -typedef CUresult(CUDAAPI *PCUCTXCREATE)(CUcontext *pctx, unsigned int flags, CUdevice dev); -typedef CUresult(CUDAAPI *PCUCTXPOPCURRENT)(CUcontext *pctx); -typedef CUresult(CUDAAPI *PCUCTXDESTROY)(CUcontext ctx); - -typedef NVENCSTATUS (NVENCAPI* PNVENCODEAPICREATEINSTANCE)(NV_ENCODE_API_FUNCTION_LIST *functionList); - -#define MAX_REGISTERED_FRAMES 64 -typedef struct NvencSurface -{ - NV_ENC_INPUT_PTR input_surface; - AVFrame *in_ref; - NV_ENC_MAP_INPUT_RESOURCE in_map; - int reg_idx; - int width; - int height; - - int lockCount; - - NV_ENC_BUFFER_FORMAT format; - - NV_ENC_OUTPUT_PTR output_surface; - int size; -} NvencSurface; +const enum AVPixelFormat ff_nvenc_pix_fmts[] = { + AV_PIX_FMT_YUV420P, + AV_PIX_FMT_NV12, + AV_PIX_FMT_YUV444P, +#if CONFIG_CUDA + AV_PIX_FMT_CUDA, +#endif + AV_PIX_FMT_NONE +}; typedef struct NvencData { @@ -103,83 +66,12 @@ typedef struct NvencData } u; } NvencData; -typedef struct NvencDynLoadFunctions -{ - PCUINIT cu_init; - PCUDEVICEGETCOUNT cu_device_get_count; - PCUDEVICEGET cu_device_get; - PCUDEVICEGETNAME cu_device_get_name; - PCUDEVICECOMPUTECAPABILITY cu_device_compute_capability; - PCUCTXCREATE cu_ctx_create; - PCUCTXPOPCURRENT cu_ctx_pop_current; - PCUCTXDESTROY cu_ctx_destroy; - - NV_ENCODE_API_FUNCTION_LIST nvenc_funcs; - int nvenc_device_count; - CUdevice nvenc_devices[16]; - -#if !CONFIG_CUDA -#if defined(_WIN32) - HMODULE cuda_lib; -#else - void* cuda_lib; -#endif -#endif -#if defined(_WIN32) - HMODULE nvenc_lib; -#else - void* nvenc_lib; -#endif -} NvencDynLoadFunctions; - typedef struct NvencValuePair { const char *str; uint32_t num; } NvencValuePair; -typedef struct NvencContext -{ - AVClass *avclass; - - NvencDynLoadFunctions nvenc_dload_funcs; - - NV_ENC_INITIALIZE_PARAMS init_encode_params; - NV_ENC_CONFIG encode_config; - CUcontext cu_context; - CUcontext cu_context_internal; - - int max_surface_count; - NvencSurface *surfaces; - - AVFifoBuffer *output_surface_queue; - AVFifoBuffer *output_surface_ready_queue; - AVFifoBuffer *timestamp_list; - int64_t last_dts; - - struct { - CUdeviceptr ptr; - NV_ENC_REGISTERED_PTR regptr; - int mapped; - } registered_frames[MAX_REGISTERED_FRAMES]; - int nb_registered_frames; - - /* the actual data pixel format, different from - * AVCodecContext.pix_fmt when using hwaccel frames on input */ - enum AVPixelFormat data_pix_fmt; - - void *nvencoder; - - char *preset; - char *profile; - char *level; - char *tier; - int cbr; - int twopass; - int gpu; - int buffer_delay; -} NvencContext; - static const NvencValuePair nvenc_h264_level_pairs[] = { { "auto", NV_ENC_LEVEL_AUTOSELECT }, { "1" , NV_ENC_LEVEL_H264_1 }, @@ -1252,7 +1144,7 @@ static av_cold int nvenc_setup_extradata(AVCodecContext *avctx) return 0; } -static av_cold int nvenc_encode_init(AVCodecContext *avctx) +av_cold int ff_nvenc_encode_init(AVCodecContext *avctx) { NvencContext *ctx = avctx->priv_data; NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs; @@ -1315,7 +1207,7 @@ error: return res; } -static av_cold int nvenc_encode_close(AVCodecContext *avctx) +av_cold int ff_nvenc_encode_close(AVCodecContext *avctx) { NvencContext *ctx = avctx->priv_data; NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs; @@ -1697,7 +1589,7 @@ static int output_ready(NvencContext *ctx, int flush) return nb_ready > 0 && (flush || nb_ready + nb_pending >= ctx->buffer_delay); } -static int nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, +int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet) { NVENCSTATUS nv_status; @@ -1786,112 +1678,3 @@ static int nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } - -static const enum AVPixelFormat pix_fmts_nvenc[] = { - AV_PIX_FMT_YUV420P, - AV_PIX_FMT_NV12, - AV_PIX_FMT_YUV444P, -#if CONFIG_CUDA - AV_PIX_FMT_CUDA, -#endif - AV_PIX_FMT_NONE -}; - -#define OFFSET(x) offsetof(NvencContext, x) -#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM -static const AVOption options[] = { - { "preset", "Set the encoding preset (one of slow = hq 2pass, medium = hq, fast = hp, hq, hp, bd, ll, llhq, llhp, lossless, losslesshp, default)", OFFSET(preset), AV_OPT_TYPE_STRING, { .str = "medium" }, 0, 0, VE }, - { "profile", "Set the encoding profile (high, main, baseline or high444p)", OFFSET(profile), AV_OPT_TYPE_STRING, { .str = "main" }, 0, 0, VE }, - { "level", "Set the encoding level restriction (auto, 1.0, 1.0b, 1.1, 1.2, ..., 4.2, 5.0, 5.1)", OFFSET(level), AV_OPT_TYPE_STRING, { .str = "auto" }, 0, 0, VE }, - { "tier", "Set the encoding tier (main or high)", OFFSET(tier), AV_OPT_TYPE_STRING, { .str = "main" }, 0, 0, VE }, - { "cbr", "Use cbr encoding mode", OFFSET(cbr), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, - { "2pass", "Use 2pass encoding mode", OFFSET(twopass), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE }, - { "gpu", "Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on.", OFFSET(gpu), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, - { "delay", "Delays frame output by the given amount of frames.", OFFSET(buffer_delay), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 0, INT_MAX, VE }, - { NULL } -}; - -static const AVCodecDefault nvenc_defaults[] = { - { "b", "2M" }, - { "qmin", "-1" }, - { "qmax", "-1" }, - { "qdiff", "-1" }, - { "qblur", "-1" }, - { "qcomp", "-1" }, - { "g", "250" }, - { "bf", "0" }, - { NULL }, -}; - -#if CONFIG_NVENC_ENCODER -static const AVClass nvenc_class = { - .class_name = "nvenc", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - -AVCodec ff_nvenc_encoder = { - .name = "nvenc", - .long_name = NULL_IF_CONFIG_SMALL("NVIDIA NVENC h264 encoder"), - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_H264, - .priv_data_size = sizeof(NvencContext), - .init = nvenc_encode_init, - .encode2 = nvenc_encode_frame, - .close = nvenc_encode_close, - .capabilities = AV_CODEC_CAP_DELAY, - .priv_class = &nvenc_class, - .defaults = nvenc_defaults, - .pix_fmts = pix_fmts_nvenc, -}; -#endif - -/* Add an alias for nvenc_h264 */ -#if CONFIG_NVENC_H264_ENCODER -static const AVClass nvenc_h264_class = { - .class_name = "nvenc_h264", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - -AVCodec ff_nvenc_h264_encoder = { - .name = "nvenc_h264", - .long_name = NULL_IF_CONFIG_SMALL("NVIDIA NVENC h264 encoder"), - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_H264, - .priv_data_size = sizeof(NvencContext), - .init = nvenc_encode_init, - .encode2 = nvenc_encode_frame, - .close = nvenc_encode_close, - .capabilities = AV_CODEC_CAP_DELAY, - .priv_class = &nvenc_h264_class, - .defaults = nvenc_defaults, - .pix_fmts = pix_fmts_nvenc, -}; -#endif - -#if CONFIG_NVENC_HEVC_ENCODER -static const AVClass nvenc_hevc_class = { - .class_name = "nvenc_hevc", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - -AVCodec ff_nvenc_hevc_encoder = { - .name = "nvenc_hevc", - .long_name = NULL_IF_CONFIG_SMALL("NVIDIA NVENC hevc encoder"), - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_H265, - .priv_data_size = sizeof(NvencContext), - .init = nvenc_encode_init, - .encode2 = nvenc_encode_frame, - .close = nvenc_encode_close, - .capabilities = AV_CODEC_CAP_DELAY, - .priv_class = &nvenc_hevc_class, - .defaults = nvenc_defaults, - .pix_fmts = pix_fmts_nvenc, -}; -#endif diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h new file mode 100644 index 00000000000..fdb63505efa --- /dev/null +++ b/libavcodec/nvenc.h @@ -0,0 +1,159 @@ +/* + * 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_NVENC_H +#define AVCODEC_NVENC_H + +#include + +#include "config.h" + +#include "libavutil/fifo.h" +#include "libavutil/opt.h" + +#include "avcodec.h" + +#if CONFIG_CUDA +#include +#else + +#if defined(_WIN32) +#define CUDAAPI __stdcall +#else +#define CUDAAPI +#endif + +typedef enum cudaError_enum { + CUDA_SUCCESS = 0 +} CUresult; +typedef int CUdevice; +typedef void* CUcontext; +typedef void* CUdeviceptr; +#endif + +#define MAX_REGISTERED_FRAMES 64 + +typedef struct NvencSurface +{ + NV_ENC_INPUT_PTR input_surface; + AVFrame *in_ref; + NV_ENC_MAP_INPUT_RESOURCE in_map; + int reg_idx; + int width; + int height; + + NV_ENC_OUTPUT_PTR output_surface; + NV_ENC_BUFFER_FORMAT format; + int size; + int lockCount; +} NvencSurface; + +typedef CUresult(CUDAAPI *PCUINIT)(unsigned int Flags); +typedef CUresult(CUDAAPI *PCUDEVICEGETCOUNT)(int *count); +typedef CUresult(CUDAAPI *PCUDEVICEGET)(CUdevice *device, int ordinal); +typedef CUresult(CUDAAPI *PCUDEVICEGETNAME)(char *name, int len, CUdevice dev); +typedef CUresult(CUDAAPI *PCUDEVICECOMPUTECAPABILITY)(int *major, int *minor, CUdevice dev); +typedef CUresult(CUDAAPI *PCUCTXCREATE)(CUcontext *pctx, unsigned int flags, CUdevice dev); +typedef CUresult(CUDAAPI *PCUCTXPOPCURRENT)(CUcontext *pctx); +typedef CUresult(CUDAAPI *PCUCTXDESTROY)(CUcontext ctx); + +typedef NVENCSTATUS (NVENCAPI *PNVENCODEAPICREATEINSTANCE)(NV_ENCODE_API_FUNCTION_LIST *functionList); + +typedef struct NvencDynLoadFunctions +{ +#if !CONFIG_CUDA +#if defined(_WIN32) + HMODULE cuda_lib; +#else + void* cuda_lib; +#endif +#endif +#if defined(_WIN32) + HMODULE nvenc_lib; +#else + void* nvenc_lib; +#endif + + PCUINIT cu_init; + PCUDEVICEGETCOUNT cu_device_get_count; + PCUDEVICEGET cu_device_get; + PCUDEVICEGETNAME cu_device_get_name; + PCUDEVICECOMPUTECAPABILITY cu_device_compute_capability; + PCUCTXCREATE cu_ctx_create; + PCUCTXPOPCURRENT cu_ctx_pop_current; + PCUCTXDESTROY cu_ctx_destroy; + + NV_ENCODE_API_FUNCTION_LIST nvenc_funcs; + int nvenc_device_count; + CUdevice nvenc_devices[16]; + +} NvencDynLoadFunctions; + +typedef struct NvencContext +{ + AVClass *avclass; + + NvencDynLoadFunctions nvenc_dload_funcs; + + NV_ENC_INITIALIZE_PARAMS init_encode_params; + NV_ENC_CONFIG encode_config; + CUcontext cu_context; + CUcontext cu_context_internal; + + int max_surface_count; + NvencSurface *surfaces; + + AVFifoBuffer *output_surface_queue; + AVFifoBuffer *output_surface_ready_queue; + AVFifoBuffer *timestamp_list; + + struct { + CUdeviceptr ptr; + NV_ENC_REGISTERED_PTR regptr; + int mapped; + } registered_frames[MAX_REGISTERED_FRAMES]; + int nb_registered_frames; + + /* the actual data pixel format, different from + * AVCodecContext.pix_fmt when using hwaccel frames on input */ + enum AVPixelFormat data_pix_fmt; + + int64_t last_dts; + + void *nvencoder; + + char *preset; + char *profile; + char *level; + char *tier; + int cbr; + int twopass; + int gpu; + int buffer_delay; +} NvencContext; + +int ff_nvenc_encode_init(AVCodecContext *avctx); + +int ff_nvenc_encode_close(AVCodecContext *avctx); + +int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, + const AVFrame *frame, int *got_packet); + +extern const enum AVPixelFormat ff_nvenc_pix_fmts[]; + +#endif /* AVCODEC_NVENC_H */ diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c new file mode 100644 index 00000000000..f91cafacaf2 --- /dev/null +++ b/libavcodec/nvenc_h264.c @@ -0,0 +1,98 @@ +/* + * 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 "libavutil/internal.h" + +#include "avcodec.h" +#include "internal.h" + +#include "nvenc.h" + +#define OFFSET(x) offsetof(NvencContext, x) +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM +static const AVOption options[] = { + { "preset", "Set the encoding preset (one of slow = hq 2pass, medium = hq, fast = hp, hq, hp, bd, ll, llhq, llhp, lossless, losslesshp, default)", OFFSET(preset), AV_OPT_TYPE_STRING, { .str = "medium" }, 0, 0, VE }, + { "profile", "Set the encoding profile (high, main, baseline or high444p)", OFFSET(profile), AV_OPT_TYPE_STRING, { .str = "main" }, 0, 0, VE }, + { "level", "Set the encoding level restriction (auto, 1.0, 1.0b, 1.1, 1.2, ..., 4.2, 5.0, 5.1)", OFFSET(level), AV_OPT_TYPE_STRING, { .str = "auto" }, 0, 0, VE }, + { "cbr", "Use cbr encoding mode", OFFSET(cbr), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, + { "2pass", "Use 2pass encoding mode", OFFSET(twopass), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE }, + { "gpu", "Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on.", OFFSET(gpu), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, + { "delay", "Delays frame output by the given amount of frames.", OFFSET(buffer_delay), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 0, INT_MAX, VE }, + { NULL } +}; + +static const AVCodecDefault defaults[] = { + { "b", "2M" }, + { "qmin", "-1" }, + { "qmax", "-1" }, + { "qdiff", "-1" }, + { "qblur", "-1" }, + { "qcomp", "-1" }, + { "g", "250" }, + { "bf", "0" }, + { NULL }, +}; + +#if CONFIG_NVENC_ENCODER +static const AVClass nvenc_class = { + .class_name = "nvenc", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_nvenc_encoder = { + .name = "nvenc", + .long_name = NULL_IF_CONFIG_SMALL("NVIDIA NVENC h264 encoder"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_H264, + .init = ff_nvenc_encode_init, + .encode2 = ff_nvenc_encode_frame, + .close = ff_nvenc_encode_close, + .priv_data_size = sizeof(NvencContext), + .priv_class = &nvenc_class, + .defaults = defaults, + .capabilities = AV_CODEC_CAP_DELAY, + .pix_fmts = ff_nvenc_pix_fmts, +}; +#endif + +/* Add an alias for nvenc_h264 */ +#if CONFIG_NVENC_H264_ENCODER +static const AVClass nvenc_h264_class = { + .class_name = "nvenc_h264", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_nvenc_h264_encoder = { + .name = "nvenc_h264", + .long_name = NULL_IF_CONFIG_SMALL("NVIDIA NVENC h264 encoder"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_H264, + .init = ff_nvenc_encode_init, + .encode2 = ff_nvenc_encode_frame, + .close = ff_nvenc_encode_close, + .priv_data_size = sizeof(NvencContext), + .priv_class = &nvenc_h264_class, + .defaults = defaults, + .capabilities = AV_CODEC_CAP_DELAY, + .pix_fmts = ff_nvenc_pix_fmts, +}; +#endif diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c new file mode 100644 index 00000000000..5f8d661040f --- /dev/null +++ b/libavcodec/nvenc_hevc.c @@ -0,0 +1,72 @@ +/* + * 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 "libavutil/internal.h" + +#include "avcodec.h" +#include "internal.h" + +#include "nvenc.h" + +#define OFFSET(x) offsetof(NvencContext, x) +#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM +static const AVOption options[] = { + { "preset", "Set the encoding preset (one of slow = hq 2pass, medium = hq, fast = hp, hq, hp, bd, ll, llhq, llhp, lossless, losslesshp, default)", OFFSET(preset), AV_OPT_TYPE_STRING, { .str = "medium" }, 0, 0, VE }, + { "profile", "Set the encoding profile (high, main, baseline or high444p)", OFFSET(profile), AV_OPT_TYPE_STRING, { .str = "main" }, 0, 0, VE }, + { "level", "Set the encoding level restriction (auto, 1.0, 1.0b, 1.1, 1.2, ..., 4.2, 5.0, 5.1)", OFFSET(level), AV_OPT_TYPE_STRING, { .str = "auto" }, 0, 0, VE }, + { "tier", "Set the encoding tier (main or high)", OFFSET(tier), AV_OPT_TYPE_STRING, { .str = "main" }, 0, 0, VE }, + { "cbr", "Use cbr encoding mode", OFFSET(cbr), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, + { "2pass", "Use 2pass encoding mode", OFFSET(twopass), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, VE }, + { "gpu", "Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on.", OFFSET(gpu), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, + { "delay", "Delays frame output by the given amount of frames.", OFFSET(buffer_delay), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 0, INT_MAX, VE }, + { NULL } +}; + +static const AVClass nvenc_hevc_class = { + .class_name = "nvenc_hevc", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +static const AVCodecDefault defaults[] = { + { "b", "2M" }, + { "qmin", "-1" }, + { "qmax", "-1" }, + { "qdiff", "-1" }, + { "qblur", "-1" }, + { "qcomp", "-1" }, + { "g", "250" }, + { "bf", "0" }, + { NULL }, +}; + +AVCodec ff_nvenc_hevc_encoder = { + .name = "nvenc_hevc", + .long_name = NULL_IF_CONFIG_SMALL("NVIDIA NVENC hevc encoder"), + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_HEVC, + .init = ff_nvenc_encode_init, + .encode2 = ff_nvenc_encode_frame, + .close = ff_nvenc_encode_close, + .priv_data_size = sizeof(NvencContext), + .priv_class = &nvenc_hevc_class, + .defaults = defaults, + .pix_fmts = ff_nvenc_pix_fmts, + .capabilities = AV_CODEC_CAP_DELAY, +}; -- 2.39.2