avcodec/nvenc: split H264/HEVC encoder definitions into separate files
authorAndrey Turkin <andrey.turkin@gmail.com>
Wed, 25 May 2016 13:04:28 +0000 (16:04 +0300)
committerUbuntu <ubuntu@ip-172-31-24-241.eu-west-1.compute.internal>
Tue, 31 May 2016 11:15:19 +0000 (11:15 +0000)
Signed-off-by: Timo Rothenpieler <timo@rothenpieler.org>
MAINTAINERS
libavcodec/Makefile
libavcodec/nvenc.c
libavcodec/nvenc.h [new file with mode: 0644]
libavcodec/nvenc_h264.c [new file with mode: 0644]
libavcodec/nvenc_hevc.c [new file with mode: 0644]

index 52c30ed..29d55c3 100644 (file)
@@ -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
index 46dd9e1..0645f21 100644 (file)
@@ -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
index 73d0584..4e42202 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+#include "config.h"
+
 #if defined(_WIN32)
 #include <windows.h>
 #else
 #include <dlfcn.h>
 #endif
 
-#include <nvEncodeAPI.h>
-
-#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 <cuda.h>
 #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 (file)
index 0000000..fdb6350
--- /dev/null
@@ -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 <nvEncodeAPI.h>
+
+#include "config.h"
+
+#include "libavutil/fifo.h"
+#include "libavutil/opt.h"
+
+#include "avcodec.h"
+
+#if CONFIG_CUDA
+#include <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
+
+#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 (file)
index 0000000..f91cafa
--- /dev/null
@@ -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 (file)
index 0000000..5f8d661
--- /dev/null
@@ -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,
+};