#pragma once #include #include #include #include #include namespace nvenc::api { constexpr uint32_t make_api_version(uint32_t major, uint32_t minor) { return major | (minor << 24); } constexpr uint32_t compiled_api_version = make_api_version(NVENCAPI_MAJOR_VERSION, NVENCAPI_MINOR_VERSION); // NvEncodeAPIGetMaxSupportedVersion() uses a distinct packed representation: // the low nibble is the minor version and all higher bits are the major. constexpr uint32_t driver_max_to_api_version(uint32_t driver_max_version) { return make_api_version(driver_max_version >> 4, driver_max_version & 0xFu); } constexpr uint32_t api_version_major(uint32_t api_version) { return api_version & 0xFFu; } constexpr uint32_t api_version_minor(uint32_t api_version) { return (api_version >> 24) & 0xFFu; } constexpr int compare_api_versions(uint32_t lhs, uint32_t rhs) { if (api_version_major(lhs) < api_version_major(rhs)) { return -1; } if (api_version_major(lhs) > api_version_major(rhs)) { return 1; } if (api_version_minor(lhs) < api_version_minor(rhs)) { return -1; } if (api_version_minor(lhs) > api_version_minor(rhs)) { return 1; } return 0; } constexpr bool api_version_less(uint32_t lhs, uint32_t rhs) { return compare_api_versions(lhs, rhs) < 0; } constexpr bool api_version_less_or_equal(uint32_t lhs, uint32_t rhs) { return compare_api_versions(lhs, rhs) <= 0; } constexpr bool api_version_greater(uint32_t lhs, uint32_t rhs) { return compare_api_versions(lhs, rhs) > 0; } constexpr bool driver_supports_api_version(uint32_t max_driver_api_version, uint32_t api_version) { return api_version_less_or_equal(api_version, max_driver_api_version); } constexpr bool is_reviewed_api_version(uint32_t api_version) { switch (api_version) { case make_api_version(11U, 0U): case make_api_version(12U, 0U): case make_api_version(12U, 1U): case make_api_version(12U, 2U): case make_api_version(13U, 0U): return true; default: return false; } } constexpr uint32_t make_struct_version(uint32_t api_version, uint32_t struct_version, bool extended = false) { return api_version | (struct_version << 16) | (0x7u << 28) | (extended ? (1u << 31) : 0u); } inline std::string version_string(uint32_t api_version) { return std::to_string(api_version_major(api_version)) + "." + std::to_string(api_version_minor(api_version)); } inline std::vector filter_to_api_version(std::vector candidates, uint32_t max_api_version) { auto it = std::remove_if(candidates.begin(), candidates.end(), [max_api_version](uint32_t candidate) { return api_version_greater(candidate, max_api_version); }); candidates.erase(it, candidates.end()); return candidates; } inline std::vector filter_to_compiled(std::vector candidates) { return filter_to_api_version(std::move(candidates), compiled_api_version); } inline std::vector h264_api_candidates() { return filter_to_compiled({ make_api_version(13U, 0U), make_api_version(12U, 2U), make_api_version(12U, 1U), make_api_version(12U, 0U), make_api_version(11U, 0U), }); } inline std::vector codec_api_candidates(int video_format) { switch (video_format) { case 0: return h264_api_candidates(); case 1: return h264_api_candidates(); case 2: return filter_to_compiled({ make_api_version(13U, 0U), make_api_version(12U, 2U), make_api_version(12U, 1U), }); default: return {}; } } constexpr bool supports_implicit_split_frame(uint32_t api_version) { switch (api_version) { case make_api_version(12U, 1U): case make_api_version(12U, 2U): case make_api_version(13U, 0U): return true; default: return false; } } constexpr bool supports_separate_bit_depth_fields(uint32_t api_version) { switch (api_version) { case make_api_version(12U, 2U): case make_api_version(13U, 0U): return true; default: return false; } } // Native MaxCLL/mastering-display insertion was added in Video Codec SDK 13.0. // Earlier API revisions use these config bits and picture pointers as reserved fields. constexpr bool supports_hdr10_metadata(uint32_t api_version) { return !api_version_less(api_version, make_api_version(13U, 0U)); } // Struct revisions below must match the NV_ENC_*_VER macros in each SDK's // nvEncodeAPI.h (ffnvcodec sdk/ branches). Drivers dispatch struct // layout by revision, so an understated revision makes the driver read the // older layout: SDK 12.2 already uses the 13.0-era revisions, including the // separate input/output bit-depth fields (10-bit silently breaks otherwise). constexpr uint32_t function_list_version(uint32_t api_version) { return make_struct_version(api_version, 2U); } constexpr uint32_t open_encode_session_ex_params_version(uint32_t api_version) { return make_struct_version(api_version, 1U); } constexpr uint32_t caps_param_version(uint32_t api_version) { return make_struct_version(api_version, 1U); } constexpr uint32_t initialize_params_version(uint32_t api_version) { switch (api_version) { case make_api_version(11U, 0U): case make_api_version(12U, 0U): return make_struct_version(api_version, 5U, true); case make_api_version(12U, 1U): return make_struct_version(api_version, 6U, true); case make_api_version(12U, 2U): case make_api_version(13U, 0U): return make_struct_version(api_version, 7U, true); default: return 0; } } constexpr uint32_t config_version(uint32_t api_version) { switch (api_version) { case make_api_version(11U, 0U): return make_struct_version(api_version, 7U, true); case make_api_version(12U, 0U): case make_api_version(12U, 1U): return make_struct_version(api_version, 8U, true); case make_api_version(12U, 2U): case make_api_version(13U, 0U): return make_struct_version(api_version, 9U, true); default: return 0; } } constexpr uint32_t preset_config_version(uint32_t api_version) { switch (api_version) { case make_api_version(11U, 0U): case make_api_version(12U, 0U): case make_api_version(12U, 1U): return make_struct_version(api_version, 4U, true); case make_api_version(12U, 2U): case make_api_version(13U, 0U): return make_struct_version(api_version, 5U, true); default: return 0; } } constexpr uint32_t reconfigure_params_version(uint32_t api_version) { switch (api_version) { case make_api_version(11U, 0U): case make_api_version(12U, 0U): case make_api_version(12U, 1U): return make_struct_version(api_version, 1U, true); case make_api_version(12U, 2U): case make_api_version(13U, 0U): return make_struct_version(api_version, 2U, true); default: return 0; } } constexpr uint32_t create_bitstream_buffer_version(uint32_t api_version) { return make_struct_version(api_version, 1U); } constexpr uint32_t event_params_version(uint32_t api_version) { switch (api_version) { case make_api_version(12U, 2U): case make_api_version(13U, 0U): return make_struct_version(api_version, 2U); default: return make_struct_version(api_version, 1U); } } constexpr uint32_t map_input_resource_version(uint32_t api_version) { return make_struct_version(api_version, 4U); } constexpr uint32_t pic_params_version(uint32_t api_version) { switch (api_version) { case make_api_version(11U, 0U): return make_struct_version(api_version, 4U, true); case make_api_version(12U, 0U): case make_api_version(12U, 1U): return make_struct_version(api_version, 6U, true); case make_api_version(12U, 2U): case make_api_version(13U, 0U): return make_struct_version(api_version, 7U, true); default: return 0; } } constexpr uint32_t lock_bitstream_version(uint32_t api_version) { switch (api_version) { case make_api_version(11U, 0U): return make_struct_version(api_version, 1U); case make_api_version(12U, 0U): return make_struct_version(api_version, 2U); case make_api_version(12U, 1U): return make_struct_version(api_version, 1U, true); case make_api_version(12U, 2U): case make_api_version(13U, 0U): return make_struct_version(api_version, 2U, true); default: return 0; } } constexpr uint32_t register_resource_version(uint32_t api_version) { switch (api_version) { case make_api_version(11U, 0U): return make_struct_version(api_version, 3U); case make_api_version(12U, 0U): case make_api_version(12U, 1U): return make_struct_version(api_version, 4U); case make_api_version(12U, 2U): case make_api_version(13U, 0U): return make_struct_version(api_version, 5U); default: return 0; } } } // namespace nvenc::api