|
|
|
@@ -28,6 +28,7 @@ |
|
|
|
#include "libavutil/imgutils.h" |
|
|
|
#include "libavutil/avassert.h" |
|
|
|
#include "libavutil/mem.h" |
|
|
|
#include "libavutil/pixdesc.h" |
|
|
|
#include "internal.h" |
|
|
|
|
|
|
|
#define NVENC_CAP 0x30 |
|
|
|
@@ -1009,49 +1010,37 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx) |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static av_cold int nvenc_alloc_surface(AVCodecContext *avctx, int idx) |
|
|
|
static NV_ENC_BUFFER_FORMAT nvenc_map_buffer_format(enum AVPixelFormat pix_fmt) |
|
|
|
{ |
|
|
|
NvencContext *ctx = avctx->priv_data; |
|
|
|
NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs; |
|
|
|
NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs; |
|
|
|
|
|
|
|
NVENCSTATUS nv_status; |
|
|
|
NV_ENC_CREATE_BITSTREAM_BUFFER allocOut = { 0 }; |
|
|
|
allocOut.version = NV_ENC_CREATE_BITSTREAM_BUFFER_VER; |
|
|
|
|
|
|
|
switch (ctx->data_pix_fmt) { |
|
|
|
switch (pix_fmt) { |
|
|
|
case AV_PIX_FMT_YUV420P: |
|
|
|
ctx->surfaces[idx].format = NV_ENC_BUFFER_FORMAT_YV12_PL; |
|
|
|
break; |
|
|
|
|
|
|
|
return NV_ENC_BUFFER_FORMAT_YV12_PL; |
|
|
|
case AV_PIX_FMT_NV12: |
|
|
|
ctx->surfaces[idx].format = NV_ENC_BUFFER_FORMAT_NV12_PL; |
|
|
|
break; |
|
|
|
|
|
|
|
return NV_ENC_BUFFER_FORMAT_NV12_PL; |
|
|
|
case AV_PIX_FMT_P010: |
|
|
|
ctx->surfaces[idx].format = NV_ENC_BUFFER_FORMAT_YUV420_10BIT; |
|
|
|
break; |
|
|
|
|
|
|
|
return NV_ENC_BUFFER_FORMAT_YUV420_10BIT; |
|
|
|
case AV_PIX_FMT_YUV444P: |
|
|
|
ctx->surfaces[idx].format = NV_ENC_BUFFER_FORMAT_YUV444_PL; |
|
|
|
break; |
|
|
|
|
|
|
|
return NV_ENC_BUFFER_FORMAT_YUV444_PL; |
|
|
|
case AV_PIX_FMT_YUV444P16: |
|
|
|
ctx->surfaces[idx].format = NV_ENC_BUFFER_FORMAT_YUV444_10BIT; |
|
|
|
break; |
|
|
|
|
|
|
|
return NV_ENC_BUFFER_FORMAT_YUV444_10BIT; |
|
|
|
case AV_PIX_FMT_0RGB32: |
|
|
|
ctx->surfaces[idx].format = NV_ENC_BUFFER_FORMAT_ARGB; |
|
|
|
break; |
|
|
|
|
|
|
|
return NV_ENC_BUFFER_FORMAT_ARGB; |
|
|
|
case AV_PIX_FMT_0BGR32: |
|
|
|
ctx->surfaces[idx].format = NV_ENC_BUFFER_FORMAT_ABGR; |
|
|
|
break; |
|
|
|
|
|
|
|
return NV_ENC_BUFFER_FORMAT_ABGR; |
|
|
|
default: |
|
|
|
av_log(avctx, AV_LOG_FATAL, "Invalid input pixel format\n"); |
|
|
|
return AVERROR(EINVAL); |
|
|
|
return NV_ENC_BUFFER_FORMAT_UNDEFINED; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static av_cold int nvenc_alloc_surface(AVCodecContext *avctx, int idx) |
|
|
|
{ |
|
|
|
NvencContext *ctx = avctx->priv_data; |
|
|
|
NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs; |
|
|
|
NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs; |
|
|
|
|
|
|
|
NVENCSTATUS nv_status; |
|
|
|
NV_ENC_CREATE_BITSTREAM_BUFFER allocOut = { 0 }; |
|
|
|
allocOut.version = NV_ENC_CREATE_BITSTREAM_BUFFER_VER; |
|
|
|
|
|
|
|
if (avctx->pix_fmt == AV_PIX_FMT_CUDA) { |
|
|
|
ctx->surfaces[idx].in_ref = av_frame_alloc(); |
|
|
|
@@ -1059,6 +1048,14 @@ static av_cold int nvenc_alloc_surface(AVCodecContext *avctx, int idx) |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
} else { |
|
|
|
NV_ENC_CREATE_INPUT_BUFFER allocSurf = { 0 }; |
|
|
|
|
|
|
|
ctx->surfaces[idx].format = nvenc_map_buffer_format(ctx->data_pix_fmt); |
|
|
|
if (ctx->surfaces[idx].format == NV_ENC_BUFFER_FORMAT_UNDEFINED) { |
|
|
|
av_log(avctx, AV_LOG_FATAL, "Invalid input pixel format: %s\n", |
|
|
|
av_get_pix_fmt_name(ctx->data_pix_fmt)); |
|
|
|
return AVERROR(EINVAL); |
|
|
|
} |
|
|
|
|
|
|
|
allocSurf.version = NV_ENC_CREATE_INPUT_BUFFER_VER; |
|
|
|
allocSurf.width = (avctx->width + 31) & ~31; |
|
|
|
allocSurf.height = (avctx->height + 31) & ~31; |
|
|
|
@@ -1351,10 +1348,16 @@ static int nvenc_register_frame(AVCodecContext *avctx, const AVFrame *frame) |
|
|
|
reg.resourceType = NV_ENC_INPUT_RESOURCE_TYPE_CUDADEVICEPTR; |
|
|
|
reg.width = frames_ctx->width; |
|
|
|
reg.height = frames_ctx->height; |
|
|
|
reg.bufferFormat = ctx->surfaces[0].format; |
|
|
|
reg.pitch = frame->linesize[0]; |
|
|
|
reg.resourceToRegister = frame->data[0]; |
|
|
|
|
|
|
|
reg.bufferFormat = nvenc_map_buffer_format(frames_ctx->sw_format); |
|
|
|
if (reg.bufferFormat == NV_ENC_BUFFER_FORMAT_UNDEFINED) { |
|
|
|
av_log(avctx, AV_LOG_FATAL, "Invalid input pixel format: %s\n", |
|
|
|
av_get_pix_fmt_name(frames_ctx->sw_format)); |
|
|
|
return AVERROR(EINVAL); |
|
|
|
} |
|
|
|
|
|
|
|
ret = p_nvenc->nvEncRegisterResource(ctx->nvencoder, ®); |
|
|
|
if (ret != NV_ENC_SUCCESS) { |
|
|
|
nvenc_print_error(avctx, ret, "Error registering an input resource"); |
|
|
|
|