Ver código fonte

obs-ffmpeg: Add NVENC AV1 support

jp9000 3 anos atrás
pai
commit
53f4627b0c

+ 9 - 2
plugins/obs-ffmpeg/CMakeLists.txt

@@ -98,6 +98,7 @@ target_compile_options(
 
 
 if(OS_WINDOWS)
 if(OS_WINDOWS)
   add_subdirectory(obs-amf-test)
   add_subdirectory(obs-amf-test)
+  add_subdirectory(obs-nvenc-test)
 
 
   if(MSVC)
   if(MSVC)
     target_link_libraries(obs-ffmpeg PRIVATE OBS::w32-pthreads)
     target_link_libraries(obs-ffmpeg PRIVATE OBS::w32-pthreads)
@@ -108,8 +109,14 @@ if(OS_WINDOWS)
                  obs-ffmpeg.rc)
                  obs-ffmpeg.rc)
 
 
   target_sources(
   target_sources(
-    obs-ffmpeg PRIVATE texture-amf.cpp texture-amf-opts.hpp jim-nvenc.c
-                       jim-nvenc.h jim-nvenc-helpers.c obs-ffmpeg.rc)
+    obs-ffmpeg
+    PRIVATE texture-amf.cpp
+            texture-amf-opts.hpp
+            jim-nvenc.c
+            jim-nvenc.h
+            jim-nvenc-helpers.c
+            jim-nvenc-ver.h
+            obs-ffmpeg.rc)
 
 
 elseif(OS_POSIX AND NOT OS_MACOS)
 elseif(OS_POSIX AND NOT OS_MACOS)
   find_package(Libpci REQUIRED)
   find_package(Libpci REQUIRED)

+ 477 - 101
plugins/obs-ffmpeg/external/nvEncodeAPI.h

@@ -1,7 +1,7 @@
 /*
 /*
  * This copyright notice applies to this header file only:
  * This copyright notice applies to this header file only:
  *
  *
- * Copyright (c) 2010-2021 NVIDIA Corporation
+ * Copyright (c) 2010-2022 NVIDIA Corporation
  *
  *
  * Permission is hereby granted, free of charge, to any person
  * Permission is hereby granted, free of charge, to any person
  * obtaining a copy of this software and associated documentation
  * obtaining a copy of this software and associated documentation
@@ -30,7 +30,7 @@
  *   NVIDIA GPUs - beginning with the Kepler generation - contain a hardware-based encoder
  *   NVIDIA GPUs - beginning with the Kepler generation - contain a hardware-based encoder
  *   (referred to as NVENC) which provides fully-accelerated hardware-based video encoding.
  *   (referred to as NVENC) which provides fully-accelerated hardware-based video encoding.
  *   NvEncodeAPI provides the interface for NVIDIA video encoder (NVENC).
  *   NvEncodeAPI provides the interface for NVIDIA video encoder (NVENC).
- * \date 2011-2020
+ * \date 2011-2022
  *  This file contains the interface constants, structure definitions and function prototypes.
  *  This file contains the interface constants, structure definitions and function prototypes.
  */
  */
 
 
@@ -67,31 +67,27 @@ extern "C" {
  * @{
  * @{
  */
  */
 
 
-#if defined(_WIN32) || defined(__CYGWIN__)
-#define NVENCAPI __stdcall
-#else
-#define NVENCAPI
-#endif
-
 #ifdef _WIN32
 #ifdef _WIN32
+#define NVENCAPI     __stdcall
 typedef RECT NVENC_RECT;
 typedef RECT NVENC_RECT;
 #else
 #else
 #define NVENCAPI
 #define NVENCAPI
 // =========================================================================================
 // =========================================================================================
-#if !defined(GUID) && !defined(GUID_DEFINED)
+#ifndef GUID_DEFINED
+#define GUID_DEFINED
 /*!
 /*!
  * \struct GUID
  * \struct GUID
  * Abstracts the GUID structure for non-windows platforms.
  * Abstracts the GUID structure for non-windows platforms.
  */
  */
 // =========================================================================================
 // =========================================================================================
-typedef struct
+typedef struct _GUID
 {
 {
     uint32_t Data1;                                      /**< [in]: Specifies the first 8 hexadecimal digits of the GUID.                                */
     uint32_t Data1;                                      /**< [in]: Specifies the first 8 hexadecimal digits of the GUID.                                */
     uint16_t Data2;                                      /**< [in]: Specifies the first group of 4 hexadecimal digits.                                   */
     uint16_t Data2;                                      /**< [in]: Specifies the first group of 4 hexadecimal digits.                                   */
     uint16_t Data3;                                      /**< [in]: Specifies the second group of 4 hexadecimal digits.                                  */
     uint16_t Data3;                                      /**< [in]: Specifies the second group of 4 hexadecimal digits.                                  */
     uint8_t  Data4[8];                                   /**< [in]: Array of 8 bytes. The first 2 bytes contain the third group of 4 hexadecimal digits.
     uint8_t  Data4[8];                                   /**< [in]: Array of 8 bytes. The first 2 bytes contain the third group of 4 hexadecimal digits.
                                                                     The remaining 6 bytes contain the final 12 hexadecimal digits.                       */
                                                                     The remaining 6 bytes contain the final 12 hexadecimal digits.                       */
-} GUID;
+} GUID, *LPGUID;
 #endif // GUID
 #endif // GUID
 
 
 /**
 /**
@@ -115,8 +111,8 @@ typedef void* NV_ENC_OUTPUT_PTR;            /**< NVENCODE API output buffer*/
 typedef void* NV_ENC_REGISTERED_PTR;        /**< A Resource that has been registered with NVENCODE API*/
 typedef void* NV_ENC_REGISTERED_PTR;        /**< A Resource that has been registered with NVENCODE API*/
 typedef void* NV_ENC_CUSTREAM_PTR;          /**< Pointer to CUstream*/
 typedef void* NV_ENC_CUSTREAM_PTR;          /**< Pointer to CUstream*/
 
 
-#define NVENCAPI_MAJOR_VERSION 11
-#define NVENCAPI_MINOR_VERSION 1
+#define NVENCAPI_MAJOR_VERSION 12
+#define NVENCAPI_MINOR_VERSION 0
 
 
 #define NVENCAPI_VERSION (NVENCAPI_MAJOR_VERSION | (NVENCAPI_MINOR_VERSION << 24))
 #define NVENCAPI_VERSION (NVENCAPI_MAJOR_VERSION | (NVENCAPI_MINOR_VERSION << 24))
 
 
@@ -136,6 +132,10 @@ typedef void* NV_ENC_CUSTREAM_PTR;          /**< Pointer to CUstream*/
 #define NV_ENC_DEPRECATED __declspec(deprecated("WILL BE REMOVED IN A FUTURE VIDEO CODEC SDK VERSION"))
 #define NV_ENC_DEPRECATED __declspec(deprecated("WILL BE REMOVED IN A FUTURE VIDEO CODEC SDK VERSION"))
 #endif
 #endif
 
 
+// All use of the AV1 encode structures in the source code is guarded by the compilation variable
+// below. Set it to 0 to disable and hide the AV1 driver code.
+#define NVENCAPI_AV1_STRUCTURES_DEFINED  1
+
 // =========================================================================================
 // =========================================================================================
 // Encode Codec GUIDS supported by the NvEncodeAPI interface.
 // Encode Codec GUIDS supported by the NvEncodeAPI interface.
 // =========================================================================================
 // =========================================================================================
@@ -148,6 +148,10 @@ static const GUID NV_ENC_CODEC_H264_GUID =
 static const GUID NV_ENC_CODEC_HEVC_GUID =
 static const GUID NV_ENC_CODEC_HEVC_GUID =
 { 0x790cdc88, 0x4522, 0x4d7b, { 0x94, 0x25, 0xbd, 0xa9, 0x97, 0x5f, 0x76, 0x3 } };
 { 0x790cdc88, 0x4522, 0x4d7b, { 0x94, 0x25, 0xbd, 0xa9, 0x97, 0x5f, 0x76, 0x3 } };
 
 
+// {0A352289-0AA7-4759-862D-5D15CD16D254}
+static const GUID NV_ENC_CODEC_AV1_GUID =
+{ 0x0a352289, 0x0aa7, 0x4759, { 0x86, 0x2d, 0x5d, 0x15, 0xcd, 0x16, 0xd2, 0x54 } };
+
 
 
 
 
 // =========================================================================================
 // =========================================================================================
@@ -199,6 +203,14 @@ static const GUID NV_ENC_HEVC_PROFILE_MAIN10_GUID =
 static const GUID NV_ENC_HEVC_PROFILE_FREXT_GUID =
 static const GUID NV_ENC_HEVC_PROFILE_FREXT_GUID =
 { 0x51ec32b5, 0x1b4c, 0x453c, { 0x9c, 0xbd, 0xb6, 0x16, 0xbd, 0x62, 0x13, 0x41 } };
 { 0x51ec32b5, 0x1b4c, 0x453c, { 0x9c, 0xbd, 0xb6, 0x16, 0xbd, 0x62, 0x13, 0x41 } };
 
 
+// {5f2a39f5-f14e-4f95-9a9e-b76d568fcf97}
+static const GUID NV_ENC_AV1_PROFILE_MAIN_GUID =
+{ 0x5f2a39f5, 0xf14e, 0x4f95, { 0x9a, 0x9e, 0xb7, 0x6d, 0x56, 0x8f, 0xcf, 0x97 } };
+
+// {7c718f81-abb7-4a0e-afe4-c88bab957997}
+static const GUID NV_ENC_AV1_PROFILE_HIGH_GUID =
+{ 0x7c718f81, 0xabb7, 0x4a0e, { 0xaf, 0xe4, 0xc8, 0x8b, 0xab, 0x95, 0x79, 0x97 } };
+
 // =========================================================================================
 // =========================================================================================
 // *   Preset GUIDS supported by the NvEncodeAPI interface.
 // *   Preset GUIDS supported by the NvEncodeAPI interface.
 // =========================================================================================
 // =========================================================================================
@@ -348,6 +360,20 @@ typedef enum _NV_ENC_PIC_STRUCT
     NV_ENC_PIC_STRUCT_FIELD_BOTTOM_TOP  = 0x03                  /**< Field encoding bottom field first */
     NV_ENC_PIC_STRUCT_FIELD_BOTTOM_TOP  = 0x03                  /**< Field encoding bottom field first */
 } NV_ENC_PIC_STRUCT;
 } NV_ENC_PIC_STRUCT;
 
 
+/**
+ * Display picture structure
+ * Currently, this enum is only used for deciding the number of clock timestamp sets in Picture Timing SEI / Time Code SEI 
+ * Otherwise, this has no impact on encoder behavior 
+ */
+typedef enum _NV_ENC_DISPLAY_PIC_STRUCT
+{
+    NV_ENC_PIC_STRUCT_DISPLAY_FRAME             = 0x00,                 /**< Field encoding top field first */
+    NV_ENC_PIC_STRUCT_DISPLAY_FIELD_TOP_BOTTOM  = 0x01,                 /**< Field encoding top field first */
+    NV_ENC_PIC_STRUCT_DISPLAY_FIELD_BOTTOM_TOP  = 0x02,                 /**< Field encoding bottom field first */
+    NV_ENC_PIC_STRUCT_DISPLAY_FRAME_DOUBLING    = 0x03,                 /**< Frame doubling */
+    NV_ENC_PIC_STRUCT_DISPLAY_FRAME_TRIPLING    = 0x04                  /**< Field tripling */
+} NV_ENC_DISPLAY_PIC_STRUCT;
+
 /**
 /**
  * Input picture type
  * Input picture type
  */
  */
@@ -463,7 +489,36 @@ typedef enum _NV_ENC_LEVEL
     NV_ENC_LEVEL_HEVC_62            = 186,
     NV_ENC_LEVEL_HEVC_62            = 186,
 
 
     NV_ENC_TIER_HEVC_MAIN           = 0,
     NV_ENC_TIER_HEVC_MAIN           = 0,
-    NV_ENC_TIER_HEVC_HIGH           = 1
+    NV_ENC_TIER_HEVC_HIGH           = 1,
+
+    NV_ENC_LEVEL_AV1_2              = 0,
+    NV_ENC_LEVEL_AV1_21             = 1,
+    NV_ENC_LEVEL_AV1_22             = 2,
+    NV_ENC_LEVEL_AV1_23             = 3,
+    NV_ENC_LEVEL_AV1_3              = 4,
+    NV_ENC_LEVEL_AV1_31             = 5,
+    NV_ENC_LEVEL_AV1_32             = 6,
+    NV_ENC_LEVEL_AV1_33             = 7,
+    NV_ENC_LEVEL_AV1_4              = 8,
+    NV_ENC_LEVEL_AV1_41             = 9,
+    NV_ENC_LEVEL_AV1_42             = 10,
+    NV_ENC_LEVEL_AV1_43             = 11,
+    NV_ENC_LEVEL_AV1_5              = 12,
+    NV_ENC_LEVEL_AV1_51             = 13,
+    NV_ENC_LEVEL_AV1_52             = 14,
+    NV_ENC_LEVEL_AV1_53             = 15,
+    NV_ENC_LEVEL_AV1_6              = 16,
+    NV_ENC_LEVEL_AV1_61             = 17,
+    NV_ENC_LEVEL_AV1_62             = 18,
+    NV_ENC_LEVEL_AV1_63             = 19,
+    NV_ENC_LEVEL_AV1_7              = 20,
+    NV_ENC_LEVEL_AV1_71             = 21,
+    NV_ENC_LEVEL_AV1_72             = 22,
+    NV_ENC_LEVEL_AV1_73             = 23,
+    NV_ENC_LEVEL_AV1_AUTOSELECT         ,
+
+    NV_ENC_TIER_AV1_0               = 0,
+    NV_ENC_TIER_AV1_1               = 1
 } NV_ENC_LEVEL;
 } NV_ENC_LEVEL;
 
 
 /**
 /**
@@ -668,7 +723,7 @@ typedef enum _NV_ENC_MEMORY_HEAP
 typedef enum _NV_ENC_BFRAME_REF_MODE
 typedef enum _NV_ENC_BFRAME_REF_MODE
 {
 {
     NV_ENC_BFRAME_REF_MODE_DISABLED = 0x0,          /**< B frame is not used for reference */
     NV_ENC_BFRAME_REF_MODE_DISABLED = 0x0,          /**< B frame is not used for reference */
-    NV_ENC_BFRAME_REF_MODE_EACH     = 0x1,          /**< Each B-frame will be used for reference. currently not supported for H.264 */
+    NV_ENC_BFRAME_REF_MODE_EACH     = 0x1,          /**< Each B-frame will be used for reference */
     NV_ENC_BFRAME_REF_MODE_MIDDLE   = 0x2,          /**< Only(Number of B-frame)/2 th B-frame will be used for reference */
     NV_ENC_BFRAME_REF_MODE_MIDDLE   = 0x2,          /**< Only(Number of B-frame)/2 th B-frame will be used for reference */
 } NV_ENC_BFRAME_REF_MODE;
 } NV_ENC_BFRAME_REF_MODE;
 
 
@@ -748,7 +803,7 @@ typedef enum _NV_ENC_BUFFER_USAGE
     NV_ENC_INPUT_IMAGE              = 0x0,          /**< Registered surface will be used for input image */
     NV_ENC_INPUT_IMAGE              = 0x0,          /**< Registered surface will be used for input image */
     NV_ENC_OUTPUT_MOTION_VECTOR     = 0x1,          /**< Registered surface will be used for output of H.264 ME only mode.
     NV_ENC_OUTPUT_MOTION_VECTOR     = 0x1,          /**< Registered surface will be used for output of H.264 ME only mode.
                                                          This buffer usage type is not supported for HEVC ME only mode. */
                                                          This buffer usage type is not supported for HEVC ME only mode. */
-    NV_ENC_OUTPUT_BITSTREAM         = 0x2           /**< Registered surface will be used for output bitstream in encoding */
+    NV_ENC_OUTPUT_BITSTREAM         = 0x2,          /**< Registered surface will be used for output bitstream in encoding */
 } NV_ENC_BUFFER_USAGE;
 } NV_ENC_BUFFER_USAGE;
 
 
 /**
 /**
@@ -1133,6 +1188,7 @@ typedef enum _NV_ENC_CAPS
      * Reserved - Not to be used by clients.
      * Reserved - Not to be used by clients.
      */
      */
     NV_ENC_CAPS_EXPOSED_COUNT
     NV_ENC_CAPS_EXPOSED_COUNT
+
 } NV_ENC_CAPS;
 } NV_ENC_CAPS;
 
 
 /**
 /**
@@ -1147,6 +1203,89 @@ typedef enum _NV_ENC_HEVC_CUSIZE
     NV_ENC_HEVC_CUSIZE_64x64      = 4,
     NV_ENC_HEVC_CUSIZE_64x64      = 4,
 }NV_ENC_HEVC_CUSIZE;
 }NV_ENC_HEVC_CUSIZE;
 
 
+/**
+*  AV1 PART SIZE
+*/
+typedef enum _NV_ENC_AV1_PART_SIZE
+{
+    NV_ENC_AV1_PART_SIZE_AUTOSELECT    = 0,
+    NV_ENC_AV1_PART_SIZE_4x4           = 1,
+    NV_ENC_AV1_PART_SIZE_8x8           = 2,
+    NV_ENC_AV1_PART_SIZE_16x16         = 3,
+    NV_ENC_AV1_PART_SIZE_32x32         = 4,
+    NV_ENC_AV1_PART_SIZE_64x64         = 5,
+}NV_ENC_AV1_PART_SIZE;
+
+/**
+*  Enums related to fields in VUI parameters.
+*/
+typedef enum _NV_ENC_VUI_VIDEO_FORMAT
+{
+    NV_ENC_VUI_VIDEO_FORMAT_COMPONENT   = 0,
+    NV_ENC_VUI_VIDEO_FORMAT_PAL         = 1,
+    NV_ENC_VUI_VIDEO_FORMAT_NTSC        = 2,
+    NV_ENC_VUI_VIDEO_FORMAT_SECAM       = 3,
+    NV_ENC_VUI_VIDEO_FORMAT_MAC         = 4,
+    NV_ENC_VUI_VIDEO_FORMAT_UNSPECIFIED = 5,
+}NV_ENC_VUI_VIDEO_FORMAT;
+
+typedef enum _NV_ENC_VUI_COLOR_PRIMARIES
+{
+    NV_ENC_VUI_COLOR_PRIMARIES_UNDEFINED   = 0,
+    NV_ENC_VUI_COLOR_PRIMARIES_BT709       = 1,
+    NV_ENC_VUI_COLOR_PRIMARIES_UNSPECIFIED = 2,
+    NV_ENC_VUI_COLOR_PRIMARIES_RESERVED    = 3,
+    NV_ENC_VUI_COLOR_PRIMARIES_BT470M      = 4,
+    NV_ENC_VUI_COLOR_PRIMARIES_BT470BG     = 5,
+    NV_ENC_VUI_COLOR_PRIMARIES_SMPTE170M   = 6,
+    NV_ENC_VUI_COLOR_PRIMARIES_SMPTE240M   = 7,
+    NV_ENC_VUI_COLOR_PRIMARIES_FILM        = 8,
+    NV_ENC_VUI_COLOR_PRIMARIES_BT2020      = 9,
+    NV_ENC_VUI_COLOR_PRIMARIES_SMPTE428    = 10,
+    NV_ENC_VUI_COLOR_PRIMARIES_SMPTE431    = 11,
+    NV_ENC_VUI_COLOR_PRIMARIES_SMPTE432    = 12,
+    NV_ENC_VUI_COLOR_PRIMARIES_JEDEC_P22   = 22,
+}NV_ENC_VUI_COLOR_PRIMARIES;
+
+typedef enum _NV_ENC_VUI_TRANSFER_CHARACTERISTIC
+{
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC_UNDEFINED     = 0,
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC_BT709         = 1,
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC_UNSPECIFIED   = 2,
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC_RESERVED      = 3,
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC_BT470M        = 4,
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC_BT470BG       = 5,
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC_SMPTE170M     = 6,
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC_SMPTE240M     = 7,
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC_LINEAR        = 8,
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC_LOG           = 9,
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC_LOG_SQRT      = 10,
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC_IEC61966_2_4  = 11,
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC_BT1361_ECG    = 12,
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC_SRGB          = 13,
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC_BT2020_10     = 14,
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC_BT2020_12     = 15,
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC_SMPTE2084     = 16,
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC_SMPTE428      = 17,
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC_ARIB_STD_B67  = 18,
+}NV_ENC_VUI_TRANSFER_CHARACTERISTIC;
+
+typedef enum _NV_ENC_VUI_MATRIX_COEFFS
+{
+    NV_ENC_VUI_MATRIX_COEFFS_RGB         = 0,
+    NV_ENC_VUI_MATRIX_COEFFS_BT709       = 1,
+    NV_ENC_VUI_MATRIX_COEFFS_UNSPECIFIED = 2,
+    NV_ENC_VUI_MATRIX_COEFFS_RESERVED    = 3,
+    NV_ENC_VUI_MATRIX_COEFFS_FCC         = 4,
+    NV_ENC_VUI_MATRIX_COEFFS_BT470BG     = 5,
+    NV_ENC_VUI_MATRIX_COEFFS_SMPTE170M   = 6,
+    NV_ENC_VUI_MATRIX_COEFFS_SMPTE240M   = 7,
+    NV_ENC_VUI_MATRIX_COEFFS_YCGCO       = 8,
+    NV_ENC_VUI_MATRIX_COEFFS_BT2020_NCL  = 9,
+    NV_ENC_VUI_MATRIX_COEFFS_BT2020_CL   = 10,
+    NV_ENC_VUI_MATRIX_COEFFS_SMPTE2085   = 11,
+}NV_ENC_VUI_MATRIX_COEFFS;
+
 /**
 /**
  * Input struct for querying Encoding capabilities.
  * Input struct for querying Encoding capabilities.
  */
  */
