Signed-off-by: Timo Rothenpieler <timo@rothenpieler.org>tags/n3.1
| @@ -234,7 +234,7 @@ Codecs: | |||||
| msvideo1.c Mike Melanson | msvideo1.c Mike Melanson | ||||
| nellymoserdec.c Benjamin Larsson | nellymoserdec.c Benjamin Larsson | ||||
| nuv.c Reimar Doeffinger | nuv.c Reimar Doeffinger | ||||
| nvenc.c Timo Rothenpieler | |||||
| nvenc* Timo Rothenpieler | |||||
| paf.* Paul B Mahol | paf.* Paul B Mahol | ||||
| pcx.c Ivo van Poorten | pcx.c Ivo van Poorten | ||||
| pgssubdec.c Reimar Doeffinger | pgssubdec.c Reimar Doeffinger | ||||
| @@ -779,6 +779,9 @@ OBJS-$(CONFIG_MPEG2_MMAL_DECODER) += mmaldec.o | |||||
| OBJS-$(CONFIG_MPEG2_QSV_DECODER) += qsvdec_mpeg2.o | OBJS-$(CONFIG_MPEG2_QSV_DECODER) += qsvdec_mpeg2.o | ||||
| OBJS-$(CONFIG_MPEG2_QSV_ENCODER) += qsvenc_mpeg2.o | OBJS-$(CONFIG_MPEG2_QSV_ENCODER) += qsvenc_mpeg2.o | ||||
| OBJS-$(CONFIG_MPEG4_OMX_ENCODER) += omx.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 | # libavformat dependencies | ||||
| OBJS-$(CONFIG_ISO_MEDIA) += mpeg4audio.o mpegaudiodata.o | OBJS-$(CONFIG_ISO_MEDIA) += mpeg4audio.o mpegaudiodata.o | ||||
| @@ -986,6 +989,7 @@ SKIPHEADERS-$(CONFIG_LIBUTVIDEO) += libutvideo.h | |||||
| SKIPHEADERS-$(CONFIG_LIBVPX) += libvpx.h | SKIPHEADERS-$(CONFIG_LIBVPX) += libvpx.h | ||||
| SKIPHEADERS-$(CONFIG_LIBWEBP_ENCODER) += libwebpenc_common.h | SKIPHEADERS-$(CONFIG_LIBWEBP_ENCODER) += libwebpenc_common.h | ||||
| SKIPHEADERS-$(CONFIG_MEDIACODEC) += mediacodecdec.h mediacodec_wrapper.h mediacodec_sw_buffer.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_QSV) += qsv.h qsv_internal.h | ||||
| SKIPHEADERS-$(CONFIG_QSVDEC) += qsvdec.h | SKIPHEADERS-$(CONFIG_QSVDEC) += qsvdec.h | ||||
| SKIPHEADERS-$(CONFIG_QSVENC) += qsvenc.h | SKIPHEADERS-$(CONFIG_QSVENC) += qsvenc.h | ||||
| @@ -19,43 +19,25 @@ | |||||
| * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||||
| */ | */ | ||||
| #include "config.h" | |||||
| #if defined(_WIN32) | #if defined(_WIN32) | ||||
| #include <windows.h> | #include <windows.h> | ||||
| #else | #else | ||||
| #include <dlfcn.h> | #include <dlfcn.h> | ||||
| #endif | #endif | ||||
| #include <nvEncodeAPI.h> | |||||
| #include "libavutil/fifo.h" | |||||
| #include "libavutil/internal.h" | |||||
| #include "libavutil/imgutils.h" | #include "libavutil/imgutils.h" | ||||
| #include "libavutil/avassert.h" | #include "libavutil/avassert.h" | ||||
| #include "libavutil/opt.h" | |||||
| #include "libavutil/mem.h" | #include "libavutil/mem.h" | ||||
| #include "libavutil/hwcontext.h" | #include "libavutil/hwcontext.h" | ||||
| #include "avcodec.h" | |||||
| #include "internal.h" | #include "internal.h" | ||||
| #include "thread.h" | #include "thread.h" | ||||
| #include "nvenc.h" | |||||
| #if CONFIG_CUDA | #if CONFIG_CUDA | ||||
| #include <cuda.h> | |||||
| #include "libavutil/hwcontext_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 | #endif | ||||
| #if defined(_WIN32) | #if defined(_WIN32) | ||||
| @@ -66,34 +48,15 @@ typedef void* CUdeviceptr; | |||||
| #define DL_CLOSE_FUNC(l) dlclose(l) | #define DL_CLOSE_FUNC(l) dlclose(l) | ||||
| #endif | #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 | typedef struct NvencData | ||||
| { | { | ||||
| @@ -103,83 +66,12 @@ typedef struct NvencData | |||||
| } u; | } u; | ||||
| } NvencData; | } 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 | typedef struct NvencValuePair | ||||
| { | { | ||||
| const char *str; | const char *str; | ||||
| uint32_t num; | uint32_t num; | ||||
| } NvencValuePair; | } 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[] = { | static const NvencValuePair nvenc_h264_level_pairs[] = { | ||||
| { "auto", NV_ENC_LEVEL_AUTOSELECT }, | { "auto", NV_ENC_LEVEL_AUTOSELECT }, | ||||
| { "1" , NV_ENC_LEVEL_H264_1 }, | { "1" , NV_ENC_LEVEL_H264_1 }, | ||||
| @@ -1252,7 +1144,7 @@ static av_cold int nvenc_setup_extradata(AVCodecContext *avctx) | |||||
| return 0; | 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; | NvencContext *ctx = avctx->priv_data; | ||||
| NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs; | NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs; | ||||
| @@ -1315,7 +1207,7 @@ error: | |||||
| return res; | 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; | NvencContext *ctx = avctx->priv_data; | ||||
| NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs; | 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); | 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) | const AVFrame *frame, int *got_packet) | ||||
| { | { | ||||
| NVENCSTATUS nv_status; | NVENCSTATUS nv_status; | ||||
| @@ -1786,112 +1678,3 @@ static int nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, | |||||
| return 0; | 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 | |||||
| @@ -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 */ | |||||
| @@ -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 | |||||
| @@ -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, | |||||
| }; | |||||