@ -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 , & reg ) ;
if ( ret ! = NV_ENC_SUCCESS ) {
nvenc_print_error ( avctx , ret , " Error registering an input resource " ) ;