@@ -1311,7 +1450,9 @@ typedef struct _NV_ENC_QP
                                                                                             lookaheadDepth is only used if enableLookahead=1.*/
                                                                                             lookaheadDepth is only used if enableLookahead=1.*/
     uint8_t                         lowDelayKeyFrameScale;                       /**< [in]: Specifies the ratio of I frame bits to P frame bits in case of single frame VBV and CBR rate control mode,
     uint8_t                         lowDelayKeyFrameScale;                       /**< [in]: Specifies the ratio of I frame bits to P frame bits in case of single frame VBV and CBR rate control mode,
                                                                                             is set to 2 by default for low latency tuning info and 1 by default for ultra low latency tuning info  */
                                                                                             is set to 2 by default for low latency tuning info and 1 by default for ultra low latency tuning info  */
-    uint8_t                         reserved1[3];
+    int8_t                          yDcQPIndexOffset;                            /**< [in]: Specifies the value of 'deltaQ_y_dc' in AV1.*/
+    int8_t                          uDcQPIndexOffset;                            /**< [in]: Specifies the value of 'deltaQ_u_dc' in AV1.*/
+    int8_t                          vDcQPIndexOffset;                            /**< [in]: Specifies the value of 'deltaQ_v_dc' in AV1 (for future use only - deltaQ_v_dc is currently always internally set to same value as deltaQ_u_dc). */
     NV_ENC_QP_MAP_MODE              qpMapMode;                                   /**< [in]: This flag is used to interpret values in array specified by NV_ENC_PIC_PARAMS::qpDeltaMap.
     NV_ENC_QP_MAP_MODE              qpMapMode;                                   /**< [in]: This flag is used to interpret values in array specified by NV_ENC_PIC_PARAMS::qpDeltaMap.
                                                                                             Set this to NV_ENC_QP_MAP_EMPHASIS to treat values specified by NV_ENC_PIC_PARAMS::qpDeltaMap as Emphasis Level Map.
                                                                                             Set this to NV_ENC_QP_MAP_EMPHASIS to treat values specified by NV_ENC_PIC_PARAMS::qpDeltaMap as Emphasis Level Map.
                                                                                             Emphasis Level can be assigned any value specified in enum NV_ENC_EMPHASIS_MAP_LEVEL.
                                                                                             Emphasis Level can be assigned any value specified in enum NV_ENC_EMPHASIS_MAP_LEVEL.
@@ -1332,8 +1473,8 @@ typedef struct _NV_ENC_QP
     NV_ENC_MULTI_PASS               multiPass;                                    /**< [in]: This flag is used to enable multi-pass encoding for a given ::NV_ENC_PARAMS_RC_MODE. This flag is not valid for H264 and HEVC MEOnly mode */
     NV_ENC_MULTI_PASS               multiPass;                                    /**< [in]: This flag is used to enable multi-pass encoding for a given ::NV_ENC_PARAMS_RC_MODE. This flag is not valid for H264 and HEVC MEOnly mode */
     uint32_t                        alphaLayerBitrateRatio;                       /**< [in]: Specifies the ratio in which bitrate should be split between base and alpha layer. A value 'x' for this field will split the target bitrate in a ratio of x : 1 between base and alpha layer.
     uint32_t                        alphaLayerBitrateRatio;                       /**< [in]: Specifies the ratio in which bitrate should be split between base and alpha layer. A value 'x' for this field will split the target bitrate in a ratio of x : 1 between base and alpha layer.
                                                                                              The default split ratio is 15.*/
                                                                                              The default split ratio is 15.*/
-    int8_t                          cbQPIndexOffset;                              /**< [in]: Specifies the value of 'chroma_qp_index_offset' in H264 / 'pps_cb_qp_offset' in HEVC.*/
-    int8_t                          crQPIndexOffset;                              /**< [in]: Specifies the value of 'second_chroma_qp_index_offset' in H264 / 'pps_cr_qp_offset' in HEVC.*/
+    int8_t                          cbQPIndexOffset;                              /**< [in]: Specifies the value of 'chroma_qp_index_offset' in H264 / 'pps_cb_qp_offset' in HEVC / 'deltaQ_u_ac' in AV1.*/
+    int8_t                          crQPIndexOffset;                              /**< [in]: Specifies the value of 'second_chroma_qp_index_offset' in H264 / 'pps_cr_qp_offset' in HEVC / 'deltaQ_v_ac' in AV1 (for future use only - deltaQ_v_ac is currently always internally set to same value as deltaQ_u_ac). */
     uint16_t                        reserved2;
     uint16_t                        reserved2;
     uint32_t                        reserved[4];
     uint32_t                        reserved[4];
  } NV_ENC_RC_PARAMS;
  } NV_ENC_RC_PARAMS;
@@ -1341,6 +1482,33 @@ typedef struct _NV_ENC_QP
 /** macro for constructing the version field of ::_NV_ENC_RC_PARAMS */
 /** macro for constructing the version field of ::_NV_ENC_RC_PARAMS */
 #define NV_ENC_RC_PARAMS_VER NVENCAPI_STRUCT_VERSION(1)
 #define NV_ENC_RC_PARAMS_VER NVENCAPI_STRUCT_VERSION(1)
 
 
+#define MAX_NUM_CLOCK_TS    3
+
+/**
+* Clock Timestamp set parameters
+* For H264, this structure is used to populate Picture Timing SEI when NV_ENC_CONFIG_H264::enableTimeCode is set to 1.
+* For HEVC, this structure is used to populate Time Code SEI when NV_ENC_CONFIG_HEVC::enableTimeCodeSEI is set to 1.
+* For more details, refer to Annex D of ITU-T Specification. 
+*/
+
+typedef struct _NV_ENC_CLOCK_TIMESTAMP_SET
+{
+    uint32_t        countingType            : 1;    /**< [in] Specifies the 'counting_type' */
+    uint32_t        discontinuityFlag       : 1;    /**< [in] Specifies the 'discontinuity_flag' */
+    uint32_t        cntDroppedFrames        : 1;    /**< [in] Specifies the 'cnt_dropped_flag' */
+    uint32_t        nFrames                 : 8;    /**< [in] Specifies the value of 'n_frames' */
+    uint32_t        secondsValue            : 6;    /**< [in] Specifies the 'seconds_value' */
+    uint32_t        minutesValue            : 6;    /**< [in] Specifies the 'minutes_value' */
+    uint32_t        hoursValue              : 5;    /**< [in] Specifies the 'hours_value' */
+    uint32_t        reserved2               : 4;    /**< [in] Reserved and must be set to 0 */
+    uint32_t        timeOffset;                     /**< [in] Specifies the 'time_offset_value' */
+} NV_ENC_CLOCK_TIMESTAMP_SET;
+
+typedef struct _NV_ENC_TIME_CODE
+{
+    NV_ENC_DISPLAY_PIC_STRUCT       displayPicStruct;                   /**< [in] Display picStruct */
+    NV_ENC_CLOCK_TIMESTAMP_SET      clockTimestamp[MAX_NUM_CLOCK_TS];   /**< [in] Clock Timestamp set */
+} NV_ENC_TIME_CODE;
 
 
 
 
 /**
 /**
@@ -1349,20 +1517,24 @@ typedef struct _NV_ENC_QP
  */
  */
 typedef struct _NV_ENC_CONFIG_H264_VUI_PARAMETERS
 typedef struct _NV_ENC_CONFIG_H264_VUI_PARAMETERS
 {
 {
-    uint32_t    overscanInfoPresentFlag;              /**< [in]: if set to 1 , it specifies that the overscanInfo is present */
-    uint32_t    overscanInfo;                         /**< [in]: Specifies the overscan info(as defined in Annex E of the ITU-T Specification). */
-    uint32_t    videoSignalTypePresentFlag;           /**< [in]: If set to 1, it specifies  that the videoFormat, videoFullRangeFlag and colourDescriptionPresentFlag are present. */
-    uint32_t    videoFormat;                          /**< [in]: Specifies the source video format(as defined in Annex E of the ITU-T Specification).*/
-    uint32_t    videoFullRangeFlag;                   /**< [in]: Specifies the output range of the luma and chroma samples(as defined in Annex E of the ITU-T Specification). */
-    uint32_t    colourDescriptionPresentFlag;         /**< [in]: If set to 1, it specifies that the colourPrimaries, transferCharacteristics and colourMatrix are present. */
-    uint32_t    colourPrimaries;                      /**< [in]: Specifies color primaries for converting to RGB(as defined in Annex E of the ITU-T Specification) */
-    uint32_t    transferCharacteristics;              /**< [in]: Specifies the opto-electronic transfer characteristics to use (as defined in Annex E of the ITU-T Specification) */
-    uint32_t    colourMatrix;                         /**< [in]: Specifies the matrix coefficients used in deriving the luma and chroma from the RGB primaries (as defined in Annex E of the ITU-T Specification). */
-    uint32_t    chromaSampleLocationFlag;             /**< [in]: if set to 1 , it specifies that the chromaSampleLocationTop and chromaSampleLocationBot are present.*/
-    uint32_t    chromaSampleLocationTop;              /**< [in]: Specifies the chroma sample location for top field(as defined in Annex E of the ITU-T Specification) */
-    uint32_t    chromaSampleLocationBot;              /**< [in]: Specifies the chroma sample location for bottom field(as defined in Annex E of the ITU-T Specification) */
-    uint32_t    bitstreamRestrictionFlag;             /**< [in]: if set to 1, it specifies the bitstream restriction parameters are present in the bitstream.*/
-    uint32_t    reserved[15];
+    uint32_t                            overscanInfoPresentFlag;        /**< [in]: If set to 1 , it specifies that the overscanInfo is present */
+    uint32_t                            overscanInfo;                   /**< [in]: Specifies the overscan info(as defined in Annex E of the ITU-T Specification). */
+    uint32_t                            videoSignalTypePresentFlag;     /**< [in]: If set to 1, it specifies  that the videoFormat, videoFullRangeFlag and colourDescriptionPresentFlag are present. */
+    NV_ENC_VUI_VIDEO_FORMAT             videoFormat;                    /**< [in]: Specifies the source video format(as defined in Annex E of the ITU-T Specification).*/
+    uint32_t                            videoFullRangeFlag;             /**< [in]: Specifies the output range of the luma and chroma samples(as defined in Annex E of the ITU-T Specification). */
+    uint32_t                            colourDescriptionPresentFlag;   /**< [in]: If set to 1, it specifies that the colourPrimaries, transferCharacteristics and colourMatrix are present. */
+    NV_ENC_VUI_COLOR_PRIMARIES          colourPrimaries;                /**< [in]: Specifies color primaries for converting to RGB(as defined in Annex E of the ITU-T Specification) */
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC  transferCharacteristics;        /**< [in]: Specifies the opto-electronic transfer characteristics to use (as defined in Annex E of the ITU-T Specification) */
+    NV_ENC_VUI_MATRIX_COEFFS            colourMatrix;                   /**< [in]: Specifies the matrix coefficients used in deriving the luma and chroma from the RGB primaries (as defined in Annex E of the ITU-T Specification). */
+    uint32_t                            chromaSampleLocationFlag;       /**< [in]: If set to 1 , it specifies that the chromaSampleLocationTop and chromaSampleLocationBot are present.*/
+    uint32_t                            chromaSampleLocationTop;        /**< [in]: Specifies the chroma sample location for top field(as defined in Annex E of the ITU-T Specification) */
+    uint32_t                            chromaSampleLocationBot;        /**< [in]: Specifies the chroma sample location for bottom field(as defined in Annex E of the ITU-T Specification) */
+    uint32_t                            bitstreamRestrictionFlag;       /**< [in]: If set to 1, it specifies the bitstream restriction parameters are present in the bitstream.*/
+    uint32_t                            timingInfoPresentFlag;          /**< [in]: If set to 1, it specifies that the timingInfo is present and the 'numUnitInTicks' and 'timeScale' fields are specified by the application. */
+                                                                        /**< [in]: If not set, the timingInfo may still be present with timing related fields calculated internally basedon the frame rate specified by the application. */
+    uint32_t                            numUnitInTicks;                 /**< [in]: Specifies the number of time units of the clock(as defined in Annex E of the ITU-T Specification). */
+    uint32_t                            timeScale;                      /**< [in]: Specifies the frquency of the clock(as defined in Annex E of the ITU-T Specification). */ 
+    uint32_t                            reserved[12];                   /**< [in]: Reserved and must be set to 0 */
 }NV_ENC_CONFIG_H264_VUI_PARAMETERS;
 }NV_ENC_CONFIG_H264_VUI_PARAMETERS;
 
 
 typedef NV_ENC_CONFIG_H264_VUI_PARAMETERS NV_ENC_CONFIG_HEVC_VUI_PARAMETERS;
 typedef NV_ENC_CONFIG_H264_VUI_PARAMETERS NV_ENC_CONFIG_HEVC_VUI_PARAMETERS;
@@ -1370,7 +1542,7 @@ typedef NV_ENC_CONFIG_H264_VUI_PARAMETERS NV_ENC_CONFIG_HEVC_VUI_PARAMETERS;
 /**
 /**
  * \struct _NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE
  * \struct _NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE
  * External motion vector hint counts per block type.
  * External motion vector hint counts per block type.
- * H264 supports multiple hint while HEVC supports one hint for each valid candidate.
+ * H264 and AV1 support multiple hint while HEVC supports one hint for each valid candidate.
  */
  */
 typedef struct _NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE
 typedef struct _NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE
 {
 {
@@ -1378,7 +1550,8 @@ typedef struct _NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE
     uint32_t   numCandsPerBlk16x8                    : 4;   /**< [in]: Supported for H264 only. Specifies the number of candidates per 16x8 block. */
     uint32_t   numCandsPerBlk16x8                    : 4;   /**< [in]: Supported for H264 only. Specifies the number of candidates per 16x8 block. */
     uint32_t   numCandsPerBlk8x16                    : 4;   /**< [in]: Supported for H264 only. Specifies the number of candidates per 8x16 block. */
     uint32_t   numCandsPerBlk8x16                    : 4;   /**< [in]: Supported for H264 only. Specifies the number of candidates per 8x16 block. */
     uint32_t   numCandsPerBlk8x8                     : 4;   /**< [in]: Supported for H264, HEVC. Specifies the number of candidates per 8x8 block. */
     uint32_t   numCandsPerBlk8x8                     : 4;   /**< [in]: Supported for H264, HEVC. Specifies the number of candidates per 8x8 block. */
-    uint32_t   reserved                              : 16;  /**< [in]: Reserved for padding. */
+    uint32_t   numCandsPerSb                         : 8;   /**< [in]: Supported for AV1 only. Specifies the number of candidates per SB. */
+    uint32_t   reserved                              : 8;   /**< [in]: Reserved for padding. */
     uint32_t   reserved1[3];                                /**< [in]: Reserved for future use. */
     uint32_t   reserved1[3];                                /**< [in]: Reserved for future use. */
 } NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE;
 } NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE;
 
 
@@ -1398,6 +1571,26 @@ typedef struct _NVENC_EXTERNAL_ME_HINT
     int32_t    lastOfMB    : 1;                         /**< [in]: Set to 1 for the last MV of macroblock. */
     int32_t    lastOfMB    : 1;                         /**< [in]: Set to 1 for the last MV of macroblock. */
 } NVENC_EXTERNAL_ME_HINT;
 } NVENC_EXTERNAL_ME_HINT;
 
 
+/**
+ * \struct _NVENC_EXTERNAL_ME_SB_HINT
+ * External Motion Vector SB hint structure for AV1
+ */
+typedef struct _NVENC_EXTERNAL_ME_SB_HINT
+{
+    int16_t    refidx         : 5;                      /**< [in]: Specifies the reference index (31=invalid) */
+    int16_t    direction      : 1;                      /**< [in]: Specifies the direction of motion estimation . 0=L0 1=L1.*/
+    int16_t    bi             : 1;                      /**< [in]: Specifies reference mode 0=single mv, 1=compound mv */
+    int16_t    partition_type : 3;                      /**< [in]: Specifies the partition type: 0: 2NX2N, 1:2NxN, 2:Nx2N. reserved 3bits for future modes */
+    int16_t    x8             : 3;                      /**< [in]: Specifies the current partition's top left x position in 8 pixel unit */
+    int16_t    last_of_cu     : 1;                      /**< [in]: Set to 1 for the last MV current CU */
+    int16_t    last_of_sb     : 1;                      /**< [in]: Set to 1 for the last MV of current SB */
+    int16_t    reserved0      : 1;                      /**< [in]: Reserved and must be set to 0 */
+    int16_t    mvx            : 14;                     /**< [in]: Specifies the x component of integer pixel MV (relative to current MB) S12.2. */
+    int16_t    cu_size        : 2;                      /**< [in]: Specifies the CU size: 0: 8x8, 1: 16x16, 2:32x32, 3:64x64 */
+    int16_t    mvy            : 12;                     /**< [in]: Specifies the y component of integer pixel MV (relative to current MB) S10.2 .*/
+    int16_t    y8             : 3;                      /**< [in]: Specifies the current partition's top left y position in 8 pixel unit */
+    int16_t    reserved1      : 1;                      /**< [in]: Reserved and must be set to 0 */
+} NVENC_EXTERNAL_ME_SB_HINT;
 
 
 /**
 /**
  * \struct _NV_ENC_CONFIG_H264
  * \struct _NV_ENC_CONFIG_H264
@@ -1410,8 +1603,7 @@ typedef struct _NV_ENC_CONFIG_H264
     uint32_t hierarchicalPFrames       :1;                          /**< [in]: Set to 1 to enable hierarchical P Frames */
     uint32_t hierarchicalPFrames       :1;                          /**< [in]: Set to 1 to enable hierarchical P Frames */
     uint32_t hierarchicalBFrames       :1;                          /**< [in]: Set to 1 to enable hierarchical B Frames */
     uint32_t hierarchicalBFrames       :1;                          /**< [in]: Set to 1 to enable hierarchical B Frames */
     uint32_t outputBufferingPeriodSEI  :1;                          /**< [in]: Set to 1 to write SEI buffering period syntax in the bitstream */
     uint32_t outputBufferingPeriodSEI  :1;                          /**< [in]: Set to 1 to write SEI buffering period syntax in the bitstream */
-    uint32_t outputPictureTimingSEI    :1;                          /**< [in]: Set to 1 to write SEI picture timing syntax in the bitstream.  When set for following rateControlMode : NV_ENC_PARAMS_RC_CBR, NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ,
-                                                                               NV_ENC_PARAMS_RC_CBR_HQ, filler data is inserted if needed to achieve HRD bitrate */
+    uint32_t outputPictureTimingSEI    :1;                          /**< [in]: Set to 1 to write SEI picture timing syntax in the bitstream. */
     uint32_t outputAUD                 :1;                          /**< [in]: Set to 1 to write access unit delimiter syntax in bitstream */
     uint32_t outputAUD                 :1;                          /**< [in]: Set to 1 to write access unit delimiter syntax in bitstream */
     uint32_t disableSPSPPS             :1;                          /**< [in]: Set to 1 to disable writing of Sequence and Picture parameter info in bitstream */
     uint32_t disableSPSPPS             :1;                          /**< [in]: Set to 1 to disable writing of Sequence and Picture parameter info in bitstream */
     uint32_t outputFramePackingSEI     :1;                          /**< [in]: Set to 1 to enable writing of frame packing arrangement SEI messages to bitstream */
     uint32_t outputFramePackingSEI     :1;                          /**< [in]: Set to 1 to enable writing of frame packing arrangement SEI messages to bitstream */
