* [FFmpeg-devel] [PATCH 1/9] avutil/hwcontext_cuda: add 4:2:2 pixel format support
2025-01-30 19:40 [FFmpeg-devel] [PATCH 0/9] Nvidia Video Codec SDK 13.0 support Timo Rothenpieler
@ 2025-01-30 19:40 ` Timo Rothenpieler
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 2/9] avcodec/nvdec: add 4:2:2 decoding and 10-bit support Timo Rothenpieler
` (8 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Timo Rothenpieler @ 2025-01-30 19:40 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Diego de Souza
From: Diego de Souza <ddesouza@nvidia.com>
This commit adds support for 4:2:2 pixel formats, namely NV16 and
P216 for NVIDIA GPUs.
Signed-off-by: Diego de Souza <ddesouza@nvidia.com>
---
libavutil/hwcontext_cuda.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libavutil/hwcontext_cuda.c b/libavutil/hwcontext_cuda.c
index 3de3847399..5721612225 100644
--- a/libavutil/hwcontext_cuda.c
+++ b/libavutil/hwcontext_cuda.c
@@ -42,11 +42,13 @@ typedef struct CUDADeviceContext {
static const enum AVPixelFormat supported_formats[] = {
AV_PIX_FMT_NV12,
+ AV_PIX_FMT_NV16,
AV_PIX_FMT_YUV420P,
AV_PIX_FMT_YUVA420P,
AV_PIX_FMT_YUV444P,
AV_PIX_FMT_P010,
AV_PIX_FMT_P016,
+ AV_PIX_FMT_P216LE,
AV_PIX_FMT_YUV444P16,
AV_PIX_FMT_0RGB32,
AV_PIX_FMT_0BGR32,
--
2.45.2
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] [PATCH 2/9] avcodec/nvdec: add 4:2:2 decoding and 10-bit support
2025-01-30 19:40 [FFmpeg-devel] [PATCH 0/9] Nvidia Video Codec SDK 13.0 support Timo Rothenpieler
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 1/9] avutil/hwcontext_cuda: add 4:2:2 pixel format support Timo Rothenpieler
@ 2025-01-30 19:40 ` Timo Rothenpieler
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 3/9] avcodec/cuviddec: add HEVC/H.264 4:2:2 and H.264 " Timo Rothenpieler
` (7 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Timo Rothenpieler @ 2025-01-30 19:40 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Diego de Souza
From: Diego de Souza <ddesouza@nvidia.com>
This commit adds support for 4:2:2 decoding for HEVC and H.264 on
NVIDIA Blackwell GPUs. Additionally, it supports 10-bit decoding
for H.264 on Blackwell GPUs.
Signed-off-by: Diego de Souza <ddesouza@nvidia.com>
---
libavcodec/h264_slice.c | 3 +++
libavcodec/hevc/hevcdec.c | 6 ++++++
libavcodec/nvdec.c | 44 ++++++++++++++++++++++++++++++++-------
libavcodec/nvdec.h | 5 +++++
libavcodec/nvdec_h264.c | 2 +-
5 files changed, 51 insertions(+), 9 deletions(-)
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index 5108fa0921..cb22b76730 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -807,6 +807,9 @@ static enum AVPixelFormat get_pixel_format(H264Context *h, int force_callback)
#endif
#if CONFIG_H264_VULKAN_HWACCEL
*fmt++ = AV_PIX_FMT_VULKAN;
+#endif
+#if CONFIG_H264_NVDEC_HWACCEL
+ *fmt++ = AV_PIX_FMT_CUDA;
#endif
if (CHROMA444(h)) {
if (h->avctx->colorspace == AVCOL_SPC_RGB) {
diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c
index 7d3e844945..e9c045f7a1 100644
--- a/libavcodec/hevc/hevcdec.c
+++ b/libavcodec/hevc/hevcdec.c
@@ -626,6 +626,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
#endif
#if CONFIG_HEVC_VULKAN_HWACCEL
*fmt++ = AV_PIX_FMT_VULKAN;
+#endif
+#if CONFIG_HEVC_NVDEC_HWACCEL
+ *fmt++ = AV_PIX_FMT_CUDA;
#endif
break;
case AV_PIX_FMT_YUV444P10:
@@ -654,6 +657,9 @@ static enum AVPixelFormat get_format(HEVCContext *s, const HEVCSPS *sps)
#endif
#if CONFIG_HEVC_VULKAN_HWACCEL
*fmt++ = AV_PIX_FMT_VULKAN;
+#endif
+#if CONFIG_HEVC_NVDEC_HWACCEL
+ *fmt++ = AV_PIX_FMT_CUDA;
#endif
break;
}
diff --git a/libavcodec/nvdec.c b/libavcodec/nvdec.c
index db9d353c61..99351661ea 100644
--- a/libavcodec/nvdec.c
+++ b/libavcodec/nvdec.c
@@ -375,13 +375,27 @@ int ff_nvdec_decode_init(AVCodecContext *avctx)
switch (sw_desc->comp[0].depth) {
case 8:
- output_format = chroma_444 ? cudaVideoSurfaceFormat_YUV444 :
- cudaVideoSurfaceFormat_NV12;
+ if (chroma_444) {
+ output_format = cudaVideoSurfaceFormat_YUV444;
+#ifdef NVDEC_HAVE_422_SUPPORT
+ } else if (cuvid_chroma_format == cudaVideoChromaFormat_422) {
+ output_format = cudaVideoSurfaceFormat_NV16;
+#endif
+ } else {
+ output_format = cudaVideoSurfaceFormat_NV12;
+ }
break;
case 10:
case 12:
- output_format = chroma_444 ? cudaVideoSurfaceFormat_YUV444_16Bit :
- cudaVideoSurfaceFormat_P016;
+ if (chroma_444) {
+ output_format = cudaVideoSurfaceFormat_YUV444_16Bit;
+#ifdef NVDEC_HAVE_422_SUPPORT
+ } else if (cuvid_chroma_format == cudaVideoChromaFormat_422) {
+ output_format = cudaVideoSurfaceFormat_P216;
+#endif
+ } else {
+ output_format = cudaVideoSurfaceFormat_P016;
+ }
break;
default:
av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth\n");
@@ -729,13 +743,27 @@ int ff_nvdec_frame_params(AVCodecContext *avctx,
switch (sw_desc->comp[0].depth) {
case 8:
- frames_ctx->sw_format = chroma_444 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_NV12;
+ if (chroma_444) {
+ frames_ctx->sw_format = AV_PIX_FMT_YUV444P;
+#ifdef NVDEC_HAVE_422_SUPPORT
+ } else if (cuvid_chroma_format == cudaVideoChromaFormat_422) {
+ frames_ctx->sw_format = AV_PIX_FMT_NV16;
+#endif
+ } else {
+ frames_ctx->sw_format = AV_PIX_FMT_NV12;
+ }
break;
case 10:
- frames_ctx->sw_format = chroma_444 ? AV_PIX_FMT_YUV444P16 : AV_PIX_FMT_P010;
- break;
case 12:
- frames_ctx->sw_format = chroma_444 ? AV_PIX_FMT_YUV444P16 : AV_PIX_FMT_P016;
+ if (chroma_444) {
+ frames_ctx->sw_format = AV_PIX_FMT_YUV444P16;
+#ifdef NVDEC_HAVE_422_SUPPORT
+ } else if (cuvid_chroma_format == cudaVideoChromaFormat_422) {
+ frames_ctx->sw_format = AV_PIX_FMT_P216LE;
+#endif
+ } else {
+ frames_ctx->sw_format = AV_PIX_FMT_P016LE;
+ }
break;
default:
return AVERROR(EINVAL);
diff --git a/libavcodec/nvdec.h b/libavcodec/nvdec.h
index 5e22f672d1..2e80c0dc1e 100644
--- a/libavcodec/nvdec.h
+++ b/libavcodec/nvdec.h
@@ -41,6 +41,11 @@
((major) < 8 || ((major) == 8 && (minor) <= 0))
#endif
+// SDK 13.0 compile time feature checks
+#if NVDECAPI_CHECK_VERSION(13, 0)
+#define NVDEC_HAVE_422_SUPPORT
+#endif
+
typedef struct NVDECFrame {
unsigned int idx;
unsigned int ref_idx;
diff --git a/libavcodec/nvdec_h264.c b/libavcodec/nvdec_h264.c
index 9adbc521ec..1ae3dfd032 100644
--- a/libavcodec/nvdec_h264.c
+++ b/libavcodec/nvdec_h264.c
@@ -97,7 +97,7 @@ static int nvdec_h264_start_frame(AVCodecContext *avctx,
.num_ref_idx_l1_active_minus1 = pps->ref_count[1] - 1,
.weighted_pred_flag = pps->weighted_pred,
.weighted_bipred_idc = pps->weighted_bipred_idc,
- .pic_init_qp_minus26 = pps->init_qp - 26,
+ .pic_init_qp_minus26 = pps->init_qp - 26 - 6 * (sps->bit_depth_luma - 8),
.deblocking_filter_control_present_flag = pps->deblocking_filter_parameters_present,
.redundant_pic_cnt_present_flag = pps->redundant_pic_cnt_present,
.transform_8x8_mode_flag = pps->transform_8x8_mode,
--
2.45.2
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] [PATCH 3/9] avcodec/cuviddec: add HEVC/H.264 4:2:2 and H.264 10-bit support
2025-01-30 19:40 [FFmpeg-devel] [PATCH 0/9] Nvidia Video Codec SDK 13.0 support Timo Rothenpieler
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 1/9] avutil/hwcontext_cuda: add 4:2:2 pixel format support Timo Rothenpieler
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 2/9] avcodec/nvdec: add 4:2:2 decoding and 10-bit support Timo Rothenpieler
@ 2025-01-30 19:40 ` Timo Rothenpieler
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 4/9] avcodec/nvenc: add 4:2:2 encoding " Timo Rothenpieler
` (6 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Timo Rothenpieler @ 2025-01-30 19:40 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Diego de Souza
From: Diego de Souza <ddesouza@nvidia.com>
This commit adds support for 4:2:2 decoding for HEVC and H.264 on
NVIDIA Blackwell GPUs for cuviddec. Moreover, it supports 10-bit
decoding for H.264 on Blackwell GPUs.
Signed-off-by: Diego de Souza <ddesouza@nvidia.com>
---
libavcodec/cuviddec.c | 83 +++++++++++++++++++++++++++++++++++++------
1 file changed, 72 insertions(+), 11 deletions(-)
diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c
index 502bcc7fc2..67076a1752 100644
--- a/libavcodec/cuviddec.c
+++ b/libavcodec/cuviddec.c
@@ -178,15 +178,39 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form
switch (format->bit_depth_luma_minus8) {
case 0: // 8-bit
- pix_fmts[1] = chroma_444 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_NV12;
+ if (chroma_444) {
+ pix_fmts[1] = AV_PIX_FMT_YUV444P;
+#ifdef NVDEC_HAVE_422_SUPPORT
+ } else if (format->chroma_format == cudaVideoChromaFormat_422) {
+ pix_fmts[1] = AV_PIX_FMT_NV16;
+#endif
+ } else {
+ pix_fmts[1] = AV_PIX_FMT_NV12;
+ }
caps = &ctx->caps8;
break;
case 2: // 10-bit
- pix_fmts[1] = chroma_444 ? AV_PIX_FMT_YUV444P16 : AV_PIX_FMT_P010;
+ if (chroma_444) {
+ pix_fmts[1] = AV_PIX_FMT_YUV444P16;
+#ifdef NVDEC_HAVE_422_SUPPORT
+ } else if (format->chroma_format == cudaVideoChromaFormat_422) {
+ pix_fmts[1] = AV_PIX_FMT_P216LE;
+#endif
+ } else {
+ pix_fmts[1] = AV_PIX_FMT_P016;
+ }
caps = &ctx->caps10;
break;
case 4: // 12-bit
- pix_fmts[1] = chroma_444 ? AV_PIX_FMT_YUV444P16 : AV_PIX_FMT_P016;
+ if (chroma_444) {
+ pix_fmts[1] = AV_PIX_FMT_YUV444P16;
+#ifdef NVDEC_HAVE_422_SUPPORT
+ } else if (format->chroma_format == cudaVideoChromaFormat_422) {
+ pix_fmts[1] = AV_PIX_FMT_P216LE;
+#endif
+ } else {
+ pix_fmts[1] = AV_PIX_FMT_P016;
+ }
caps = &ctx->caps12;
break;
default:
@@ -304,6 +328,14 @@ static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* form
case AV_PIX_FMT_P016:
cuinfo.OutputFormat = cudaVideoSurfaceFormat_P016;
break;
+#ifdef NVDEC_HAVE_422_SUPPORT
+ case AV_PIX_FMT_NV16:
+ cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV16;
+ break;
+ case AV_PIX_FMT_P216:
+ cuinfo.OutputFormat = cudaVideoSurfaceFormat_P216;
+ break;
+#endif
case AV_PIX_FMT_YUV444P:
cuinfo.OutputFormat = cudaVideoSurfaceFormat_YUV444;
break;
@@ -578,6 +610,10 @@ static int cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame)
} else if (avctx->pix_fmt == AV_PIX_FMT_NV12 ||
avctx->pix_fmt == AV_PIX_FMT_P010 ||
avctx->pix_fmt == AV_PIX_FMT_P016 ||
+#ifdef NVDEC_HAVE_422_SUPPORT
+ avctx->pix_fmt == AV_PIX_FMT_NV16 ||
+ avctx->pix_fmt == AV_PIX_FMT_P216 ||
+#endif
avctx->pix_fmt == AV_PIX_FMT_YUV444P ||
avctx->pix_fmt == AV_PIX_FMT_YUV444P16) {
unsigned int offset = 0;
@@ -734,6 +770,7 @@ static int cuvid_test_capabilities(AVCodecContext *avctx,
{
CuvidContext *ctx = avctx->priv_data;
CUVIDDECODECAPS *caps;
+ cudaVideoChromaFormat chroma_format;
int res8 = 0, res10 = 0, res12 = 0;
if (!ctx->cvdl->cuvidGetDecoderCaps) {
@@ -753,8 +790,28 @@ static int cuvid_test_capabilities(AVCodecContext *avctx,
ctx->caps8.eCodecType = ctx->caps10.eCodecType = ctx->caps12.eCodecType
= cuparseinfo->CodecType;
+ switch (avctx->pix_fmt) {
+ case AV_PIX_FMT_YUV444P16:
+ case AV_PIX_FMT_YUV444P:
+ chroma_format = cudaVideoChromaFormat_444;
+ break;
+#ifdef NVDEC_HAVE_422_SUPPORT
+ case AV_PIX_FMT_P216:
+ case AV_PIX_FMT_P210:
+ case AV_PIX_FMT_NV16:
+ chroma_format = cudaVideoChromaFormat_422;
+ break;
+#endif
+ case AV_PIX_FMT_P016:
+ case AV_PIX_FMT_P010:
+ case AV_PIX_FMT_NV12:
+ chroma_format = cudaVideoChromaFormat_420;
+ break;
+ default:
+ chroma_format = cudaVideoChromaFormat_Monochrome;
+ }
ctx->caps8.eChromaFormat = ctx->caps10.eChromaFormat = ctx->caps12.eChromaFormat
- = cudaVideoChromaFormat_420;
+ = chroma_format;
ctx->caps8.nBitDepthMinus8 = 0;
ctx->caps10.nBitDepthMinus8 = 2;
@@ -790,12 +847,12 @@ static int cuvid_test_capabilities(AVCodecContext *avctx,
}
if (!ctx->caps8.bIsSupported) {
- av_log(avctx, AV_LOG_ERROR, "Codec %s is not supported.\n", avctx->codec->name);
+ av_log(avctx, AV_LOG_ERROR, "Codec %s is not supported with this chroma format.\n", avctx->codec->name);
return AVERROR(EINVAL);
}
if (!caps->bIsSupported) {
- av_log(avctx, AV_LOG_ERROR, "Bit depth %d is not supported.\n", bit_depth);
+ av_log(avctx, AV_LOG_ERROR, "Bit depth %d with this chroma format is not supported.\n", bit_depth);
return AVERROR(EINVAL);
}
@@ -839,7 +896,7 @@ static av_cold int cuvid_decode_init(AVCodecContext *avctx)
int probed_width = avctx->coded_width ? avctx->coded_width : 1280;
int probed_height = avctx->coded_height ? avctx->coded_height : 720;
- int probed_bit_depth = 8, is_yuv444 = 0;
+ int probed_bit_depth = 8, is_yuv444 = 0, is_yuv422 = 0;
const AVPixFmtDescriptor *probe_desc = av_pix_fmt_desc_get(avctx->pix_fmt);
if (probe_desc && probe_desc->nb_components)
@@ -848,17 +905,21 @@ static av_cold int cuvid_decode_init(AVCodecContext *avctx)
if (probe_desc && !probe_desc->log2_chroma_w && !probe_desc->log2_chroma_h)
is_yuv444 = 1;
+#ifdef NVDEC_HAVE_422_SUPPORT
+ if (probe_desc && probe_desc->log2_chroma_w && !probe_desc->log2_chroma_h)
+ is_yuv422 = 1;
+#endif
+
// Pick pixel format based on bit depth and chroma sampling.
- // Only 420 and 444 sampling are supported by HW so far, no need to check for 422.
switch (probed_bit_depth) {
case 10:
- pix_fmts[1] = is_yuv444 ? AV_PIX_FMT_YUV444P16 : AV_PIX_FMT_P010;
+ pix_fmts[1] = is_yuv444 ? AV_PIX_FMT_YUV444P16 : (is_yuv422 ? AV_PIX_FMT_P216 : AV_PIX_FMT_P010);
break;
case 12:
- pix_fmts[1] = is_yuv444 ? AV_PIX_FMT_YUV444P16 : AV_PIX_FMT_P016;
+ pix_fmts[1] = is_yuv444 ? AV_PIX_FMT_YUV444P16 : (is_yuv422 ? AV_PIX_FMT_P216 : AV_PIX_FMT_P016);
break;
default:
- pix_fmts[1] = is_yuv444 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_NV12;
+ pix_fmts[1] = is_yuv444 ? AV_PIX_FMT_YUV444P : (is_yuv422 ? AV_PIX_FMT_NV16 : AV_PIX_FMT_NV12);
break;
}
--
2.45.2
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] [PATCH 4/9] avcodec/nvenc: add 4:2:2 encoding and H.264 10-bit support
2025-01-30 19:40 [FFmpeg-devel] [PATCH 0/9] Nvidia Video Codec SDK 13.0 support Timo Rothenpieler
` (2 preceding siblings ...)
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 3/9] avcodec/cuviddec: add HEVC/H.264 4:2:2 and H.264 " Timo Rothenpieler
@ 2025-01-30 19:40 ` Timo Rothenpieler
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 5/9] avcodec/nvenc: add UHQ to AV1 for NVENC Timo Rothenpieler
` (5 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Timo Rothenpieler @ 2025-01-30 19:40 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Diego de Souza
From: Diego de Souza <ddesouza@nvidia.com>
This commit adds support for 4:2:2 encoding for HEVC and H.264 on
NVIDIA Blackwell GPUs. Additionally, it supports 10-bit encoding
for H.264 on Blackwell GPUs.
Signed-off-by: Diego de Souza <ddesouza@nvidia.com>
---
libavcodec/nvenc.c | 68 +++++++++++++++++++++++++++++++++++++----
libavcodec/nvenc.h | 12 ++++++++
libavcodec/nvenc_h264.c | 9 ++++++
3 files changed, 83 insertions(+), 6 deletions(-)
diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index 06e3fb81a4..f301269dbd 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -59,6 +59,11 @@ const enum AVPixelFormat ff_nvenc_pix_fmts[] = {
AV_PIX_FMT_P010,
AV_PIX_FMT_YUV444P,
AV_PIX_FMT_P016, // Truncated to 10bits
+#ifdef NVENC_HAVE_422_SUPPORT
+ AV_PIX_FMT_NV16,
+ AV_PIX_FMT_P210,
+ AV_PIX_FMT_P216,
+#endif
AV_PIX_FMT_YUV444P16, // Truncated to 10bits
AV_PIX_FMT_0RGB32,
AV_PIX_FMT_RGB32,
@@ -87,6 +92,8 @@ const AVCodecHWConfigInternal *const ff_nvenc_hw_configs[] = {
#define IS_10BIT(pix_fmt) (pix_fmt == AV_PIX_FMT_P010 || \
pix_fmt == AV_PIX_FMT_P016 || \
+ pix_fmt == AV_PIX_FMT_P210 || \
+ pix_fmt == AV_PIX_FMT_P216 || \
pix_fmt == AV_PIX_FMT_YUV444P16 || \
pix_fmt == AV_PIX_FMT_X2RGB10 || \
pix_fmt == AV_PIX_FMT_X2BGR10 || \
@@ -105,6 +112,10 @@ const AVCodecHWConfigInternal *const ff_nvenc_hw_configs[] = {
pix_fmt == AV_PIX_FMT_GBRP16 || \
(ctx->rgb_mode == NVENC_RGB_MODE_444 && IS_RGB(pix_fmt)))
+#define IS_YUV422(pix_fmt) (pix_fmt == AV_PIX_FMT_NV16 || \
+ pix_fmt == AV_PIX_FMT_P210 || \
+ pix_fmt == AV_PIX_FMT_P216)
+
#define IS_GBRP(pix_fmt) (pix_fmt == AV_PIX_FMT_GBRP || \
pix_fmt == AV_PIX_FMT_GBRP16)
@@ -477,6 +488,16 @@ static int nvenc_check_capabilities(AVCodecContext *avctx)
return AVERROR(ENOSYS);
}
+#ifdef NVENC_HAVE_422_SUPPORT
+ ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_YUV422_ENCODE);
+#else
+ ret = 0;
+#endif
+ if (IS_YUV422(ctx->data_pix_fmt) && ret <= 0) {
+ av_log(avctx, AV_LOG_WARNING, "YUV422P not supported\n");
+ return AVERROR(ENOSYS);
+ }
+
ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_LOSSLESS_ENCODE);
if (ctx->flags & NVENC_LOSSLESS && ret <= 0) {
av_log(avctx, AV_LOG_WARNING, "Lossless encoding not supported\n");
@@ -1297,6 +1318,18 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx)
cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_GUID;
avctx->profile = AV_PROFILE_H264_HIGH;
break;
+#ifdef NVENC_HAVE_H264_10BIT_SUPPORT
+ case NV_ENC_H264_PROFILE_HIGH_10:
+ cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_10_GUID;
+ avctx->profile = AV_PROFILE_H264_HIGH_10;
+ break;
+#endif
+#ifdef NVENC_HAVE_422_SUPPORT
+ case NV_ENC_H264_PROFILE_HIGH_422:
+ cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_422_GUID;
+ avctx->profile = AV_PROFILE_H264_HIGH_422;
+ break;
+#endif
case NV_ENC_H264_PROFILE_HIGH_444P:
cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_444_GUID;
avctx->profile = AV_PROFILE_H264_HIGH_444_PREDICTIVE;
@@ -1304,21 +1337,37 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx)
}
}
+#ifdef NVENC_HAVE_H264_10BIT_SUPPORT
+ // force setting profile as high10 if input is 10 bit or if it should be encoded as 10 bit
+ if (IS_10BIT(ctx->data_pix_fmt) || ctx->highbitdepth) {
+ cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_10_GUID;
+ avctx->profile = AV_PROFILE_H264_HIGH_10;
+ }
+#endif
+
// force setting profile as high444p if input is AV_PIX_FMT_YUV444P
if (IS_YUV444(ctx->data_pix_fmt)) {
cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_444_GUID;
avctx->profile = AV_PROFILE_H264_HIGH_444_PREDICTIVE;
}
+#ifdef NVENC_HAVE_422_SUPPORT
+ // force setting profile as high422p if input is AV_PIX_FMT_YUV422P
+ if (IS_YUV422(ctx->data_pix_fmt)) {
+ cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_422_GUID;
+ avctx->profile = AV_PROFILE_H264_HIGH_422;
+ }
+#endif
+
vui->bitstreamRestrictionFlag = cc->gopLength != 1 || avctx->profile < AV_PROFILE_H264_HIGH;
- h264->chromaFormatIDC = avctx->profile == AV_PROFILE_H264_HIGH_444_PREDICTIVE ? 3 : 1;
+ h264->chromaFormatIDC = IS_YUV444(ctx->data_pix_fmt) ? 3 : IS_YUV422(ctx->data_pix_fmt) ? 2 : 1;
h264->level = ctx->level;
#ifdef NVENC_HAVE_NEW_BIT_DEPTH_API
- h264->inputBitDepth = h264->outputBitDepth =
- IS_10BIT(ctx->data_pix_fmt) ? NV_ENC_BIT_DEPTH_10 : NV_ENC_BIT_DEPTH_8;
+ h264->inputBitDepth = IS_10BIT(ctx->data_pix_fmt) ? NV_ENC_BIT_DEPTH_10 : NV_ENC_BIT_DEPTH_8;
+ h264->outputBitDepth = (IS_10BIT(ctx->data_pix_fmt) || ctx->highbitdepth) ? NV_ENC_BIT_DEPTH_10 : NV_ENC_BIT_DEPTH_8;
#endif
if (ctx->coder >= 0)
@@ -1428,13 +1477,13 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
avctx->profile = AV_PROFILE_HEVC_MAIN_10;
}
- // force setting profile as rext if input is yuv444
- if (IS_YUV444(ctx->data_pix_fmt)) {
+ // force setting profile as rext if input is yuv444 or yuv422
+ if (IS_YUV444(ctx->data_pix_fmt) || IS_YUV422(ctx->data_pix_fmt)) {
cc->profileGUID = NV_ENC_HEVC_PROFILE_FREXT_GUID;
avctx->profile = AV_PROFILE_HEVC_REXT;
}
- hevc->chromaFormatIDC = IS_YUV444(ctx->data_pix_fmt) ? 3 : 1;
+ hevc->chromaFormatIDC = IS_YUV444(ctx->data_pix_fmt) ? 3 : IS_YUV422(ctx->data_pix_fmt) ? 2 : 1;
#ifdef NVENC_HAVE_NEW_BIT_DEPTH_API
hevc->inputBitDepth = IS_10BIT(ctx->data_pix_fmt) ? NV_ENC_BIT_DEPTH_10 : NV_ENC_BIT_DEPTH_8;
@@ -1821,6 +1870,13 @@ static NV_ENC_BUFFER_FORMAT nvenc_map_buffer_format(enum AVPixelFormat pix_fmt)
return NV_ENC_BUFFER_FORMAT_ARGB10;
case AV_PIX_FMT_X2BGR10:
return NV_ENC_BUFFER_FORMAT_ABGR10;
+#ifdef NVENC_HAVE_422_SUPPORT
+ case AV_PIX_FMT_NV16:
+ return NV_ENC_BUFFER_FORMAT_NV16;
+ case AV_PIX_FMT_P210:
+ case AV_PIX_FMT_P216:
+ return NV_ENC_BUFFER_FORMAT_P210;
+#endif
default:
return NV_ENC_BUFFER_FORMAT_UNDEFINED;
}
diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
index 0130b99369..34774b6a72 100644
--- a/libavcodec/nvenc.h
+++ b/libavcodec/nvenc.h
@@ -93,6 +93,12 @@ typedef void ID3D11Device;
#define NVENC_HAVE_UNIDIR_B
#endif
+// SDK 13.0 compile time feature checks
+#if NVENCAPI_CHECK_VERSION(13, 0)
+#define NVENC_HAVE_H264_10BIT_SUPPORT
+#define NVENC_HAVE_422_SUPPORT
+#endif
+
typedef struct NvencSurface
{
NV_ENC_INPUT_PTR input_surface;
@@ -151,6 +157,12 @@ enum {
NV_ENC_H264_PROFILE_BASELINE,
NV_ENC_H264_PROFILE_MAIN,
NV_ENC_H264_PROFILE_HIGH,
+#ifdef NVENC_HAVE_H264_10BIT_SUPPORT
+ NV_ENC_H264_PROFILE_HIGH_10,
+#endif
+#ifdef NVENC_HAVE_422_SUPPORT
+ NV_ENC_H264_PROFILE_HIGH_422,
+#endif
NV_ENC_H264_PROFILE_HIGH_444P,
};
diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c
index 8cbe4dca39..ca997da209 100644
--- a/libavcodec/nvenc_h264.c
+++ b/libavcodec/nvenc_h264.c
@@ -61,6 +61,12 @@ static const AVOption options[] = {
{ "baseline", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_PROFILE_BASELINE }, 0, 0, VE, .unit = "profile" },
{ "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_PROFILE_MAIN }, 0, 0, VE, .unit = "profile" },
{ "high", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_PROFILE_HIGH }, 0, 0, VE, .unit = "profile" },
+#ifdef NVENC_HAVE_H264_10BIT_SUPPORT
+ { "high10", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_PROFILE_HIGH_10 }, 0, 0, VE, .unit = "profile" },
+#endif
+#ifdef NVENC_HAVE_422_SUPPORT
+ { "high422", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_PROFILE_HIGH_422 }, 0, 0, VE, .unit = "profile" },
+#endif
{ "high444p", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_H264_PROFILE_HIGH_444P }, 0, 0, VE, .unit = "profile" },
#ifdef NVENC_HAVE_H264_LVL6
{ "level", "Set the encoding level restriction", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = NV_ENC_LEVEL_AUTOSELECT }, NV_ENC_LEVEL_AUTOSELECT, NV_ENC_LEVEL_H264_62, VE, .unit = "level" },
@@ -199,6 +205,9 @@ static const AVOption options[] = {
{ "fullres", "Two Pass encoding is enabled where first Pass is full resolution",
0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TWO_PASS_FULL_RESOLUTION }, 0, 0, VE, .unit = "multipass" },
#endif
+#ifdef NVENC_HAVE_H264_10BIT_SUPPORT
+ { "highbitdepth", "Enable 10 bit encode for 8 bit input",OFFSET(highbitdepth),AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
+#endif
#ifdef NVENC_HAVE_LDKFS
{ "ldkfs", "Low delay key frame scale; Specifies the Scene Change frame size increase allowed in case of single frame VBV and CBR",
OFFSET(ldkfs), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, UCHAR_MAX, VE },
--
2.45.2
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] [PATCH 5/9] avcodec/nvenc: add UHQ to AV1 for NVENC
2025-01-30 19:40 [FFmpeg-devel] [PATCH 0/9] Nvidia Video Codec SDK 13.0 support Timo Rothenpieler
` (3 preceding siblings ...)
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 4/9] avcodec/nvenc: add 4:2:2 encoding " Timo Rothenpieler
@ 2025-01-30 19:40 ` Timo Rothenpieler
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 6/9] avcodec/nvenc: add Temporal Filtering for AV1 and H.264 in NVENC Timo Rothenpieler
` (4 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Timo Rothenpieler @ 2025-01-30 19:40 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Diego de Souza
From: Diego de Souza <ddesouza@nvidia.com>
This commit adds support for Ultra High Quality mode for AV1 on
NVIDIA GPUs.
Signed-off-by: Diego de Souza <ddesouza@nvidia.com>
---
libavcodec/nvenc.h | 1 +
libavcodec/nvenc_av1.c | 5 ++++-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
index 34774b6a72..2d8e8bef44 100644
--- a/libavcodec/nvenc.h
+++ b/libavcodec/nvenc.h
@@ -97,6 +97,7 @@ typedef void ID3D11Device;
#if NVENCAPI_CHECK_VERSION(13, 0)
#define NVENC_HAVE_H264_10BIT_SUPPORT
#define NVENC_HAVE_422_SUPPORT
+#define NVENC_HAVE_AV1_UHQ_TUNING
#endif
typedef struct NvencSurface
diff --git a/libavcodec/nvenc_av1.c b/libavcodec/nvenc_av1.c
index 79253cff66..bccc63dd5b 100644
--- a/libavcodec/nvenc_av1.c
+++ b/libavcodec/nvenc_av1.c
@@ -38,8 +38,11 @@ static const AVOption options[] = {
{ "p5", "slow (good quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P5 }, 0, 0, VE, .unit = "preset" },
{ "p6", "slower (better quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P6 }, 0, 0, VE, .unit = "preset" },
{ "p7", "slowest (best quality)", 0, AV_OPT_TYPE_CONST, { .i64 = PRESET_P7 }, 0, 0, VE, .unit = "preset" },
- { "tune", "Set the encoding tuning info", OFFSET(tuning_info), AV_OPT_TYPE_INT, { .i64 = NV_ENC_TUNING_INFO_HIGH_QUALITY }, NV_ENC_TUNING_INFO_HIGH_QUALITY, NV_ENC_TUNING_INFO_LOSSLESS, VE, .unit = "tune" },
+ { "tune", "Set the encoding tuning info", OFFSET(tuning_info), AV_OPT_TYPE_INT, { .i64 = NV_ENC_TUNING_INFO_HIGH_QUALITY }, NV_ENC_TUNING_INFO_HIGH_QUALITY, NV_ENC_TUNING_INFO_COUNT - 1, VE, .unit = "tune" },
{ "hq", "High quality", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_HIGH_QUALITY }, 0, 0, VE, .unit = "tune" },
+#ifdef NVENC_HAVE_AV1_UHQ_TUNING
+ { "uhq", "Ultra high quality", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_ULTRA_HIGH_QUALITY }, 0, 0, VE, .unit = "tune" },
+#endif
{ "ll", "Low latency", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_LOW_LATENCY }, 0, 0, VE, .unit = "tune" },
{ "ull", "Ultra low latency", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY }, 0, 0, VE, .unit = "tune" },
{ "lossless", "Lossless", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_LOSSLESS }, 0, 0, VE, .unit = "tune" },
--
2.45.2
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] [PATCH 6/9] avcodec/nvenc: add Temporal Filtering for AV1 and H.264 in NVENC
2025-01-30 19:40 [FFmpeg-devel] [PATCH 0/9] Nvidia Video Codec SDK 13.0 support Timo Rothenpieler
` (4 preceding siblings ...)
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 5/9] avcodec/nvenc: add UHQ to AV1 for NVENC Timo Rothenpieler
@ 2025-01-30 19:40 ` Timo Rothenpieler
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 7/9] avcodec/nvenc: add MV-HEVC encoding support Timo Rothenpieler
` (3 subsequent siblings)
9 siblings, 0 replies; 17+ messages in thread
From: Timo Rothenpieler @ 2025-01-30 19:40 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Diego de Souza
From: Diego de Souza <ddesouza@nvidia.com>
This commit extends the support for Temporal Filtering in NVENC for
AV1 and H.264 codecs. For natural videos with noise, NVENC temporal
filtering improves video coding efficiency by 4-5%.
Signed-off-by: Diego de Souza <ddesouza@nvidia.com>
---
libavcodec/nvenc.c | 40 +++++++++++++++++++++++++++++++++++++++-
libavcodec/nvenc.h | 1 +
libavcodec/nvenc_av1.c | 6 ++++++
libavcodec/nvenc_h264.c | 6 ++++++
4 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index f301269dbd..3403fa8996 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -627,7 +627,7 @@ static int nvenc_check_capabilities(AVCodecContext *avctx)
return AVERROR(ENOSYS);
}
-#ifdef NVENC_HAVE_TEMPORAL_FILTER
+#if defined(NVENC_HAVE_TEMPORAL_FILTER) || defined(NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER)
ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_TEMPORAL_FILTER);
if(ctx->tf_level > 0 && ret <= 0) {
av_log(avctx, AV_LOG_WARNING, "Temporal filtering not supported by the device\n");
@@ -1383,6 +1383,25 @@ static av_cold int nvenc_setup_h264_config(AVCodecContext *avctx)
h264->numRefL1 = avctx->refs;
#endif
+#ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
+ if (ctx->tf_level >= 0) {
+ h264->tfLevel = ctx->tf_level;
+
+ switch (ctx->tf_level)
+ {
+ case NV_ENC_TEMPORAL_FILTER_LEVEL_0:
+ case NV_ENC_TEMPORAL_FILTER_LEVEL_4:
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "Invalid temporal filtering level.\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (ctx->encode_config.frameIntervalP < 5)
+ av_log(avctx, AV_LOG_WARNING, "Temporal filtering needs at least 4 B-Frames (-bf 4).\n");
+ }
+#endif
+
return 0;
}
@@ -1608,6 +1627,25 @@ static av_cold int nvenc_setup_av1_config(AVCodecContext *avctx)
av1->numFwdRefs = avctx->refs;
av1->numBwdRefs = avctx->refs;
+#ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
+ if (ctx->tf_level >= 0) {
+ av1->tfLevel = ctx->tf_level;
+
+ switch (ctx->tf_level)
+ {
+ case NV_ENC_TEMPORAL_FILTER_LEVEL_0:
+ case NV_ENC_TEMPORAL_FILTER_LEVEL_4:
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "Invalid temporal filtering level.\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (ctx->encode_config.frameIntervalP < 5)
+ av_log(avctx, AV_LOG_WARNING, "Temporal filtering needs at least 4 B-Frames (-bf 4).\n");
+ }
+#endif
+
return 0;
}
#endif
diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
index 2d8e8bef44..6f7f8d4e7f 100644
--- a/libavcodec/nvenc.h
+++ b/libavcodec/nvenc.h
@@ -98,6 +98,7 @@ typedef void ID3D11Device;
#define NVENC_HAVE_H264_10BIT_SUPPORT
#define NVENC_HAVE_422_SUPPORT
#define NVENC_HAVE_AV1_UHQ_TUNING
+#define NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
#endif
typedef struct NvencSurface
diff --git a/libavcodec/nvenc_av1.c b/libavcodec/nvenc_av1.c
index bccc63dd5b..5dd27fe872 100644
--- a/libavcodec/nvenc_av1.c
+++ b/libavcodec/nvenc_av1.c
@@ -152,6 +152,12 @@ static const AVOption options[] = {
OFFSET(extra_sei), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
{ "a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
{ "s12m_tc", "Use timecode (if available)", OFFSET(s12m_tc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
+#ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
+ { "tf_level", "Specifies the strength of the temporal filtering",
+ OFFSET(tf_level), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
+ { "0", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TEMPORAL_FILTER_LEVEL_0 }, 0, 0, VE, .unit = "tf_level" },
+ { "4", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TEMPORAL_FILTER_LEVEL_4 }, 0, 0, VE, .unit = "tf_level" },
+#endif
#ifdef NVENC_HAVE_LOOKAHEAD_LEVEL
{ "lookahead_level", "Specifies the lookahead level. Higher level may improve quality at the expense of performance.",
OFFSET(lookahead_level), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, NV_ENC_LOOKAHEAD_LEVEL_AUTOSELECT, VE, .unit = "lookahead_level" },
diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c
index ca997da209..5e9f73412f 100644
--- a/libavcodec/nvenc_h264.c
+++ b/libavcodec/nvenc_h264.c
@@ -224,6 +224,12 @@ static const AVOption options[] = {
OFFSET(max_slice_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE },
{ "constrained-encoding", "Enable constrainedFrame encoding where each slice in the constrained picture is independent of other slices",
OFFSET(constrained_encoding), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
+#ifdef NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
+ { "tf_level", "Specifies the strength of the temporal filtering",
+ OFFSET(tf_level), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, VE, .unit = "tf_level" },
+ { "0", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TEMPORAL_FILTER_LEVEL_0 }, 0, 0, VE, .unit = "tf_level" },
+ { "4", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TEMPORAL_FILTER_LEVEL_4 }, 0, 0, VE, .unit = "tf_level" },
+#endif
#ifdef NVENC_HAVE_LOOKAHEAD_LEVEL
{ "lookahead_level", "Specifies the lookahead level. Higher level may improve quality at the expense of performance.",
OFFSET(lookahead_level), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, NV_ENC_LOOKAHEAD_LEVEL_AUTOSELECT, VE, .unit = "lookahead_level" },
--
2.45.2
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] [PATCH 7/9] avcodec/nvenc: add MV-HEVC encoding support
2025-01-30 19:40 [FFmpeg-devel] [PATCH 0/9] Nvidia Video Codec SDK 13.0 support Timo Rothenpieler
` (5 preceding siblings ...)
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 6/9] avcodec/nvenc: add Temporal Filtering for AV1 and H.264 in NVENC Timo Rothenpieler
@ 2025-01-30 19:40 ` Timo Rothenpieler
2025-01-30 20:17 ` James Almer
2025-01-30 23:23 ` [FFmpeg-devel] [PATCH v2 " Timo Rothenpieler
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 8/9] avcodec/nvenc: use encoder level options for qmin/qmax Timo Rothenpieler
` (2 subsequent siblings)
9 siblings, 2 replies; 17+ messages in thread
From: Timo Rothenpieler @ 2025-01-30 19:40 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Diego de Souza
From: Diego de Souza <ddesouza@nvidia.com>
Added support for MV-HEVC encoding for stereoscopic videos (2 views
only). Compatible with the framepack filter when using the
AV_STEREO3D_FRAMESEQUENCE format.
Signed-off-by: Diego de Souza <ddesouza@nvidia.com>
---
libavcodec/nvenc.c | 49 +++++++++++++++++++++++++++++++++++++++++
libavcodec/nvenc.h | 4 ++++
libavcodec/nvenc_hevc.c | 6 +++++
3 files changed, 59 insertions(+)
diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index 3403fa8996..a528f1ce93 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -35,6 +35,7 @@
#include "libavutil/mem.h"
#include "libavutil/pixdesc.h"
#include "libavutil/mathematics.h"
+#include "libavutil/stereo3d.h"
#include "atsc_a53.h"
#include "codec_desc.h"
#include "encode.h"
@@ -656,6 +657,14 @@ static int nvenc_check_capabilities(AVCodecContext *avctx)
ctx->support_dyn_bitrate = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_DYN_BITRATE_CHANGE);
+#ifdef NVENC_HAVE_MVHEVC
+ ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_MVHEVC_ENCODE);
+ if(ctx->multiview && ret <= 0) {
+ av_log(avctx, AV_LOG_WARNING, "Multiview not supported by the device\n");
+ return AVERROR(ENOSYS);
+ }
+#endif
+
return 0;
}
@@ -1544,6 +1553,11 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
}
#endif
+#ifdef NVENC_HAVE_MVHEVC
+ hevc->enableMVHEVC = ctx->multiview;
+ hevc->outputHevc3DReferenceDisplayInfo = ctx->display_sei;
+#endif
+
return 0;
}
@@ -2469,6 +2483,9 @@ static int nvenc_set_timestamp(AVCodecContext *avctx,
// This can be more than necessary, but we don't know the real reorder delay.
delay = FFMAX(ctx->encode_config.frameIntervalP - 1, 0);
+#ifdef NVENC_HAVE_MVHEVC
+ delay *= ctx->multiview + 1;
+#endif
if (ctx->output_frame_num >= delay) {
pkt->dts = timestamp_queue_dequeue(ctx->timestamp_list);
ctx->output_frame_num++;
@@ -2875,6 +2892,9 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
int res, res2;
int sei_count = 0;
int i;
+#ifdef NVENC_HAVE_MVHEVC
+ HEVC_3D_REFERENCE_DISPLAY_INFO ref_disp_info = { 0 };
+#endif
NvencContext *ctx = avctx->priv_data;
NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
@@ -2952,6 +2972,35 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
if (res < 0)
return res;
+#ifdef NVENC_HAVE_MVHEVC
+ if (ctx->multiview)
+ {
+ const AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_STEREO3D);
+ if (sd)
+ {
+ const AVStereo3D *stereo = (const AVStereo3D*)sd->data;
+ if (stereo->type == AV_STEREO3D_FRAMESEQUENCE) {
+ ctx->next_view_id = (stereo->view == AV_STEREO3D_VIEW_LEFT) ? 0 : 1;
+ } else {
+ sd = NULL;
+ av_log(avctx, AV_LOG_ERROR, "Stereo format %d not supported! Only AV_STEREO3D_FRAMESEQUENCE is supported!\n", stereo->type);
+ }
+ }
+
+ pic_params.codecPicParams.hevcPicParams.viewId = ctx->next_view_id;
+ if (!sd)
+ ctx->next_view_id ^= 1;
+
+ if (ctx->display_sei)
+ {
+ ref_disp_info.precRefDisplayWidth = 31;
+ ref_disp_info.leftViewId[0] = 0;
+ ref_disp_info.rightViewId[0] = 1;
+ pic_params.codecPicParams.hevcPicParams.p3DReferenceDisplayInfo = &ref_disp_info;
+ }
+ }
+#endif
+
nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params);
for (i = 0; i < sei_count; i++)
diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
index 6f7f8d4e7f..77aef3f188 100644
--- a/libavcodec/nvenc.h
+++ b/libavcodec/nvenc.h
@@ -99,6 +99,7 @@ typedef void ID3D11Device;
#define NVENC_HAVE_422_SUPPORT
#define NVENC_HAVE_AV1_UHQ_TUNING
#define NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
+#define NVENC_HAVE_MVHEVC
#endif
typedef struct NvencSurface
@@ -245,6 +246,7 @@ typedef struct NvencContext
void *nvencoder;
uint32_t frame_idx_counter;
+ uint32_t next_view_id;
int preset;
int profile;
@@ -291,6 +293,7 @@ typedef struct NvencContext
int single_slice_intra_refresh;
int constrained_encoding;
int udu_sei;
+ int display_sei;
int timing_info;
int highbitdepth;
int max_slice_size;
@@ -299,6 +302,7 @@ typedef struct NvencContext
int lookahead_level;
int unidir_b;
int split_encode_mode;
+ int multiview;
} NvencContext;
int ff_nvenc_encode_init(AVCodecContext *avctx);
diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c
index 5696e14dd4..f821eaee50 100644
--- a/libavcodec/nvenc_hevc.c
+++ b/libavcodec/nvenc_hevc.c
@@ -194,6 +194,12 @@ static const AVOption options[] = {
OFFSET(extra_sei), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
{ "udu_sei", "Pass on user data unregistered SEI if available",
OFFSET(udu_sei), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
+#ifdef NVENC_HAVE_MVHEVC
+ { "display_sei", "Pass on 3D reference display information SEI message for MV-HEVC",
+ OFFSET(display_sei), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
+ { "mvhevc", "Set to 1 to enable MV-HEVC. This feature currently supports only 2 views",
+ OFFSET(multiview), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
+#endif
{ "intra-refresh","Use Periodic Intra Refresh instead of IDR frames",
OFFSET(intra_refresh),AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
{ "single-slice-intra-refresh", "Use single slice intra refresh",
--
2.45.2
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [FFmpeg-devel] [PATCH 7/9] avcodec/nvenc: add MV-HEVC encoding support
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 7/9] avcodec/nvenc: add MV-HEVC encoding support Timo Rothenpieler
@ 2025-01-30 20:17 ` James Almer
2025-01-30 23:23 ` [FFmpeg-devel] [PATCH v2 " Timo Rothenpieler
1 sibling, 0 replies; 17+ messages in thread
From: James Almer @ 2025-01-30 20:17 UTC (permalink / raw)
To: ffmpeg-devel
[-- Attachment #1.1.1: Type: text/plain, Size: 6914 bytes --]
On 1/30/2025 4:40 PM, Timo Rothenpieler wrote:
> From: Diego de Souza <ddesouza@nvidia.com>
>
> Added support for MV-HEVC encoding for stereoscopic videos (2 views
> only). Compatible with the framepack filter when using the
> AV_STEREO3D_FRAMESEQUENCE format.
>
> Signed-off-by: Diego de Souza <ddesouza@nvidia.com>
> ---
> libavcodec/nvenc.c | 49 +++++++++++++++++++++++++++++++++++++++++
> libavcodec/nvenc.h | 4 ++++
> libavcodec/nvenc_hevc.c | 6 +++++
> 3 files changed, 59 insertions(+)
>
> diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
> index 3403fa8996..a528f1ce93 100644
> --- a/libavcodec/nvenc.c
> +++ b/libavcodec/nvenc.c
> @@ -35,6 +35,7 @@
> #include "libavutil/mem.h"
> #include "libavutil/pixdesc.h"
> #include "libavutil/mathematics.h"
> +#include "libavutil/stereo3d.h"
> #include "atsc_a53.h"
> #include "codec_desc.h"
> #include "encode.h"
> @@ -656,6 +657,14 @@ static int nvenc_check_capabilities(AVCodecContext *avctx)
>
> ctx->support_dyn_bitrate = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_DYN_BITRATE_CHANGE);
>
> +#ifdef NVENC_HAVE_MVHEVC
> + ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_MVHEVC_ENCODE);
> + if(ctx->multiview && ret <= 0) {
> + av_log(avctx, AV_LOG_WARNING, "Multiview not supported by the device\n");
> + return AVERROR(ENOSYS);
> + }
> +#endif
> +
> return 0;
> }
>
> @@ -1544,6 +1553,11 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
> }
> #endif
>
> +#ifdef NVENC_HAVE_MVHEVC
> + hevc->enableMVHEVC = ctx->multiview;
> + hevc->outputHevc3DReferenceDisplayInfo = ctx->display_sei;
> +#endif
> +
> return 0;
> }
>
> @@ -2469,6 +2483,9 @@ static int nvenc_set_timestamp(AVCodecContext *avctx,
>
> // This can be more than necessary, but we don't know the real reorder delay.
> delay = FFMAX(ctx->encode_config.frameIntervalP - 1, 0);
> +#ifdef NVENC_HAVE_MVHEVC
> + delay *= ctx->multiview + 1;
> +#endif
> if (ctx->output_frame_num >= delay) {
> pkt->dts = timestamp_queue_dequeue(ctx->timestamp_list);
> ctx->output_frame_num++;
> @@ -2875,6 +2892,9 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
> int res, res2;
> int sei_count = 0;
> int i;
> +#ifdef NVENC_HAVE_MVHEVC
> + HEVC_3D_REFERENCE_DISPLAY_INFO ref_disp_info = { 0 };
> +#endif
>
> NvencContext *ctx = avctx->priv_data;
> NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
> @@ -2952,6 +2972,35 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
> if (res < 0)
> return res;
>
> +#ifdef NVENC_HAVE_MVHEVC
> + if (ctx->multiview)
> + {
> + const AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_STEREO3D);
> + if (sd)
> + {
> + const AVStereo3D *stereo = (const AVStereo3D*)sd->data;
> + if (stereo->type == AV_STEREO3D_FRAMESEQUENCE) {
No brackets for single line blocks.
> + ctx->next_view_id = (stereo->view == AV_STEREO3D_VIEW_LEFT) ? 0 : 1;
> + } else {
> + sd = NULL;
> + av_log(avctx, AV_LOG_ERROR, "Stereo format %d not supported! Only AV_STEREO3D_FRAMESEQUENCE is supported!\n", stereo->type);
> + }
> + }
> +
> + pic_params.codecPicParams.hevcPicParams.viewId = ctx->next_view_id;
> + if (!sd)
> + ctx->next_view_id ^= 1;
> +
> + if (ctx->display_sei)
> + {
> + ref_disp_info.precRefDisplayWidth = 31;
> + ref_disp_info.leftViewId[0] = 0;
> + ref_disp_info.rightViewId[0] = 1;
There's AV_FRAME_DATA_VIEW_ID, which the native hevc decoder uses to
export the view ids when the 3D reference display information SEI
message is present in the bitstream.
It should be used here too.
> + pic_params.codecPicParams.hevcPicParams.p3DReferenceDisplayInfo = &ref_disp_info;
> + }
> + }
> +#endif
> +
> nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params);
>
> for (i = 0; i < sei_count; i++)
> diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
> index 6f7f8d4e7f..77aef3f188 100644
> --- a/libavcodec/nvenc.h
> +++ b/libavcodec/nvenc.h
> @@ -99,6 +99,7 @@ typedef void ID3D11Device;
> #define NVENC_HAVE_422_SUPPORT
> #define NVENC_HAVE_AV1_UHQ_TUNING
> #define NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
> +#define NVENC_HAVE_MVHEVC
> #endif
>
> typedef struct NvencSurface
> @@ -245,6 +246,7 @@ typedef struct NvencContext
> void *nvencoder;
>
> uint32_t frame_idx_counter;
> + uint32_t next_view_id;
>
> int preset;
> int profile;
> @@ -291,6 +293,7 @@ typedef struct NvencContext
> int single_slice_intra_refresh;
> int constrained_encoding;
> int udu_sei;
> + int display_sei;
> int timing_info;
> int highbitdepth;
> int max_slice_size;
> @@ -299,6 +302,7 @@ typedef struct NvencContext
> int lookahead_level;
> int unidir_b;
> int split_encode_mode;
> + int multiview;
> } NvencContext;
>
> int ff_nvenc_encode_init(AVCodecContext *avctx);
> diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c
> index 5696e14dd4..f821eaee50 100644
> --- a/libavcodec/nvenc_hevc.c
> +++ b/libavcodec/nvenc_hevc.c
> @@ -194,6 +194,12 @@ static const AVOption options[] = {
> OFFSET(extra_sei), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE },
> { "udu_sei", "Pass on user data unregistered SEI if available",
> OFFSET(udu_sei), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
> +#ifdef NVENC_HAVE_MVHEVC
> + { "display_sei", "Pass on 3D reference display information SEI message for MV-HEVC",
> + OFFSET(display_sei), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
Shouldn't this SEI message always be present for stereoscopic MV-HEVC?
> + { "mvhevc", "Set to 1 to enable MV-HEVC. This feature currently supports only 2 views",
This should instead be a check for the AV_PROFILE_HEVC_MULTIVIEW_MAIN
profile.
> + OFFSET(multiview), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
> +#endif
> { "intra-refresh","Use Periodic Intra Refresh instead of IDR frames",
> OFFSET(intra_refresh),AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
> { "single-slice-intra-refresh", "Use single slice intra refresh",
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]
[-- Attachment #2: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] [PATCH v2 7/9] avcodec/nvenc: add MV-HEVC encoding support
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 7/9] avcodec/nvenc: add MV-HEVC encoding support Timo Rothenpieler
2025-01-30 20:17 ` James Almer
@ 2025-01-30 23:23 ` Timo Rothenpieler
2025-01-31 3:26 ` James Almer
1 sibling, 1 reply; 17+ messages in thread
From: Timo Rothenpieler @ 2025-01-30 23:23 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Diego de Souza
From: Diego de Souza <ddesouza@nvidia.com>
Added support for MV-HEVC encoding for stereoscopic videos (2 views
only). Compatible with the framepack filter when using the
AV_STEREO3D_FRAMESEQUENCE format.
Signed-off-by: Diego de Souza <ddesouza@nvidia.com>
---
libavcodec/nvenc.c | 70 +++++++++++++++++++++++++++++++++++++++++
libavcodec/nvenc.h | 8 +++++
libavcodec/nvenc_hevc.c | 5 ++-
3 files changed, 82 insertions(+), 1 deletion(-)
diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index 3403fa8996..ad53eaaf98 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -35,6 +35,7 @@
#include "libavutil/mem.h"
#include "libavutil/pixdesc.h"
#include "libavutil/mathematics.h"
+#include "libavutil/stereo3d.h"
#include "atsc_a53.h"
#include "codec_desc.h"
#include "encode.h"
@@ -656,6 +657,14 @@ static int nvenc_check_capabilities(AVCodecContext *avctx)
ctx->support_dyn_bitrate = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_DYN_BITRATE_CHANGE);
+#ifdef NVENC_HAVE_MVHEVC
+ ctx->multiview_supported = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_MVHEVC_ENCODE) > 0;
+ if(ctx->profile == NV_ENC_HEVC_PROFILE_MULTIVIEW_MAIN && !ctx->multiview_supported) {
+ av_log(avctx, AV_LOG_WARNING, "Multiview not supported by the device\n");
+ return AVERROR(ENOSYS);
+ }
+#endif
+
return 0;
}
@@ -1475,6 +1484,13 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
hevc->outputPictureTimingSEI = 1;
+#ifdef NVENC_HAVE_MVHEVC
+ if (ctx->multiview_supported && ctx->profile == NV_ENC_HEVC_PROFILE_MAIN &&
+ (av_frame_side_data_get(avctx->decoded_side_data, avctx->nb_decoded_side_data, AV_FRAME_DATA_STEREO3D) ||
+ av_frame_side_data_get(avctx->decoded_side_data, avctx->nb_decoded_side_data, AV_FRAME_DATA_VIEW_ID)))
+ ctx->profile = NV_ENC_HEVC_PROFILE_MULTIVIEW_MAIN;
+#endif
+
switch (ctx->profile) {
case NV_ENC_HEVC_PROFILE_MAIN:
cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN_GUID;
@@ -1488,6 +1504,16 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
cc->profileGUID = NV_ENC_HEVC_PROFILE_FREXT_GUID;
avctx->profile = AV_PROFILE_HEVC_REXT;
break;
+#ifdef NVENC_HAVE_MVHEVC
+ case NV_ENC_HEVC_PROFILE_MULTIVIEW_MAIN:
+ cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN_GUID;
+ avctx->profile = AV_PROFILE_HEVC_MULTIVIEW_MAIN;
+ ctx->multiview = 1;
+
+ hevc->enableMVHEVC = 1;
+ hevc->outputHevc3DReferenceDisplayInfo = 1;
+ break;
+#endif
}
// force setting profile as main10 if input is 10 bit or if it should be encoded as 10 bit
@@ -1502,6 +1528,13 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
avctx->profile = AV_PROFILE_HEVC_REXT;
}
+#ifdef NVENC_HAVE_MVHEVC
+ if (ctx->multiview && avctx->profile != AV_PROFILE_HEVC_MULTIVIEW_MAIN) {
+ av_log(avctx, AV_LOG_ERROR, "Multiview encoding only works for Main profile content.\n");
+ return AVERROR(EINVAL);
+ }
+#endif
+
hevc->chromaFormatIDC = IS_YUV444(ctx->data_pix_fmt) ? 3 : IS_YUV422(ctx->data_pix_fmt) ? 2 : 1;
#ifdef NVENC_HAVE_NEW_BIT_DEPTH_API
@@ -2469,6 +2502,9 @@ static int nvenc_set_timestamp(AVCodecContext *avctx,
// This can be more than necessary, but we don't know the real reorder delay.
delay = FFMAX(ctx->encode_config.frameIntervalP - 1, 0);
+#ifdef NVENC_HAVE_MVHEVC
+ delay *= ctx->multiview ? 2 : 1;
+#endif
if (ctx->output_frame_num >= delay) {
pkt->dts = timestamp_queue_dequeue(ctx->timestamp_list);
ctx->output_frame_num++;
@@ -2875,6 +2911,9 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
int res, res2;
int sei_count = 0;
int i;
+#ifdef NVENC_HAVE_MVHEVC
+ HEVC_3D_REFERENCE_DISPLAY_INFO ref_disp_info = { 0 };
+#endif
NvencContext *ctx = avctx->priv_data;
NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
@@ -2952,6 +2991,37 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
if (res < 0)
return res;
+#ifdef NVENC_HAVE_MVHEVC
+ if (ctx->multiview) {
+ const AVFrameSideData *sd_stereo3d = av_frame_get_side_data(frame, AV_FRAME_DATA_STEREO3D);
+ const AVFrameSideData *sd_view_id = av_frame_get_side_data(frame, AV_FRAME_DATA_VIEW_ID);
+ int view_ids_reversed = 0;
+
+ if (sd_view_id)
+ ctx->next_view_id = *(int*)sd_view_id->data;
+
+ if (sd_stereo3d) {
+ const AVStereo3D *stereo = (const AVStereo3D*)sd_stereo3d->data;
+
+ if (stereo->type == AV_STEREO3D_FRAMESEQUENCE) {
+ if (!sd_view_id)
+ ctx->next_view_id = (stereo->view == AV_STEREO3D_VIEW_LEFT) ? 0 : 1;
+ if (stereo->view == AV_STEREO3D_VIEW_LEFT && ctx->next_view_id)
+ view_ids_reversed = 1;
+ } else
+ av_log(avctx, AV_LOG_ERROR, "Stereo format %d not supported! Only AV_STEREO3D_FRAMESEQUENCE is supported!\n", stereo->type);
+ }
+
+ pic_params.codecPicParams.hevcPicParams.viewId = ctx->next_view_id;
+ ctx->next_view_id ^= 1;
+
+ ref_disp_info.precRefDisplayWidth = 31;
+ ref_disp_info.leftViewId[0] = view_ids_reversed ? 1 : 0;
+ ref_disp_info.rightViewId[0] = view_ids_reversed ? 0 : 1;
+ pic_params.codecPicParams.hevcPicParams.p3DReferenceDisplayInfo = &ref_disp_info;
+ }
+#endif
+
nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params);
for (i = 0; i < sei_count; i++)
diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
index 6f7f8d4e7f..d085b08260 100644
--- a/libavcodec/nvenc.h
+++ b/libavcodec/nvenc.h
@@ -99,6 +99,7 @@ typedef void ID3D11Device;
#define NVENC_HAVE_422_SUPPORT
#define NVENC_HAVE_AV1_UHQ_TUNING
#define NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
+#define NVENC_HAVE_MVHEVC
#endif
typedef struct NvencSurface
@@ -172,6 +173,11 @@ enum {
NV_ENC_HEVC_PROFILE_MAIN,
NV_ENC_HEVC_PROFILE_MAIN_10,
NV_ENC_HEVC_PROFILE_REXT,
+#ifdef NVENC_HAVE_MVHEVC
+ NV_ENC_HEVC_PROFILE_MULTIVIEW_MAIN,
+#endif
+
+ NV_ENC_HEVC_PROFILE_COUNT
};
enum {
@@ -245,6 +251,7 @@ typedef struct NvencContext
void *nvencoder;
uint32_t frame_idx_counter;
+ uint32_t next_view_id;
int preset;
int profile;
@@ -299,6 +306,7 @@ typedef struct NvencContext
int lookahead_level;
int unidir_b;
int split_encode_mode;
+ int multiview, multiview_supported;
} NvencContext;
int ff_nvenc_encode_init(AVCodecContext *avctx);
diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c
index 5696e14dd4..3c08563c1f 100644
--- a/libavcodec/nvenc_hevc.c
+++ b/libavcodec/nvenc_hevc.c
@@ -60,10 +60,13 @@ static const AVOption options[] = {
{ "ull", "Ultra low latency", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY }, 0, 0, VE, .unit = "tune" },
{ "lossless", "Lossless", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_LOSSLESS }, 0, 0, VE, .unit = "tune" },
#endif
- { "profile", "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = NV_ENC_HEVC_PROFILE_MAIN }, NV_ENC_HEVC_PROFILE_MAIN, AV_PROFILE_HEVC_REXT, VE, .unit = "profile" },
+ { "profile", "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = NV_ENC_HEVC_PROFILE_MAIN }, NV_ENC_HEVC_PROFILE_MAIN, NV_ENC_HEVC_PROFILE_COUNT - 1, VE, .unit = "profile" },
{ "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_HEVC_PROFILE_MAIN }, 0, 0, VE, .unit = "profile" },
{ "main10", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_HEVC_PROFILE_MAIN_10 }, 0, 0, VE, .unit = "profile" },
{ "rext", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_HEVC_PROFILE_REXT }, 0, 0, VE, .unit = "profile" },
+#ifdef NVENC_HAVE_MVHEVC
+ { "mv", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_HEVC_PROFILE_MULTIVIEW_MAIN }, 0, 0, VE, .unit = "profile" },
+#endif
{ "level", "Set the encoding level restriction", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = NV_ENC_LEVEL_AUTOSELECT }, NV_ENC_LEVEL_AUTOSELECT, NV_ENC_LEVEL_HEVC_62, VE, .unit = "level" },
{ "auto", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_AUTOSELECT }, 0, 0, VE, .unit = "level" },
{ "1", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_HEVC_1 }, 0, 0, VE, .unit = "level" },
--
2.45.2
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [FFmpeg-devel] [PATCH v2 7/9] avcodec/nvenc: add MV-HEVC encoding support
2025-01-30 23:23 ` [FFmpeg-devel] [PATCH v2 " Timo Rothenpieler
@ 2025-01-31 3:26 ` James Almer
0 siblings, 0 replies; 17+ messages in thread
From: James Almer @ 2025-01-31 3:26 UTC (permalink / raw)
To: ffmpeg-devel
[-- Attachment #1.1.1: Type: text/plain, Size: 10136 bytes --]
On 1/30/2025 8:23 PM, Timo Rothenpieler wrote:
> From: Diego de Souza <ddesouza@nvidia.com>
>
> Added support for MV-HEVC encoding for stereoscopic videos (2 views
> only). Compatible with the framepack filter when using the
> AV_STEREO3D_FRAMESEQUENCE format.
>
> Signed-off-by: Diego de Souza <ddesouza@nvidia.com>
> ---
> libavcodec/nvenc.c | 70 +++++++++++++++++++++++++++++++++++++++++
> libavcodec/nvenc.h | 8 +++++
> libavcodec/nvenc_hevc.c | 5 ++-
> 3 files changed, 82 insertions(+), 1 deletion(-)
>
> diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
> index 3403fa8996..ad53eaaf98 100644
> --- a/libavcodec/nvenc.c
> +++ b/libavcodec/nvenc.c
> @@ -35,6 +35,7 @@
> #include "libavutil/mem.h"
> #include "libavutil/pixdesc.h"
> #include "libavutil/mathematics.h"
> +#include "libavutil/stereo3d.h"
> #include "atsc_a53.h"
> #include "codec_desc.h"
> #include "encode.h"
> @@ -656,6 +657,14 @@ static int nvenc_check_capabilities(AVCodecContext *avctx)
>
> ctx->support_dyn_bitrate = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_DYN_BITRATE_CHANGE);
>
> +#ifdef NVENC_HAVE_MVHEVC
> + ctx->multiview_supported = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_MVHEVC_ENCODE) > 0;
> + if(ctx->profile == NV_ENC_HEVC_PROFILE_MULTIVIEW_MAIN && !ctx->multiview_supported) {
> + av_log(avctx, AV_LOG_WARNING, "Multiview not supported by the device\n");
> + return AVERROR(ENOSYS);
> + }
> +#endif
> +
> return 0;
> }
>
> @@ -1475,6 +1484,13 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
>
> hevc->outputPictureTimingSEI = 1;
>
> +#ifdef NVENC_HAVE_MVHEVC
> + if (ctx->multiview_supported && ctx->profile == NV_ENC_HEVC_PROFILE_MAIN &&
> + (av_frame_side_data_get(avctx->decoded_side_data, avctx->nb_decoded_side_data, AV_FRAME_DATA_STEREO3D) ||
Stereo 3D side data being present in the encoder global side data array
is not guarantee that it's there to signal stereoscopic video as it
could have a type of AV_STEREO3D_2D, for example.
You need to ensure it's either AV_STEREO3D_UNSPEC, or
AV_STEREO3D_FRAMESEQUENCE (which afaik we don't export at the global
level, only for frames containing one of the two views).
> + av_frame_side_data_get(avctx->decoded_side_data, avctx->nb_decoded_side_data, AV_FRAME_DATA_VIEW_ID)))
VIEW_ID is not a global type, so it should not be there are at all.
> + ctx->profile = NV_ENC_HEVC_PROFILE_MULTIVIEW_MAIN;
> +#endif
> +
> switch (ctx->profile) {
> case NV_ENC_HEVC_PROFILE_MAIN:
> cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN_GUID;
> @@ -1488,6 +1504,16 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
> cc->profileGUID = NV_ENC_HEVC_PROFILE_FREXT_GUID;
> avctx->profile = AV_PROFILE_HEVC_REXT;
> break;
> +#ifdef NVENC_HAVE_MVHEVC
> + case NV_ENC_HEVC_PROFILE_MULTIVIEW_MAIN:
> + cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN_GUID;
> + avctx->profile = AV_PROFILE_HEVC_MULTIVIEW_MAIN;
> + ctx->multiview = 1;
> +
> + hevc->enableMVHEVC = 1;
> + hevc->outputHevc3DReferenceDisplayInfo = 1;
> + break;
> +#endif
> }
>
> // force setting profile as main10 if input is 10 bit or if it should be encoded as 10 bit
> @@ -1502,6 +1528,13 @@ static av_cold int nvenc_setup_hevc_config(AVCodecContext *avctx)
> avctx->profile = AV_PROFILE_HEVC_REXT;
> }
>
> +#ifdef NVENC_HAVE_MVHEVC
> + if (ctx->multiview && avctx->profile != AV_PROFILE_HEVC_MULTIVIEW_MAIN) {
> + av_log(avctx, AV_LOG_ERROR, "Multiview encoding only works for Main profile content.\n");
> + return AVERROR(EINVAL);
> + }
> +#endif
> +
> hevc->chromaFormatIDC = IS_YUV444(ctx->data_pix_fmt) ? 3 : IS_YUV422(ctx->data_pix_fmt) ? 2 : 1;
>
> #ifdef NVENC_HAVE_NEW_BIT_DEPTH_API
> @@ -2469,6 +2502,9 @@ static int nvenc_set_timestamp(AVCodecContext *avctx,
>
> // This can be more than necessary, but we don't know the real reorder delay.
> delay = FFMAX(ctx->encode_config.frameIntervalP - 1, 0);
> +#ifdef NVENC_HAVE_MVHEVC
> + delay *= ctx->multiview ? 2 : 1;
> +#endif
> if (ctx->output_frame_num >= delay) {
> pkt->dts = timestamp_queue_dequeue(ctx->timestamp_list);
> ctx->output_frame_num++;
> @@ -2875,6 +2911,9 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
> int res, res2;
> int sei_count = 0;
> int i;
> +#ifdef NVENC_HAVE_MVHEVC
> + HEVC_3D_REFERENCE_DISPLAY_INFO ref_disp_info = { 0 };
> +#endif
>
> NvencContext *ctx = avctx->priv_data;
> NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs;
> @@ -2952,6 +2991,37 @@ static int nvenc_send_frame(AVCodecContext *avctx, const AVFrame *frame)
> if (res < 0)
> return res;
>
> +#ifdef NVENC_HAVE_MVHEVC
> + if (ctx->multiview) {
> + const AVFrameSideData *sd_stereo3d = av_frame_get_side_data(frame, AV_FRAME_DATA_STEREO3D);
> + const AVFrameSideData *sd_view_id = av_frame_get_side_data(frame, AV_FRAME_DATA_VIEW_ID);
> + int view_ids_reversed = 0;
> +
> + if (sd_view_id)
> + ctx->next_view_id = *(int*)sd_view_id->data;
> +
> + if (sd_stereo3d) {
> + const AVStereo3D *stereo = (const AVStereo3D*)sd_stereo3d->data;
> +
> + if (stereo->type == AV_STEREO3D_FRAMESEQUENCE) {
> + if (!sd_view_id)
> + ctx->next_view_id = (stereo->view == AV_STEREO3D_VIEW_LEFT) ? 0 : 1;
> + if (stereo->view == AV_STEREO3D_VIEW_LEFT && ctx->next_view_id)
> + view_ids_reversed = 1;
> + } else
> + av_log(avctx, AV_LOG_ERROR, "Stereo format %d not supported! Only AV_STEREO3D_FRAMESEQUENCE is supported!\n", stereo->type);
> + }
> +
> + pic_params.codecPicParams.hevcPicParams.viewId = ctx->next_view_id;
> + ctx->next_view_id ^= 1;
> +
> + ref_disp_info.precRefDisplayWidth = 31;
> + ref_disp_info.leftViewId[0] = view_ids_reversed ? 1 : 0;
> + ref_disp_info.rightViewId[0] = view_ids_reversed ? 0 : 1;
> + pic_params.codecPicParams.hevcPicParams.p3DReferenceDisplayInfo = &ref_disp_info;
> + }
> +#endif
> +
> nv_status = p_nvenc->nvEncEncodePicture(ctx->nvencoder, &pic_params);
>
> for (i = 0; i < sei_count; i++)
> diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
> index 6f7f8d4e7f..d085b08260 100644
> --- a/libavcodec/nvenc.h
> +++ b/libavcodec/nvenc.h
> @@ -99,6 +99,7 @@ typedef void ID3D11Device;
> #define NVENC_HAVE_422_SUPPORT
> #define NVENC_HAVE_AV1_UHQ_TUNING
> #define NVENC_HAVE_H264_AND_AV1_TEMPORAL_FILTER
> +#define NVENC_HAVE_MVHEVC
> #endif
>
> typedef struct NvencSurface
> @@ -172,6 +173,11 @@ enum {
> NV_ENC_HEVC_PROFILE_MAIN,
> NV_ENC_HEVC_PROFILE_MAIN_10,
> NV_ENC_HEVC_PROFILE_REXT,
> +#ifdef NVENC_HAVE_MVHEVC
> + NV_ENC_HEVC_PROFILE_MULTIVIEW_MAIN,
> +#endif
> +
> + NV_ENC_HEVC_PROFILE_COUNT
> };
>
> enum {
> @@ -245,6 +251,7 @@ typedef struct NvencContext
> void *nvencoder;
>
> uint32_t frame_idx_counter;
> + uint32_t next_view_id;
>
> int preset;
> int profile;
> @@ -299,6 +306,7 @@ typedef struct NvencContext
> int lookahead_level;
> int unidir_b;
> int split_encode_mode;
> + int multiview, multiview_supported;
> } NvencContext;
>
> int ff_nvenc_encode_init(AVCodecContext *avctx);
> diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c
> index 5696e14dd4..3c08563c1f 100644
> --- a/libavcodec/nvenc_hevc.c
> +++ b/libavcodec/nvenc_hevc.c
> @@ -60,10 +60,13 @@ static const AVOption options[] = {
> { "ull", "Ultra low latency", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY }, 0, 0, VE, .unit = "tune" },
> { "lossless", "Lossless", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_TUNING_INFO_LOSSLESS }, 0, 0, VE, .unit = "tune" },
> #endif
> - { "profile", "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = NV_ENC_HEVC_PROFILE_MAIN }, NV_ENC_HEVC_PROFILE_MAIN, AV_PROFILE_HEVC_REXT, VE, .unit = "profile" },
> + { "profile", "Set the encoding profile", OFFSET(profile), AV_OPT_TYPE_INT, { .i64 = NV_ENC_HEVC_PROFILE_MAIN }, NV_ENC_HEVC_PROFILE_MAIN, NV_ENC_HEVC_PROFILE_COUNT - 1, VE, .unit = "profile" },
> { "main", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_HEVC_PROFILE_MAIN }, 0, 0, VE, .unit = "profile" },
> { "main10", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_HEVC_PROFILE_MAIN_10 }, 0, 0, VE, .unit = "profile" },
> { "rext", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_HEVC_PROFILE_REXT }, 0, 0, VE, .unit = "profile" },
> +#ifdef NVENC_HAVE_MVHEVC
> + { "mv", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_HEVC_PROFILE_MULTIVIEW_MAIN }, 0, 0, VE, .unit = "profile" },
> +#endif
> { "level", "Set the encoding level restriction", OFFSET(level), AV_OPT_TYPE_INT, { .i64 = NV_ENC_LEVEL_AUTOSELECT }, NV_ENC_LEVEL_AUTOSELECT, NV_ENC_LEVEL_HEVC_62, VE, .unit = "level" },
> { "auto", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_AUTOSELECT }, 0, 0, VE, .unit = "level" },
> { "1", "", 0, AV_OPT_TYPE_CONST, { .i64 = NV_ENC_LEVEL_HEVC_1 }, 0, 0, VE, .unit = "level" },
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]
[-- Attachment #2: Type: text/plain, Size: 251 bytes --]
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] [PATCH 8/9] avcodec/nvenc: use encoder level options for qmin/qmax
2025-01-30 19:40 [FFmpeg-devel] [PATCH 0/9] Nvidia Video Codec SDK 13.0 support Timo Rothenpieler
` (6 preceding siblings ...)
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 7/9] avcodec/nvenc: add MV-HEVC encoding support Timo Rothenpieler
@ 2025-01-30 19:40 ` Timo Rothenpieler
2025-01-31 6:16 ` Zhao Zhili
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 9/9] avcodec/nvenc: finalize SDK 13.0 support Timo Rothenpieler
2025-02-01 21:15 ` [FFmpeg-devel] [PATCH 0/9] Nvidia Video Codec " Timo Rothenpieler
9 siblings, 1 reply; 17+ messages in thread
From: Timo Rothenpieler @ 2025-01-30 19:40 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Timo Rothenpieler
AV1 uses a vastly different range than what the global options permit,
and also for the other codecs the range of the global options is at
least misaligned.
Fixes #11365
---
libavcodec/nvenc.c | 49 +++++++++++++++++++++++++----------------
libavcodec/nvenc.h | 2 ++
libavcodec/nvenc_av1.c | 4 ++++
libavcodec/nvenc_h264.c | 4 ++++
libavcodec/nvenc_hevc.c | 4 ++++
5 files changed, 44 insertions(+), 19 deletions(-)
diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index a528f1ce93..a5c507150c 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -893,8 +893,8 @@ static av_cold void set_constqp(AVCodecContext *avctx)
rc->constQP.qpIntra = av_clip(ctx->cqp * fabs(avctx->i_quant_factor) + avctx->i_quant_offset + 0.5, 0, qmax);
}
- avctx->qmin = -1;
- avctx->qmax = -1;
+ avctx->qmin = ctx->qmin = -1;
+ avctx->qmax = ctx->qmax = -1;
}
static av_cold void set_vbr(AVCodecContext *avctx)
@@ -908,27 +908,37 @@ static av_cold void set_vbr(AVCodecContext *avctx)
int qmax = 51;
#endif
- if (avctx->qmin >= 0 && avctx->qmax >= 0) {
+ if (avctx->qmin >= 0 || avctx->qmax >= 0)
+ av_log(avctx, AV_LOG_WARNING, "Passing qmin/qmax via global AVCodecContext options. Use encoder options instead.\n");
+
+ if (avctx->qmin >= 0 && ctx->qmin < 0)
+ ctx->qmin = avctx->qmin;
+ if (avctx->qmax >= 0 && ctx->qmax < 0)
+ ctx->qmax = avctx->qmax;
+ avctx->qmin = ctx->qmin;
+ avctx->qmax = ctx->qmax;
+
+ if (ctx->qmin >= 0 && ctx->qmax >= 0) {
rc->enableMinQP = 1;
rc->enableMaxQP = 1;
- rc->minQP.qpInterB = avctx->qmin;
- rc->minQP.qpInterP = avctx->qmin;
- rc->minQP.qpIntra = avctx->qmin;
+ rc->minQP.qpInterB = ctx->qmin;
+ rc->minQP.qpInterP = ctx->qmin;
+ rc->minQP.qpIntra = ctx->qmin;
- rc->maxQP.qpInterB = avctx->qmax;
- rc->maxQP.qpInterP = avctx->qmax;
- rc->maxQP.qpIntra = avctx->qmax;
+ rc->maxQP.qpInterB = ctx->qmax;
+ rc->maxQP.qpInterP = ctx->qmax;
+ rc->maxQP.qpIntra = ctx->qmax;
- qp_inter_p = (avctx->qmax + 3 * avctx->qmin) / 4; // biased towards Qmin
- } else if (avctx->qmin >= 0) {
+ qp_inter_p = (ctx->qmax + 3 * ctx->qmin) / 4; // biased towards Qmin
+ } else if (ctx->qmin >= 0) {
rc->enableMinQP = 1;
- rc->minQP.qpInterB = avctx->qmin;
- rc->minQP.qpInterP = avctx->qmin;
- rc->minQP.qpIntra = avctx->qmin;
+ rc->minQP.qpInterB = ctx->qmin;
+ rc->minQP.qpInterP = ctx->qmin;
+ rc->minQP.qpIntra = ctx->qmin;
- qp_inter_p = avctx->qmin;
+ qp_inter_p = ctx->qmin;
} else {
qp_inter_p = 26; // default to 26
}
@@ -974,8 +984,8 @@ static av_cold void set_lossless(AVCodecContext *avctx)
rc->constQP.qpInterP = 0;
rc->constQP.qpIntra = 0;
- avctx->qmin = -1;
- avctx->qmax = -1;
+ avctx->qmin = ctx->qmin = -1;
+ avctx->qmax = ctx->qmax = -1;
}
static void nvenc_override_rate_control(AVCodecContext *avctx)
@@ -989,7 +999,7 @@ static void nvenc_override_rate_control(AVCodecContext *avctx)
return;
#ifndef NVENC_NO_DEPRECATED_RC
case NV_ENC_PARAMS_RC_VBR_MINQP:
- if (avctx->qmin < 0) {
+ if (avctx->qmin < 0 && ctx->qmin < 0) {
av_log(avctx, AV_LOG_WARNING,
"The variable bitrate rate-control requires "
"the 'qmin' option set.\n");
@@ -1112,7 +1122,8 @@ static av_cold int nvenc_setup_rate_control(AVCodecContext *avctx)
ctx->rc = NV_ENC_PARAMS_RC_CONSTQP;
} else if (ctx->twopass) {
ctx->rc = NV_ENC_PARAMS_RC_VBR_HQ;
- } else if (avctx->qmin >= 0 && avctx->qmax >= 0) {
+ } else if ((avctx->qmin >= 0 && avctx->qmax >= 0) ||
+ (ctx->qmin >= 0 && ctx->qmax >= 0)) {
ctx->rc = NV_ENC_PARAMS_RC_VBR_MINQP;
}
}
diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
index 77aef3f188..f84adbdd55 100644
--- a/libavcodec/nvenc.h
+++ b/libavcodec/nvenc.h
@@ -273,6 +273,8 @@ typedef struct NvencContext
float quality;
int aud;
int bluray_compat;
+ int qmin;
+ int qmax;
int init_qp_p;
int init_qp_b;
int init_qp_i;
diff --git a/libavcodec/nvenc_av1.c b/libavcodec/nvenc_av1.c
index 5dd27fe872..ceb046e4be 100644
--- a/libavcodec/nvenc_av1.c
+++ b/libavcodec/nvenc_av1.c
@@ -119,6 +119,10 @@ static const AVOption options[] = {
OFFSET(qp_cb_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, -12, 12, VE },
{ "qp_cr_offset", "Quantization parameter offset for cr channel",
OFFSET(qp_cr_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, -12, 12, VE },
+ { "qmin", "Specifies the minimum QP used for rate control",
+ OFFSET(qmin), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 255, VE },
+ { "qmax", "Specifies the maximum QP used for rate control",
+ OFFSET(qmax), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 255, VE },
{ "no-scenecut", "When lookahead is enabled, set this to 1 to disable adaptive I-frame insertion at scene cuts",
OFFSET(no_scenecut), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
{ "forced-idr", "If forcing keyframes, force them as IDR frames.",
diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c
index 5e9f73412f..c7267a082a 100644
--- a/libavcodec/nvenc_h264.c
+++ b/libavcodec/nvenc_h264.c
@@ -174,6 +174,10 @@ static const AVOption options[] = {
OFFSET(qp_cb_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, -12, 12, VE },
{ "qp_cr_offset", "Quantization parameter offset for cr channel",
OFFSET(qp_cr_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, -12, 12, VE },
+ { "qmin", "Specifies the minimum QP used for rate control",
+ OFFSET(qmin), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
+ { "qmax", "Specifies the maximum QP used for rate control",
+ OFFSET(qmax), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
{ "weighted_pred","Set 1 to enable weighted prediction",
OFFSET(weighted_pred),AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
{ "coder", "Coder type", OFFSET(coder), AV_OPT_TYPE_INT, { .i64 = -1 },-1, 2, VE, .unit = "coder" },
diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c
index f821eaee50..f1b7062902 100644
--- a/libavcodec/nvenc_hevc.c
+++ b/libavcodec/nvenc_hevc.c
@@ -158,6 +158,10 @@ static const AVOption options[] = {
OFFSET(qp_cb_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, -12, 12, VE },
{ "qp_cr_offset", "Quantization parameter offset for cr channel",
OFFSET(qp_cr_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, -12, 12, VE },
+ { "qmin", "Specifies the minimum QP used for rate control",
+ OFFSET(qmin), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
+ { "qmax", "Specifies the maximum QP used for rate control",
+ OFFSET(qmax), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
{ "weighted_pred","Set 1 to enable weighted prediction",
OFFSET(weighted_pred),AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
#ifdef NVENC_HAVE_HEVC_BFRAME_REF_MODE
--
2.45.2
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [FFmpeg-devel] [PATCH 8/9] avcodec/nvenc: use encoder level options for qmin/qmax
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 8/9] avcodec/nvenc: use encoder level options for qmin/qmax Timo Rothenpieler
@ 2025-01-31 6:16 ` Zhao Zhili
2025-01-31 13:20 ` Timo Rothenpieler
0 siblings, 1 reply; 17+ messages in thread
From: Zhao Zhili @ 2025-01-31 6:16 UTC (permalink / raw)
To: FFmpeg development discussions and patches; +Cc: Timo Rothenpieler
> On Jan 31, 2025, at 03:40, Timo Rothenpieler <timo@rothenpieler.org> wrote:
>
> AV1 uses a vastly different range than what the global options permit,
> and also for the other codecs the range of the global options is at
> least misaligned.
It ’s simpler to update qmin upper threshold than add qmin/qmax for each encoder.
And there is no mismatch issue between global options and local options.
>
> Fixes #11365
> ---
> libavcodec/nvenc.c | 49 +++++++++++++++++++++++++----------------
> libavcodec/nvenc.h | 2 ++
> libavcodec/nvenc_av1.c | 4 ++++
> libavcodec/nvenc_h264.c | 4 ++++
> libavcodec/nvenc_hevc.c | 4 ++++
> 5 files changed, 44 insertions(+), 19 deletions(-)
>
> diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
> index a528f1ce93..a5c507150c 100644
> --- a/libavcodec/nvenc.c
> +++ b/libavcodec/nvenc.c
> @@ -893,8 +893,8 @@ static av_cold void set_constqp(AVCodecContext *avctx)
> rc->constQP.qpIntra = av_clip(ctx->cqp * fabs(avctx->i_quant_factor) + avctx->i_quant_offset + 0.5, 0, qmax);
> }
>
> - avctx->qmin = -1;
> - avctx->qmax = -1;
> + avctx->qmin = ctx->qmin = -1;
> + avctx->qmax = ctx->qmax = -1;
> }
>
> static av_cold void set_vbr(AVCodecContext *avctx)
> @@ -908,27 +908,37 @@ static av_cold void set_vbr(AVCodecContext *avctx)
> int qmax = 51;
> #endif
>
> - if (avctx->qmin >= 0 && avctx->qmax >= 0) {
> + if (avctx->qmin >= 0 || avctx->qmax >= 0)
> + av_log(avctx, AV_LOG_WARNING, "Passing qmin/qmax via global AVCodecContext options. Use encoder options instead.\n");
> +
> + if (avctx->qmin >= 0 && ctx->qmin < 0)
> + ctx->qmin = avctx->qmin;
> + if (avctx->qmax >= 0 && ctx->qmax < 0)
> + ctx->qmax = avctx->qmax;
> + avctx->qmin = ctx->qmin;
> + avctx->qmax = ctx->qmax;
> +
> + if (ctx->qmin >= 0 && ctx->qmax >= 0) {
> rc->enableMinQP = 1;
> rc->enableMaxQP = 1;
>
> - rc->minQP.qpInterB = avctx->qmin;
> - rc->minQP.qpInterP = avctx->qmin;
> - rc->minQP.qpIntra = avctx->qmin;
> + rc->minQP.qpInterB = ctx->qmin;
> + rc->minQP.qpInterP = ctx->qmin;
> + rc->minQP.qpIntra = ctx->qmin;
>
> - rc->maxQP.qpInterB = avctx->qmax;
> - rc->maxQP.qpInterP = avctx->qmax;
> - rc->maxQP.qpIntra = avctx->qmax;
> + rc->maxQP.qpInterB = ctx->qmax;
> + rc->maxQP.qpInterP = ctx->qmax;
> + rc->maxQP.qpIntra = ctx->qmax;
>
> - qp_inter_p = (avctx->qmax + 3 * avctx->qmin) / 4; // biased towards Qmin
> - } else if (avctx->qmin >= 0) {
> + qp_inter_p = (ctx->qmax + 3 * ctx->qmin) / 4; // biased towards Qmin
> + } else if (ctx->qmin >= 0) {
> rc->enableMinQP = 1;
>
> - rc->minQP.qpInterB = avctx->qmin;
> - rc->minQP.qpInterP = avctx->qmin;
> - rc->minQP.qpIntra = avctx->qmin;
> + rc->minQP.qpInterB = ctx->qmin;
> + rc->minQP.qpInterP = ctx->qmin;
> + rc->minQP.qpIntra = ctx->qmin;
>
> - qp_inter_p = avctx->qmin;
> + qp_inter_p = ctx->qmin;
> } else {
> qp_inter_p = 26; // default to 26
> }
> @@ -974,8 +984,8 @@ static av_cold void set_lossless(AVCodecContext *avctx)
> rc->constQP.qpInterP = 0;
> rc->constQP.qpIntra = 0;
>
> - avctx->qmin = -1;
> - avctx->qmax = -1;
> + avctx->qmin = ctx->qmin = -1;
> + avctx->qmax = ctx->qmax = -1;
> }
>
> static void nvenc_override_rate_control(AVCodecContext *avctx)
> @@ -989,7 +999,7 @@ static void nvenc_override_rate_control(AVCodecContext *avctx)
> return;
> #ifndef NVENC_NO_DEPRECATED_RC
> case NV_ENC_PARAMS_RC_VBR_MINQP:
> - if (avctx->qmin < 0) {
> + if (avctx->qmin < 0 && ctx->qmin < 0) {
> av_log(avctx, AV_LOG_WARNING,
> "The variable bitrate rate-control requires "
> "the 'qmin' option set.\n");
> @@ -1112,7 +1122,8 @@ static av_cold int nvenc_setup_rate_control(AVCodecContext *avctx)
> ctx->rc = NV_ENC_PARAMS_RC_CONSTQP;
> } else if (ctx->twopass) {
> ctx->rc = NV_ENC_PARAMS_RC_VBR_HQ;
> - } else if (avctx->qmin >= 0 && avctx->qmax >= 0) {
> + } else if ((avctx->qmin >= 0 && avctx->qmax >= 0) ||
> + (ctx->qmin >= 0 && ctx->qmax >= 0)) {
> ctx->rc = NV_ENC_PARAMS_RC_VBR_MINQP;
> }
> }
> diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h
> index 77aef3f188..f84adbdd55 100644
> --- a/libavcodec/nvenc.h
> +++ b/libavcodec/nvenc.h
> @@ -273,6 +273,8 @@ typedef struct NvencContext
> float quality;
> int aud;
> int bluray_compat;
> + int qmin;
> + int qmax;
> int init_qp_p;
> int init_qp_b;
> int init_qp_i;
> diff --git a/libavcodec/nvenc_av1.c b/libavcodec/nvenc_av1.c
> index 5dd27fe872..ceb046e4be 100644
> --- a/libavcodec/nvenc_av1.c
> +++ b/libavcodec/nvenc_av1.c
> @@ -119,6 +119,10 @@ static const AVOption options[] = {
> OFFSET(qp_cb_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, -12, 12, VE },
> { "qp_cr_offset", "Quantization parameter offset for cr channel",
> OFFSET(qp_cr_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, -12, 12, VE },
> + { "qmin", "Specifies the minimum QP used for rate control",
> + OFFSET(qmin), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 255, VE },
> + { "qmax", "Specifies the maximum QP used for rate control",
> + OFFSET(qmax), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 255, VE },
> { "no-scenecut", "When lookahead is enabled, set this to 1 to disable adaptive I-frame insertion at scene cuts",
> OFFSET(no_scenecut), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE },
> { "forced-idr", "If forcing keyframes, force them as IDR frames.",
> diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c
> index 5e9f73412f..c7267a082a 100644
> --- a/libavcodec/nvenc_h264.c
> +++ b/libavcodec/nvenc_h264.c
> @@ -174,6 +174,10 @@ static const AVOption options[] = {
> OFFSET(qp_cb_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, -12, 12, VE },
> { "qp_cr_offset", "Quantization parameter offset for cr channel",
> OFFSET(qp_cr_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, -12, 12, VE },
> + { "qmin", "Specifies the minimum QP used for rate control",
> + OFFSET(qmin), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
> + { "qmax", "Specifies the maximum QP used for rate control",
> + OFFSET(qmax), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
> { "weighted_pred","Set 1 to enable weighted prediction",
> OFFSET(weighted_pred),AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
> { "coder", "Coder type", OFFSET(coder), AV_OPT_TYPE_INT, { .i64 = -1 },-1, 2, VE, .unit = "coder" },
> diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c
> index f821eaee50..f1b7062902 100644
> --- a/libavcodec/nvenc_hevc.c
> +++ b/libavcodec/nvenc_hevc.c
> @@ -158,6 +158,10 @@ static const AVOption options[] = {
> OFFSET(qp_cb_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, -12, 12, VE },
> { "qp_cr_offset", "Quantization parameter offset for cr channel",
> OFFSET(qp_cr_offset), AV_OPT_TYPE_INT, { .i64 = 0 }, -12, 12, VE },
> + { "qmin", "Specifies the minimum QP used for rate control",
> + OFFSET(qmin), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
> + { "qmax", "Specifies the maximum QP used for rate control",
> + OFFSET(qmax), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 51, VE },
> { "weighted_pred","Set 1 to enable weighted prediction",
> OFFSET(weighted_pred),AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE },
> #ifdef NVENC_HAVE_HEVC_BFRAME_REF_MODE
> --
> 2.45.2
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [FFmpeg-devel] [PATCH 8/9] avcodec/nvenc: use encoder level options for qmin/qmax
2025-01-31 6:16 ` Zhao Zhili
@ 2025-01-31 13:20 ` Timo Rothenpieler
0 siblings, 0 replies; 17+ messages in thread
From: Timo Rothenpieler @ 2025-01-31 13:20 UTC (permalink / raw)
To: ffmpeg-devel
On 31/01/2025 07:16, Zhao Zhili wrote:
>
>
>> On Jan 31, 2025, at 03:40, Timo Rothenpieler <timo@rothenpieler.org> wrote:
>>
>> AV1 uses a vastly different range than what the global options permit,
>> and also for the other codecs the range of the global options is at
>> least misaligned.
>
> It ’s simpler to update qmin upper threshold than add qmin/qmax for each encoder.
> And there is no mismatch issue between global options and local options.
The three nvenc encoders already have different ranges on those values.
And making the range of the global parameters biggers might have
implications on other things using them, which now might get values that
are out of range. So that'd need to be checked individually in every
encoder now.
So I'm not sure if it's really less or even more work to go that route.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 17+ messages in thread
* [FFmpeg-devel] [PATCH 9/9] avcodec/nvenc: finalize SDK 13.0 support
2025-01-30 19:40 [FFmpeg-devel] [PATCH 0/9] Nvidia Video Codec SDK 13.0 support Timo Rothenpieler
` (7 preceding siblings ...)
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 8/9] avcodec/nvenc: use encoder level options for qmin/qmax Timo Rothenpieler
@ 2025-01-30 19:40 ` Timo Rothenpieler
2025-02-01 21:15 ` [FFmpeg-devel] [PATCH 0/9] Nvidia Video Codec " Timo Rothenpieler
9 siblings, 0 replies; 17+ messages in thread
From: Timo Rothenpieler @ 2025-01-30 19:40 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Timo Rothenpieler
---
libavcodec/nvenc.c | 4 +++-
libavcodec/version.h | 4 ++--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c
index a5c507150c..eb813ba32e 100644
--- a/libavcodec/nvenc.c
+++ b/libavcodec/nvenc.c
@@ -254,8 +254,10 @@ static void nvenc_map_preset(NvencContext *ctx)
static void nvenc_print_driver_requirement(AVCodecContext *avctx, int level)
{
-#if NVENCAPI_CHECK_VERSION(12, 3)
+#if NVENCAPI_CHECK_VERSION(13, 1)
const char *minver = "(unknown)";
+#elif NVENCAPI_CHECK_VERSION(13, 0)
+ const char *minver = "570.0";
#elif NVENCAPI_CHECK_VERSION(12, 2)
# if defined(_WIN32) || defined(__CYGWIN__)
const char *minver = "551.76";
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 1030154c0e..56dbb9238d 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,8 +29,8 @@
#include "version_major.h"
-#define LIBAVCODEC_VERSION_MINOR 31
-#define LIBAVCODEC_VERSION_MICRO 101
+#define LIBAVCODEC_VERSION_MINOR 32
+#define LIBAVCODEC_VERSION_MICRO 100
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \
--
2.45.2
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [FFmpeg-devel] [PATCH 0/9] Nvidia Video Codec SDK 13.0 support
2025-01-30 19:40 [FFmpeg-devel] [PATCH 0/9] Nvidia Video Codec SDK 13.0 support Timo Rothenpieler
` (8 preceding siblings ...)
2025-01-30 19:40 ` [FFmpeg-devel] [PATCH 9/9] avcodec/nvenc: finalize SDK 13.0 support Timo Rothenpieler
@ 2025-02-01 21:15 ` Timo Rothenpieler
2025-02-02 19:05 ` Timo Rothenpieler
9 siblings, 1 reply; 17+ messages in thread
From: Timo Rothenpieler @ 2025-02-01 21:15 UTC (permalink / raw)
To: ffmpeg-devel
On 30.01.2025 20:40, Timo Rothenpieler wrote:
> This series adds support for new features and capabilities added in
> todays release of the Video Codec SDK 13.0.
>
> Diego de Souza (7):
> avutil/hwcontext_cuda: add 4:2:2 pixel format support
> avcodec/nvdec: add 4:2:2 decoding and 10-bit support
> avcodec/cuviddec: add HEVC/H.264 4:2:2 and H.264 10-bit support
> avcodec/nvenc: add 4:2:2 encoding and H.264 10-bit support
> avcodec/nvenc: add UHQ to AV1 for NVENC
> avcodec/nvenc: add Temporal Filtering for AV1 and H.264 in NVENC
> avcodec/nvenc: add MV-HEVC encoding support
>
> Timo Rothenpieler (2):
> avcodec/nvenc: use encoder level options for qmin/qmax
> avcodec/nvenc: finalize SDK 13.0 support
Will push this series minus the MV-HEVC patch tomorrow if nobody objects.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [FFmpeg-devel] [PATCH 0/9] Nvidia Video Codec SDK 13.0 support
2025-02-01 21:15 ` [FFmpeg-devel] [PATCH 0/9] Nvidia Video Codec " Timo Rothenpieler
@ 2025-02-02 19:05 ` Timo Rothenpieler
0 siblings, 0 replies; 17+ messages in thread
From: Timo Rothenpieler @ 2025-02-02 19:05 UTC (permalink / raw)
To: ffmpeg-devel
On 01.02.2025 22:15, Timo Rothenpieler wrote:
> On 30.01.2025 20:40, Timo Rothenpieler wrote:
>> This series adds support for new features and capabilities added in
>> todays release of the Video Codec SDK 13.0.
>>
>> Diego de Souza (7):
>> avutil/hwcontext_cuda: add 4:2:2 pixel format support
>> avcodec/nvdec: add 4:2:2 decoding and 10-bit support
>> avcodec/cuviddec: add HEVC/H.264 4:2:2 and H.264 10-bit support
>> avcodec/nvenc: add 4:2:2 encoding and H.264 10-bit support
>> avcodec/nvenc: add UHQ to AV1 for NVENC
>> avcodec/nvenc: add Temporal Filtering for AV1 and H.264 in NVENC
>> avcodec/nvenc: add MV-HEVC encoding support
>>
>> Timo Rothenpieler (2):
>> avcodec/nvenc: use encoder level options for qmin/qmax
>> avcodec/nvenc: finalize SDK 13.0 support
>
> Will push this series minus the MV-HEVC patch tomorrow if nobody objects.
applied
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 17+ messages in thread