|
|
|
@@ -76,13 +76,21 @@ |
|
|
|
const enum AVPixelFormat ff_nvenc_pix_fmts[] = { |
|
|
|
AV_PIX_FMT_YUV420P, |
|
|
|
AV_PIX_FMT_NV12, |
|
|
|
AV_PIX_FMT_P010, |
|
|
|
AV_PIX_FMT_YUV444P, |
|
|
|
AV_PIX_FMT_YUV444P16, |
|
|
|
#if CONFIG_CUDA |
|
|
|
AV_PIX_FMT_CUDA, |
|
|
|
#endif |
|
|
|
AV_PIX_FMT_NONE |
|
|
|
}; |
|
|
|
|
|
|
|
#define IS_10BIT(pix_fmt) (pix_fmt == AV_PIX_FMT_P010 || \ |
|
|
|
pix_fmt == AV_PIX_FMT_YUV444P16) |
|
|
|
|
|
|
|
#define IS_YUV444(pix_fmt) (pix_fmt == AV_PIX_FMT_YUV444P || \ |
|
|
|
pix_fmt == AV_PIX_FMT_YUV444P16) |
|
|
|
|
|
|
|
static const struct { |
|
|
|
NVENCSTATUS nverr; |
|
|
|
int averr; |
|
|
|
@@ -273,7 +281,7 @@ static int nvenc_check_capabilities(AVCodecContext *avctx) |
|
|
|
} |
|
|
|
|
|
|
|
ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_YUV444_ENCODE); |
|
|
|
if (ctx->data_pix_fmt == AV_PIX_FMT_YUV444P && ret <= 0) { |
|
|
|
if (IS_YUV444(ctx->data_pix_fmt) && ret <= 0) { |
|
|
|
av_log(avctx, AV_LOG_VERBOSE, "YUV444P not supported\n"); |
|
|
|
return AVERROR(ENOSYS); |
|
|
|
} |
|
|
|
@@ -314,6 +322,12 @@ static int nvenc_check_capabilities(AVCodecContext *avctx) |
|
|
|
return AVERROR(ENOSYS); |
|
|
|
} |
|
|
|
|
|
|
|
ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_10BIT_ENCODE); |
|
|
|
if (IS_10BIT(ctx->data_pix_fmt) && ret <= 0) { |
|
|
|
av_log(avctx, AV_LOG_VERBOSE, "10 bit encode not supported\n"); |
|
|
|
return AVERROR(ENOSYS); |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
@@ -800,9 +814,26 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx) |
|
|
|
hevc->outputPictureTimingSEI = 1; |
|
|
|
} |
|
|
|
|
|
|
|
/* No other profile is supported in the current SDK version 5 */ |
|
|
|
cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN_GUID; |
|
|
|
avctx->profile = FF_PROFILE_HEVC_MAIN; |
|
|
|
switch(ctx->profile) { |
|
|
|
case NV_ENC_HEVC_PROFILE_MAIN: |
|
|
|
cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN_GUID; |
|
|
|
avctx->profile = FF_PROFILE_HEVC_MAIN; |
|
|
|
break; |
|
|
|
case NV_ENC_HEVC_PROFILE_MAIN_10: |
|
|
|
cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN10_GUID; |
|
|
|
avctx->profile = FF_PROFILE_HEVC_MAIN_10; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
// force setting profile as main10 if input is 10 bit |
|
|
|
if (IS_10BIT(ctx->data_pix_fmt)) { |
|
|
|
cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN10_GUID; |
|
|
|
avctx->profile = FF_PROFILE_HEVC_MAIN_10; |
|
|
|
} |
|
|
|
|
|
|
|
hevc->chromaFormatIDC = IS_YUV444(ctx->data_pix_fmt) ? 3 : 1; |
|
|
|
|
|
|
|
hevc->pixelBitDepthMinus8 = IS_10BIT(ctx->data_pix_fmt) ? 2 : 0; |
|
|
|
|
|
|
|
hevc->level = ctx->level; |
|
|
|
|
|
|
|
@@ -958,10 +989,18 @@ static av_cold int nvenc_alloc_surface(AVCodecContext *avctx, int idx) |
|
|
|
ctx->surfaces[idx].format = NV_ENC_BUFFER_FORMAT_NV12_PL; |
|
|
|
break; |
|
|
|
|
|
|
|
case AV_PIX_FMT_P010: |
|
|
|
ctx->surfaces[idx].format = NV_ENC_BUFFER_FORMAT_YUV420_10BIT; |
|
|
|
break; |
|
|
|
|
|
|
|
case AV_PIX_FMT_YUV444P: |
|
|
|
ctx->surfaces[idx].format = NV_ENC_BUFFER_FORMAT_YUV444_PL; |
|
|
|
break; |
|
|
|
|
|
|
|
case AV_PIX_FMT_YUV444P16: |
|
|
|
ctx->surfaces[idx].format = NV_ENC_BUFFER_FORMAT_YUV444_10BIT; |
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
av_log(avctx, AV_LOG_FATAL, "Invalid input pixel format\n"); |
|
|
|
return AVERROR(EINVAL); |
|
|
|
@@ -1238,6 +1277,16 @@ static int nvenc_copy_frame(AVCodecContext *avctx, NvencSurface *inSurf, |
|
|
|
av_image_copy_plane(buf, lockBufferParams->pitch, |
|
|
|
frame->data[1], frame->linesize[1], |
|
|
|
avctx->width, avctx->height >> 1); |
|
|
|
} else if (frame->format == AV_PIX_FMT_P010) { |
|
|
|
av_image_copy_plane(buf, lockBufferParams->pitch, |
|
|
|
frame->data[0], frame->linesize[0], |
|
|
|
avctx->width << 1, avctx->height); |
|
|
|
|
|
|
|
buf += off; |
|
|
|
|
|
|
|
av_image_copy_plane(buf, lockBufferParams->pitch, |
|
|
|
frame->data[1], frame->linesize[1], |
|
|
|
avctx->width << 1, avctx->height >> 1); |
|
|
|
} else if (frame->format == AV_PIX_FMT_YUV444P) { |
|
|
|
av_image_copy_plane(buf, lockBufferParams->pitch, |
|
|
|
frame->data[0], frame->linesize[0], |
|
|
|
@@ -1254,6 +1303,22 @@ static int nvenc_copy_frame(AVCodecContext *avctx, NvencSurface *inSurf, |
|
|
|
av_image_copy_plane(buf, lockBufferParams->pitch, |
|
|
|
frame->data[2], frame->linesize[2], |
|
|
|
avctx->width, avctx->height); |
|
|
|
} else if (frame->format == AV_PIX_FMT_YUV444P16) { |
|
|
|
av_image_copy_plane(buf, lockBufferParams->pitch, |
|
|
|
frame->data[0], frame->linesize[0], |
|
|
|
avctx->width << 1, avctx->height); |
|
|
|
|
|
|
|
buf += off; |
|
|
|
|
|
|
|
av_image_copy_plane(buf, lockBufferParams->pitch, |
|
|
|
frame->data[1], frame->linesize[1], |
|
|
|
avctx->width << 1, avctx->height); |
|
|
|
|
|
|
|
buf += off; |
|
|
|
|
|
|
|
av_image_copy_plane(buf, lockBufferParams->pitch, |
|
|
|
frame->data[2], frame->linesize[2], |
|
|
|
avctx->width << 1, avctx->height); |
|
|
|
} else { |
|
|
|
av_log(avctx, AV_LOG_FATAL, "Invalid pixel format!\n"); |
|
|
|
return AVERROR(EINVAL); |
|
|
|
|