@@ -1447,10 +1639,11 @@ typedef struct _NV_ENC_CONFIG_H264
                                                                                Applicable only when temporal SVC is enabled (NV_ENC_CONFIG_H264::enableTemporalSVC = 1). */
                                                                                Applicable only when temporal SVC is enabled (NV_ENC_CONFIG_H264::enableTemporalSVC = 1). */
     uint32_t enableScalabilityInfoSEI  :1;                          /**< [in]: Set to 1 to enable writing of Scalability Information SEI message preceding each IDR picture in bitstream
     uint32_t enableScalabilityInfoSEI  :1;                          /**< [in]: Set to 1 to enable writing of Scalability Information SEI message preceding each IDR picture in bitstream
                                                                                Applicable only when temporal SVC is enabled (NV_ENC_CONFIG_H264::enableTemporalSVC = 1). */
                                                                                Applicable only when temporal SVC is enabled (NV_ENC_CONFIG_H264::enableTemporalSVC = 1). */
-    uint32_t singleSliceIntraRefresh : 1;                           /**< [in]: Set to 1 to maintain single slice in frames during intra refresh.
+    uint32_t singleSliceIntraRefresh   :1;                          /**< [in]: Set to 1 to maintain single slice in frames during intra refresh.
                                                                                Check support for single slice intra refresh using ::NV_ENC_CAPS_SINGLE_SLICE_INTRA_REFRESH caps.
                                                                                Check support for single slice intra refresh using ::NV_ENC_CAPS_SINGLE_SLICE_INTRA_REFRESH caps.
                                                                                This flag will be ignored if the value returned for ::NV_ENC_CAPS_SINGLE_SLICE_INTRA_REFRESH caps is false. */
                                                                                This flag will be ignored if the value returned for ::NV_ENC_CAPS_SINGLE_SLICE_INTRA_REFRESH caps is false. */
-    uint32_t reservedBitFields : 11;                                /**< [in]: Reserved bitfields and must be set to 0 */
+    uint32_t enableTimeCode            :1;                          /**< [in]: Set to 1 to enable writing of clock timestamp sets in picture timing SEI.  Note that this flag will be ignored for D3D12 interface. */
+    uint32_t reservedBitFields         :10;                         /**< [in]: Reserved bitfields and must be set to 0 */
     uint32_t level;                                                 /**< [in]: Specifies the encoding level. Client is recommended to set this to NV_ENC_LEVEL_AUTOSELECT in order to enable the NvEncodeAPI interface to select the correct level. */
     uint32_t level;                                                 /**< [in]: Specifies the encoding level. Client is recommended to set this to NV_ENC_LEVEL_AUTOSELECT in order to enable the NvEncodeAPI interface to select the correct level. */
     uint32_t idrPeriod;                                             /**< [in]: Specifies the IDR interval. If not set, this is made equal to gopLength in NV_ENC_CONFIG.Low latency application client can set IDR interval to NVENC_INFINITE_GOPLENGTH so that IDR frames are not inserted automatically. */
     uint32_t idrPeriod;                                             /**< [in]: Specifies the IDR interval. If not set, this is made equal to gopLength in NV_ENC_CONFIG.Low latency application client can set IDR interval to NVENC_INFINITE_GOPLENGTH so that IDR frames are not inserted automatically. */
     uint32_t separateColourPlaneFlag;                               /**< [in]: Set to 1 to enable 4:4:4 separate colour planes */
     uint32_t separateColourPlaneFlag;                               /**< [in]: Set to 1 to enable 4:4:4 separate colour planes */
@@ -1493,7 +1686,7 @@ typedef struct _NV_ENC_CONFIG_H264
                                                                                Set to 0 when using "LTR Per Picture" mode of LTR operation. */
                                                                                Set to 0 when using "LTR Per Picture" mode of LTR operation. */
     uint32_t                            chromaFormatIDC;            /**< [in]: Specifies the chroma format. Should be set to 1 for yuv420 input, 3 for yuv444 input.
     uint32_t                            chromaFormatIDC;            /**< [in]: Specifies the chroma format. Should be set to 1 for yuv420 input, 3 for yuv444 input.
                                                                                Check support for YUV444 encoding using ::NV_ENC_CAPS_SUPPORT_YUV444_ENCODE caps.*/
                                                                                Check support for YUV444 encoding using ::NV_ENC_CAPS_SUPPORT_YUV444_ENCODE caps.*/
-    uint32_t                            maxTemporalLayers;          /**< [in]: Specifies the maximum temporal layer used for temporal SVC / hierarchical coding.
+    uint32_t                            maxTemporalLayers;          /**< [in]: Specifies the max temporal layer used for temporal SVC / hierarchical coding.
                                                                                Defaut value of this field is NV_ENC_CAPS::NV_ENC_CAPS_NUM_MAX_TEMPORAL_LAYERS. Note that the value NV_ENC_CONFIG_H264::maxNumRefFrames should
                                                                                Defaut value of this field is NV_ENC_CAPS::NV_ENC_CAPS_NUM_MAX_TEMPORAL_LAYERS. Note that the value NV_ENC_CONFIG_H264::maxNumRefFrames should
                                                                                be greater than or equal to (NV_ENC_CONFIG_H264::maxTemporalLayers - 2) * 2, for NV_ENC_CONFIG_H264::maxTemporalLayers >= 2.*/
                                                                                be greater than or equal to (NV_ENC_CONFIG_H264::maxTemporalLayers - 2) * 2, for NV_ENC_CONFIG_H264::maxTemporalLayers >= 2.*/
     NV_ENC_BFRAME_REF_MODE              useBFramesAsRef;            /**< [in]: Specifies the B-Frame as reference mode. Check support for useBFramesAsRef mode using ::NV_ENC_CAPS_SUPPORT_BFRAME_REF_MODE caps.*/
     NV_ENC_BFRAME_REF_MODE              useBFramesAsRef;            /**< [in]: Specifies the B-Frame as reference mode. Check support for useBFramesAsRef mode using ::NV_ENC_CAPS_SUPPORT_BFRAME_REF_MODE caps.*/
@@ -1501,6 +1694,7 @@ typedef struct _NV_ENC_CONFIG_H264
                                                                                Check support for numRefL0 using ::NV_ENC_CAPS_SUPPORT_MULTIPLE_REF_FRAMES caps. */
                                                                                Check support for numRefL0 using ::NV_ENC_CAPS_SUPPORT_MULTIPLE_REF_FRAMES caps. */
     NV_ENC_NUM_REF_FRAMES               numRefL1;                   /**< [in]: Specifies max number of reference frames in reference picture list L1, that can be used by hardware for prediction of a frame.
     NV_ENC_NUM_REF_FRAMES               numRefL1;                   /**< [in]: Specifies max number of reference frames in reference picture list L1, that can be used by hardware for prediction of a frame.
                                                                                Check support for numRefL1 using ::NV_ENC_CAPS_SUPPORT_MULTIPLE_REF_FRAMES caps. */
                                                                                Check support for numRefL1 using ::NV_ENC_CAPS_SUPPORT_MULTIPLE_REF_FRAMES caps. */
+
     uint32_t                            reserved1[267];             /**< [in]: Reserved and must be set to 0 */
     uint32_t                            reserved1[267];             /**< [in]: Reserved and must be set to 0 */
     void*                               reserved2[64];              /**< [in]: Reserved and must be set to NULL */
     void*                               reserved2[64];              /**< [in]: Reserved and must be set to NULL */
 } NV_ENC_CONFIG_H264;
 } NV_ENC_CONFIG_H264;
@@ -1546,10 +1740,12 @@ typedef struct _NV_ENC_CONFIG_HEVC
                                                                                Constrained encoding works only with rectangular slices.
                                                                                Constrained encoding works only with rectangular slices.
                                                                                Check support for constrained encoding using ::NV_ENC_CAPS_SUPPORT_CONSTRAINED_ENCODING caps. */
                                                                                Check support for constrained encoding using ::NV_ENC_CAPS_SUPPORT_CONSTRAINED_ENCODING caps. */
     uint32_t enableAlphaLayerEncoding              :1;              /**< [in]: Set this to 1 to enable HEVC encode with alpha layer. */
     uint32_t enableAlphaLayerEncoding              :1;              /**< [in]: Set this to 1 to enable HEVC encode with alpha layer. */
-    uint32_t singleSliceIntraRefresh : 1;                           /**< [in]: Set this to 1 to maintain single slice frames during intra refresh.
+    uint32_t singleSliceIntraRefresh               :1;              /**< [in]: Set this to 1 to maintain single slice frames during intra refresh.
                                                                                Check support for single slice intra refresh using ::NV_ENC_CAPS_SINGLE_SLICE_INTRA_REFRESH caps.
                                                                                Check support for single slice intra refresh using ::NV_ENC_CAPS_SINGLE_SLICE_INTRA_REFRESH caps.
                                                                                This flag will be ignored if the value returned for ::NV_ENC_CAPS_SINGLE_SLICE_INTRA_REFRESH caps is false. */
                                                                                This flag will be ignored if the value returned for ::NV_ENC_CAPS_SINGLE_SLICE_INTRA_REFRESH caps is false. */
-    uint32_t reserved : 14;                                         /**< [in]: Reserved bitfields.*/
+    uint32_t outputRecoveryPointSEI                :1;              /**< [in]: Set to 1 to enable writing of recovery point SEI message */
+    uint32_t outputTimeCodeSEI                     :1;              /**< [in]: Set 1 to write SEI time code syntax in the bitstream. Note that this flag will be ignored for D3D12 interface.*/
+    uint32_t reserved                              :12;             /**< [in]: Reserved bitfields.*/
     uint32_t idrPeriod;                                             /**< [in]: Specifies the IDR interval. If not set, this is made equal to gopLength in NV_ENC_CONFIG. Low latency application client can set IDR interval to NVENC_INFINITE_GOPLENGTH so that IDR frames are not inserted automatically. */
     uint32_t idrPeriod;                                             /**< [in]: Specifies the IDR interval. If not set, this is made equal to gopLength in NV_ENC_CONFIG. Low latency application client can set IDR interval to NVENC_INFINITE_GOPLENGTH so that IDR frames are not inserted automatically. */
     uint32_t intraRefreshPeriod;                                    /**< [in]: Specifies the interval between successive intra refresh if enableIntrarefresh is set. Requires enableIntraRefresh to be set.
     uint32_t intraRefreshPeriod;                                    /**< [in]: Specifies the interval between successive intra refresh if enableIntrarefresh is set. Requires enableIntraRefresh to be set.
                                                                     Will be disabled if NV_ENC_CONFIG::gopLength is not set to NVENC_INFINITE_GOPLENGTH. */
                                                                     Will be disabled if NV_ENC_CONFIG::gopLength is not set to NVENC_INFINITE_GOPLENGTH. */
@@ -1557,7 +1753,10 @@ typedef struct _NV_ENC_CONFIG_HEVC
     uint32_t maxNumRefFramesInDPB;                                  /**< [in]: Specifies the maximum number of references frames in the DPB.*/
     uint32_t maxNumRefFramesInDPB;                                  /**< [in]: Specifies the maximum number of references frames in the DPB.*/
     uint32_t ltrNumFrames;                                          /**< [in]: This parameter has different meaning in two LTR modes.
     uint32_t ltrNumFrames;                                          /**< [in]: This parameter has different meaning in two LTR modes.
                                                                                In "LTR Trust" mode (ltrTrustMode = 1), encoder will mark the first ltrNumFrames base layer reference frames within each IDR interval as LTR.
                                                                                In "LTR Trust" mode (ltrTrustMode = 1), encoder will mark the first ltrNumFrames base layer reference frames within each IDR interval as LTR.
-                                                                               In "LTR Per Picture" mode (ltrTrustMode = 0 and ltrMarkFrame = 1), ltrNumFrames specifies maximum number of LTR frames in DPB. */
+                                                                               In "LTR Per Picture" mode (ltrTrustMode = 0 and ltrMarkFrame = 1), ltrNumFrames specifies maximum number of LTR frames in DPB.
+                                                                               These ltrNumFrames acts as a guidance to the encoder and are not necessarily honored. To achieve a right balance between the encoding
+                                                                               quality and keeping LTR frames in the DPB queue, the encoder can internally limit the number of LTR frames.
+                                                                               The number of LTR frames actually used depends upon the encoding preset being used; Faster encoding presets will use fewer LTR frames.*/
     uint32_t vpsId;                                                 /**< [in]: Specifies the VPS id of the video parameter set */
     uint32_t vpsId;                                                 /**< [in]: Specifies the VPS id of the video parameter set */
     uint32_t spsId;                                                 /**< [in]: Specifies the SPS id of the sequence header */
     uint32_t spsId;                                                 /**< [in]: Specifies the SPS id of the sequence header */
     uint32_t ppsId;                                                 /**< [in]: Specifies the PPS id of the picture header */
     uint32_t ppsId;                                                 /**< [in]: Specifies the PPS id of the picture header */
@@ -1584,6 +1783,105 @@ typedef struct _NV_ENC_CONFIG_HEVC
     void*                               reserved2[64];              /**< [in]: Reserved and must be set to NULL */
     void*                               reserved2[64];              /**< [in]: Reserved and must be set to NULL */
 } NV_ENC_CONFIG_HEVC;
 } NV_ENC_CONFIG_HEVC;
 
 
+#define NV_MAX_TILE_COLS_AV1               64
+#define NV_MAX_TILE_ROWS_AV1               64
+
+/**
+ * \struct _NV_ENC_FILM_GRAIN_PARAMS_AV1
+ * AV1 Film Grain Parameters structure
+ */
+
+typedef struct _NV_ENC_FILM_GRAIN_PARAMS_AV1
+{
+    uint32_t applyGrain                 :1;                         /**< [in]: Set to 1 to specify film grain should be added to frame */
+    uint32_t chromaScalingFromLuma      :1;                         /**< [in]: Set to 1 to specify the chroma scaling is inferred from luma scaling */
+    uint32_t overlapFlag                :1;                         /**< [in]: Set to 1 to indicate that overlap between film grain blocks should be applied*/
+    uint32_t clipToRestrictedRange      :1;                         /**< [in]: Set to 1 to clip values to restricted (studio) range after adding film grain  */
+    uint32_t grainScalingMinus8         :2;                         /**< [in]: Represents the shift - 8 applied to the values of the chroma component */
+    uint32_t arCoeffLag                 :2;                         /**< [in]: Specifies the number of auto-regressive coefficients for luma and chroma */
+    uint32_t numYPoints                 :4;                         /**< [in]: Specifies the number of points for the piecewise linear scaling function of the luma component */
+    uint32_t numCbPoints                :4;                         /**< [in]: Specifies the number of points for the piecewise linear scaling function of the cb component */
+    uint32_t numCrPoints                :4;                         /**< [in]: Specifies the number of points for the piecewise linear scaling function of the cr component */
+    uint32_t arCoeffShiftMinus6         :2;                         /**< [in]: specifies the range of the auto-regressive coefficients */
+    uint32_t grainScaleShift            :2;                         /**< [in]: Specifies how much the Gaussian random numbers should be scaled down during the grain synthesi process  */
+    uint32_t reserved1                  :8;                         /**< [in]: Reserved bits field - should be set to 0 */
+    uint8_t  pointYValue[14];                                       /**< [in]: pointYValue[i]: x coordinate for i-th point of luma piecewise linear scaling function. Values on a scale of 0...255 */
+    uint8_t  pointYScaling[14];                                     /**< [in]: pointYScaling[i]: i-th point output value of luma piecewise linear scaling function */
+    uint8_t  pointCbValue[10];                                      /**< [in]: pointCbValue[i]: x coordinate for i-th point of cb piecewise linear scaling function. Values on a scale of 0...255 */
+    uint8_t  pointCbScaling[10];                                    /**< [in]: pointCbScaling[i]: i-th point output value of cb piecewise linear scaling function */
+    uint8_t  pointCrValue[10];                                      /**< [in]: pointCrValue[i]: x coordinate for i-th point of cr piecewise linear scaling function. Values on a scale of 0...255 */
+    uint8_t  pointCrScaling[10];                                    /**< [in]: pointCrScaling[i]: i-th point output value of cr piecewise linear scaling function */
+    uint8_t  arCoeffsYPlus128[24];                                  /**< [in]: Specifies auto-regressive coefficients used for the Y plane */
+    uint8_t  arCoeffsCbPlus128[25];                                 /**< [in]: Specifies auto-regressive coefficients used for the U plane */
+    uint8_t  arCoeffsCrPlus128[25];                                 /**< [in]: Specifies auto-regressive coefficients used for the V plane */
+    uint8_t  reserved2[2];                                          /**< [in]: Reserved bytes -  should be set to 0 */
+    uint8_t  cbMult;                                                /**< [in]: Represents a multiplier for the cb component used in derivation of the input index to the cb component scaling function */
+    uint8_t  cbLumaMult;                                            /**< [in]: represents a multiplier for the average luma component used in derivation of the input index to the cb component scaling function. */
+    uint16_t cbOffset;                                              /**< [in]: Represents an offset used in derivation of the input index to the cb component scaling function */
+    uint8_t  crMult;                                                /**< [in]: Represents a multiplier for the cr component used in derivation of the input index to the cr component scaling function */
+    uint8_t  crLumaMult;                                            /**< [in]: represents a multiplier for the average luma component used in derivation of the input index to the cr component scaling function. */
+    uint16_t crOffset;                                              /**< [in]: Represents an offset used in derivation of the input index to the cr component scaling function */
+} NV_ENC_FILM_GRAIN_PARAMS_AV1;
+
+/**
+* \struct _NV_ENC_CONFIG_AV1
+* AV1 encoder configuration parameters to be set during initialization.
+*/
+typedef struct _NV_ENC_CONFIG_AV1
+{
+    uint32_t level;                                                 /**< [in]: Specifies the level of the encoded bitstream.*/
+    uint32_t tier;                                                  /**< [in]: Specifies the level tier of the encoded bitstream.*/
+    NV_ENC_AV1_PART_SIZE minPartSize;                               /**< [in]: Specifies the minimum size of luma coding block partition.*/
+    NV_ENC_AV1_PART_SIZE maxPartSize;                               /**< [in]: Specifies the maximum size of luma coding block partition.*/
+    uint32_t outputAnnexBFormat             : 1;                    /**< [in]: Set 1 to use Annex B format for bitstream output.*/
+    uint32_t enableTimingInfo               : 1;                    /**< [in]: Set 1 to write Timing Info into sequence/frame headers */
+    uint32_t enableDecoderModelInfo         : 1;                    /**< [in]: Set 1 to write Decoder Model Info into sequence/frame headers */
+    uint32_t enableFrameIdNumbers           : 1;                    /**< [in]: Set 1 to write Frame id numbers in  bitstream */
+    uint32_t disableSeqHdr                  : 1;                    /**< [in]: Set 1 to disable Sequence Header signaling in the bitstream. */
+    uint32_t repeatSeqHdr                   : 1;                    /**< [in]: Set 1 to output Sequence Header for every Key frame.*/
+    uint32_t enableIntraRefresh             : 1;                    /**< [in]: Set 1 to enable gradual decoder refresh or intra refresh. If the GOP structure uses B frames this will be ignored */
+    uint32_t chromaFormatIDC                : 2;                    /**< [in]: Specifies the chroma format. Should be set to 1 for yuv420 input (yuv444 input currently not supported).*/
+    uint32_t enableBitstreamPadding         : 1;                    /**< [in]: Set 1 to enable bitstream padding. */
+    uint32_t enableCustomTileConfig         : 1;                    /**< [in]: Set 1 to enable custom tile configuration: numTileColumns and numTileRows must have non zero values and tileWidths and tileHeights must point to a valid address  */
+    uint32_t enableFilmGrainParams          : 1;                    /**< [in]: Set 1 to enable custom film grain parameters: filmGrainParams must point to a valid address  */
+    uint32_t inputPixelBitDepthMinus8       : 3;                    /**< [in]: Specifies pixel bit depth minus 8 of video input. Should be set to 0 for 8 bit input, 2 for 10 bit input.*/
+    uint32_t pixelBitDepthMinus8            : 3;                    /**< [in]: Specifies pixel bit depth minus 8 of encoded video. Should be set to 0 for 8 bit, 2 for 10 bit.
+                                                                               HW will do the bitdepth conversion internally from inputPixelBitDepthMinus8 -> pixelBitDepthMinus8 if bit dpeths differ
+                                                                               Support for 8 bit input to 10 bit encode conversion only */
+    uint32_t reserved                       : 14;                   /**< [in]: Reserved bitfields.*/
+    uint32_t idrPeriod;                                             /**< [in]: Specifies the IDR/Key frame interval. If not set, this is made equal to gopLength in NV_ENC_CONFIG.Low latency application client can set IDR interval to NVENC_INFINITE_GOPLENGTH so that IDR frames are not inserted automatically. */
+    uint32_t intraRefreshPeriod;                                    /**< [in]: Specifies the interval between successive intra refresh if enableIntrarefresh is set. Requires enableIntraRefresh to be set.
+                                                                               Will be disabled if NV_ENC_CONFIG::gopLength is not set to NVENC_INFINITE_GOPLENGTH. */
+    uint32_t intraRefreshCnt;                                       /**< [in]: Specifies the length of intra refresh in number of frames for periodic intra refresh. This value should be smaller than intraRefreshPeriod */
+    uint32_t maxNumRefFramesInDPB;                                  /**< [in]: Specifies the maximum number of references frames in the DPB.*/
+    uint32_t numTileColumns;                                        /**< [in]: This parameter in conjunction with the flag enableCustomTileConfig and the array tileWidths[] specifies the way in which the picture is divided into tile columns.
+                                                                               When enableCustomTileConfig == 0, the picture will be uniformly divided into numTileColumns tile columns. If numTileColumns is not a power of 2,
+                                                                               it will be rounded down to the next power of 2 value. If numTileColumns == 0, the picture will be coded with the smallest number of vertical tiles as allowed by standard.
+                                                                               When enableCustomTileConfig == 1, numTileColumns must be > 0 and <= NV_MAX_TILE_COLS_AV1 and tileWidths must point to a valid array of numTileColumns entries.
+                                                                               Entry i specifies the width in 64x64 CTU unit of tile colum i. The sum of all the entries should be equal to the picture width in 64x64 CTU units. */
+    uint32_t numTileRows;                                           /**< [in]: This parameter in conjunction with the flag enableCustomTileConfig and the array tileHeights[] specifies the way in which the picture is divided into tiles rows
+                                                                               When enableCustomTileConfig == 0, the picture will be uniformly divided into numTileRows tile rows. If numTileRows is not a power of 2,
+                                                                               it will be rounded down to the next power of 2 value. If numTileRows == 0, the picture will be coded with the smallest number of horizontal tiles as allowed by standard.
+                                                                               When enableCustomTileConfig == 1, numTileRows must be > 0 and <= NV_MAX_TILE_ROWS_AV1 and tileHeights must point to a valid array of numTileRows entries.
+                                                                               Entry i specifies the height in 64x64 CTU unit of tile row i. The sum of all the entries should be equal to the picture hieght in 64x64 CTU units. */
+    uint32_t *tileWidths;                                           /**< [in]: If enableCustomTileConfig == 1, tileWidths[i] specifies the width of tile column i in 64x64 CTU unit, with 0 <= i <= numTileColumns -1. */
+    uint32_t *tileHeights;                                          /**< [in]: If enableCustomTileConfig == 1, tileHeights[i] specifies the height of tile row i in 64x64 CTU unit, with 0 <= i <= numTileRows -1. */
+    uint32_t maxTemporalLayersMinus1;                               /**< [in]: Specifies the max temporal layer used for hierarchical coding. */
+    NV_ENC_VUI_COLOR_PRIMARIES colorPrimaries;                      /**< [in]: as defined in section of ISO/IEC 23091-4/ITU-T H.273 */
+    NV_ENC_VUI_TRANSFER_CHARACTERISTIC transferCharacteristics;     /**< [in]: as defined in section of ISO/IEC 23091-4/ITU-T H.273 */
+    NV_ENC_VUI_MATRIX_COEFFS matrixCoefficients;                    /**< [in]: as defined in section of ISO/IEC 23091-4/ITU-T H.273 */
+    uint32_t colorRange;                                            /**< [in]: 0: studio swing representation - 1: full swing representation */
+    uint32_t chromaSamplePosition;                                  /**< [in]: 0: unknown
+                                                                               1: Horizontally collocated with luma (0,0) sample, between two vertical samples
+                                                                               2: Co-located with luma (0,0) sample */
+    NV_ENC_BFRAME_REF_MODE useBFramesAsRef;                         /**< [in]: Specifies the B-Frame as reference mode. Check support for useBFramesAsRef mode using  ::NV_ENC_CAPS_SUPPORT_BFRAME_REF_MODE caps.*/
+    NV_ENC_FILM_GRAIN_PARAMS_AV1 *filmGrainParams;                  /**< [in]: If enableFilmGrainParams == 1, filmGrainParams must point to a valid NV_ENC_FILM_GRAIN_PARAMS_AV1 structure */
+    NV_ENC_NUM_REF_FRAMES  numFwdRefs;                              /**< [in]: Specifies max number of forward reference frame used for prediction of a frame. It must be in range 1-4 (Last, Last2, last3 and Golden). It's a suggestive value not necessarily be honored always. */
+    NV_ENC_NUM_REF_FRAMES  numBwdRefs;                              /**< [in]: Specifies max number of L1 list reference frame used for prediction of a frame. It must be in range 1-3 (Backward, Altref2, Altref). It's a suggestive value not necessarily be honored always. */
+    uint32_t reserved1[235];                                        /**< [in]: Reserved and must be set to 0.*/
+    void*    reserved2[62];                                         /**< [in]: Reserved and must be set to NULL */
+} NV_ENC_CONFIG_AV1;
+
 /**
 /**
  * \struct _NV_ENC_CONFIG_H264_MEONLY
  * \struct _NV_ENC_CONFIG_H264_MEONLY
  * H264 encoder configuration parameters for ME only Mode
  * H264 encoder configuration parameters for ME only Mode
@@ -1622,6 +1920,7 @@ typedef union _NV_ENC_CODEC_CONFIG
 {
 {
     NV_ENC_CONFIG_H264        h264Config;                /**< [in]: Specifies the H.264-specific encoder configuration. */
     NV_ENC_CONFIG_H264        h264Config;                /**< [in]: Specifies the H.264-specific encoder configuration. */
     NV_ENC_CONFIG_HEVC        hevcConfig;                /**< [in]: Specifies the HEVC-specific encoder configuration. */
     NV_ENC_CONFIG_HEVC        hevcConfig;                /**< [in]: Specifies the HEVC-specific encoder configuration. */
