avcodec/nvenc: split H264/HEVC encoder definitions into separate files
Signed-off-by: Timo Rothenpieler <timo@rothenpieler.org>
This commit is contained in:
@ -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);
|
const enum AVPixelFormat ff_nvenc_pix_fmts[] = {
|
||||||
typedef CUresult(CUDAAPI *PCUDEVICEGETCOUNT)(int *count);
|
AV_PIX_FMT_YUV420P,
|
||||||
typedef CUresult(CUDAAPI *PCUDEVICEGET)(CUdevice *device, int ordinal);
|
AV_PIX_FMT_NV12,
|
||||||
typedef CUresult(CUDAAPI *PCUDEVICEGETNAME)(char *name, int len, CUdevice dev);
|
AV_PIX_FMT_YUV444P,
|
||||||
typedef CUresult(CUDAAPI *PCUDEVICECOMPUTECAPABILITY)(int *major, int *minor, CUdevice dev);
|
#if CONFIG_CUDA
|
||||||
typedef CUresult(CUDAAPI *PCUCTXCREATE)(CUcontext *pctx, unsigned int flags, CUdevice dev);
|
AV_PIX_FMT_CUDA,
|
||||||
typedef CUresult(CUDAAPI *PCUCTXPOPCURRENT)(CUcontext *pctx);
|
#endif
|
||||||
typedef CUresult(CUDAAPI *PCUCTXDESTROY)(CUcontext ctx);
|
AV_PIX_FMT_NONE
|
||||||
|
};
|
||||||
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;
|
|
||||||
|
|
||||||
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
|
|
||||||
|
159
libavcodec/nvenc.h
Normal file
159
libavcodec/nvenc.h
Normal file
@ -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 */
|
98
libavcodec/nvenc_h264.c
Normal file
98
libavcodec/nvenc_h264.c
Normal file
@ -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
|
72
libavcodec/nvenc_hevc.c
Normal file
72
libavcodec/nvenc_hevc.c
Normal file
@ -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,
|
||||||
|
};
|
Reference in New Issue
Block a user