+    NV_ENC_CONFIG_AV1         av1Config;                 /**< [in]: Specifies the AV1-specific encoder configuration. */
     NV_ENC_CONFIG_H264_MEONLY h264MeOnlyConfig;          /**< [in]: Specifies the H.264-specific ME only encoder configuration. */
     NV_ENC_CONFIG_H264_MEONLY h264MeOnlyConfig;          /**< [in]: Specifies the H.264-specific ME only encoder configuration. */
     NV_ENC_CONFIG_HEVC_MEONLY hevcMeOnlyConfig;          /**< [in]: Specifies the HEVC-specific ME only encoder configuration. */
     NV_ENC_CONFIG_HEVC_MEONLY hevcMeOnlyConfig;          /**< [in]: Specifies the HEVC-specific ME only encoder configuration. */
     uint32_t                reserved[320];               /**< [in]: Reserved and must be set to 0 */
     uint32_t                reserved[320];               /**< [in]: Reserved and must be set to 0 */
@@ -1650,7 +1949,7 @@ typedef struct _NV_ENC_CONFIG
 } NV_ENC_CONFIG;
 } NV_ENC_CONFIG;
 
 
 /** macro for constructing the version field of ::_NV_ENC_CONFIG */
 /** macro for constructing the version field of ::_NV_ENC_CONFIG */
-#define NV_ENC_CONFIG_VER (NVENCAPI_STRUCT_VERSION(7) | ( 1u<<31 ))
+#define NV_ENC_CONFIG_VER (NVENCAPI_STRUCT_VERSION(8) | ( 1<<31 ))
 
 
 /**
 /**
  *  Tuning information of NVENC encoding (TuningInfo is not applicable to H264 and HEVC MEOnly mode).
  *  Tuning information of NVENC encoding (TuningInfo is not applicable to H264 and HEVC MEOnly mode).
@@ -1684,8 +1983,8 @@ typedef struct _NV_ENC_INITIALIZE_PARAMS
     uint32_t                                   enablePTD;                       /**< [in]: Set this to 1 to enable the Picture Type Decision is be taken by the NvEncodeAPI interface. */
     uint32_t                                   enablePTD;                       /**< [in]: Set this to 1 to enable the Picture Type Decision is be taken by the NvEncodeAPI interface. */
     uint32_t                                   reportSliceOffsets        :1;    /**< [in]: Set this to 1 to enable reporting slice offsets in ::_NV_ENC_LOCK_BITSTREAM. NV_ENC_INITIALIZE_PARAMS::enableEncodeAsync must be set to 0 to use this feature. Client must set this to 0 if NV_ENC_CONFIG_H264::sliceMode is 1 on Kepler GPUs */
     uint32_t                                   reportSliceOffsets        :1;    /**< [in]: Set this to 1 to enable reporting slice offsets in ::_NV_ENC_LOCK_BITSTREAM. NV_ENC_INITIALIZE_PARAMS::enableEncodeAsync must be set to 0 to use this feature. Client must set this to 0 if NV_ENC_CONFIG_H264::sliceMode is 1 on Kepler GPUs */
     uint32_t                                   enableSubFrameWrite       :1;    /**< [in]: Set this to 1 to write out available bitstream to memory at subframe intervals.
     uint32_t                                   enableSubFrameWrite       :1;    /**< [in]: Set this to 1 to write out available bitstream to memory at subframe intervals.
-                                                                                           If enableSubFrameWrite = 1, then the hardware encoder returns data as soon as a slice has completed encoding.
-                                                                                           This results in better encoding latency, but the downside is that the application has to keep polling via a call to nvEncLockBitstream API continuously to see if any encoded slice data is available.
+                                                                                           If enableSubFrameWrite = 1, then the hardware encoder returns data as soon as a slice (H264/HEVC) or tile (AV1) has completed encoding.
+                                                                                           This results in better encoding latency, but the downside is that the application has to keep polling via a call to nvEncLockBitstream API continuously to see if any encoded slice/tile data is available.
                                                                                            Use this mode if you feel that the marginal reduction in latency from sub-frame encoding is worth the increase in complexity due to CPU-based polling. */
                                                                                            Use this mode if you feel that the marginal reduction in latency from sub-frame encoding is worth the increase in complexity due to CPU-based polling. */
     uint32_t                                   enableExternalMEHints     :1;    /**< [in]: Set to 1 to enable external ME hints for the current frame. For NV_ENC_INITIALIZE_PARAMS::enablePTD=1 with B frames, programming L1 hints is optional for B frames since Client doesn't know internal GOP structure.
     uint32_t                                   enableExternalMEHints     :1;    /**< [in]: Set to 1 to enable external ME hints for the current frame. For NV_ENC_INITIALIZE_PARAMS::enablePTD=1 with B frames, programming L1 hints is optional for B frames since Client doesn't know internal GOP structure.
                                                                                            NV_ENC_PIC_PARAMS::meHintRefPicDist should preferably be set with enablePTD=1. */
                                                                                            NV_ENC_PIC_PARAMS::meHintRefPicDist should preferably be set with enablePTD=1. */
@@ -1703,17 +2002,17 @@ typedef struct _NV_ENC_INITIALIZE_PARAMS
                                                                                            Client should allocate output buffers according to this dimension for dynamic resolution change. If set to 0, Encoder will not allow dynamic resolution change. */
                                                                                            Client should allocate output buffers according to this dimension for dynamic resolution change. If set to 0, Encoder will not allow dynamic resolution change. */
     uint32_t                                   maxEncodeHeight;                 /**< [in]: Maximum encode height to be allowed for current Encode session.
     uint32_t                                   maxEncodeHeight;                 /**< [in]: Maximum encode height to be allowed for current Encode session.
                                                                                            Client should allocate output buffers according to this dimension for dynamic resolution change. If set to 0, Encode will not allow dynamic resolution change. */
                                                                                            Client should allocate output buffers according to this dimension for dynamic resolution change. If set to 0, Encode will not allow dynamic resolution change. */
-    NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE maxMEHintCountsPerBlock[2];      /**< [in]: If Client wants to pass external motion vectors in NV_ENC_PIC_PARAMS::meExternalHints buffer it must specify the maximum number of hint candidates per block per direction for the encode session.
+    NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE maxMEHintCountsPerBlock[2];     /**< [in]: If Client wants to pass external motion vectors in NV_ENC_PIC_PARAMS::meExternalHints buffer it must specify the maximum number of hint candidates per block per direction for the encode session.
                                                                                            The NV_ENC_INITIALIZE_PARAMS::maxMEHintCountsPerBlock[0] is for L0 predictors and NV_ENC_INITIALIZE_PARAMS::maxMEHintCountsPerBlock[1] is for L1 predictors.
                                                                                            The NV_ENC_INITIALIZE_PARAMS::maxMEHintCountsPerBlock[0] is for L0 predictors and NV_ENC_INITIALIZE_PARAMS::maxMEHintCountsPerBlock[1] is for L1 predictors.
                                                                                            This client must also set NV_ENC_INITIALIZE_PARAMS::enableExternalMEHints to 1. */
                                                                                            This client must also set NV_ENC_INITIALIZE_PARAMS::enableExternalMEHints to 1. */
     NV_ENC_TUNING_INFO                         tuningInfo;                      /**< [in]: Tuning Info of NVENC encoding(TuningInfo is not applicable to H264 and HEVC meonly mode). */
     NV_ENC_TUNING_INFO                         tuningInfo;                      /**< [in]: Tuning Info of NVENC encoding(TuningInfo is not applicable to H264 and HEVC meonly mode). */
-    NV_ENC_BUFFER_FORMAT                       bufferFormat;                    /**< [in]: Specifies input buffer format. Client should set input buffer format only when D3D12 interface type is used. */
-    uint32_t                                   reserved[287];                   /**< [in]: Reserved and must be set to 0 */
+    NV_ENC_BUFFER_FORMAT                       bufferFormat;                    /**< [in]: Input buffer format. Used only when DX12 interface type is used */
+    uint32_t                                   reserved [287];                  /**< [in]: Reserved and must be set to 0 */
     void*                                      reserved2[64];                   /**< [in]: Reserved and must be set to NULL */
     void*                                      reserved2[64];                   /**< [in]: Reserved and must be set to NULL */
 } NV_ENC_INITIALIZE_PARAMS;
 } NV_ENC_INITIALIZE_PARAMS;
 
 
 /** macro for constructing the version field of ::_NV_ENC_INITIALIZE_PARAMS */
 /** macro for constructing the version field of ::_NV_ENC_INITIALIZE_PARAMS */
-#define NV_ENC_INITIALIZE_PARAMS_VER (NVENCAPI_STRUCT_VERSION(5) | ( 1u<<31 ))
+#define NV_ENC_INITIALIZE_PARAMS_VER (NVENCAPI_STRUCT_VERSION(5) | ( 1<<31 ))
 
 
 
 
 /**
 /**
@@ -1747,7 +2046,7 @@ typedef struct _NV_ENC_RECONFIGURE_PARAMS
 }NV_ENC_RECONFIGURE_PARAMS;
 }NV_ENC_RECONFIGURE_PARAMS;
 
 
 /** macro for constructing the version field of ::_NV_ENC_RECONFIGURE_PARAMS */
 /** macro for constructing the version field of ::_NV_ENC_RECONFIGURE_PARAMS */
-#define NV_ENC_RECONFIGURE_PARAMS_VER (NVENCAPI_STRUCT_VERSION(1) | ( 1u<<31 ))
+#define NV_ENC_RECONFIGURE_PARAMS_VER (NVENCAPI_STRUCT_VERSION(1) | ( 1<<31 ))
 
 
 /**
 /**
  * \struct _NV_ENC_PRESET_CONFIG
  * \struct _NV_ENC_PRESET_CONFIG
@@ -1762,7 +2061,7 @@ typedef struct _NV_ENC_PRESET_CONFIG
 }NV_ENC_PRESET_CONFIG;
 }NV_ENC_PRESET_CONFIG;
 
 
 /** macro for constructing the version field of ::_NV_ENC_PRESET_CONFIG */
 /** macro for constructing the version field of ::_NV_ENC_PRESET_CONFIG */
-#define NV_ENC_PRESET_CONFIG_VER (NVENCAPI_STRUCT_VERSION(4) | ( 1u<<31 ))
+#define NV_ENC_PRESET_CONFIG_VER (NVENCAPI_STRUCT_VERSION(4) | ( 1<<31 ))
 
 
 
 
 /**
 /**
@@ -1847,7 +2146,8 @@ typedef struct _NV_ENC_PIC_PARAMS_H264
     uint32_t *forceIntraSliceIdx;                        /**< [in]: Slice indices to be forced to intra in the current picture. Each slice index should be <= num_slices_in_picture -1. Index starts from 0 for first slice.
     uint32_t *forceIntraSliceIdx;                        /**< [in]: Slice indices to be forced to intra in the current picture. Each slice index should be <= num_slices_in_picture -1. Index starts from 0 for first slice.
                                                                     The number of entries in this array should be equal to forceIntraSliceCount */
                                                                     The number of entries in this array should be equal to forceIntraSliceCount */
     NV_ENC_PIC_PARAMS_H264_EXT h264ExtPicParams;         /**< [in]: Specifies the H264 extension config parameters using this config. */
     NV_ENC_PIC_PARAMS_H264_EXT h264ExtPicParams;         /**< [in]: Specifies the H264 extension config parameters using this config. */
-    uint32_t reserved [210];                             /**< [in]: Reserved and must be set to 0. */
+    NV_ENC_TIME_CODE timeCode;                           /**< [in]: Specifies the clock timestamp sets used in picture timing SEI. Applicable only when NV_ENC_CONFIG_H264::enableTimeCode is set to 1. */
+    uint32_t reserved [203];                             /**< [in]: Reserved and must be set to 0. */
     void*    reserved2[61];                              /**< [in]: Reserved and must be set to NULL. */
     void*    reserved2[61];                              /**< [in]: Reserved and must be set to NULL. */
 } NV_ENC_PIC_PARAMS_H264;
 } NV_ENC_PIC_PARAMS_H264;
 
 
@@ -1890,10 +2190,60 @@ typedef struct _NV_ENC_PIC_PARAMS_HEVC
     uint32_t seiPayloadArrayCnt;                         /**< [in]: Specifies the number of elements allocated in  seiPayloadArray array. */
     uint32_t seiPayloadArrayCnt;                         /**< [in]: Specifies the number of elements allocated in  seiPayloadArray array. */
     uint32_t reserved;                                   /**< [in]: Reserved and must be set to 0. */
     uint32_t reserved;                                   /**< [in]: Reserved and must be set to 0. */
     NV_ENC_SEI_PAYLOAD* seiPayloadArray;                 /**< [in]: Array of SEI payloads which will be inserted for this frame. */
     NV_ENC_SEI_PAYLOAD* seiPayloadArray;                 /**< [in]: Array of SEI payloads which will be inserted for this frame. */
-    uint32_t reserved2 [244];                             /**< [in]: Reserved and must be set to 0. */
+    NV_ENC_TIME_CODE timeCode;                           /**< [in]: Specifies the clock timestamp sets used in time code SEI. Applicable only when NV_ENC_CONFIG_HEVC::enableTimeCodeSEI is set to 1. */
+    uint32_t reserved2 [237];                            /**< [in]: Reserved and must be set to 0. */
     void*    reserved3[61];                              /**< [in]: Reserved and must be set to NULL. */
     void*    reserved3[61];                              /**< [in]: Reserved and must be set to NULL. */
 } NV_ENC_PIC_PARAMS_HEVC;
 } NV_ENC_PIC_PARAMS_HEVC;
 
 
+#define NV_ENC_AV1_OBU_PAYLOAD NV_ENC_SEI_PAYLOAD
+
+/**
+* \struct _NV_ENC_PIC_PARAMS_AV1
+* AV1 specific enc pic params. sent on a per frame basis.
+*/
+typedef struct _NV_ENC_PIC_PARAMS_AV1
+{
+    uint32_t displayPOCSyntax;                           /**< [in]: Specifies the display POC syntax This is required to be set if client is handling the picture type decision. */
+    uint32_t refPicFlag;                                 /**< [in]: Set to 1 for a reference picture. This is ignored if NV_ENC_INITIALIZE_PARAMS::enablePTD is set to 1. */
+    uint32_t temporalId;                                 /**< [in]: Specifies the temporal id of the picture */
+    uint32_t forceIntraRefreshWithFrameCnt;              /**< [in]: Forces an intra refresh with duration equal to intraRefreshFrameCnt.
+                                                                    forceIntraRefreshWithFrameCnt cannot be used if B frames are used in the GOP structure specified */
+    uint32_t goldenFrameFlag            : 1;             /**< [in]: Encode frame as Golden Frame. This is ignored if NV_ENC_INITIALIZE_PARAMS::enablePTD is set to 1. */
+    uint32_t arfFrameFlag               : 1;             /**< [in]: Encode frame as Alternate Reference Frame. This is ignored if NV_ENC_INITIALIZE_PARAMS::enablePTD is set to 1. */
+    uint32_t arf2FrameFlag              : 1;             /**< [in]: Encode frame as Alternate Reference 2 Frame. This is ignored if NV_ENC_INITIALIZE_PARAMS::enablePTD is set to 1. */
+    uint32_t bwdFrameFlag               : 1;             /**< [in]: Encode frame as Backward Reference Frame. This is ignored if NV_ENC_INITIALIZE_PARAMS::enablePTD is set to 1. */
+    uint32_t overlayFrameFlag           : 1;             /**< [in]: Encode frame as overlay frame. A previously encoded frame with the same displayPOCSyntax value should be present in reference frame buffer.
+                                                                    This is ignored if NV_ENC_INITIALIZE_PARAMS::enablePTD is set to 1. */
+    uint32_t showExistingFrameFlag      : 1;             /**< [in]: When ovelayFrameFlag is set to 1, this flag controls the value of the show_existing_frame syntax element associated with the overlay frame.
+                                                                    This flag is added to the interface as a placeholder. Its value is ignored for now and always assumed to be set to 1.
+                                                                    This is ignored if NV_ENC_INITIALIZE_PARAMS::enablePTD is set to 1. */
+    uint32_t errorResilientModeFlag     : 1;             /**< [in]: encode frame independently from previously encoded frames */
+
+    uint32_t tileConfigUpdate           : 1;             /**< [in]: Set to 1 if client wants to overwrite the default tile configuration with the tile parameters specified below
+                                                                    When forceIntraRefreshWithFrameCnt is set it will have priority over tileConfigUpdate setting */
+    uint32_t enableCustomTileConfig     : 1;             /**< [in]: Set 1 to enable custom tile configuration: numTileColumns and numTileRows must have non zero values and tileWidths and tileHeights must point to a valid address  */
+    uint32_t filmGrainParamsUpdate      : 1;             /**< [in]: Set to 1 if client wants to update previous film grain parameters: filmGrainParams must point to a valid address and encoder must have been configured with film grain enabled  */
+    uint32_t reservedBitFields          : 22;            /**< [in]: Reserved bitfields and must be set to 0 */
+    uint32_t numTileColumns;                             /**< [in]: This parameter in conjunction with the flag enableCustomTileConfig and the array tileWidths[] specifies the way in which the picture is divided into tile columns.
+                                                                    When enableCustomTileConfig == 0, the picture will be uniformly divided into numTileColumns tile columns. If numTileColumns is not a power of 2,
+                                                                    it will be rounded down to the next power of 2 value. If numTileColumns == 0, the picture will be coded with the smallest number of vertical tiles as allowed by standard.
+                                                                    When enableCustomTileConfig == 1, numTileColumns must be > 0 and <= NV_MAX_TILE_COLS_AV1 and tileWidths must point to a valid array of numTileColumns entries.
+                                                                    Entry i specifies the width in 64x64 CTU unit of tile colum i. The sum of all the entries should be equal to the picture width in 64x64 CTU units. */
+    uint32_t numTileRows;                                /**< [in]: This parameter in conjunction with the flag enableCustomTileConfig and the array tileHeights[] specifies the way in which the picture is divided into tiles rows
+                                                                    When enableCustomTileConfig == 0, the picture will be uniformly divided into numTileRows tile rows. If numTileRows is not a power of 2,
+                                                                    it will be rounded down to the next power of 2 value. If numTileRows == 0, the picture will be coded with the smallest number of horizontal tiles as allowed by standard.
+                                                                    When enableCustomTileConfig == 1, numTileRows must be > 0 and <= NV_MAX_TILE_ROWS_AV1 and tileHeights must point to a valid array of numTileRows entries.
+                                                                    Entry i specifies the height in 64x64 CTU unit of tile row i. The sum of all the entries should be equal to the picture hieght in 64x64 CTU units. */
+    uint32_t *tileWidths;                                /**< [in]: If enableCustomTileConfig == 1, tileWidths[i] specifies the width of tile column i in 64x64 CTU unit, with 0 <= i <= numTileColumns -1. */
+    uint32_t *tileHeights;                               /**< [in]: If enableCustomTileConfig == 1, tileHeights[i] specifies the height of tile row i in 64x64 CTU unit, with 0 <= i <= numTileRows -1. */
+    uint32_t obuPayloadArrayCnt;                         /**< [in]: Specifies the number of elements allocated in  obuPayloadArray array. */
+    uint32_t reserved;                                   /**< [in]: Reserved and must be set to 0. */
+    NV_ENC_AV1_OBU_PAYLOAD* obuPayloadArray;             /**< [in]: Array of OBU payloads which will be inserted for this frame. */
+    NV_ENC_FILM_GRAIN_PARAMS_AV1 *filmGrainParams;       /**< [in]: If filmGrainParamsUpdate == 1, filmGrainParams must point to a valid NV_ENC_FILM_GRAIN_PARAMS_AV1 structure */
+    uint32_t reserved2[247];                             /**< [in]: Reserved and must be set to 0. */
+    void*    reserved3[61];                              /**< [in]: Reserved and must be set to NULL. */
+} NV_ENC_PIC_PARAMS_AV1;
+
 /**
 /**
  * Codec specific per-picture encoding parameters.
  * Codec specific per-picture encoding parameters.
  */
  */
@@ -1901,9 +2251,11 @@ typedef union _NV_ENC_CODEC_PIC_PARAMS
 {
 {
     NV_ENC_PIC_PARAMS_H264 h264PicParams;                /**< [in]: H264 encode picture params. */
     NV_ENC_PIC_PARAMS_H264 h264PicParams;                /**< [in]: H264 encode picture params. */
     NV_ENC_PIC_PARAMS_HEVC hevcPicParams;                /**< [in]: HEVC encode picture params. */
     NV_ENC_PIC_PARAMS_HEVC hevcPicParams;                /**< [in]: HEVC encode picture params. */
+    NV_ENC_PIC_PARAMS_AV1  av1PicParams;                 /**< [in]: AV1 encode picture params. */
     uint32_t               reserved[256];                /**< [in]: Reserved and must be set to 0. */
     uint32_t               reserved[256];                /**< [in]: Reserved and must be set to 0. */
 } NV_ENC_CODEC_PIC_PARAMS;
 } NV_ENC_CODEC_PIC_PARAMS;
 
 
+
 /**
 /**
  * \struct _NV_ENC_PIC_PARAMS
  * \struct _NV_ENC_PIC_PARAMS
  * Encoding parameters that need to be sent on a per frame basis.
  * Encoding parameters that need to be sent on a per frame basis.
@@ -1936,28 +2288,33 @@ typedef struct _NV_ENC_PIC_PARAMS
     NV_ENC_CODEC_PIC_PARAMS                     codecPicParams;                 /**< [in]: Specifies the codec specific per-picture encoding parameters. */
     NV_ENC_CODEC_PIC_PARAMS                     codecPicParams;                 /**< [in]: Specifies the codec specific per-picture encoding parameters. */
     NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE meHintCountsPerBlock[2];        /**< [in]: For H264 and Hevc, specifies the number of hint candidates per block per direction for the current frame. meHintCountsPerBlock[0] is for L0 predictors and meHintCountsPerBlock[1] is for L1 predictors.
     NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE meHintCountsPerBlock[2];        /**< [in]: For H264 and Hevc, specifies the number of hint candidates per block per direction for the current frame. meHintCountsPerBlock[0] is for L0 predictors and meHintCountsPerBlock[1] is for L1 predictors.
                                                                                            The candidate count in NV_ENC_PIC_PARAMS::meHintCountsPerBlock[lx] must never exceed NV_ENC_INITIALIZE_PARAMS::maxMEHintCountsPerBlock[lx] provided during encoder initialization. */
                                                                                            The candidate count in NV_ENC_PIC_PARAMS::meHintCountsPerBlock[lx] must never exceed NV_ENC_INITIALIZE_PARAMS::maxMEHintCountsPerBlock[lx] provided during encoder initialization. */
-    NVENC_EXTERNAL_ME_HINT*                     meExternalHints;                /**< [in]: For H264 and Hevc, Specifies the pointer to ME external hints for the current frame. The size of ME hint buffer should be equal to number of macroblocks * the total number of candidates per macroblock.
+    NVENC_EXTERNAL_ME_HINT                     *meExternalHints;                /**< [in]: For H264 and Hevc, Specifies the pointer to ME external hints for the current frame. The size of ME hint buffer should be equal to number of macroblocks * the total number of candidates per macroblock.
                                                                                            The total number of candidates per MB per direction = 1*meHintCountsPerBlock[Lx].numCandsPerBlk16x16 + 2*meHintCountsPerBlock[Lx].numCandsPerBlk16x8 + 2*meHintCountsPerBlock[Lx].numCandsPerBlk8x8
                                                                                            The total number of candidates per MB per direction = 1*meHintCountsPerBlock[Lx].numCandsPerBlk16x16 + 2*meHintCountsPerBlock[Lx].numCandsPerBlk16x8 + 2*meHintCountsPerBlock[Lx].numCandsPerBlk8x8
                                                                                            + 4*meHintCountsPerBlock[Lx].numCandsPerBlk8x8. For frames using bidirectional ME , the total number of candidates for single macroblock is sum of total number of candidates per MB for each direction (L0 and L1) */
                                                                                            + 4*meHintCountsPerBlock[Lx].numCandsPerBlk8x8. For frames using bidirectional ME , the total number of candidates for single macroblock is sum of total number of candidates per MB for each direction (L0 and L1) */
     uint32_t                                    reserved1[6];                    /**< [in]: Reserved and must be set to 0 */
     uint32_t                                    reserved1[6];                    /**< [in]: Reserved and must be set to 0 */
     void*                                       reserved2[2];                    /**< [in]: Reserved and must be set to NULL */
     void*                                       reserved2[2];                    /**< [in]: Reserved and must be set to NULL */
-    int8_t                                     *qpDeltaMap;                      /**< [in]: Specifies the pointer to signed byte array containing value per MB for H264 and per CTB for HEVC in raster scan order for the current picture, which will be interpreted depending on NV_ENC_RC_PARAMS::qpMapMode.
-                                                                                            If NV_ENC_RC_PARAMS::qpMapMode is NV_ENC_QP_MAP_DELTA, qpDeltaMap specifies QP modifier per MB for H264 and per CTB for HEVC. This QP modifier will be applied on top of the QP chosen by rate control.
+    int8_t                                     *qpDeltaMap;                      /**< [in]: Specifies the pointer to signed byte array containing value per MB for H264, per CTB for HEVC and per SB for AV1 in raster scan order for the current picture, which will be interpreted depending on NV_ENC_RC_PARAMS::qpMapMode.
+                                                                                            If NV_ENC_RC_PARAMS::qpMapMode is NV_ENC_QP_MAP_DELTA, qpDeltaMap specifies QP modifier per MB for H264, per CTB for HEVC and per SB for AV1. This QP modifier will be applied on top of the QP chosen by rate control.
                                                                                             If NV_ENC_RC_PARAMS::qpMapMode is NV_ENC_QP_MAP_EMPHASIS, qpDeltaMap specifies Emphasis Level Map per MB for H264. This level value along with QP chosen by rate control is used to
                                                                                             If NV_ENC_RC_PARAMS::qpMapMode is NV_ENC_QP_MAP_EMPHASIS, qpDeltaMap specifies Emphasis Level Map per MB for H264. This level value along with QP chosen by rate control is used to
                                                                                             compute the QP modifier, which in turn is applied on top of QP chosen by rate control.
                                                                                             compute the QP modifier, which in turn is applied on top of QP chosen by rate control.
                                                                                             If NV_ENC_RC_PARAMS::qpMapMode is NV_ENC_QP_MAP_DISABLED, value in qpDeltaMap will be ignored.*/
                                                                                             If NV_ENC_RC_PARAMS::qpMapMode is NV_ENC_QP_MAP_DISABLED, value in qpDeltaMap will be ignored.*/
-    uint32_t                                    qpDeltaMapSize;                  /**< [in]: Specifies the size in bytes of qpDeltaMap surface allocated by client and pointed to by NV_ENC_PIC_PARAMS::qpDeltaMap. Surface (array) should be picWidthInMbs * picHeightInMbs for H264 and picWidthInCtbs * picHeightInCtbs for HEVC */
+    uint32_t                                    qpDeltaMapSize;                  /**< [in]: Specifies the size in bytes of qpDeltaMap surface allocated by client and pointed to by NV_ENC_PIC_PARAMS::qpDeltaMap. Surface (array) should be picWidthInMbs * picHeightInMbs for H264, picWidthInCtbs * picHeightInCtbs for HEVC and 
+                                                                                            picWidthInSbs * picHeightInSbs for AV1 */
     uint32_t                                    reservedBitFields;               /**< [in]: Reserved bitfields and must be set to 0 */
     uint32_t                                    reservedBitFields;               /**< [in]: Reserved bitfields and must be set to 0 */
     uint16_t                                    meHintRefPicDist[2];             /**< [in]: Specifies temporal distance for reference picture (NVENC_EXTERNAL_ME_HINT::refidx = 0) used during external ME with NV_ENC_INITALIZE_PARAMS::enablePTD = 1 . meHintRefPicDist[0] is for L0 hints and meHintRefPicDist[1] is for L1 hints.
     uint16_t                                    meHintRefPicDist[2];             /**< [in]: Specifies temporal distance for reference picture (NVENC_EXTERNAL_ME_HINT::refidx = 0) used during external ME with NV_ENC_INITALIZE_PARAMS::enablePTD = 1 . meHintRefPicDist[0] is for L0 hints and meHintRefPicDist[1] is for L1 hints.
                                                                                             If not set, will internally infer distance of 1. Ignored for NV_ENC_INITALIZE_PARAMS::enablePTD = 0 */
                                                                                             If not set, will internally infer distance of 1. Ignored for NV_ENC_INITALIZE_PARAMS::enablePTD = 0 */
     NV_ENC_INPUT_PTR                            alphaBuffer;                     /**< [in]: Specifies the input alpha buffer pointer. Client must use a pointer obtained from ::NvEncCreateInputBuffer() or ::NvEncMapInputResource() APIs.
     NV_ENC_INPUT_PTR                            alphaBuffer;                     /**< [in]: Specifies the input alpha buffer pointer. Client must use a pointer obtained from ::NvEncCreateInputBuffer() or ::NvEncMapInputResource() APIs.
                                                                                             Applicable only when encoding hevc with alpha layer is enabled. */
                                                                                             Applicable only when encoding hevc with alpha layer is enabled. */
-    uint32_t                                    reserved3[286];                  /**< [in]: Reserved and must be set to 0 */
-    void*                                       reserved4[59];                   /**< [in]: Reserved and must be set to NULL */
+    NVENC_EXTERNAL_ME_SB_HINT                  *meExternalSbHints;               /**< [in]: For AV1,Specifies the pointer to ME external SB hints for the current frame. The size of ME hint buffer should be equal to meSbHintsCount. */
+    uint32_t                                    meSbHintsCount;                  /**< [in]: For AV1, specifies the total number of external ME SB hint candidates for the frame
+                                                                                            NV_ENC_PIC_PARAMS::meSbHintsCount must never exceed the total number of SBs in frame * the max number of candidates per SB provided during encoder initialization.
+                                                                                            The max number of candidates per SB is maxMeHintCountsPerBlock[0].numCandsPerSb + maxMeHintCountsPerBlock[1].numCandsPerSb */
+    uint32_t                                    reserved3[285];                  /**< [in]: Reserved and must be set to 0 */
+    void*                                       reserved4[58];                   /**< [in]: Reserved and must be set to NULL */
 } NV_ENC_PIC_PARAMS;
 } NV_ENC_PIC_PARAMS;
 
 
 /** Macro for constructing the version field of ::_NV_ENC_PIC_PARAMS */
 /** Macro for constructing the version field of ::_NV_ENC_PIC_PARAMS */
-#define NV_ENC_PIC_PARAMS_VER (NVENCAPI_STRUCT_VERSION(4) | ( 1u<<31 ))
+#define NV_ENC_PIC_PARAMS_VER (NVENCAPI_STRUCT_VERSION(6) | ( 1<<31 ))
 
 
 
 
 /**
 /**
@@ -2010,12 +2367,13 @@ typedef struct _NV_ENC_LOCK_BITSTREAM
     uint32_t                getRCStats        :1;        /**< [in]: If this flag is set then lockBitstream call will add additional intra-inter MB count and average MVX, MVY */
     uint32_t                getRCStats        :1;        /**< [in]: If this flag is set then lockBitstream call will add additional intra-inter MB count and average MVX, MVY */
     uint32_t                reservedBitFields :29;       /**< [in]: Reserved bit fields and must be set to 0 */
     uint32_t                reservedBitFields :29;       /**< [in]: Reserved bit fields and must be set to 0 */
     void*                   outputBitstream;             /**< [in]: Pointer to the bitstream buffer being locked. */
     void*                   outputBitstream;             /**< [in]: Pointer to the bitstream buffer being locked. */
-    uint32_t*               sliceOffsets;                /**< [in, out]: Array which receives the slice offsets. This is not supported if NV_ENC_CONFIG_H264::sliceMode is 1 on Kepler GPUs. Array size must be equal to size of frame in MBs. */
+    uint32_t*               sliceOffsets;                /**< [in, out]: Array which receives the slice (H264/HEVC) or tile (AV1) offsets. This is not supported if NV_ENC_CONFIG_H264::sliceMode is 1 on Kepler GPUs. Array size must be equal to size of frame in MBs. */
     uint32_t                frameIdx;                    /**< [out]: Frame no. for which the bitstream is being retrieved. */
     uint32_t                frameIdx;                    /**< [out]: Frame no. for which the bitstream is being retrieved. */
     uint32_t                hwEncodeStatus;              /**< [out]: The NvEncodeAPI interface status for the locked picture. */
     uint32_t                hwEncodeStatus;              /**< [out]: The NvEncodeAPI interface status for the locked picture. */
-    uint32_t                numSlices;                   /**< [out]: Number of slices in the encoded picture. Will be reported only if NV_ENC_INITIALIZE_PARAMS::reportSliceOffsets set to 1. */
+    uint32_t                numSlices;                   /**< [out]: Number of slices (H264/HEVC) or tiles (AV1) in the encoded picture. Will be reported only if NV_ENC_INITIALIZE_PARAMS::reportSliceOffsets set to 1. */
     uint32_t                bitstreamSizeInBytes;        /**< [out]: Actual number of bytes generated and copied to the memory pointed by bitstreamBufferPtr.
     uint32_t                bitstreamSizeInBytes;        /**< [out]: Actual number of bytes generated and copied to the memory pointed by bitstreamBufferPtr.
-                                                                     When HEVC alpha layer encoding is enabled, this field reports the total encoded size in bytes i.e it is the encoded size of the base plus the alpha layer. */
+                                                                     When HEVC alpha layer encoding is enabled, this field reports the total encoded size in bytes i.e it is the encoded size of the base plus the alpha layer. 
+                                                                     For AV1 when enablePTD is set, this field reports the total encoded size in bytes of all the encoded frames packed into the current output surface i.e. show frame plus all preceding no-show frames */
     uint64_t                outputTimeStamp;             /**< [out]: Presentation timestamp associated with the encoded output. */
     uint64_t                outputTimeStamp;             /**< [out]: Presentation timestamp associated with the encoded output. */
     uint64_t                outputDuration;              /**< [out]: Presentation duration associates with the encoded output. */
     uint64_t                outputDuration;              /**< [out]: Presentation duration associates with the encoded output. */
     void*                   bitstreamBufferPtr;          /**< [out]: Pointer to the generated output bitstream.
     void*                   bitstreamBufferPtr;          /**< [out]: Pointer to the generated output bitstream.
@@ -2028,9 +2386,9 @@ typedef struct _NV_ENC_LOCK_BITSTREAM
     uint32_t                ltrFrameIdx;                 /**< [out]: Frame index associated with this LTR frame. */
     uint32_t                ltrFrameIdx;                 /**< [out]: Frame index associated with this LTR frame. */
     uint32_t                ltrFrameBitmap;              /**< [out]: Bitmap of LTR frames indices which were used for encoding this frame. Value of 0 if no LTR frames were used. */
     uint32_t                ltrFrameBitmap;              /**< [out]: Bitmap of LTR frames indices which were used for encoding this frame. Value of 0 if no LTR frames were used. */
     uint32_t                temporalId;                  /**< [out]: TemporalId value of the frame when using temporalSVC encoding */
     uint32_t                temporalId;                  /**< [out]: TemporalId value of the frame when using temporalSVC encoding */
-    uint32_t                reserved[12];                /**< [in]:  Reserved and must be set to 0 */
-    uint32_t                intraMBCount;                /**< [out]: For H264, Number of Intra MBs in the encoded frame. For HEVC, Number of Intra CTBs in the encoded frame. Supported only if _NV_ENC_LOCK_BITSTREAM::getRCStats set to 1. */
-    uint32_t                interMBCount;                /**< [out]: For H264, Number of Inter MBs in the encoded frame, includes skip MBs. For HEVC, Number of Inter CTBs in the encoded frame. Supported only if _NV_ENC_LOCK_BITSTREAM::getRCStats set to 1. */
+    uint32_t                reserved[12];                /**< [in]: Reserved and must be set to 0 */
+    uint32_t                intraMBCount;                /**< [out]: For H264, Number of Intra MBs in the encoded frame. For HEVC, Number of Intra CTBs in the encoded frame. For AV1, Number of Intra SBs in the encoded show frame. Supported only if _NV_ENC_LOCK_BITSTREAM::getRCStats set to 1. */
+    uint32_t                interMBCount;                /**< [out]: For H264, Number of Inter MBs in the encoded frame, includes skip MBs. For HEVC, Number of Inter CTBs in the encoded frame. For AV1, Number of Inter SBs in the encoded show frame. Supported only if _NV_ENC_LOCK_BITSTREAM::getRCStats set to 1. */
     int32_t                 averageMVX;                  /**< [out]: Average Motion Vector in X direction for the encoded frame. Supported only if _NV_ENC_LOCK_BITSTREAM::getRCStats set to 1. */
     int32_t                 averageMVX;                  /**< [out]: Average Motion Vector in X direction for the encoded frame. Supported only if _NV_ENC_LOCK_BITSTREAM::getRCStats set to 1. */
     int32_t                 averageMVY;                  /**< [out]: Average Motion Vector in y direction for the encoded frame. Supported only if _NV_ENC_LOCK_BITSTREAM::getRCStats set to 1. */
     int32_t                 averageMVY;                  /**< [out]: Average Motion Vector in y direction for the encoded frame. Supported only if _NV_ENC_LOCK_BITSTREAM::getRCStats set to 1. */
     uint32_t                alphaLayerSizeInBytes;       /**< [out]: Number of bytes generated for the alpha layer in the encoded output. Applicable only when HEVC with alpha encoding is enabled. */
     uint32_t                alphaLayerSizeInBytes;       /**< [out]: Number of bytes generated for the alpha layer in the encoded output. Applicable only when HEVC with alpha encoding is enabled. */
@@ -2040,7 +2398,7 @@ typedef struct _NV_ENC_LOCK_BITSTREAM
 } NV_ENC_LOCK_BITSTREAM;
 } NV_ENC_LOCK_BITSTREAM;
 
 
 /** Macro for constructing the version field of ::_NV_ENC_LOCK_BITSTREAM */
 /** Macro for constructing the version field of ::_NV_ENC_LOCK_BITSTREAM */
-#define NV_ENC_LOCK_BITSTREAM_VER NVENCAPI_STRUCT_VERSION(1)
+#define NV_ENC_LOCK_BITSTREAM_VER NVENCAPI_STRUCT_VERSION(2)
 
 
 
 
 /**
 /**
@@ -2094,44 +2452,59 @@ typedef struct _NV_ENC_INPUT_RESOURCE_OPENGL_TEX
 } NV_ENC_INPUT_RESOURCE_OPENGL_TEX;
 } NV_ENC_INPUT_RESOURCE_OPENGL_TEX;
 
 
 /** \struct NV_ENC_FENCE_POINT_D3D12
 /** \struct NV_ENC_FENCE_POINT_D3D12
-  * Fence and fence value for synchronization.
-  */
+* Fence and fence value for synchronization.
+*/
 typedef struct _NV_ENC_FENCE_POINT_D3D12
 typedef struct _NV_ENC_FENCE_POINT_D3D12
 {
 {
+    uint32_t                version;                   /**< [in]: Struct version. Must be set to ::NV_ENC_FENCE_POINT_D3D12_VER. */
+    uint32_t                reserved;                  /**< [in]: Reserved and must be set to 0. */
     void*                   pFence;                    /**< [in]: Pointer to ID3D12Fence. This fence object is used for synchronization. */
     void*                   pFence;                    /**< [in]: Pointer to ID3D12Fence. This fence object is used for synchronization. */
-    uint64_t                value;                     /**< [in]: Fence value to reach or exceed before the GPU operation or
-                                                                  fence value to set the fence to, after the GPU operation. */
+    uint64_t                waitValue;                 /**< [in]: Fence value to reach or exceed before the GPU operation. */
+    uint64_t                signalValue;               /**< [in]: Fence value to set the fence to, after the GPU operation. */
+    uint32_t                bWait:1;                   /**< [in]: Wait on 'waitValue' if bWait is set to 1, before starting GPU operation. */
+    uint32_t                bSignal:1;                 /**< [in]: Signal on 'signalValue' if bSignal is set to 1, after GPU operation is complete. */
+    uint32_t                reservedBitField:30;       /**< [in]: Reserved and must be set to 0. */
+    uint32_t                reserved1[7];              /**< [in]: Reserved and must be set to 0. */
 } NV_ENC_FENCE_POINT_D3D12;
 } NV_ENC_FENCE_POINT_D3D12;
 
 
+#define NV_ENC_FENCE_POINT_D3D12_VER NVENCAPI_STRUCT_VERSION(1)
+
 /**
 /**
-  * \struct _NV_ENC_INPUT_RESOURCE_D3D12
-  * NV_ENC_PIC_PARAMS::inputBuffer and NV_ENC_PIC_PARAMS::alphaBuffer must be a pointer to a struct of this type,
-  * when D3D12 interface is used
-  */
+ * \struct _NV_ENC_INPUT_RESOURCE_D3D12
+ * NV_ENC_PIC_PARAMS::inputBuffer and NV_ENC_PIC_PARAMS::alphaBuffer must be a pointer to a struct of this type,
+ * when D3D12 interface is used
+ */
 typedef struct _NV_ENC_INPUT_RESOURCE_D3D12
 typedef struct _NV_ENC_INPUT_RESOURCE_D3D12
 {
 {
-    NV_ENC_REGISTERED_PTR       pInputBuffer;          /**< [in]: Specifies the input surface pointer. Client must use a pointer obtained from NvEncRegisterResource() in NV_ENC_REGISTER_RESOURCE::registeredResource
-                                                                  when registering input surface. */
-    NV_ENC_FENCE_POINT_D3D12    inputFencePoint;       /**< [in]: Specifies the input fence and corresponding fence value to do GPU wait.
-                                                                  This fence will be used to do GPU wait until the specified fence reaches or exceeds the specified value. */
-    uint32_t                    reserved1[16];         /**< [in]: Reserved and must be set to 0. */
-    void*                       reserved2[16];         /**< [in]: Reserved and must be set to NULL. */
+    uint32_t                    version;                /**< [in]: Struct version. Must be set to ::NV_ENC_INPUT_RESOURCE_D3D12_VER. */
+    uint32_t                    reserved;               /**< [in]: Reserved and must be set to 0. */
+    NV_ENC_INPUT_PTR            pInputBuffer;           /**< [in]: Specifies the input surface pointer. Client must use a pointer obtained from NvEncMapInputResource() in NV_ENC_MAP_INPUT_RESOURCE::mappedResource
+                                                                   when mapping the input surface. */
+    NV_ENC_FENCE_POINT_D3D12    inputFencePoint;        /**< [in]: Specifies the fence and corresponding fence values to do GPU wait and signal. */
+    uint32_t                    reserved1[16];          /**< [in]: Reserved and must be set to 0. */
+    void*                       reserved2[16];          /**< [in]: Reserved and must be set to NULL. */
 } NV_ENC_INPUT_RESOURCE_D3D12;
 } NV_ENC_INPUT_RESOURCE_D3D12;
 
 
+#define NV_ENC_INPUT_RESOURCE_D3D12_VER NVENCAPI_STRUCT_VERSION(1)
+
 /**
 /**
-  * \struct _NV_ENC_OUTPUT_RESOURCE_D3D12
-  * NV_ENC_PIC_PARAMS::outputBitstream and NV_ENC_LOCK_BITSTREAM::outputBitstream must be a pointer to a struct of this type,
-  * when D3D12 interface is used
-  */
+ * \struct _NV_ENC_OUTPUT_RESOURCE_D3D12
+ * NV_ENC_PIC_PARAMS::outputBitstream and NV_ENC_LOCK_BITSTREAM::outputBitstream must be a pointer to a struct of this type,
+ * when D3D12 interface is used
+ */
 typedef struct _NV_ENC_OUTPUT_RESOURCE_D3D12
 typedef struct _NV_ENC_OUTPUT_RESOURCE_D3D12
 {
 {
-    NV_ENC_REGISTERED_PTR      pOutputBuffer;          /**< [in]: Specifies the output buffer pointer. Client must use a pointer obtained from NvEncRegisterResource() in NV_ENC_REGISTER_RESOURCE::registeredResource
-                                                                  when registering output bitstream buffer */
-    NV_ENC_FENCE_POINT_D3D12   outputFencePoint;       /**< [in]: Specifies the output fence and corresponding fence value to set after GPU operation is finished.*/
-    uint32_t                   reserved1[16];          /**< [in]: Reserved and must be set to 0. */
-    void*                      reserved2[16];          /**< [in]: Reserved and must be set to NULL. */
+    uint32_t                    version;                /**< [in]: Struct version. Must be set to ::NV_ENC_OUTPUT_RESOURCE_D3D12_VER. */
+    uint32_t                    reserved;               /**< [in]: Reserved and must be set to 0. */
+    NV_ENC_INPUT_PTR            pOutputBuffer;          /**< [in]: Specifies the output buffer pointer. Client must use a pointer obtained from NvEncMapInputResource() in NV_ENC_MAP_INPUT_RESOURCE::mappedResource
+                                                                   when mapping output bitstream buffer */
+    NV_ENC_FENCE_POINT_D3D12    outputFencePoint;       /**< [in]: Specifies the fence and corresponding fence values to do GPU wait and signal.*/
+    uint32_t                    reserved1[16];          /**< [in]: Reserved and must be set to 0. */
+    void*                       reserved2[16];          /**< [in]: Reserved and must be set to NULL. */
 } NV_ENC_OUTPUT_RESOURCE_D3D12;
 } NV_ENC_OUTPUT_RESOURCE_D3D12;
 
 
+#define NV_ENC_OUTPUT_RESOURCE_D3D12_VER NVENCAPI_STRUCT_VERSION(1)
+
 /**
 /**
  * \struct _NV_ENC_REGISTER_RESOURCE
  * \struct _NV_ENC_REGISTER_RESOURCE
  * Register a resource for future use with the Nvidia Video Encoder Interface.
  * Register a resource for future use with the Nvidia Video Encoder Interface.
@@ -2163,19 +2536,19 @@ typedef struct _NV_ENC_REGISTER_RESOURCE
     NV_ENC_REGISTERED_PTR       registeredResource;             /**< [out]: Registered resource handle. This should be used in future interactions with the Nvidia Video Encoder Interface. */
     NV_ENC_REGISTERED_PTR       registeredResource;             /**< [out]: Registered resource handle. This should be used in future interactions with the Nvidia Video Encoder Interface. */
     NV_ENC_BUFFER_FORMAT        bufferFormat;                   /**< [in]: Buffer format of resource to be registered. */
     NV_ENC_BUFFER_FORMAT        bufferFormat;                   /**< [in]: Buffer format of resource to be registered. */
     NV_ENC_BUFFER_USAGE         bufferUsage;                    /**< [in]: Usage of resource to be registered. */
     NV_ENC_BUFFER_USAGE         bufferUsage;                    /**< [in]: Usage of resource to be registered. */
-    NV_ENC_FENCE_POINT_D3D12*   pInputFencePoint;               /**< [in]: Specifies the pointer to input fence and corresponding fence value to do GPU wait.
+    NV_ENC_FENCE_POINT_D3D12*   pInputFencePoint;               /**< [in]: Specifies the input fence and corresponding fence values to do GPU wait and signal.
                                                                            To be used only when NV_ENC_REGISTER_RESOURCE::resourceToRegister represents D3D12 surface and
                                                                            To be used only when NV_ENC_REGISTER_RESOURCE::resourceToRegister represents D3D12 surface and
                                                                            NV_ENC_BUFFER_USAGE::bufferUsage is NV_ENC_INPUT_IMAGE.
                                                                            NV_ENC_BUFFER_USAGE::bufferUsage is NV_ENC_INPUT_IMAGE.
-                                                                           This fence will be used to do GPU wait until the specified fence reaches or exceeds the specified value. */
-    NV_ENC_FENCE_POINT_D3D12*   pOutputFencePoint;              /**< [in]: Specifies the pointer to output fence and corresponding fence value to set after GPU operation is finished.
-                                                                           To be used only when NV_ENC_REGISTER_RESOURCE::resourceToRegister represents D3D12 surface and
-                                                                           NV_ENC_BUFFER_USAGE::bufferUsage is NV_ENC_INPUT_IMAGE. */
+                                                                           The fence NV_ENC_FENCE_POINT_D3D12::pFence and NV_ENC_FENCE_POINT_D3D12::waitValue will be used to do GPU wait 
+                                                                           before starting GPU operation, if NV_ENC_FENCE_POINT_D3D12::bWait is set. 
+                                                                           The fence NV_ENC_FENCE_POINT_D3D12::pFence and NV_ENC_FENCE_POINT_D3D12::signalValue will be used to do GPU signal 
+                                                                           when GPU operation finishes, if NV_ENC_FENCE_POINT_D3D12::bSignal is set. */
     uint32_t                    reserved1[247];                 /**< [in]: Reserved and must be set to 0. */
     uint32_t                    reserved1[247];                 /**< [in]: Reserved and must be set to 0. */
-    void*                       reserved2[60];                  /**< [in]: Reserved and must be set to NULL. */
+    void*                       reserved2[61];                  /**< [in]: Reserved and must be set to NULL. */
 } NV_ENC_REGISTER_RESOURCE;
 } NV_ENC_REGISTER_RESOURCE;
 
 
 /** Macro for constructing the version field of ::_NV_ENC_REGISTER_RESOURCE */
 /** Macro for constructing the version field of ::_NV_ENC_REGISTER_RESOURCE */
-#define NV_ENC_REGISTER_RESOURCE_VER NVENCAPI_STRUCT_VERSION(3)
+#define NV_ENC_REGISTER_RESOURCE_VER NVENCAPI_STRUCT_VERSION(4)
 
 
 /**
 /**
  * \struct _NV_ENC_STAT
  * \struct _NV_ENC_STAT
@@ -2580,8 +2953,9 @@ NVENCSTATUS NVENCAPI NvEncGetEncodePresetGUIDs                  (void* encoder,
 /**
 /**
  * \brief Returns a preset config structure supported for given preset GUID.
  * \brief Returns a preset config structure supported for given preset GUID.
  *
  *
- * The function returns a preset config structure for a given preset GUID. Before
- * using this function the client must enumerate the preset GUIDs available for
+ * The function returns a preset config structure for a given preset GUID.
+ * NvEncGetEncodePresetConfig() API is not applicable to AV1.
+ * Before using this function the client must enumerate the preset GUIDs available for
  * a given codec. The preset config structure can be modified by the client depending
  * a given codec. The preset config structure can be modified by the client depending
  * upon its use case and can be then used to initialize the encoder using
  * upon its use case and can be then used to initialize the encoder using
  * ::NvEncInitializeEncoder() API. The client can use this function only if it
  * ::NvEncInitializeEncoder() API. The client can use this function only if it
@@ -3236,6 +3610,8 @@ NVENCSTATUS NVENCAPI NvEncUnlockInputBuffer                     (void* encoder,
  *
  *
  * This function is used to retrieve the encoding statistics.
  * This function is used to retrieve the encoding statistics.
  * This API is not supported when encode device type is CUDA.
  * This API is not supported when encode device type is CUDA.
+ * Note that this API will be removed in future Video Codec SDK release.
+ * Clients should use NvEncLockBitstream() API to retrieve the encoding statistics.
  *
  *
  * \param [in] encoder
  * \param [in] encoder
  *   Pointer to the NvEncodeAPI interface.
  *   Pointer to the NvEncodeAPI interface.
@@ -3503,7 +3879,7 @@ NVENCSTATUS NVENCAPI NvEncDestroyEncoder                        (void* encoder);
  * Invalidates reference frame based on the time stamp provided by the client.
  * Invalidates reference frame based on the time stamp provided by the client.
  * The encoder marks any reference frames or any frames which have been reconstructed
  * The encoder marks any reference frames or any frames which have been reconstructed
  * using the corrupt frame as invalid for motion estimation and uses older reference
  * using the corrupt frame as invalid for motion estimation and uses older reference
- * frames for motion estimation. The encoded forces the current frame to be encoded
+ * frames for motion estimation. The encoder forces the current frame to be encoded
  * as an intra frame if no reference frames are left after invalidation process.
  * as an intra frame if no reference frames are left after invalidation process.
  * This is useful for low latency application for error resiliency. The client
  * This is useful for low latency application for error resiliency. The client
  * is recommended to set NV_ENC_CONFIG_H264::maxNumRefFrames to a large value so
  * is recommended to set NV_ENC_CONFIG_H264::maxNumRefFrames to a large value so

+ 99 - 12
plugins/obs-ffmpeg/jim-nvenc-helpers.c

@@ -1,7 +1,9 @@
 #include "jim-nvenc.h"
 #include "jim-nvenc.h"
 #include <util/platform.h>
 #include <util/platform.h>
 #include <util/threading.h>
 #include <util/threading.h>
+#include <util/config-file.h>
 #include <util/dstr.h>
 #include <util/dstr.h>
+#include <util/pipe.h>
 
 
 static void *nvenc_lib = NULL;
 static void *nvenc_lib = NULL;
 static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -94,6 +96,30 @@ static void *load_nv_func(const char *func)
 
 
 typedef NVENCSTATUS(NVENCAPI *NV_MAX_VER_FUNC)(uint32_t *);
 typedef NVENCSTATUS(NVENCAPI *NV_MAX_VER_FUNC)(uint32_t *);
 
 
+uint32_t get_nvenc_ver()
+{
+	static NV_MAX_VER_FUNC nv_max_ver = NULL;
+	static bool failed = false;
+
+	if (!nv_max_ver) {
+		if (failed)
+			return 0;
+
+		nv_max_ver = (NV_MAX_VER_FUNC)load_nv_func(
+			"NvEncodeAPIGetMaxSupportedVersion");
+		if (!nv_max_ver) {
+			failed = true;
+			return 0;
+		}
+	}
+
+	uint32_t ver = 0;
+	if (nv_max_ver(&ver) != NV_ENC_SUCCESS) {
+		return 0;
+	}
+	return ver;
+}
+
 const char *nv_error_name(NVENCSTATUS err)
 const char *nv_error_name(NVENCSTATUS err)
 {
 {
 #define RETURN_CASE(x) \
 #define RETURN_CASE(x) \
@@ -142,9 +168,8 @@ static inline bool init_nvenc_internal(obs_encoder_t *encoder)
 		return success;
 		return success;
 	initialized = true;
 	initialized = true;
 
 
-	NV_MAX_VER_FUNC nv_max_ver = (NV_MAX_VER_FUNC)load_nv_func(
-		"NvEncodeAPIGetMaxSupportedVersion");
-	if (!nv_max_ver) {
+	uint32_t ver = get_nvenc_ver();
+	if (ver == 0) {
 		obs_encoder_set_last_error(
 		obs_encoder_set_last_error(
 			encoder,
 			encoder,
 			"Missing NvEncodeAPIGetMaxSupportedVersion, check "
 			"Missing NvEncodeAPIGetMaxSupportedVersion, check "
@@ -152,14 +177,9 @@ static inline bool init_nvenc_internal(obs_encoder_t *encoder)
 		return false;
 		return false;
 	}
 	}
 
 
-	uint32_t ver = 0;
-	if (NV_FAILED(encoder, nv_max_ver(&ver))) {
-		return false;
-	}
-
-	uint32_t cur_ver = (NVENCAPI_MAJOR_VERSION << 4) |
-			   NVENCAPI_MINOR_VERSION;
-	if (cur_ver > ver) {
+	uint32_t supported_ver = (NVENC_COMPAT_MAJOR_VER << 4) |
+				 NVENC_COMPAT_MINOR_VER;
+	if (supported_ver > ver) {
 		obs_encoder_set_last_error(
 		obs_encoder_set_last_error(
 			encoder, obs_module_text("NVENC.OutdatedDriver"));
 			encoder, obs_module_text("NVENC.OutdatedDriver"));
 
 
@@ -200,8 +220,71 @@ extern struct obs_encoder_info h264_nvenc_info;
 #ifdef ENABLE_HEVC
 #ifdef ENABLE_HEVC
 extern struct obs_encoder_info hevc_nvenc_info;
 extern struct obs_encoder_info hevc_nvenc_info;
 #endif
 #endif
+extern struct obs_encoder_info av1_nvenc_info;
+
+static bool av1_supported(void)
+{
+	char *test_exe = os_get_executable_path_ptr("obs-nvenc-test.exe");
+	struct dstr caps_str = {0};
+	bool av1_supported = false;
+	config_t *config = NULL;
+
+	os_process_pipe_t *pp = os_process_pipe_create(test_exe, "r");
+	if (!pp) {
+		blog(LOG_WARNING, "[NVENC] Failed to launch the NVENC "
+				  "test process I guess");
+		goto fail;
+	}
+
+	for (;;) {
+		char data[2048];
+		size_t len =
+			os_process_pipe_read(pp, (uint8_t *)data, sizeof(data));
+		if (!len)
+			break;
+
+		dstr_ncat(&caps_str, data, len);
+	}
+
+	os_process_pipe_destroy(pp);
+
+	if (dstr_is_empty(&caps_str)) {
+		blog(LOG_WARNING,
+		     "[NVENC] Seems the NVENC test subprocess crashed. "
+		     "Better there than here I guess. Let's just "
+		     "skip NVENC AV1 detection then I suppose.");
+		goto fail;
+	}
+
+	if (config_open_string(&config, caps_str.array) != 0) {
+		blog(LOG_WARNING, "[NVENC] Failed to open config string");
+		goto fail;
+	}
+
+	const char *error = config_get_string(config, "error", "string");
+	if (error) {
+		blog(LOG_WARNING, "[NVENC] AV1 test process failed: %s", error);
+		goto fail;
+	}
+
+	uint32_t adapter_count = (uint32_t)config_num_sections(config);
+	bool avc_supported = false;
+	bool hevc_supported = false;
+
+	/* for now, just check AV1 support on device 0 */
+	av1_supported = config_get_bool(config, "0", "supports_av1");
+
+fail:
+	if (config)
+		config_close(config);
+	dstr_free(&caps_str);
+	if (test_exe)
+		bfree(test_exe);
+
+	return av1_supported;
+}
 
 
-void jim_nvenc_load(bool h264, bool hevc)
+void jim_nvenc_load(bool h264, bool hevc, bool av1)
 {
 {
 	pthread_mutex_init(&init_mutex, NULL);
 	pthread_mutex_init(&init_mutex, NULL);
 	if (h264)
 	if (h264)
@@ -210,6 +293,10 @@ void jim_nvenc_load(bool h264, bool hevc)
 	if (hevc)
 	if (hevc)
 		obs_register_encoder(&hevc_nvenc_info);
 		obs_register_encoder(&hevc_nvenc_info);
 #endif
 #endif
+	if (av1 && av1_supported())
+		obs_register_encoder(&av1_nvenc_info);
+	else
+		blog(LOG_WARNING, "[NVENC] AV1 is not supported");
 }
 }
 
 
 void jim_nvenc_unload(void)
 void jim_nvenc_unload(void)

+ 7 - 0
plugins/obs-ffmpeg/jim-nvenc-ver.h

@@ -0,0 +1,7 @@
+#pragma once
+
+#define NVENC_COMPAT_MAJOR_VER 11
+#define NVENC_COMPAT_MINOR_VER 1
+
+#define NVENC_COMPAT_VER \
+	(NVENC_COMPAT_MAJOR_VER | (NVENC_COMPAT_MINOR_VER << 24))

+ 177 - 20
plugins/obs-ffmpeg/jim-nvenc.c

@@ -10,6 +10,32 @@
 #include <d3d11_1.h>
 #include <d3d11_1.h>
 #include <obs-hevc.h>
 #include <obs-hevc.h>
 
 
+/* ========================================================================= */
+/* a hack of the ages: nvenc backward compatibility                          */
+
+#define CONFIGURED_NVENC_MAJOR 12
+#define CONFIGURED_NVENC_MINOR 0
+#define CONFIGURED_NVENC_VER \
+	(CONFIGURED_NVENC_MAJOR | (CONFIGURED_NVENC_MINOR << 24))
+
+/* we cannot guarantee structures haven't changed, so purposely break on
+ * version change to force the programmer to update or remove backward
+ * compatibility NVENC code. */
+#if CONFIGURED_NVENC_VER != NVENCAPI_VERSION
+#error NVENC version changed, update or remove NVENC compatibility code
+#endif
+
+#undef NVENCAPI_STRUCT_VERSION
+#define NVENCAPI_STRUCT_VERSION(ver)                              \
+	((uint32_t)(enc->codec == CODEC_AV1 ? NVENCAPI_VERSION    \
+					    : NVENC_COMPAT_VER) | \
+	 ((ver) << 16) | (0x7 << 28))
+
+#define NV_ENC_CONFIG_COMPAT_VER (NVENCAPI_STRUCT_VERSION(7) | (1 << 31))
+#define NV_ENC_PIC_PARAMS_COMPAT_VER (NVENCAPI_STRUCT_VERSION(4) | (1 << 31))
+#define NV_ENC_LOCK_BITSTREAM_COMPAT_VER NVENCAPI_STRUCT_VERSION(1)
+#define NV_ENC_REGISTER_RESOURCE_COMPAT_VER NVENCAPI_STRUCT_VERSION(3)
+
 /* ========================================================================= */
 /* ========================================================================= */
 
 
 #define EXTRA_BUFFERS 5
 #define EXTRA_BUFFERS 5
@@ -40,6 +66,7 @@ struct handle_tex {
 enum codec_type {
 enum codec_type {
 	CODEC_H264,
 	CODEC_H264,
 	CODEC_HEVC,
 	CODEC_HEVC,
+	CODEC_AV1,
 };
 };
 
 
 static const char *get_codec_name(enum codec_type type)
 static const char *get_codec_name(enum codec_type type)
@@ -49,6 +76,8 @@ static const char *get_codec_name(enum codec_type type)
 		return "H264";
 		return "H264";
 	case CODEC_HEVC:
 	case CODEC_HEVC:
 		return "HEVC";
 		return "HEVC";
+	case CODEC_AV1:
+		return "AV1";
 	}
 	}
 
 
 	return "Unknown";
 	return "Unknown";
@@ -157,7 +186,11 @@ static bool nv_texture_init(struct nvenc_data *enc, struct nv_texture *nvtex)
 
 
 	tex->lpVtbl->SetEvictionPriority(tex, DXGI_RESOURCE_PRIORITY_MAXIMUM);
 	tex->lpVtbl->SetEvictionPriority(tex, DXGI_RESOURCE_PRIORITY_MAXIMUM);
 
 
-	NV_ENC_REGISTER_RESOURCE res = {NV_ENC_REGISTER_RESOURCE_VER};
+	uint32_t struct_ver = enc->codec == CODEC_AV1
+				      ? NV_ENC_REGISTER_RESOURCE_VER
+				      : NV_ENC_REGISTER_RESOURCE_COMPAT_VER;
+
+	NV_ENC_REGISTER_RESOURCE res = {struct_ver};
 	res.resourceType = NV_ENC_INPUT_RESOURCE_TYPE_DIRECTX;
 	res.resourceType = NV_ENC_INPUT_RESOURCE_TYPE_DIRECTX;
 	res.resourceToRegister = tex;
 	res.resourceToRegister = tex;
 	res.width = enc->cx;
 	res.width = enc->cx;
@@ -205,6 +238,12 @@ static const char *hevc_nvenc_get_name(void *type_data)
 }
 }
 #endif
 #endif
 
 
+static const char *av1_nvenc_get_name(void *type_data)
+{
+	UNUSED_PARAMETER(type_data);
+	return "NVIDIA NVENC AV1";
+}
+
 static inline int nv_get_cap(struct nvenc_data *enc, NV_ENC_CAPS cap)
 static inline int nv_get_cap(struct nvenc_data *enc, NV_ENC_CAPS cap)
 {
 {
 	if (!enc->session)
 	if (!enc->session)
@@ -316,7 +355,8 @@ static bool init_session(struct nvenc_data *enc)
 		NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER};
 		NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER};
 	params.device = enc->device;
 	params.device = enc->device;
 	params.deviceType = NV_ENC_DEVICE_TYPE_DIRECTX;
 	params.deviceType = NV_ENC_DEVICE_TYPE_DIRECTX;
-	params.apiVersion = NVENCAPI_VERSION;
+	params.apiVersion = enc->codec == CODEC_AV1 ? NVENCAPI_VERSION
+						    : NVENC_COMPAT_VER;
 
 
 	if (NV_FAILED(nv.nvEncOpenEncodeSessionEx(&params, &enc->session))) {
 	if (NV_FAILED(nv.nvEncOpenEncodeSessionEx(&params, &enc->session))) {
 		return false;
 		return false;
@@ -324,28 +364,28 @@ static bool init_session(struct nvenc_data *enc)
 	return true;
 	return true;
 }
 }
 
 
-static void initialize_params(NV_ENC_INITIALIZE_PARAMS *params,
-			      const GUID *nv_encode, const GUID *nv_preset,
+static void initialize_params(struct nvenc_data *enc, const GUID *nv_preset,
 			      NV_ENC_TUNING_INFO nv_tuning, uint32_t width,
 			      NV_ENC_TUNING_INFO nv_tuning, uint32_t width,
 			      uint32_t height, uint32_t fps_num,
 			      uint32_t height, uint32_t fps_num,
-			      uint32_t fps_den, NV_ENC_CONFIG *config)
+			      uint32_t fps_den)
 {
 {
 	int darWidth, darHeight;
 	int darWidth, darHeight;
 	av_reduce(&darWidth, &darHeight, width, height, 1024 * 1024);
 	av_reduce(&darWidth, &darHeight, width, height, 1024 * 1024);
 
 
+	NV_ENC_INITIALIZE_PARAMS *params = &enc->params;
 	memset(params, 0, sizeof(*params));
 	memset(params, 0, sizeof(*params));
 	params->version = NV_ENC_INITIALIZE_PARAMS_VER;
 	params->version = NV_ENC_INITIALIZE_PARAMS_VER;
-	params->encodeGUID = *nv_encode;
+	params->encodeGUID = enc->codec_guid;
 	params->presetGUID = *nv_preset;
 	params->presetGUID = *nv_preset;
 	params->encodeWidth = width;
 	params->encodeWidth = width;
 	params->encodeHeight = height;
 	params->encodeHeight = height;
-	params->darWidth = darWidth;
-	params->darHeight = darHeight;
+	params->darWidth = enc->codec == CODEC_AV1 ? width : darWidth;
+	params->darHeight = enc->codec == CODEC_AV1 ? height : darHeight;
 	params->frameRateNum = fps_num;
 	params->frameRateNum = fps_num;
 	params->frameRateDen = fps_den;
 	params->frameRateDen = fps_den;
 	params->enableEncodeAsync = 0;
 	params->enableEncodeAsync = 0;
 	params->enablePTD = 1;
 	params->enablePTD = 1;
-	params->encodeConfig = config;
+	params->encodeConfig = &enc->config;
 	params->tuningInfo = nv_tuning;
 	params->tuningInfo = nv_tuning;
 }
 }
 
 
@@ -473,8 +513,12 @@ static bool init_encoder_base(struct nvenc_data *enc, obs_data_t *settings,
 	/* -------------------------- */
 	/* -------------------------- */
 	/* get preset default config  */
 	/* get preset default config  */
 
 
+	uint32_t config_ver = enc->codec == CODEC_AV1
+				      ? NV_ENC_CONFIG_VER
+				      : NV_ENC_CONFIG_COMPAT_VER;
+
 	NV_ENC_PRESET_CONFIG preset_config = {NV_ENC_PRESET_CONFIG_VER,
 	NV_ENC_PRESET_CONFIG preset_config = {NV_ENC_PRESET_CONFIG_VER,
-					      {NV_ENC_CONFIG_VER}};
+					      {config_ver}};
 
 
 	err = nv.nvEncGetEncodePresetConfigEx(enc->session, enc->codec_guid,
 	err = nv.nvEncGetEncodePresetConfigEx(enc->session, enc->codec_guid,
 					      nv_preset, nv_tuning,
 					      nv_preset, nv_tuning,
@@ -494,9 +538,8 @@ static bool init_encoder_base(struct nvenc_data *enc, obs_data_t *settings,
 
 
 	NV_ENC_CONFIG *config = &enc->config;
 	NV_ENC_CONFIG *config = &enc->config;
 
 
-	initialize_params(&enc->params, &enc->codec_guid, &nv_preset, nv_tuning,
-			  voi->width, voi->height, voi->fps_num, voi->fps_den,
-			  &enc->config);
+	initialize_params(enc, &nv_preset, nv_tuning, voi->width, voi->height,
+			  voi->fps_num, voi->fps_den);
 
 
 	config->gopLength = gop_size;
 	config->gopLength = gop_size;
 	config->frameIntervalP = 1 + bf;
 	config->frameIntervalP = 1 + bf;
@@ -561,10 +604,12 @@ static bool init_encoder_base(struct nvenc_data *enc, obs_data_t *settings,
 		if (*lossless)
 		if (*lossless)
 			cqp = 0;
 			cqp = 0;
 
 
+		int cqp_val = enc->codec == CODEC_AV1 ? cqp * 4 : cqp;
+
 		config->rcParams.rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
 		config->rcParams.rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
-		config->rcParams.constQP.qpInterP = cqp;
-		config->rcParams.constQP.qpInterB = cqp;
-		config->rcParams.constQP.qpIntra = cqp;
+		config->rcParams.constQP.qpInterP = cqp_val;
+		config->rcParams.constQP.qpInterB = cqp_val;
+		config->rcParams.constQP.qpIntra = cqp_val;
 		enc->can_change_bitrate = false;
 		enc->can_change_bitrate = false;
 
 
 		bitrate = 0;
 		bitrate = 0;
@@ -790,6 +835,81 @@ static bool init_encoder_hevc(struct nvenc_data *enc, obs_data_t *settings,
 	return true;
 	return true;
 }
 }
 
 
+static bool init_encoder_av1(struct nvenc_data *enc, obs_data_t *settings,
+			     int bf, bool psycho_aq)
+{
+	const char *rc = obs_data_get_string(settings, "rate_control");
+	int keyint_sec = (int)obs_data_get_int(settings, "keyint_sec");
+	bool lossless;
+
+	if (!init_encoder_base(enc, settings, bf, psycho_aq, &lossless)) {
+		return false;
+	}
+
+	NV_ENC_INITIALIZE_PARAMS *params = &enc->params;
+	NV_ENC_CONFIG *config = &enc->config;
+	NV_ENC_CONFIG_AV1 *av1_config = &config->encodeCodecConfig.av1Config;
+
+	video_t *video = obs_encoder_video(enc->encoder);
+	const struct video_output_info *voi = video_output_get_info(video);
+	uint32_t gop_size =
+		(keyint_sec) ? keyint_sec * voi->fps_num / voi->fps_den : 250;
+
+	av1_config->idrPeriod = gop_size;
+
+	av1_config->useBFramesAsRef = NV_ENC_BFRAME_REF_MODE_DISABLED;
+
+	av1_config->colorRange = (voi->range == VIDEO_RANGE_FULL);
+
+	switch (voi->colorspace) {
+	case VIDEO_CS_601:
+		av1_config->colorPrimaries = 6;
+		av1_config->transferCharacteristics = 6;
+		av1_config->matrixCoefficients = 6;
+		break;
+	case VIDEO_CS_DEFAULT:
+	case VIDEO_CS_709:
+		av1_config->colorPrimaries = 1;
+		av1_config->transferCharacteristics = 1;
+		av1_config->matrixCoefficients = 1;
+		break;
+	case VIDEO_CS_SRGB:
+		av1_config->colorPrimaries = 1;
+		av1_config->transferCharacteristics = 13;
+		av1_config->matrixCoefficients = 1;
+		break;
+	case VIDEO_CS_2100_PQ:
+		av1_config->colorPrimaries = 9;
+		av1_config->transferCharacteristics = 16;
+		av1_config->matrixCoefficients = 9;
+		break;
+	case VIDEO_CS_2100_HLG:
+		av1_config->colorPrimaries = 9;
+		av1_config->transferCharacteristics = 18;
+		av1_config->matrixCoefficients = 9;
+	}
+
+	/* -------------------------- */
+	/* profile                    */
+
+	config->profileGUID = NV_ENC_AV1_PROFILE_MAIN_GUID;
+	av1_config->tier = NV_ENC_TIER_AV1_0;
+
+	av1_config->level = NV_ENC_LEVEL_AV1_AUTOSELECT;
+	av1_config->chromaFormatIDC = 1;
+	av1_config->pixelBitDepthMinus8 = obs_p010_tex_active() ? 2 : 0;
+	av1_config->inputPixelBitDepthMinus8 = av1_config->pixelBitDepthMinus8;
+	av1_config->numFwdRefs = 1;
+	av1_config->numBwdRefs = 1;
+	av1_config->repeatSeqHdr = 1;
+
+	if (NV_FAILED(nv.nvEncInitializeEncoder(enc->session, &enc->params))) {
+		return false;
+	}
+
+	return true;
+}
+
 static bool init_bitstreams(struct nvenc_data *enc)
 static bool init_bitstreams(struct nvenc_data *enc)
 {
 {
 	da_reserve(enc->bitstreams, enc->buf_count);
 	da_reserve(enc->bitstreams, enc->buf_count);
@@ -830,6 +950,8 @@ static bool init_specific_encoder(struct nvenc_data *enc, obs_data_t *settings,
 		return init_encoder_hevc(enc, settings, bf, psycho_aq);
 		return init_encoder_hevc(enc, settings, bf, psycho_aq);
 	case CODEC_H264:
 	case CODEC_H264:
 		return init_encoder_h264(enc, settings, bf, psycho_aq);
 		return init_encoder_h264(enc, settings, bf, psycho_aq);
+	case CODEC_AV1:
+		return init_encoder_av1(enc, settings, bf, psycho_aq);
 	}
 	}
 
 
 	return false;
 	return false;
@@ -893,12 +1015,13 @@ static bool init_encoder(struct nvenc_data *enc, enum codec_type codec,
 static void *nvenc_create_internal(enum codec_type codec, obs_data_t *settings,
 static void *nvenc_create_internal(enum codec_type codec, obs_data_t *settings,
 				   obs_encoder_t *encoder)
 				   obs_encoder_t *encoder)
 {
 {
-	NV_ENCODE_API_FUNCTION_LIST init = {NV_ENCODE_API_FUNCTION_LIST_VER};
 	struct nvenc_data *enc = bzalloc(sizeof(*enc));
 	struct nvenc_data *enc = bzalloc(sizeof(*enc));
 	enc->encoder = encoder;
 	enc->encoder = encoder;
 	enc->codec = codec;
 	enc->codec = codec;
 	enc->first_packet = true;
 	enc->first_packet = true;
 
 
+	NV_ENCODE_API_FUNCTION_LIST init = {NV_ENCODE_API_FUNCTION_LIST_VER};
+
 	switch (enc->codec) {
 	switch (enc->codec) {
 	case CODEC_H264:
 	case CODEC_H264:
 		enc->codec_guid = NV_ENC_CODEC_H264_GUID;
 		enc->codec_guid = NV_ENC_CODEC_H264_GUID;
@@ -906,6 +1029,9 @@ static void *nvenc_create_internal(enum codec_type codec, obs_data_t *settings,
 	case CODEC_HEVC:
 	case CODEC_HEVC:
 		enc->codec_guid = NV_ENC_CODEC_HEVC_GUID;
 		enc->codec_guid = NV_ENC_CODEC_HEVC_GUID;
 		break;
 		break;
+	case CODEC_AV1:
+		enc->codec_guid = NV_ENC_CODEC_AV1_GUID;
+		break;
 	}
 	}
 
 
 	if (!init_nvenc(encoder)) {
 	if (!init_nvenc(encoder)) {
@@ -995,6 +1121,11 @@ static void *hevc_nvenc_create(obs_data_t *settings, obs_encoder_t *encoder)
 }
 }
 #endif
 #endif
 
 
+static void *av1_nvenc_create(obs_data_t *settings, obs_encoder_t *encoder)
+{
+	return nvenc_create_base(CODEC_AV1, settings, encoder);
+}
+
 static bool get_encoded_packet(struct nvenc_data *enc, bool finalize);
 static bool get_encoded_packet(struct nvenc_data *enc, bool finalize);
 
 
 static void nvenc_destroy(void *data)
 static void nvenc_destroy(void *data)
@@ -1004,7 +1135,10 @@ static void nvenc_destroy(void *data)
 	if (enc->encode_started) {
 	if (enc->encode_started) {
 		size_t next_bitstream = enc->next_bitstream;
 		size_t next_bitstream = enc->next_bitstream;
 
 
-		NV_ENC_PIC_PARAMS params = {NV_ENC_PIC_PARAMS_VER};
+		uint32_t struct_ver = enc->codec == CODEC_AV1
+					      ? NV_ENC_PIC_PARAMS_VER
+					      : NV_ENC_PIC_PARAMS_COMPAT_VER;
+		NV_ENC_PIC_PARAMS params = {struct_ver};
 		params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
 		params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
 		nv.nvEncEncodePicture(enc->session, &params);
 		nv.nvEncEncodePicture(enc->session, &params);
 		get_encoded_packet(enc, true);
 		get_encoded_packet(enc, true);
@@ -1105,7 +1239,12 @@ static bool get_encoded_packet(struct nvenc_data *enc, bool finalize)
 
 
 		/* ---------------- */
 		/* ---------------- */
 
 
-		NV_ENC_LOCK_BITSTREAM lock = {NV_ENC_LOCK_BITSTREAM_VER};
+		uint32_t struct_ver =
+			enc->codec == CODEC_AV1
+				? NV_ENC_LOCK_BITSTREAM_VER
+				: NV_ENC_LOCK_BITSTREAM_COMPAT_VER;
+
+		NV_ENC_LOCK_BITSTREAM lock = {struct_ver};
 		lock.outputBitstream = bs->ptr;
 		lock.outputBitstream = bs->ptr;
 		lock.doNotWait = false;
 		lock.doNotWait = false;
 
 
@@ -1221,7 +1360,8 @@ static bool nvenc_encode_tex(void *data, uint32_t handle, int64_t pts,
 	/* do actual encode call                */
 	/* do actual encode call                */
 
 
 	NV_ENC_PIC_PARAMS params = {0};
 	NV_ENC_PIC_PARAMS params = {0};
-	params.version = NV_ENC_PIC_PARAMS_VER;
+	params.version = enc->codec == CODEC_AV1 ? NV_ENC_PIC_PARAMS_VER
+						 : NV_ENC_PIC_PARAMS_COMPAT_VER;
 	params.pictureStruct = NV_ENC_PIC_STRUCT_FRAME;
 	params.pictureStruct = NV_ENC_PIC_STRUCT_FRAME;
 	params.inputBuffer = nvtex->mapped_res;
 	params.inputBuffer = nvtex->mapped_res;
 	params.bufferFmt = obs_p010_tex_active()
 	params.bufferFmt = obs_p010_tex_active()
@@ -1284,6 +1424,8 @@ extern obs_properties_t *h264_nvenc_properties(void *unused);
 extern void hevc_nvenc_defaults(obs_data_t *settings);
 extern void hevc_nvenc_defaults(obs_data_t *settings);
 extern obs_properties_t *hevc_nvenc_properties(void *unused);
 extern obs_properties_t *hevc_nvenc_properties(void *unused);
 #endif
 #endif
+extern obs_properties_t *av1_nvenc_properties(void *unused);
+extern void av1_nvenc_defaults(obs_data_t *settings);
 
 
 static bool nvenc_extra_data(void *data, uint8_t **header, size_t *size)
 static bool nvenc_extra_data(void *data, uint8_t **header, size_t *size)
 {
 {
@@ -1344,3 +1486,18 @@ struct obs_encoder_info hevc_nvenc_info = {
 	.get_sei_data = nvenc_sei_data,
 	.get_sei_data = nvenc_sei_data,
 };
 };
 #endif
 #endif
+
+struct obs_encoder_info av1_nvenc_info = {
+	.id = "jim_av1_nvenc",
+	.codec = "av1",
+	.type = OBS_ENCODER_VIDEO,
+	.caps = OBS_ENCODER_CAP_PASS_TEXTURE | OBS_ENCODER_CAP_DYN_BITRATE,
+	.get_name = av1_nvenc_get_name,
+	.create = av1_nvenc_create,
+	.destroy = nvenc_destroy,
+	.update = nvenc_update,
+	.encode_texture = nvenc_encode_tex,
+	.get_defaults = av1_nvenc_defaults,
+	.get_properties = av1_nvenc_properties,
+	.get_extra_data = nvenc_extra_data,
+};

+ 1 - 0
plugins/obs-ffmpeg/jim-nvenc.h

@@ -5,6 +5,7 @@
 
 
 #include <obs-module.h>
 #include <obs-module.h>
 #include "external/nvEncodeAPI.h"
 #include "external/nvEncodeAPI.h"
+#include "jim-nvenc-ver.h"
 
 
 typedef NVENCSTATUS(NVENCAPI *NV_CREATE_INSTANCE_FUNC)(
 typedef NVENCSTATUS(NVENCAPI *NV_CREATE_INSTANCE_FUNC)(
 	NV_ENCODE_API_FUNCTION_LIST *);
 	NV_ENCODE_API_FUNCTION_LIST *);

+ 16 - 2
plugins/obs-ffmpeg/obs-ffmpeg-nvenc.c

@@ -408,6 +408,7 @@ static bool nvenc_encode(void *data, struct encoder_frame *frame,
 enum codec_type {
 enum codec_type {
 	CODEC_H264,
 	CODEC_H264,
 	CODEC_HEVC,
 	CODEC_HEVC,
+	CODEC_AV1,
 };
 };
 
 
 static void nvenc_defaults_base(enum codec_type codec, obs_data_t *settings)
 static void nvenc_defaults_base(enum codec_type codec, obs_data_t *settings)
@@ -421,7 +422,7 @@ static void nvenc_defaults_base(enum codec_type codec, obs_data_t *settings)
 	obs_data_set_default_string(settings, "multipass", "qres");
 	obs_data_set_default_string(settings, "multipass", "qres");
 	obs_data_set_default_string(settings, "tune", "hq");
 	obs_data_set_default_string(settings, "tune", "hq");
 	obs_data_set_default_string(settings, "profile",
 	obs_data_set_default_string(settings, "profile",
-				    codec == CODEC_HEVC ? "main" : "high");
+				    codec != CODEC_H264 ? "main" : "high");
 	obs_data_set_default_bool(settings, "psycho_aq", true);
 	obs_data_set_default_bool(settings, "psycho_aq", true);
 	obs_data_set_default_int(settings, "gpu", 0);
 	obs_data_set_default_int(settings, "gpu", 0);
 	obs_data_set_default_int(settings, "bf", 2);
 	obs_data_set_default_int(settings, "bf", 2);
@@ -438,6 +439,11 @@ void hevc_nvenc_defaults(obs_data_t *settings)
 	nvenc_defaults_base(CODEC_HEVC, settings);
 	nvenc_defaults_base(CODEC_HEVC, settings);
 }
 }
 
 
+void av1_nvenc_defaults(obs_data_t *settings)
+{
+	nvenc_defaults_base(CODEC_AV1, settings);
+}
+
 static bool rate_control_modified(obs_properties_t *ppts, obs_property_t *p,
 static bool rate_control_modified(obs_properties_t *ppts, obs_property_t *p,
 				  obs_data_t *settings)
 				  obs_data_t *settings)
 {
 {
@@ -486,7 +492,7 @@ obs_properties_t *nvenc_properties_internal(enum codec_type codec, bool ffmpeg)
 	obs_property_int_set_suffix(p, " Kbps");
 	obs_property_int_set_suffix(p, " Kbps");
 
 
 	obs_properties_add_int(props, "cqp", obs_module_text("NVENC.CQLevel"),
 	obs_properties_add_int(props, "cqp", obs_module_text("NVENC.CQLevel"),
-			       1, 51, 1);
+			       1, codec == CODEC_AV1 ? 63 : 51, 1);
 
 
 	p = obs_properties_add_int(props, "keyint_sec",
 	p = obs_properties_add_int(props, "keyint_sec",
 				   obs_module_text("KeyframeIntervalSec"), 0,
 				   obs_module_text("KeyframeIntervalSec"), 0,
@@ -543,6 +549,8 @@ obs_properties_t *nvenc_properties_internal(enum codec_type codec, bool ffmpeg)
 	if (codec == CODEC_HEVC) {
 	if (codec == CODEC_HEVC) {
 		add_profile("main10");
 		add_profile("main10");
 		add_profile("main");
 		add_profile("main");
+	} else if (codec == CODEC_AV1) {
+		add_profile("main");
 	} else {
 	} else {
 		add_profile("high");
 		add_profile("high");
 		add_profile("main");
 		add_profile("main");
@@ -587,6 +595,12 @@ obs_properties_t *hevc_nvenc_properties(void *unused)
 }
 }
 #endif
 #endif
 
 
+obs_properties_t *av1_nvenc_properties(void *unused)
+{
+	UNUSED_PARAMETER(unused);
+	return nvenc_properties_internal(CODEC_AV1, false);
+}
+
 obs_properties_t *h264_nvenc_properties_ffmpeg(void *unused)
 obs_properties_t *h264_nvenc_properties_ffmpeg(void *unused)
 {
 {
 	UNUSED_PARAMETER(unused);
 	UNUSED_PARAMETER(unused);

+ 13 - 4
plugins/obs-ffmpeg/obs-ffmpeg.c

@@ -10,6 +10,8 @@
 #include <dxgi.h>
 #include <dxgi.h>
 #include <util/dstr.h>
 #include <util/dstr.h>
 #include <util/windows/win-version.h>
 #include <util/windows/win-version.h>
+
+#include "jim-nvenc.h"
 #endif
 #endif
 
 
 OBS_DECLARE_MODULE()
 OBS_DECLARE_MODULE()
@@ -226,6 +228,7 @@ static bool nvenc_device_available(void)
 
 
 #ifdef _WIN32
 #ifdef _WIN32
 extern bool load_nvenc_lib(void);
 extern bool load_nvenc_lib(void);
+extern uint32_t get_nvenc_ver();
 #endif
 #endif
 
 
 static bool nvenc_codec_exists(const char *name, const char *fallback)
 static bool nvenc_codec_exists(const char *name, const char *fallback)
@@ -237,7 +240,7 @@ static bool nvenc_codec_exists(const char *name, const char *fallback)
 	return nvenc != NULL;
 	return nvenc != NULL;
 }
 }
 
 
-static bool nvenc_supported(bool *out_h264, bool *out_hevc)
+static bool nvenc_supported(bool *out_h264, bool *out_hevc, bool *out_av1)
 {
 {
 	profile_start(nvenc_check_name);
 	profile_start(nvenc_check_name);
 
 
@@ -252,10 +255,14 @@ static bool nvenc_supported(bool *out_h264, bool *out_hevc)
 	const bool hevc = false;
 	const bool hevc = false;
 #endif
 #endif
 
 
+	bool av1 = false;
+
 	bool success = h264 || hevc;
 	bool success = h264 || hevc;
 	if (success) {
 	if (success) {
 #if defined(_WIN32)
 #if defined(_WIN32)
 		success = nvenc_device_available() && load_nvenc_lib();
 		success = nvenc_device_available() && load_nvenc_lib();
+		av1 = success && (get_nvenc_ver() >= ((12 << 4) | 0));
+
 #elif defined(__linux__)
 #elif defined(__linux__)
 		success = nvenc_device_available();
 		success = nvenc_device_available();
 		if (success) {
 		if (success) {
@@ -274,6 +281,7 @@ static bool nvenc_supported(bool *out_h264, bool *out_hevc)
 		if (success) {
 		if (success) {
 			*out_h264 = h264;
 			*out_h264 = h264;
 			*out_hevc = hevc;
 			*out_hevc = hevc;
+			*out_av1 = av1;
 		}
 		}
 	}
 	}
 
 
@@ -292,7 +300,7 @@ static bool vaapi_supported(void)
 #endif
 #endif
 
 
 #ifdef _WIN32
 #ifdef _WIN32
-extern void jim_nvenc_load(bool h264, bool hevc);
+extern void jim_nvenc_load(bool h264, bool hevc, bool av1);
 extern void jim_nvenc_unload(void);
 extern void jim_nvenc_unload(void);
 extern void amf_load(void);
 extern void amf_load(void);
 extern void amf_unload(void);
 extern void amf_unload(void);
@@ -327,11 +335,12 @@ bool obs_module_load(void)
 #ifndef __APPLE__
 #ifndef __APPLE__
 	bool h264 = false;
 	bool h264 = false;
 	bool hevc = false;
 	bool hevc = false;
-	if (nvenc_supported(&h264, &hevc)) {
+	bool av1 = false;
+	if (nvenc_supported(&h264, &hevc, &av1)) {
 		blog(LOG_INFO, "NVENC supported");
 		blog(LOG_INFO, "NVENC supported");
 #ifdef _WIN32
 #ifdef _WIN32
 		if (get_win_ver_int() > 0x0601) {
 		if (get_win_ver_int() > 0x0601) {
-			jim_nvenc_load(h264, hevc);
+			jim_nvenc_load(h264, hevc, av1);
 		} else {
 		} else {
 			// if on Win 7, new nvenc isn't available so there's
 			// if on Win 7, new nvenc isn't available so there's
 			// no nvenc encoder for the user to select, expose
 			// no nvenc encoder for the user to select, expose

+ 9 - 0
plugins/obs-ffmpeg/obs-nvenc-test/CMakeLists.txt

@@ -0,0 +1,9 @@
+project(obs-nvenc-test)
+
+add_executable(obs-nvenc-test)
+target_sources(obs-nvenc-test PRIVATE jim-nvenc-test.c ../jim-nvenc-ver.h)
+target_link_libraries(obs-nvenc-test d3d11 dxgi dxguid)
+
+set_target_properties(obs-nvenc-test PROPERTIES FOLDER "plugins/obs-ffmpeg")
+
+setup_binary_target(obs-nvenc-test)

+ 215 - 0
plugins/obs-ffmpeg/obs-nvenc-test/jim-nvenc-test.c

@@ -0,0 +1,215 @@
+#include <stdbool.h>
+#include <stdio.h>
+
+#include "../external/nvEncodeAPI.h"
+#include "../jim-nvenc-ver.h"
+
+#include <dxgi.h>
+#include <d3d11.h>
+#include <d3d11_1.h>
+
+__declspec(dllexport) DWORD NvOptimusEnablement = 1;
+NV_ENCODE_API_FUNCTION_LIST nv = {NV_ENCODE_API_FUNCTION_LIST_VER};
+static void *nvenc_lib = NULL;
+static bool av1_supported = false;
+
+#define NVIDIA_VENDOR_ID 0x10DE
+
+struct nvenc_info {
+	bool is_nvidia;
+	bool supports_av1;
+};
+
+#define MAX_CAPS 10
+static struct nvenc_info adapter_info[MAX_CAPS] = {0};
+
+bool load_nvenc_lib(void)
+{
+	const char *const file = (sizeof(void *) == 8) ? "nvEncodeAPI64.dll"
+						       : "nvEncodeAPI.dll";
+	nvenc_lib = LoadLibraryA(file);
+	return nvenc_lib != NULL;
+}
+
+static inline void *load_nv_func(const char *func)
+{
+	void *func_ptr = (void *)GetProcAddress(nvenc_lib, func);
+	return func_ptr;
+}
+
+static bool get_adapter_caps(IDXGIFactory *factory, uint32_t adapter_idx)
+{
+	struct nvenc_info *caps = &adapter_info[adapter_idx];
+	IDXGIAdapter *adapter = NULL;
+	IDXGIOutput *output = NULL;
+	ID3D11Device *device = NULL;
+	ID3D11DeviceContext *context = NULL;
+	GUID *guids = NULL;
+	void *session = NULL;
+	HRESULT hr;
+
+	if (adapter_idx == MAX_CAPS)
+		return false;
+
+	hr = factory->lpVtbl->EnumAdapters(factory, adapter_idx, &adapter);
+	if (FAILED(hr))
+		return false;
+
+	DXGI_ADAPTER_DESC desc;
+	adapter->lpVtbl->GetDesc(adapter, &desc);
+
+	if (desc.VendorId != NVIDIA_VENDOR_ID)
+		return true;
+
+	caps->is_nvidia = true;
+
+	hr = adapter->lpVtbl->EnumOutputs(adapter, 0, &output);
+	if (FAILED(hr))
+		goto finish;
+
+	hr = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, NULL, 0, NULL,
+			       0, D3D11_SDK_VERSION, &device, NULL, &context);
+	if (FAILED(hr))
+		goto finish;
+
+	/* ---------------------------------------------------------------- */
+
+	NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS params = {
+		NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER};
+	params.device = device;
+	params.deviceType = NV_ENC_DEVICE_TYPE_DIRECTX;
+	params.apiVersion = NVENCAPI_VERSION;
+
+	NVENCSTATUS stat = nv.nvEncOpenEncodeSessionEx(&params, &session);
+	if (stat != NV_ENC_SUCCESS)
+		goto finish;
+
+	uint32_t guid_count = 0;
+	if (nv.nvEncGetEncodeGUIDCount(session, &guid_count) != NV_ENC_SUCCESS)
+		goto finish;
+
+	guids = malloc(guid_count * sizeof(GUID));
+	stat = nv.nvEncGetEncodeGUIDs(session, guids, guid_count, &guid_count);
+	if (stat != NV_ENC_SUCCESS)
+		goto finish;
+
+	for (uint32_t i = 0; i < guid_count; i++) {
+		GUID *guid = &guids[i];
+
+		if (memcmp(guid, &NV_ENC_CODEC_AV1_GUID, sizeof(GUID)) == 0) {
+			caps->supports_av1 = true;
+			break;
+		}
+	}
+
+finish:
+	if (guids)
+		free(guids);
+	if (session)
+		nv.nvEncDestroyEncoder(session);
+	if (context)
+		context->lpVtbl->Release(context);
+	if (device)
+		device->lpVtbl->Release(device);
+	if (output)
+		output->lpVtbl->Release(output);
+	if (adapter)
+		adapter->lpVtbl->Release(adapter);
+	return true;
+}
+
+typedef NVENCSTATUS(NVENCAPI *NV_MAX_VER_FUNC)(uint32_t *);
+typedef NVENCSTATUS(NVENCAPI *NV_CREATE_INSTANCE_FUNC)(
+	NV_ENCODE_API_FUNCTION_LIST *);
+
+static inline uint32_t get_nvenc_ver(void)
+{
+	NV_MAX_VER_FUNC nv_max_ver = (NV_MAX_VER_FUNC)load_nv_func(
+		"NvEncodeAPIGetMaxSupportedVersion");
+	if (!nv_max_ver) {
+		return 0;
+	}
+
+	uint32_t ver = 0;
+	if (nv_max_ver(&ver) != NV_ENC_SUCCESS) {
+		return 0;
+	}
+	return ver;
+}
+
+static inline bool init_nvenc_internal(void)
+{
+	if (!load_nvenc_lib())
+		return false;
+
+	uint32_t ver = get_nvenc_ver();
+	if (ver == 0)
+		return false;
+
+	uint32_t supported_ver = (NVENC_COMPAT_MAJOR_VER << 4) |
+				 NVENC_COMPAT_MINOR_VER;
+	if (supported_ver > ver)
+		return false;
+
+	NV_CREATE_INSTANCE_FUNC nv_create_instance =
+		(NV_CREATE_INSTANCE_FUNC)load_nv_func(
+			"NvEncodeAPICreateInstance");
+	if (!nv_create_instance)
+		return false;
+
+	return nv_create_instance(&nv) == NV_ENC_SUCCESS;
+}
+
+DWORD WINAPI TimeoutThread(LPVOID param)
+{
+	HANDLE hMainThread = (HANDLE)param;
+
+	DWORD ret = WaitForSingleObject(hMainThread, 2500);
+	if (ret == WAIT_TIMEOUT)
+		TerminateProcess(GetCurrentProcess(), STATUS_TIMEOUT);
+
+	CloseHandle(hMainThread);
+	return 0;
+}
+
+int main(void)
+{
+	IDXGIFactory *factory = NULL;
+	HRESULT hr;
+
+	HANDLE hMainThread;
+	DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
+			GetCurrentProcess(), &hMainThread, 0, FALSE,
+			DUPLICATE_SAME_ACCESS);
+	DWORD threadId;
+	HANDLE hThread;
+	hThread =
+		CreateThread(NULL, 0, TimeoutThread, hMainThread, 0, &threadId);
+	CloseHandle(hThread);
+
+	/* --------------------------------------------------------- */
+	/* try initializing nvenc, I guess                           */
+
+	if (!init_nvenc_internal())
+		return 0;
+
+	hr = CreateDXGIFactory1(&IID_IDXGIFactory1, (void **)&factory);
+	if (FAILED(hr))
+		return 0;
+
+	uint32_t idx = 0;
+	while (get_adapter_caps(factory, idx++))
+		;
+
+	for (uint32_t i = 0; i < idx; i++) {
+		struct nvenc_info caps = adapter_info[i];
+
+		printf("[%u]\n", i);
+		printf("is_nvidia=%s\n", caps.is_nvidia ? "true" : "false");
+		printf("supports_av1=%s\n",
+		       caps.supports_av1 ? "true" : "false");
+	}
+
+	factory->lpVtbl->Release(factory);
+	return 0;
+}