diff --git a/alvr/dashboard/js/app/monitor.js b/alvr/dashboard/js/app/monitor.js
index 4d18bf8635..3accebdd70 100644
--- a/alvr/dashboard/js/app/monitor.js
+++ b/alvr/dashboard/js/app/monitor.js
@@ -892,42 +892,6 @@ define([
}
function updateStatistics(statistics) {
- clearTimeout(timeoutHandler);
- // $("#connectionCard").hide();
- // $("#statisticsCard").show();
- if (!clientConnected) {
- clientConnected = true;
- // hide connection
- if ($("#connectionTab").hasClass("active"))
- $("#connectionTab").removeClass("active");
- if ($("#connection").hasClass("active")) $("#connection").removeClass("active");
- // show statistics
- if (!$("#statisticsTab").hasClass("active")) $("#statisticsTab").addClass("active");
- if (!$("#statistics").hasClass("active")) $("#statistics").addClass("active");
- if (!$("#statistics").hasClass("show")) $("#statistics").addClass("show");
- // hide logging
- if ($("#loggingTab").hasClass("active")) $("#loggingTab").removeClass("active");
- if ($("#logging").hasClass("active")) $("#logging").removeClass("active");
- if ($("#logging").hasClass("show")) $("#logging").removeClass("show");
- }
- timeoutHandler = setTimeout(() => {
- // $("#connectionCard").show();
- // $("#statisticsCard").hide();
- clientConnected = false;
- // show connection
- if (!$("#connectionTab").hasClass("active")) $("#connectionTab").addClass("active");
- if (!$("#connection").hasClass("active")) $("#connection").addClass("active");
- // hide statistics
- if ($("#statisticsTab").hasClass("active"))
- $("#statisticsTab").removeClass("active");
- if ($("#statistics").hasClass("active")) $("#statistics").removeClass("active");
- if ($("#statistics").hasClass("show")) $("#statistics").removeClass("show");
- // hide logging
- if ($("#loggingTab").hasClass("active")) $("#loggingTab").removeClass("active");
- if ($("#logging").hasClass("active")) $("#logging").removeClass("active");
- if ($("#logging").hasClass("show")) $("#logging").removeClass("show");
- }, 2000);
-
for (const stat in statistics) {
$("#statistic_" + stat).text(statistics[stat]);
}
diff --git a/alvr/dashboard/js/app/nls/settings.js b/alvr/dashboard/js/app/nls/settings.js
index 8d2af8463f..3fac9100cc 100644
--- a/alvr/dashboard/js/app/nls/settings.js
+++ b/alvr/dashboard/js/app/nls/settings.js
@@ -68,12 +68,47 @@ define({
"HEVC is preferred to achieve better visual quality on lower bitrates. AMD video cards work best with HEVC.",
"_root_video_codec_H264-choice-.name": "h264",
"_root_video_codec_HEVC-choice-.name": "HEVC (h265)",
+ "_root_video_colorRange-choice-.name": "Color Range",
+ "_root_video_colorRange-choice-.description":
+ "Controls how colors are processed when converting between different color systems. Full Range uses all available colors for richer, more detailed images, while Limited Range adjusts the colors to match common video standards.",
"_root_video_clientRequestRealtimeDecoder.name":
"Request realtime decoder priority (client)", // adv
"_root_video_use10bitEncoder.name":
"Reduce color banding (newer nVidia cards or SW encoding only)",
"_root_video_use10bitEncoder.description":
- "This increases visual quality by streaming 10 bit per color channel instead of 8",
+ "This increases visual quality by streaming 10 bits per color channel instead of 8. Works on all supported platforms except nvidia on linux.",
+ "_root_video_rateControlMode-choice-.name":
+ "Rate control mode",
+ "_root_video_rateControlMode-choice-.description":
+ "Specifies the bitrate control method (Windows with AMD and nVidia cards only). CBR - constant bitrate, VBR - variable bitrate.",
+ "_root_video_rateControlMode_cbr-choice-.name": "CBR",
+ "_root_video_rateControlMode_vbr-choice-.name": "VBR",
+ "_root_video_entropyCoding-choice-.name": "Entropy coding method",
+ "_root_video_entropyCoding-choice-.description":
+ "Specifies the entropy coding method (h264 only). CABAC - provides better quality at lower bitrate, but may increase the encoder/decoder latency, CAVLC - provides worse quality that can be compensated with higher bitrate, and may significantly decrease encoder/decoder latency.",
+ "_root_video_entropyCoding_cabac-choice-.name": "CABAC",
+ "_root_video_entropyCoding_cavlc-choice-.name": "CAVLC",
+ "_root_video_advancedCodecOptions_amfControls_enableVbaq.name":
+ "Enable VBAQ",
+ "_root_video_advancedCodecOptions_amfControls_enableVbaq.description":
+ "Enables Variance Based Adaptive Quantization (VBAQ) that allocates more bits to smooth areas (gradients, solid colors), but picture details may suffer from compression artifacts.",
+ "_root_video_advancedCodecOptions_amfControls_usePreproc.name":
+ "Enable Pre-Processor component",
+ "_root_video_advancedCodecOptions_amfControls_usePreproc.description":
+ "Enables Pre-Processor component (RX 5000+ models with 8-bit encoding only). Removing bit-expensive high frequency details that are deemed not important for the human visual system.",
+ "_root_video_advancedCodecOptions_amfControls_preprocSigma.name": "Pre-Processor strength",
+ "_root_video_advancedCodecOptions_amfControls_preprocSigma.description":
+ "Strength of the pre-processing filter. The higher the strength, the stronger the filtering.",
+ "_root_video_advancedCodecOptions_amfControls_preprocTor.name": "Pre-Processor sensitivity",
+ "_root_video_advancedCodecOptions_amfControls_preprocTor.description":
+ "Sensitivity to edges. The higher the value, the more likely edges will be detected, and hence the less likely filtering will occur.",
+ "_root_video_advancedCodecOptions_amfControls_encoderQualityPreset.name":
+ "Encoder quality preset",
+ "_root_video_advancedCodecOptions_amfControls_encoderQualityPreset.description":
+ "Controls the encoder quality.",
+ "_root_video_forceSwEncoding.name": "Force Software Encoding",
+ "_root_video_forceSwEncoding.description":
+ "This forces the Encoder to use CPU(Software Encoding) instead of GPU(Hardware Encoding).",
"_root_video_swThreadCount.name": "Number of threads (software encoding)",
"_root_video_swThreadCount.description":
"Sets the amount of threads to use when using software encoding. Setting to 0 will use the max amount available.",
diff --git a/alvr/dashboard/js/app/setupWizard.js b/alvr/dashboard/js/app/setupWizard.js
index 9830b00850..5adc0744ec 100644
--- a/alvr/dashboard/js/app/setupWizard.js
+++ b/alvr/dashboard/js/app/setupWizard.js
@@ -50,6 +50,18 @@ define([
keyboard: false,
});
+ var trackingRadioButton = $("input:radio[name='tracking'][value='oculus']");
+ if (trackingRadioButton.length > 0) {
+ trackingRadioButton.prop("checked", "true");
+ trackingRadioButton.parent().addClass("active");
+ }
+
+ var perfRadioButton = $("input:radio[name='performance'][value='visual_quality']");
+ if (perfRadioButton.length > 0) {
+ perfRadioButton.prop("checked", "true");
+ perfRadioButton.parent().addClass("active");
+ }
+
$("#wizardBackButton").hide();
$("#GPUSupportText").text(getAndCheckGPUSupport());
@@ -169,15 +181,17 @@ define([
const ffrStrengthTarget = $("#_root_video_foveatedRendering_content_strength");
const bitrateTarget = $("#_root_video_encodeBitrateMbs");
const preferredFps = $("#_root_video_preferredFps");
+ const adaptiveBitrate = $("#_root_connection_adaptiveBitrateEnabled");
switch (target.attr("value")) {
case "compatibility":
- renderResolutionScale.val(0.75);
- targetResolutionScale.val(0.75);
- bitrateTarget.val(15);
+ renderResolutionScale.val(1.25);
+ targetResolutionScale.val(1.25);
+ bitrateTarget.val(60);
enableFfrTarget.prop("checked", true);
+ adaptiveBitrate.prop("checked", true);
ffrStrengthTarget.val(2);
- preferredFps.val(72);
+ preferredFps.val(90);
const h264CodecTarget = $("#_root_video_codec_H264-choice-");
h264CodecTarget
@@ -190,10 +204,11 @@ define([
alvrSettings.storeParam(h264CodecTarget);
break;
case "visual_quality":
- renderResolutionScale.val(1);
- targetResolutionScale.val(1);
- bitrateTarget.val(40);
- enableFfrTarget.prop("checked", false);
+ renderResolutionScale.val(1.4);
+ targetResolutionScale.val(1.4);
+ bitrateTarget.val(150);
+ adaptiveBitrate.prop("checked", false);
+ enableFfrTarget.prop("checked", true);
preferredFps.val(90);
const hevcCodecTarget = $("#_root_video_codec_HEVC-choice-");
diff --git a/alvr/dashboard/js/app/templates/wizard.html b/alvr/dashboard/js/app/templates/wizard.html
index 0e38d702c1..591c3d2405 100644
--- a/alvr/dashboard/js/app/templates/wizard.html
+++ b/alvr/dashboard/js/app/templates/wizard.html
@@ -44,7 +44,7 @@
<%= titleTracking %>
diff --git a/alvr/filesystem/src/lib.rs b/alvr/filesystem/src/lib.rs
index a15932ab42..f66d0775a6 100644
--- a/alvr/filesystem/src/lib.rs
+++ b/alvr/filesystem/src/lib.rs
@@ -209,6 +209,10 @@ impl Layout {
self.executables_dir.join(exe)
}
+ pub fn launcher_pdb(&self) -> PathBuf {
+ self.executables_dir.join("alvr_launcher.pdb")
+ }
+
pub fn resources_dir(&self) -> PathBuf {
self.openvr_driver_root_dir.join("resources")
}
@@ -267,6 +271,11 @@ impl Layout {
.join(format!("driver_alvr_server.{ext}"))
}
+ pub fn openvr_driver_pdb(&self) -> PathBuf {
+ self.openvr_driver_lib_dir()
+ .join(format!("driver_alvr_server.pdb"))
+ }
+
// path to the manifest file for openVR
pub fn openvr_driver_manifest(&self) -> PathBuf {
self.openvr_driver_root_dir.join("driver.vrdrivermanifest")
diff --git a/alvr/server/build.rs b/alvr/server/build.rs
index 04f79aef9a..e701656715 100644
--- a/alvr/server/build.rs
+++ b/alvr/server/build.rs
@@ -9,7 +9,7 @@ use std::{env, path::PathBuf};
#[cfg(target_os = "linux")]
fn do_ffmpeg_pkg_config(build: &mut cc::Build) {
let ffmpeg_path =
- env::var("CARGO_MANIFEST_DIR").unwrap() + "/../../deps/linux/FFmpeg-release-5.1";
+ env::var("CARGO_MANIFEST_DIR").unwrap() + "/../../deps/linux/FFmpeg-release-5.1/";
#[cfg(feature = "bundled_ffmpeg")]
{
@@ -108,17 +108,22 @@ fn main() {
let mut build = cc::Build::new();
build
.cpp(true)
+ .std("c++20")
.files(source_files_paths)
.flag_if_supported("-isystemcpp/openvr/headers") // silences many warnings from openvr headers
- .flag_if_supported("-std=c++17")
+ .flag_if_supported("-std=c++20")
.include("cpp/openvr/headers")
.include("cpp");
#[cfg(windows)]
build
.debug(false) // This is because we cannot link to msvcrtd (see below)
- .flag("/std:c++17")
+ .flag("/std:c++20")
.flag("/permissive-")
+ .flag_if_supported("/Oi")
+ .flag_if_supported("/Ob2")
+ .flag_if_supported("/fp:contract")
+ //.flag_if_supported("/GL")
.define("NOMINMAX", None)
.define("_WINSOCKAPI_", None)
.define("_MBCS", None)
diff --git a/alvr/server/cpp/ALVR-common/packet_types.h b/alvr/server/cpp/ALVR-common/packet_types.h
index 48980878cf..76a722d35a 100644
--- a/alvr/server/cpp/ALVR-common/packet_types.h
+++ b/alvr/server/cpp/ALVR-common/packet_types.h
@@ -18,8 +18,20 @@ enum ALVR_CODEC {
ALVR_CODEC_H265 = 1,
};
-enum ALVR_LOST_FRAME_TYPE {
- ALVR_LOST_FRAME_TYPE_VIDEO = 0,
+enum ALVR_RATE_CONTROL_METHOD {
+ ALVR_CBR = 0,
+ ALVR_VBR = 1,
+};
+
+enum ALVR_ENTROPY_CODING {
+ ALVR_CABAC = 0,
+ ALVR_CAVLC = 1,
+};
+
+enum ALVR_ENCODER_QUALITY_PRESET {
+ ALVR_QUALITY = 0,
+ ALVR_BALANCED = 1,
+ ALVR_SPEED = 2
};
enum ALVR_INPUT {
diff --git a/alvr/server/cpp/ALVR-common/reedsolomon/rs.c b/alvr/server/cpp/ALVR-common/reedsolomon/rs.c
index ad1f7c56fc..28b5e4c446 100644
--- a/alvr/server/cpp/ALVR-common/reedsolomon/rs.c
+++ b/alvr/server/cpp/ALVR-common/reedsolomon/rs.c
@@ -320,9 +320,17 @@ static int invert_mat(gf *src, int k) {
}
for (col = k-1 ; col >= 0 ; col-- ) {
if (indxr[col] <0 || indxr[col] >= k)
+#ifdef NDEBUG
+ continue;
+#else
fprintf(stderr, "AARGH, indxr[col] %d\n", indxr[col]);
+#endif
else if (indxc[col] <0 || indxc[col] >= k)
+#ifdef NDEBUG
+ continue;
+#else
fprintf(stderr, "AARGH, indxc[col] %d\n", indxc[col]);
+#endif
else
if (indxr[col] != indxc[col] ) {
for (row = 0 ; row < k ; row++ )
@@ -375,16 +383,14 @@ void reed_solomon_init(void) {
init_mul_table();
}
-reed_solomon* reed_solomon_new(int data_shards, int parity_shards) {
+int reed_solomon_new(int data_shards, int parity_shards, reed_solomon* rs) {
gf* vm = NULL;
gf* top = NULL;
int err = 0;
- reed_solomon* rs = NULL;
do {
- rs = (reed_solomon *)malloc(sizeof(reed_solomon));
if (NULL == rs)
- return NULL;
+ return -1;
rs->data_shards = data_shards;
rs->parity_shards = parity_shards;
@@ -440,39 +446,33 @@ reed_solomon* reed_solomon_new(int data_shards, int parity_shards) {
free(top);
vm = NULL;
top = NULL;
- return rs;
+ return 0;
} while(0);
- fprintf(stderr, "err=%d\n", err);
+ if (err != 0) {
+ fprintf(stderr, "err=%d\n", err);
+ }
+
if (NULL != vm)
free(vm);
-
if (NULL != top)
free(top);
- if (NULL != rs) {
- if (NULL != rs->m)
- free(rs->m);
-
- if (NULL != rs->parity)
- free(rs->parity);
-
- free(rs);
- }
-
- return NULL;
+ reed_solomon_release(rs);
+ return -1;
}
void reed_solomon_release(reed_solomon* rs) {
- if (NULL != rs) {
- if (NULL != rs->m)
- free(rs->m);
-
- if (NULL != rs->parity)
- free(rs->parity);
-
- free(rs);
+ if (NULL == rs)
+ return ;
+ if (NULL != rs->m) {
+ free(rs->m);
+ rs->m = NULL;
+ }
+ if (NULL != rs->parity) {
+ free(rs->parity);
+ rs->parity = NULL;
}
}
diff --git a/alvr/server/cpp/ALVR-common/reedsolomon/rs.h b/alvr/server/cpp/ALVR-common/reedsolomon/rs.h
index afb0b92fca..72f9f467c8 100644
--- a/alvr/server/cpp/ALVR-common/reedsolomon/rs.h
+++ b/alvr/server/cpp/ALVR-common/reedsolomon/rs.h
@@ -21,7 +21,7 @@ extern "C" {
* */
void reed_solomon_init(void);
- reed_solomon* reed_solomon_new(int data_shards, int parity_shards);
+ int reed_solomon_new(int data_shards, int parity_shards, reed_solomon* rs_out);
void reed_solomon_release(reed_solomon* rs);
/**
diff --git a/alvr/server/cpp/alvr_server/ClientConnection.cpp b/alvr/server/cpp/alvr_server/ClientConnection.cpp
index f15afee92d..6f91237c46 100644
--- a/alvr/server/cpp/alvr_server/ClientConnection.cpp
+++ b/alvr/server/cpp/alvr_server/ClientConnection.cpp
@@ -22,26 +22,27 @@ ClientConnection::ClientConnection() : m_LastStatisticsUpdate(0) {
m_Statistics->ResetAll();
}
-void ClientConnection::FECSend(uint8_t *buf, int len, uint64_t targetTimestampNs, uint64_t videoFrameIndex) {
- int shardPackets = CalculateFECShardPackets(len, m_fecPercentage);
+void ClientConnection::FECSend(const uint8_t *buf, uint32_t len, uint64_t targetTimestampNs, uint64_t videoFrameIndex) {
+ const int shardPackets = CalculateFECShardPackets(len, m_fecPercentage);
- int blockSize = shardPackets * ALVR_MAX_VIDEO_BUFFER_SIZE;
+ const int blockSize = shardPackets * ALVR_MAX_VIDEO_BUFFER_SIZE;
- int dataShards = (len + blockSize - 1) / blockSize;
- int totalParityShards = CalculateParityShards(dataShards, m_fecPercentage);
- int totalShards = dataShards + totalParityShards;
+ const int dataShards = (len + blockSize - 1) / blockSize;
+ const int totalParityShards = CalculateParityShards(dataShards, m_fecPercentage);
+ const int totalShards = dataShards + totalParityShards;
assert(totalShards <= DATA_SHARDS_MAX);
Debug("reed_solomon_new. dataShards=%d totalParityShards=%d totalShards=%d blockSize=%d shardPackets=%d\n"
, dataShards, totalParityShards, totalShards, blockSize, shardPackets);
- reed_solomon *rs = reed_solomon_new(dataShards, totalParityShards);
+ reed_solomon rs = {};
+ reed_solomon_new(dataShards, totalParityShards, &rs);
std::vector shards(totalShards);
- for (int i = 0; i < dataShards; i++) {
- shards[i] = buf + i * blockSize;
+ for (int i = 0; i < dataShards; ++i) {
+ shards[i] = const_cast(buf) + i * blockSize;
}
if (len % blockSize != 0) {
// Padding
@@ -49,29 +50,31 @@ void ClientConnection::FECSend(uint8_t *buf, int len, uint64_t targetTimestampNs
memset(shards[dataShards - 1], 0, blockSize);
memcpy(shards[dataShards - 1], buf + (dataShards - 1) * blockSize, len % blockSize);
}
- for (int i = 0; i < totalParityShards; i++) {
+ for (int i = 0; i < totalParityShards; ++i) {
shards[dataShards + i] = new uint8_t[blockSize];
}
- int ret = reed_solomon_encode(rs, &shards[0], totalShards, blockSize);
+ const int ret = reed_solomon_encode(&rs, &shards[0], totalShards, blockSize);
assert(ret == 0);
- reed_solomon_release(rs);
+ reed_solomon_release(&rs);
- uint8_t packetBuffer[2000];
+ thread_local uint8_t packetBuffer[2000];
VideoFrame *header = (VideoFrame *)packetBuffer;
uint8_t *payload = packetBuffer + sizeof(VideoFrame);
int dataRemain = len;
- header->type = ALVR_PACKET_TYPE_VIDEO_FRAME;
- header->trackingFrameIndex = targetTimestampNs;
- header->videoFrameIndex = videoFrameIndex;
- header->sentTime = GetTimestampUs();
- header->frameByteSize = len;
- header->fecIndex = 0;
- header->fecPercentage = (uint16_t)m_fecPercentage;
- for (int i = 0; i < dataShards; i++) {
- for (int j = 0; j < shardPackets; j++) {
+ *header = {
+ .type = ALVR_PACKET_TYPE_VIDEO_FRAME,
+ .trackingFrameIndex = targetTimestampNs,
+ .videoFrameIndex = videoFrameIndex,
+ .sentTime = GetSystemTimestampUs(),
+ .frameByteSize = len,
+ .fecIndex = 0,
+ .fecPercentage = (uint16_t)m_fecPercentage,
+ };
+ for (int i = 0; i < dataShards; ++i) {
+ for (int j = 0; j < shardPackets; ++j) {
int copyLength = std::min(ALVR_MAX_VIDEO_BUFFER_SIZE, dataRemain);
if (copyLength <= 0) {
break;
@@ -80,24 +83,24 @@ void ClientConnection::FECSend(uint8_t *buf, int len, uint64_t targetTimestampNs
dataRemain -= ALVR_MAX_VIDEO_BUFFER_SIZE;
header->packetCounter = videoPacketCounter;
- videoPacketCounter++;
- VideoSend(*header, (unsigned char *)packetBuffer + sizeof(VideoFrame), copyLength);
+ ++videoPacketCounter;
+ VideoSend(header, (unsigned char *)packetBuffer + sizeof(VideoFrame), copyLength);
m_Statistics->CountPacket(sizeof(VideoFrame) + copyLength);
- header->fecIndex++;
+ ++header->fecIndex;
}
}
header->fecIndex = dataShards * shardPackets;
- for (int i = 0; i < totalParityShards; i++) {
- for (int j = 0; j < shardPackets; j++) {
+ for (int i = 0; i < totalParityShards; ++i) {
+ for (int j = 0; j < shardPackets; ++j) {
int copyLength = ALVR_MAX_VIDEO_BUFFER_SIZE;
memcpy(payload, shards[dataShards + i] + j * ALVR_MAX_VIDEO_BUFFER_SIZE, copyLength);
header->packetCounter = videoPacketCounter;
- videoPacketCounter++;
+ ++videoPacketCounter;
- VideoSend(*header, (unsigned char *)packetBuffer + sizeof(VideoFrame), copyLength);
+ VideoSend(header, (unsigned char *)packetBuffer + sizeof(VideoFrame), copyLength);
m_Statistics->CountPacket(sizeof(VideoFrame) + copyLength);
- header->fecIndex++;
+ ++header->fecIndex;
}
}
@@ -109,7 +112,7 @@ void ClientConnection::FECSend(uint8_t *buf, int len, uint64_t targetTimestampNs
}
}
-void ClientConnection::SendVideo(uint8_t *buf, int len, uint64_t targetTimestampNs) {
+void ClientConnection::SendVideo(const uint8_t *buf, uint32_t len, uint64_t targetTimestampNs) {
if (Settings::Instance().m_enableFec) {
FECSend(buf, len, targetTimestampNs, mVideoFrameIndex);
} else {
@@ -117,10 +120,10 @@ void ClientConnection::SendVideo(uint8_t *buf, int len, uint64_t targetTimestamp
header.packetCounter = this->videoPacketCounter;
header.trackingFrameIndex = targetTimestampNs;
header.videoFrameIndex = mVideoFrameIndex;
- header.sentTime = GetTimestampUs();
+ header.sentTime = GetSystemTimestampUs();
header.frameByteSize = len;
- VideoSend(header, buf, len);
+ VideoSend(&header, buf, len);
m_Statistics->CountPacket(sizeof(VideoFrame) + len);
@@ -130,11 +133,11 @@ void ClientConnection::SendVideo(uint8_t *buf, int len, uint64_t targetTimestamp
mVideoFrameIndex++;
}
-void ClientConnection::ProcessTimeSync(TimeSync data) {
+void ClientConnection::ProcessTimeSync(const TimeSync &data) {
m_Statistics->CountPacket(sizeof(TrackingInfo));
- TimeSync *timeSync = &data;
- uint64_t Current = GetTimestampUs();
+ const TimeSync * const timeSync = &data;
+ const std::uint64_t Current = GetSystemTimestampUs();
if (timeSync->mode == 0) {
//timings might be a little incorrect since it is a mix from a previous sent frame and latest frame
@@ -148,7 +151,7 @@ void ClientConnection::ProcessTimeSync(TimeSync data) {
sendBuf.mode = 1;
sendBuf.serverTime = Current;
sendBuf.serverTotalLatency = (int)(m_reportedStatistics.averageSendLatency + (timing[0].m_flPreSubmitGpuMs + timing[0].m_flPostSubmitGpuMs + timing[0].m_flTotalRenderGpuMs + timing[0].m_flCompositorRenderGpuMs + timing[0].m_flCompositorRenderCpuMs + timing[0].m_flCompositorIdleCpuMs + timing[0].m_flClientFrameIntervalMs + timing[0].m_flPresentCallCpuMs + timing[0].m_flWaitForPresentCpuMs + timing[0].m_flSubmitFrameMs) * 1000 + m_Statistics->GetEncodeLatencyAverage() + m_reportedStatistics.averageTransportLatency + m_reportedStatistics.averageDecodeLatency + m_reportedStatistics.idleTime);
- TimeSyncSend(sendBuf);
+ TimeSyncSend(&sendBuf);
m_Statistics->NetworkTotal(sendBuf.serverTotalLatency);
m_Statistics->NetworkSend(m_reportedStatistics.averageTransportLatency);
@@ -168,7 +171,7 @@ void ClientConnection::ProcessTimeSync(TimeSync data) {
m_reportedStatistics.fps,
m_RTT / 2. / 1000.);
- uint64_t now = GetTimestampUs();
+ const std::uint64_t now = GetSteadyTimeStampUS();
if (now - m_LastStatisticsUpdate > STATISTICS_TIMEOUT_US)
{
// Text statistics only, some values averaged
@@ -252,12 +255,13 @@ float ClientConnection::GetPoseTimeOffset() {
void ClientConnection::OnFecFailure() {
Debug("Listener::OnFecFailure()\n");
- if (GetTimestampUs() - m_lastFecFailure < CONTINUOUS_FEC_FAILURE) {
+ const std::uint64_t timestamp = GetSteadyTimeStampUS();
+ if (timestamp - m_lastFecFailure < CONTINUOUS_FEC_FAILURE) {
if (m_fecPercentage < MAX_FEC_PERCENTAGE) {
m_fecPercentage += 5;
}
}
- m_lastFecFailure = GetTimestampUs();
+ m_lastFecFailure = timestamp;
}
std::shared_ptr ClientConnection::GetStatistics() {
diff --git a/alvr/server/cpp/alvr_server/ClientConnection.h b/alvr/server/cpp/alvr_server/ClientConnection.h
index 63be5e9d05..95e4c81276 100644
--- a/alvr/server/cpp/alvr_server/ClientConnection.h
+++ b/alvr/server/cpp/alvr_server/ClientConnection.h
@@ -17,9 +17,9 @@ class ClientConnection {
ClientConnection();
- void FECSend(uint8_t *buf, int len, uint64_t targetTimestampNs, uint64_t videoFrameIndex);
- void SendVideo(uint8_t *buf, int len, uint64_t targetTimestampNs);
- void ProcessTimeSync(TimeSync data);
+ void FECSend(const uint8_t *buf, uint32_t len, uint64_t targetTimestampNs, uint64_t videoFrameIndex);
+ void SendVideo(const uint8_t *buf, uint32_t len, uint64_t targetTimestampNs);
+ void ProcessTimeSync(const TimeSync &data);
float GetPoseTimeOffset();
void OnFecFailure();
std::shared_ptr GetStatistics();
diff --git a/alvr/server/cpp/alvr_server/IDRScheduler.cpp b/alvr/server/cpp/alvr_server/IDRScheduler.cpp
index 9f574e2681..ba977b0d62 100644
--- a/alvr/server/cpp/alvr_server/IDRScheduler.cpp
+++ b/alvr/server/cpp/alvr_server/IDRScheduler.cpp
@@ -20,9 +20,10 @@ void IDRScheduler::OnPacketLoss()
// Waiting next insertion.
return;
}
- if (GetTimestampUs() - m_insertIDRTime > m_minIDRFrameInterval) {
+ const std::uint64_t timestamp = GetSteadyTimeStampUS();
+ if (timestamp - m_insertIDRTime > m_minIDRFrameInterval) {
// Insert immediately
- m_insertIDRTime = GetTimestampUs();
+ m_insertIDRTime = timestamp;
m_scheduled = true;
}
else {
@@ -46,7 +47,7 @@ void IDRScheduler::InsertIDR()
{
std::unique_lock lock(m_mutex);
- m_insertIDRTime = GetTimestampUs() - MIN_IDR_FRAME_INTERVAL * 2;
+ m_insertIDRTime = GetSteadyTimeStampUS() - MIN_IDR_FRAME_INTERVAL * 2;
m_scheduled = true;
}
@@ -54,7 +55,7 @@ bool IDRScheduler::CheckIDRInsertion() {
std::unique_lock lock(m_mutex);
if (m_scheduled) {
- if (m_insertIDRTime <= GetTimestampUs()) {
+ if (m_insertIDRTime <= GetSteadyTimeStampUS()) {
m_scheduled = false;
return true;
}
diff --git a/alvr/server/cpp/alvr_server/OvrController.cpp b/alvr/server/cpp/alvr_server/OvrController.cpp
index 69085a2ce0..d13792a968 100644
--- a/alvr/server/cpp/alvr_server/OvrController.cpp
+++ b/alvr/server/cpp/alvr_server/OvrController.cpp
@@ -934,51 +934,51 @@ bool OvrController::onPoseUpdate(const TrackingInfo::Controller &c) {
if (c.isHand) {
vr::HmdQuaternion_t rootBoneRot =
- HmdQuaternion_Init(c.boneRootOrientation.w,
- c.boneRootOrientation.x,
- c.boneRootOrientation.y,
- c.boneRootOrientation.z);
+ HmdQuaternion_Init(c.boneRootPose.orientation.w,
+ c.boneRootPose.orientation.x,
+ c.boneRootPose.orientation.y,
+ c.boneRootPose.orientation.z);
vr::HmdQuaternion_t boneFixer = this->device_path == LEFT_HAND_PATH
? HmdQuaternion_Init(-0.5, 0.5, 0.5, -0.5)
: HmdQuaternion_Init(0.5, 0.5, 0.5, 0.5);
m_pose.qRotation = QuatMultiply(&rootBoneRot, &boneFixer);
- m_pose.vecPosition[0] = c.boneRootPosition.x;
- m_pose.vecPosition[1] = c.boneRootPosition.y;
- m_pose.vecPosition[2] = c.boneRootPosition.z;
+ m_pose.vecPosition[0] = c.boneRootPose.position.x;
+ m_pose.vecPosition[1] = c.boneRootPose.position.y;
+ m_pose.vecPosition[2] = c.boneRootPose.position.z;
if (this->device_path == LEFT_HAND_PATH) {
double bonePosFixer[3] = {0.0, 0.05, -0.05};
vr::HmdVector3d_t posFix =
vrmath::quaternionRotateVector(m_pose.qRotation, bonePosFixer);
m_pose.vecPosition[0] =
- c.boneRootPosition.x + posFix.v[0];
+ c.boneRootPose.position.x + posFix.v[0];
m_pose.vecPosition[1] =
- c.boneRootPosition.y + posFix.v[1];
+ c.boneRootPose.position.y + posFix.v[1];
m_pose.vecPosition[2] =
- c.boneRootPosition.z + posFix.v[2];
+ c.boneRootPose.position.z + posFix.v[2];
} else {
double bonePosFixer[3] = {0.0, 0.05, -0.05};
vr::HmdVector3d_t posFix =
vrmath::quaternionRotateVector(m_pose.qRotation, bonePosFixer);
m_pose.vecPosition[0] =
- c.boneRootPosition.x + posFix.v[0];
+ c.boneRootPose.position.x + posFix.v[0];
m_pose.vecPosition[1] =
- c.boneRootPosition.y + posFix.v[1];
+ c.boneRootPose.position.y + posFix.v[1];
m_pose.vecPosition[2] =
- c.boneRootPosition.z + posFix.v[2];
+ c.boneRootPose.position.z + posFix.v[2];
}
} else {
m_pose.qRotation = HmdQuaternion_Init(
- c.orientation.w,
- c.orientation.x,
- c.orientation.y,
- c.orientation.z); // controllerRotation;
-
- m_pose.vecPosition[0] = c.position.x;
- m_pose.vecPosition[1] = c.position.y;
- m_pose.vecPosition[2] = c.position.z;
+ c.pose.orientation.w,
+ c.pose.orientation.x,
+ c.pose.orientation.y,
+ c.pose.orientation.z); // controllerRotation;
+
+ m_pose.vecPosition[0] = c.pose.position.x;
+ m_pose.vecPosition[1] = c.pose.position.y;
+ m_pose.vecPosition[2] = c.pose.position.z;
}
// use cutoffs for velocity to stop jitter when there is not a lot of movement
@@ -1254,7 +1254,7 @@ bool OvrController::onPoseUpdate(const TrackingInfo::Controller &c) {
// Will use one of the existing poses from the implementation below instead for position
// data.
- // COPY3(c.boneRootPosition, m_boneTransform[HSB_Root].position);
+ // COPY3(c.boneRootPose.position, m_boneTransform[HSB_Root].position);
// COPY3(c.bonePositionsBase[alvrHandBone_WristRoot], m_boneTransform[HSB_Wrist].position);
// COPY3(c.bonePositionsBase[alvrHandBone_Thumb0], m_boneTransform[HSB_Thumb0].position);
// COPY3(c.bonePositionsBase[alvrHandBone_Thumb1], m_boneTransform[HSB_Thumb1].position);
diff --git a/alvr/server/cpp/alvr_server/OvrHMD.cpp b/alvr/server/cpp/alvr_server/OvrHMD.cpp
index 320c6bcb08..9ead9f0274 100644
--- a/alvr/server/cpp/alvr_server/OvrHMD.cpp
+++ b/alvr/server/cpp/alvr_server/OvrHMD.cpp
@@ -186,6 +186,13 @@ vr::EVRInitError OvrHmd::Activate(vr::TrackedDeviceIndex_t unObjectId) {
this->prop_container, vr::Prop_DriverDirectModeSendsVsyncEvents_Bool, true);
#endif
+ // workaround-fix to jittery system overlays during low frame-rates,
+ // only workaround as the driver compositor doesn't do warping or
+ // handle overlay type layers properly.
+ // this setting will become on by default in SteamVR 2.9.6
+ vr::VRProperties()->SetBoolProperty(
+ this->prop_container, vr::Prop_ForceSystemLayerUseAppPoses_Bool, true);
+
// Set battery as true
vr::VRProperties()->SetBoolProperty(
this->prop_container, vr::Prop_DeviceProvidesBatteryStatus_Bool, true);
@@ -321,14 +328,14 @@ vr::DriverPose_t OvrHmd::GetPose() {
if (m_TrackingInfo.targetTimestampNs > 0) {
TrackingInfo &info = m_TrackingInfo;
- pose.qRotation = HmdQuaternion_Init(info.HeadPose_Pose_Orientation.w,
- info.HeadPose_Pose_Orientation.x,
- info.HeadPose_Pose_Orientation.y,
- info.HeadPose_Pose_Orientation.z);
+ pose.qRotation = HmdQuaternion_Init(info.headPose.orientation.w,
+ info.headPose.orientation.x,
+ info.headPose.orientation.y,
+ info.headPose.orientation.z);
- pose.vecPosition[0] = info.HeadPose_Pose_Position.x;
- pose.vecPosition[1] = info.HeadPose_Pose_Position.y;
- pose.vecPosition[2] = info.HeadPose_Pose_Position.z;
+ pose.vecPosition[0] = info.headPose.position.x;
+ pose.vecPosition[1] = info.headPose.position.y;
+ pose.vecPosition[2] = info.headPose.position.z;
// set prox sensor
vr::VRDriverInput()->UpdateBooleanComponent(m_proximity, info.mounted == 1, 0.0);
@@ -348,17 +355,17 @@ vr::DriverPose_t OvrHmd::GetPose() {
return pose;
}
-void OvrHmd::OnPoseUpdated(TrackingInfo info) {
+void OvrHmd::OnPoseUpdated(const TrackingInfo& info) {
if (this->object_id != vr::k_unTrackedDeviceIndexInvalid) {
+
+ m_TrackingInfo = info;
// if 3DOF, zero the positional data!
if (Settings::Instance().m_force3DOF) {
- info.HeadPose_Pose_Position.x = 0;
- info.HeadPose_Pose_Position.y = 0;
- info.HeadPose_Pose_Position.z = 0;
+ m_TrackingInfo.headPose.position.x = 0;
+ m_TrackingInfo.headPose.position.y = 0;
+ m_TrackingInfo.headPose.position.z = 0;
}
-
- m_TrackingInfo = info;
-
+
// TODO: Right order?
if (!Settings::Instance().m_disableController) {
@@ -543,3 +550,15 @@ void OvrHmd::GetProjectionRaw(
vr::DistortionCoordinates_t OvrHmd::ComputeDistortion(vr::EVREye, float u, float v) {
return {{u, v}, {u, v}, {u, v}};
}
+
+bool OvrHmd::ComputeInverseDistortion(vr::HmdVector2_t *pResult, vr::EVREye eEye, uint32_t unChannel, float fU, float fV) {
+ if (pResult == nullptr) {
+ return false;
+ }
+ // Since the original ComputeDistortion is an identity function,
+ // the inverse is also an identity function, and does not depend
+ // on the eye or channel.
+ pResult->v[0] = fU;
+ pResult->v[1] = fV;
+ return true; // Operation successful
+}
diff --git a/alvr/server/cpp/alvr_server/OvrHMD.h b/alvr/server/cpp/alvr_server/OvrHMD.h
index 553864696b..e31a080b90 100644
--- a/alvr/server/cpp/alvr_server/OvrHMD.h
+++ b/alvr/server/cpp/alvr_server/OvrHMD.h
@@ -40,7 +40,7 @@ class OvrHmd : public TrackedDevice,
virtual void DebugRequest(const char *request, char *response_buffer, uint32_t size) {}
virtual vr::DriverPose_t GetPose();
- void OnPoseUpdated(TrackingInfo info);
+ void OnPoseUpdated(const TrackingInfo& info);
void StartStreaming();
@@ -64,7 +64,7 @@ class OvrHmd : public TrackedDevice,
virtual void
GetProjectionRaw(vr::EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom);
virtual vr::DistortionCoordinates_t ComputeDistortion(vr::EVREye eEye, float fU, float fV);
-
+ virtual bool ComputeInverseDistortion(vr::HmdVector2_t *pResult, vr::EVREye eEye, uint32_t unChannel, float fU, float fV ) override;
std::shared_ptr m_Listener;
float m_poseTimeOffset;
diff --git a/alvr/server/cpp/alvr_server/PoseHistory.cpp b/alvr/server/cpp/alvr_server/PoseHistory.cpp
index de2ac1b14a..fd93d1005c 100644
--- a/alvr/server/cpp/alvr_server/PoseHistory.cpp
+++ b/alvr/server/cpp/alvr_server/PoseHistory.cpp
@@ -1,19 +1,23 @@
#include "PoseHistory.h"
#include "Utils.h"
#include "Logger.h"
+#include
#include
#include
+#undef max
+#undef min
+
void PoseHistory::OnPoseUpdated(const TrackingInfo &info) {
// Put pose history buffer
TrackingHistoryFrame history;
history.info = info;
- HmdMatrix_QuatToMat(info.HeadPose_Pose_Orientation.w,
- info.HeadPose_Pose_Orientation.x,
- info.HeadPose_Pose_Orientation.y,
- info.HeadPose_Pose_Orientation.z,
+ HmdMatrix_QuatToMat(info.headPose.orientation.w,
+ info.headPose.orientation.x,
+ info.headPose.orientation.y,
+ info.headPose.orientation.z,
&history.rotationMatrix);
Debug("Rotation Matrix=(%f, %f, %f, %f) (%f, %f, %f, %f) (%f, %f, %f, %f)\n"
@@ -21,7 +25,7 @@ void PoseHistory::OnPoseUpdated(const TrackingInfo &info) {
, history.rotationMatrix.m[1][0], history.rotationMatrix.m[1][1], history.rotationMatrix.m[1][2], history.rotationMatrix.m[1][3]
, history.rotationMatrix.m[2][0], history.rotationMatrix.m[2][1], history.rotationMatrix.m[2][2], history.rotationMatrix.m[2][3]);
- std::unique_lock lock(m_mutex);
+ std::unique_lock lock(m_mutex);
if (m_poseBuffer.size() == 0) {
m_poseBuffer.push_back(history);
}
@@ -39,8 +43,8 @@ void PoseHistory::OnPoseUpdated(const TrackingInfo &info) {
std::optional PoseHistory::GetBestPoseMatch(const vr::HmdMatrix34_t &pose) const
{
- std::unique_lock lock(m_mutex);
- float minDiff = 100000;
+ std::shared_lock lock(m_mutex);
+ float minDiff = std::numeric_limits::max();
auto minIt = m_poseBuffer.begin();
for (auto it = m_poseBuffer.begin(); it != m_poseBuffer.end(); ++it) {
float distance = 0;
@@ -49,7 +53,8 @@ std::optional PoseHistory::GetBestPoseMatch(c
// And bottom side and right side of matrix should not be compared, because pPose does not contain that part of matrix.
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
- distance += pow(it->rotationMatrix.m[j][i] - pose.m[j][i], 2);
+ const float x = it->rotationMatrix.m[j][i] - pose.m[j][i];
+ distance += (x * x);
}
}
//LogDriver("diff %f %llu", distance, it->info.FrameIndex);
@@ -61,16 +66,16 @@ std::optional PoseHistory::GetBestPoseMatch(c
if (minIt != m_poseBuffer.end()) {
return *minIt;
}
- return {};
+ return std::nullopt;
}
std::optional PoseHistory::GetPoseAt(uint64_t client_timestamp_ns) const
{
- std::unique_lock lock(m_mutex);
+ std::shared_lock lock(m_mutex);
for (auto it = m_poseBuffer.rbegin(), end = m_poseBuffer.rend() ; it != end ; ++it)
{
if (it->info.targetTimestampNs == client_timestamp_ns)
return *it;
}
- return {};
+ return std::nullopt;
}
diff --git a/alvr/server/cpp/alvr_server/PoseHistory.h b/alvr/server/cpp/alvr_server/PoseHistory.h
index e321af7e76..ca8c1b0636 100644
--- a/alvr/server/cpp/alvr_server/PoseHistory.h
+++ b/alvr/server/cpp/alvr_server/PoseHistory.h
@@ -2,6 +2,7 @@
#include
#include
+#include
#include
#include
#include "ALVR-common/packet_types.h"
@@ -21,6 +22,6 @@ class PoseHistory
std::optional GetPoseAt(uint64_t client_timestamp_us) const;
private:
- mutable std::mutex m_mutex;
+ mutable std::shared_mutex m_mutex{};
std::list m_poseBuffer;
};
diff --git a/alvr/server/cpp/alvr_server/Settings.cpp b/alvr/server/cpp/alvr_server/Settings.cpp
index 022024b5bf..cb9b254345 100644
--- a/alvr/server/cpp/alvr_server/Settings.cpp
+++ b/alvr/server/cpp/alvr_server/Settings.cpp
@@ -85,6 +85,10 @@ void Settings::Load()
m_nAdapterIndex = (int32_t)config.get("adapter_index").get();
m_codec = (int32_t)config.get("codec").get();
+ m_colorRange = static_cast(config.get("color_range").get());
+ m_rateControlMode = (uint32_t)config.get("rate_control_mode").get();
+ m_fillerData = config.get("filler_data").get();
+ m_entropyCoding = (uint32_t)config.get("entropy_coding").get();
m_refreshRate = (int)config.get("refresh_rate").get();
mEncodeBitrateMBs = (int)config.get("encode_bitrate_mbs").get();
m_enableAdaptiveBitrate = config.get("enable_adaptive_bitrate").get();
@@ -98,6 +102,12 @@ void Settings::Load()
m_adaptiveBitrateDownRate = (int)config.get("bitrate_down_rate").get();
m_adaptiveBitrateLightLoadThreshold = config.get("bitrate_light_load_threshold").get();
m_use10bitEncoder = config.get("use_10bit_encoder").get();
+ m_enableVbaq = config.get("enable_vbaq").get();
+ m_usePreproc = config.get("use_preproc").get();
+ m_preProcSigma = (uint32_t)config.get("preproc_sigma").get();
+ m_preProcTor = (uint32_t)config.get("preproc_tor").get();
+ m_encoderQualityPreset = (uint32_t)config.get("encoder_quality_preset").get();
+ m_force_sw_encoding = config.get("force_sw_encoding").get();
m_swThreadCount = (int32_t)config.get("sw_thread_count").get();
m_controllerTrackingSystemName = config.get("controllers_tracking_system_name").get();
@@ -163,7 +173,25 @@ void Settings::Load()
m_enableFec = config.get("enable_fec").get();
m_enableLinuxVulkanAsync = config.get("linux_async_reprojection").get();
-
+
+ m_nvencTuningPreset = (uint32_t)config.get("nvenc_tuning_preset").get();
+ m_nvencMultiPass = (uint32_t)config.get("nvenc_multi_pass").get();
+ m_nvencAdaptiveQuantizationMode = (uint32_t)config.get("nvenc_adaptive_quantization_mode").get();
+ m_nvencLowDelayKeyFrameScale = config.get("nvenc_low_delay_key_frame_scale").get();
+ m_nvencRefreshRate = config.get("nvenc_refresh_rate").get();
+ m_nvencEnableIntraRefresh = config.get("enable_intra_refresh").get();
+ m_nvencIntraRefreshPeriod = config.get("intra_refresh_period").get();
+ m_nvencIntraRefreshCount = config.get("intra_refresh_count").get();
+ m_nvencMaxNumRefFrames = config.get("max_num_ref_frames").get();
+ m_nvencGopLength = config.get("gop_length").get();
+ m_nvencPFrameStrategy = config.get("p_frame_strategy").get();
+ m_nvencRateControlMode = config.get("nvenc_rate_control_mode").get();
+ m_nvencRcBufferSize = config.get("rc_buffer_size").get();
+ m_nvencRcInitialDelay = config.get("rc_initial_delay").get();
+ m_nvencRcMaxBitrate = config.get("rc_max_bitrate").get();
+ m_nvencRcAverageBitrate = config.get("rc_average_bitrate").get();
+ m_nvencEnableWeightedPrediction = config.get("nvenc_enable_weighted_prediction").get();
+
Debug("Config JSON: %hs\n", json.c_str());
Info("Serial Number: %hs\n", mSerialNumber.c_str());
Info("Model Number: %hs\n", mModelNumber.c_str());
diff --git a/alvr/server/cpp/alvr_server/Settings.h b/alvr/server/cpp/alvr_server/Settings.h
index 2f879f4a19..b9d892cea3 100644
--- a/alvr/server/cpp/alvr_server/Settings.h
+++ b/alvr/server/cpp/alvr_server/Settings.h
@@ -1,5 +1,6 @@
#pragma once
+#include
#include
#include "ALVR-common/packet_types.h"
@@ -62,6 +63,12 @@ class Settings
float m_sharpening;
int m_codec;
+ enum class ColorRange : std::uint32_t {
+ Full = 0,
+ Limited = 1,
+ };
+ ColorRange m_colorRange { ColorRange::Full };
+ bool IsColorRangeItuFull() const { return m_colorRange == ColorRange::Full; }
uint64_t mEncodeBitrateMBs;
bool m_enableAdaptiveBitrate;
uint64_t m_adaptiveBitrateMaximum;
@@ -74,6 +81,15 @@ class Settings
uint64_t m_adaptiveBitrateDownRate;
float m_adaptiveBitrateLightLoadThreshold;
bool m_use10bitEncoder;
+ bool m_enableVbaq;
+ bool m_usePreproc;
+ uint32_t m_preProcSigma;
+ uint32_t m_preProcTor;
+ uint32_t m_encoderQualityPreset;
+ uint32_t m_rateControlMode;
+ bool m_fillerData;
+ uint32_t m_entropyCoding;
+ bool m_force_sw_encoding;
uint32_t m_swThreadCount;
// Controller configs
@@ -129,4 +145,22 @@ class Settings
bool m_enableFec;
bool m_enableLinuxVulkanAsync;
+
+ uint32_t m_nvencTuningPreset;
+ uint32_t m_nvencMultiPass;
+ uint32_t m_nvencAdaptiveQuantizationMode;
+ int64_t m_nvencLowDelayKeyFrameScale;
+ int64_t m_nvencRefreshRate;
+ bool m_nvencEnableIntraRefresh;
+ int64_t m_nvencIntraRefreshPeriod;
+ int64_t m_nvencIntraRefreshCount;
+ int64_t m_nvencMaxNumRefFrames;
+ int64_t m_nvencGopLength;
+ int64_t m_nvencPFrameStrategy;
+ int64_t m_nvencRateControlMode;
+ int64_t m_nvencRcBufferSize;
+ int64_t m_nvencRcInitialDelay;
+ int64_t m_nvencRcMaxBitrate;
+ int64_t m_nvencRcAverageBitrate;
+ bool m_nvencEnableWeightedPrediction;
};
diff --git a/alvr/server/cpp/alvr_server/Utils.h b/alvr/server/cpp/alvr_server/Utils.h
index b6f15f961c..9217c877a0 100644
--- a/alvr/server/cpp/alvr_server/Utils.h
+++ b/alvr/server/cpp/alvr_server/Utils.h
@@ -31,28 +31,15 @@ const float DEG_TO_RAD = (float)(M_PI / 180.);
extern uint64_t gPerformanceCounterFrequency;
// Get elapsed time in us from Unix Epoch
-inline uint64_t GetTimestampUs() {
- auto duration = std::chrono::system_clock::now().time_since_epoch();
+inline uint64_t GetSystemTimestampUs() {
+ const auto duration = std::chrono::system_clock::now().time_since_epoch();
return std::chrono::duration_cast(duration).count();
}
-// Get performance counter in us
-inline uint64_t GetCounterUs() {
-#ifdef _WIN32
- if (gPerformanceCounterFrequency == 0) {
- LARGE_INTEGER freq;
- QueryPerformanceFrequency(&freq);
- gPerformanceCounterFrequency = freq.QuadPart;
- }
-
- LARGE_INTEGER counter;
- QueryPerformanceCounter(&counter);
-
- return counter.QuadPart * 1000000LLU / gPerformanceCounterFrequency;
-#else
- auto duration = std::chrono::steady_clock::now().time_since_epoch();
+inline std::uint64_t GetSteadyTimeStampUS() {
+ static_assert(std::chrono::steady_clock::is_steady);
+ const auto duration = std::chrono::steady_clock::now().time_since_epoch();
return std::chrono::duration_cast(duration).count();
-#endif
}
inline std::string DumpMatrix(const float *m) {
diff --git a/alvr/server/cpp/alvr_server/VSyncThread.cpp b/alvr/server/cpp/alvr_server/VSyncThread.cpp
index da34a12999..2c258b4dbf 100644
--- a/alvr/server/cpp/alvr_server/VSyncThread.cpp
+++ b/alvr/server/cpp/alvr_server/VSyncThread.cpp
@@ -15,15 +15,15 @@ void VSyncThread::Run() {
m_PreviousVsync = 0;
while (!m_bExit) {
- uint64_t current = GetTimestampUs();
- uint64_t interval = 1000 * 1000 / m_refreshRate;
+ const std::uint64_t current = GetSteadyTimeStampUS();
+ const std::uint64_t interval = 1000 * 1000 / m_refreshRate;
if (m_PreviousVsync + interval > current) {
- uint64_t sleepTimeMs = (m_PreviousVsync + interval - current) / 1000;
+ const std::uint64_t sleepTimeUs = (m_PreviousVsync + interval - current);
- if (sleepTimeMs > 0) {
- Debug("Sleep %llu ms for next VSync.\n", sleepTimeMs);
- std::this_thread::sleep_for(std::chrono::milliseconds(sleepTimeMs));
+ if (sleepTimeUs > 0) {
+ Debug("Sleep %llu us for next VSync.\n", sleepTimeUs);
+ std::this_thread::sleep_for(std::chrono::microseconds(sleepTimeUs));
}
m_PreviousVsync += interval;
diff --git a/alvr/server/cpp/alvr_server/alvr_server.cpp b/alvr/server/cpp/alvr_server/alvr_server.cpp
index c0cc68dafc..4e29c608cb 100644
--- a/alvr/server/cpp/alvr_server/alvr_server.cpp
+++ b/alvr/server/cpp/alvr_server/alvr_server.cpp
@@ -165,9 +165,9 @@ void (*LogWarn)(const char *stringPtr);
void (*LogInfo)(const char *stringPtr);
void (*LogDebug)(const char *stringPtr);
void (*DriverReadyIdle)(bool setDefaultChaprone);
-void (*VideoSend)(VideoFrame header, unsigned char *buf, int len);
+void (*VideoSend)(const VideoFrame* header, const uint8_t *buf, uint32_t len);
void (*HapticsSend)(unsigned long long path, float duration_s, float frequency, float amplitude);
-void (*TimeSyncSend)(TimeSync packet);
+void (*TimeSyncSend)(const TimeSync* packet);
void (*ShutdownRuntime)();
unsigned long long (*PathStringToHash)(const char *path);
@@ -207,23 +207,23 @@ void RequestIDR() {
}
}
-void InputReceive(TrackingInfo data) {
+void InputReceive(const TrackingInfo* data) {
if (g_driver_provider.hmd && g_driver_provider.hmd->m_Listener) {
g_driver_provider.hmd->m_Listener->m_Statistics->CountPacket(sizeof(TrackingInfo));
- uint64_t Current = GetTimestampUs();
+ const uint64_t Current = GetSystemTimestampUs();
TimeSync sendBuf = {};
sendBuf.mode = 3;
sendBuf.serverTime = Current - g_driver_provider.hmd->m_Listener->m_TimeDiff;
- sendBuf.trackingRecvFrameIndex = data.targetTimestampNs;
- TimeSyncSend(sendBuf);
+ sendBuf.trackingRecvFrameIndex = data->targetTimestampNs;
+ TimeSyncSend(&sendBuf);
- g_driver_provider.hmd->OnPoseUpdated(data);
+ g_driver_provider.hmd->OnPoseUpdated(*data);
}
}
-void TimeSyncReceive(TimeSync data) {
+void TimeSyncReceive(const TimeSync *data) {
if (g_driver_provider.hmd && g_driver_provider.hmd->m_Listener) {
- g_driver_provider.hmd->m_Listener->ProcessTimeSync(data);
+ g_driver_provider.hmd->m_Listener->ProcessTimeSync(*data);
}
}
void VideoErrorReportReceive() {
@@ -240,7 +240,7 @@ void ShutdownSteamvr() {
}
}
-void SetOpenvrProperty(unsigned long long top_level_path, OpenvrProperty prop) {
+void SetOpenvrProperty(uint64_t top_level_path, OpenvrProperty prop) {
auto device_it = g_driver_provider.tracked_devices.find(top_level_path);
if (device_it != g_driver_provider.tracked_devices.end()) {
@@ -254,7 +254,7 @@ void SetViewsConfig(const ViewsConfigData *config) {
}
}
-void SetBattery(unsigned long long top_level_path, float gauge_value, bool is_plugged) {
+void SetBattery(uint64_t top_level_path, float gauge_value, bool is_plugged) {
auto device_it = g_driver_provider.tracked_devices.find(top_level_path);
if (device_it != g_driver_provider.tracked_devices.end()) {
diff --git a/alvr/server/cpp/alvr_server/bindings.h b/alvr/server/cpp/alvr_server/bindings.h
index 67524c218b..15e1b4e95f 100644
--- a/alvr/server/cpp/alvr_server/bindings.h
+++ b/alvr/server/cpp/alvr_server/bindings.h
@@ -1,114 +1,122 @@
#pragma once
-struct EyeFov {
+#ifdef __cplusplus
+extern "C" {;
+#endif
+
+#include
+
+typedef struct EyeFov {
float left = 49.;
float right = 45.;
float top = 50.;
float bottom = 48.;
-};
+} EyeFov;
-struct TrackingQuat {
+typedef struct TrackingQuat {
float x;
float y;
float z;
float w;
-};
-struct TrackingVector3 {
+} TrackingQuat;
+typedef struct TrackingVector3 {
float x;
float y;
float z;
-};
-struct TrackingVector2 {
+} TrackingVector3;
+typedef struct TrackingVector2 {
float x;
float y;
-};
-struct TrackingInfo {
- static const unsigned int MAX_CONTROLLERS = 2;
- static const unsigned int BONE_COUNT = 19;
+} TrackingVector2;
+
+typedef struct TrackingPosef {
+ TrackingQuat orientation;
+ TrackingVector3 position;
+} TrackingPosef;
+
+typedef struct TrackingInfo {
+ static constexpr const uint32_t MAX_CONTROLLERS = 2;
+ static constexpr const uint32_t BONE_COUNT = 19;
+
struct Controller {
// Tracking info of hand. A3
- TrackingQuat boneRotations[BONE_COUNT];
- // TrackingQuat boneRotationsBase[alvrHandBone_MaxSkinnable];
+ TrackingQuat boneRotations[BONE_COUNT];
TrackingVector3 bonePositionsBase[BONE_COUNT];
- TrackingQuat boneRootOrientation;
- TrackingVector3 boneRootPosition;
+ TrackingPosef boneRootPose;
// Tracking info of controller. (float * 19 = 76 bytes)
- TrackingQuat orientation;
- TrackingVector3 position;
+ TrackingPosef pose;
TrackingVector3 angularVelocity;
TrackingVector3 linearVelocity;
TrackingVector2 joystickPosition;
TrackingVector2 trackpadPosition;
- unsigned long long buttons;
+ uint64_t buttons;
float triggerValue;
float gripValue;
- unsigned int handFingerConfidences;
+ uint32_t handFingerConfidences;
bool enabled;
bool isHand;
} controller[MAX_CONTROLLERS];
-
- TrackingQuat HeadPose_Pose_Orientation;
- TrackingVector3 HeadPose_Pose_Position;
-
- unsigned long long targetTimestampNs;
- unsigned char mounted;
-};
+
+ TrackingPosef headPose;
+ uint64_t targetTimestampNs;
+ uint8_t mounted;
+} TrackingInfo;
// Client >----(mode 0)----> Server
// Client <----(mode 1)----< Server
// Client >----(mode 2)----> Server
// Client <----(mode 3)----< Server
-struct TimeSync {
- unsigned int mode; // 0,1,2,3
- unsigned long long sequence;
- unsigned long long serverTime;
- unsigned long long clientTime;
+typedef struct TimeSync {
+ uint32_t mode; // 0,1,2,3
+ uint64_t sequence;
+ uint64_t serverTime;
+ uint64_t clientTime;
// Following value are filled by client only when mode=0.
- unsigned long long packetsLostTotal;
- unsigned long long packetsLostInSecond;
-
- unsigned int averageTotalLatency;
+ uint64_t packetsLostTotal;
+ uint64_t packetsLostInSecond;
- unsigned int averageSendLatency;
+ uint64_t averageDecodeLatency;
- unsigned int averageTransportLatency;
+ uint32_t averageTotalLatency;
- unsigned long long averageDecodeLatency;
+ uint32_t averageSendLatency;
- unsigned int idleTime;
+ uint32_t averageTransportLatency;
+
+ uint32_t idleTime;
- unsigned int fecFailure;
- unsigned long long fecFailureInSecond;
- unsigned long long fecFailureTotal;
+ uint64_t fecFailureInSecond;
+ uint64_t fecFailureTotal;
+ uint32_t fecFailure;
float fps;
- // Following value are filled by server only when mode=1.
- unsigned int serverTotalLatency;
-
// Following value are filled by server only when mode=3.
- unsigned long long trackingRecvFrameIndex;
-};
-struct VideoFrame {
- unsigned int type; // ALVR_PACKET_TYPE_VIDEO_FRAME
- unsigned int packetCounter;
- unsigned long long trackingFrameIndex;
+ uint64_t trackingRecvFrameIndex;
+
+ // Following value are filled by server only when mode=1.
+ uint32_t serverTotalLatency;
+} TimeSync;
+typedef struct VideoFrame {
+ uint32_t type; // ALVR_PACKET_TYPE_VIDEO_FRAME
+ uint32_t packetCounter;
+ uint64_t trackingFrameIndex;
// FEC decoder needs some value for identify video frame number to detect new frame.
// trackingFrameIndex becomes sometimes same value as previous video frame (in case of low
// tracking rate).
- unsigned long long videoFrameIndex;
- unsigned long long sentTime;
- unsigned int frameByteSize;
- unsigned int fecIndex;
- unsigned short fecPercentage;
+ uint64_t videoFrameIndex;
+ uint64_t sentTime;
+ uint32_t frameByteSize;
+ uint32_t fecIndex;
+ uint16_t fecPercentage;
// char frameBuffer[];
-};
+} VideoFrame;
enum OpenvrPropertyType {
Bool,
Float,
@@ -122,15 +130,15 @@ enum OpenvrPropertyType {
union OpenvrPropertyValue {
bool bool_;
float float_;
- int int32;
- unsigned long long uint64;
+ int32_t int32;
+ uint64_t uint64;
float vector3[3];
double double_;
char string[64];
};
struct OpenvrProperty {
- unsigned int key;
+ uint32_t key;
OpenvrPropertyType type;
OpenvrPropertyValue value;
};
@@ -167,12 +175,12 @@ extern "C" void (*LogWarn)(const char *stringPtr);
extern "C" void (*LogInfo)(const char *stringPtr);
extern "C" void (*LogDebug)(const char *stringPtr);
extern "C" void (*DriverReadyIdle)(bool setDefaultChaprone);
-extern "C" void (*VideoSend)(VideoFrame header, unsigned char *buf, int len);
+extern "C" void (*VideoSend)(const VideoFrame* header, const uint8_t *buf, uint32_t len);
extern "C" void (*HapticsSend)(unsigned long long path,
float duration_s,
float frequency,
float amplitude);
-extern "C" void (*TimeSyncSend)(TimeSync packet);
+extern "C" void (*TimeSyncSend)(const TimeSync* packet);
extern "C" void (*ShutdownRuntime)();
extern "C" unsigned long long (*PathStringToHash)(const char *path);
@@ -181,11 +189,15 @@ extern "C" void InitializeStreaming();
extern "C" void DeinitializeStreaming();
extern "C" void RequestIDR();
extern "C" void SetChaperone(float areaWidth, float areaHeight);
-extern "C" void InputReceive(TrackingInfo data);
-extern "C" void TimeSyncReceive(TimeSync data);
+extern "C" void InputReceive(const TrackingInfo* data);
+extern "C" void TimeSyncReceive(const TimeSync* data);
extern "C" void VideoErrorReportReceive();
extern "C" void ShutdownSteamvr();
-extern "C" void SetOpenvrProperty(unsigned long long topLevelPath, OpenvrProperty prop);
+extern "C" void SetOpenvrProperty(uint64_t topLevelPath, OpenvrProperty prop);
extern "C" void SetViewsConfig(const ViewsConfigData* config);
-extern "C" void SetBattery(unsigned long long topLevelPath, float gauge_value, bool is_plugged);
\ No newline at end of file
+extern "C" void SetBattery(uint64_t topLevelPath, float gauge_value, bool is_plugged);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/alvr/server/cpp/alvr_server/nvEncodeAPI.h b/alvr/server/cpp/alvr_server/nvEncodeAPI.h
index 8825f266d3..ac0abd57ff 100644
--- a/alvr/server/cpp/alvr_server/nvEncodeAPI.h
+++ b/alvr/server/cpp/alvr_server/nvEncodeAPI.h
@@ -1,7 +1,7 @@
/*
* This copyright notice applies to this header file only:
*
- * Copyright (c) 2010-2018 NVIDIA Corporation
+ * Copyright (c) 2010-2024 NVIDIA Corporation
*
* Permission is hereby granted, free of charge, to any person
* 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
* (referred to as NVENC) which provides fully-accelerated hardware-based video encoding.
* NvEncodeAPI provides the interface for NVIDIA video encoder (NVENC).
- * \date 2011-2018
+ * \date 2011-2024
* This file contains the interface constants, structure definitions and function prototypes.
*/
@@ -73,20 +73,21 @@ typedef RECT NVENC_RECT;
#else
#define NVENCAPI
// =========================================================================================
-#ifndef GUID
+#ifndef GUID_DEFINED
+#define GUID_DEFINED
/*!
* \struct GUID
* 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. */
uint16_t Data2; /**< [in]: Specifies the first 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.
The remaining 6 bytes contain the final 12 hexadecimal digits. */
-} GUID;
+} GUID, *LPGUID;
#endif // GUID
/**
@@ -108,9 +109,10 @@ typedef struct _NVENC_RECT
typedef void* NV_ENC_INPUT_PTR; /**< NVENCODE API input buffer */
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_CUSTREAM_PTR; /**< Pointer to CUstream*/
-#define NVENCAPI_MAJOR_VERSION 8
-#define NVENCAPI_MINOR_VERSION 1
+#define NVENCAPI_MAJOR_VERSION 13
+#define NVENCAPI_MINOR_VERSION 0
#define NVENCAPI_VERSION (NVENCAPI_MAJOR_VERSION | (NVENCAPI_MINOR_VERSION << 24))
@@ -124,6 +126,12 @@ typedef void* NV_ENC_REGISTERED_PTR; /**< A Resource that has been regist
#define NV_MAX_SEQ_HDR_LEN (512)
+#ifdef __GNUC__
+#define NV_ENC_DEPRECATED __attribute__ ((deprecated("WILL BE REMOVED IN A FUTURE VIDEO CODEC SDK VERSION")))
+#elif defined(_MSC_VER)
+#define NV_ENC_DEPRECATED __declspec(deprecated("WILL BE REMOVED IN A FUTURE VIDEO CODEC SDK VERSION"))
+#endif
+
// =========================================================================================
// Encode Codec GUIDS supported by the NvEncodeAPI interface.
// =========================================================================================
@@ -133,9 +141,13 @@ static const GUID NV_ENC_CODEC_H264_GUID =
{ 0x6bc82762, 0x4e63, 0x4ca4, { 0xaa, 0x85, 0x1e, 0x50, 0xf3, 0x21, 0xf6, 0xbf } };
// {790CDC88-4522-4d7b-9425-BDA9975F7603}
-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 } };
+// {0A352289-0AA7-4759-862D-5D15CD16D254}
+static const GUID NV_ENC_CODEC_AV1_GUID =
+{ 0x0a352289, 0x0aa7, 0x4759, { 0x86, 0x2d, 0x5d, 0x15, 0xcd, 0x16, 0xd2, 0x54 } };
+
// =========================================================================================
@@ -143,7 +155,7 @@ static const GUID NV_ENC_CODEC_HEVC_GUID =
// =========================================================================================
// {BFD6F8E7-233C-4341-8B3E-4818523803F4}
-static const GUID NV_ENC_CODEC_PROFILE_AUTOSELECT_GUID =
+static const GUID NV_ENC_CODEC_PROFILE_AUTOSELECT_GUID =
{ 0xbfd6f8e7, 0x233c, 0x4341, { 0x8b, 0x3e, 0x48, 0x18, 0x52, 0x38, 0x3, 0xf4 } };
// {0727BCAA-78C4-4c83-8C2F-EF3DFF267C6A}
@@ -158,77 +170,81 @@ static const GUID NV_ENC_H264_PROFILE_MAIN_GUID =
static const GUID NV_ENC_H264_PROFILE_HIGH_GUID =
{ 0xe7cbc309, 0x4f7a, 0x4b89, { 0xaf, 0x2a, 0xd5, 0x37, 0xc9, 0x2b, 0xe3, 0x10 } };
+// {8F0C337E-186C-48E9-A69D-7A8334089758}
+static const GUID NV_ENC_H264_PROFILE_HIGH_10_GUID =
+{ 0x8f0c337e, 0x186c, 0x48e9, { 0xa6, 0x9d, 0x7a, 0x83, 0x34, 0x08, 0x97, 0x58} };
+
+// {FF3242E9-613C-4295-A1E8-2A7FE94D8133}
+static const GUID NV_ENC_H264_PROFILE_HIGH_422_GUID =
+{ 0xff3242e9, 0x613c, 0x4295, { 0xa1, 0xe8, 0x2a, 0x7f, 0xe9, 0x4d, 0x81, 0x33 } };
+
// {7AC663CB-A598-4960-B844-339B261A7D52}
-static const GUID NV_ENC_H264_PROFILE_HIGH_444_GUID =
+static const GUID NV_ENC_H264_PROFILE_HIGH_444_GUID =
{ 0x7ac663cb, 0xa598, 0x4960, { 0xb8, 0x44, 0x33, 0x9b, 0x26, 0x1a, 0x7d, 0x52 } };
// {40847BF5-33F7-4601-9084-E8FE3C1DB8B7}
static const GUID NV_ENC_H264_PROFILE_STEREO_GUID =
{ 0x40847bf5, 0x33f7, 0x4601, { 0x90, 0x84, 0xe8, 0xfe, 0x3c, 0x1d, 0xb8, 0xb7 } };
-// {CE788D20-AAA9-4318-92BB-AC7E858C8D36}
-static const GUID NV_ENC_H264_PROFILE_SVC_TEMPORAL_SCALABILTY =
-{ 0xce788d20, 0xaaa9, 0x4318, { 0x92, 0xbb, 0xac, 0x7e, 0x85, 0x8c, 0x8d, 0x36 } };
-
// {B405AFAC-F32B-417B-89C4-9ABEED3E5978}
-static const GUID NV_ENC_H264_PROFILE_PROGRESSIVE_HIGH_GUID =
+static const GUID NV_ENC_H264_PROFILE_PROGRESSIVE_HIGH_GUID =
{ 0xb405afac, 0xf32b, 0x417b, { 0x89, 0xc4, 0x9a, 0xbe, 0xed, 0x3e, 0x59, 0x78 } };
// {AEC1BD87-E85B-48f2-84C3-98BCA6285072}
-static const GUID NV_ENC_H264_PROFILE_CONSTRAINED_HIGH_GUID =
+static const GUID NV_ENC_H264_PROFILE_CONSTRAINED_HIGH_GUID =
{ 0xaec1bd87, 0xe85b, 0x48f2, { 0x84, 0xc3, 0x98, 0xbc, 0xa6, 0x28, 0x50, 0x72 } };
// {B514C39A-B55B-40fa-878F-F1253B4DFDEC}
-static const GUID NV_ENC_HEVC_PROFILE_MAIN_GUID =
+static const GUID NV_ENC_HEVC_PROFILE_MAIN_GUID =
{ 0xb514c39a, 0xb55b, 0x40fa, { 0x87, 0x8f, 0xf1, 0x25, 0x3b, 0x4d, 0xfd, 0xec } };
// {fa4d2b6c-3a5b-411a-8018-0a3f5e3c9be5}
-static const GUID NV_ENC_HEVC_PROFILE_MAIN10_GUID =
+static const GUID NV_ENC_HEVC_PROFILE_MAIN10_GUID =
{ 0xfa4d2b6c, 0x3a5b, 0x411a, { 0x80, 0x18, 0x0a, 0x3f, 0x5e, 0x3c, 0x9b, 0xe5 } };
-// For HEVC Main 444 8 bit and HEVC Main 444 10 bit profiles only
+// For HEVC Main 422/444 8 bit and HEVC Main 422/444 10 bit profiles only
// {51ec32b5-1b4c-453c-9cbd-b616bd621341}
-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 } };
+// {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 } };
+
// =========================================================================================
// * Preset GUIDS supported by the NvEncodeAPI interface.
// =========================================================================================
-// {B2DFB705-4EBD-4C49-9B5F-24A777D3E587}
-static const GUID NV_ENC_PRESET_DEFAULT_GUID =
-{ 0xb2dfb705, 0x4ebd, 0x4c49, { 0x9b, 0x5f, 0x24, 0xa7, 0x77, 0xd3, 0xe5, 0x87 } };
-
-// {60E4C59F-E846-4484-A56D-CD45BE9FDDF6}
-static const GUID NV_ENC_PRESET_HP_GUID =
-{ 0x60e4c59f, 0xe846, 0x4484, { 0xa5, 0x6d, 0xcd, 0x45, 0xbe, 0x9f, 0xdd, 0xf6 } };
-// {34DBA71D-A77B-4B8F-9C3E-B6D5DA24C012}
-static const GUID NV_ENC_PRESET_HQ_GUID =
-{ 0x34dba71d, 0xa77b, 0x4b8f, { 0x9c, 0x3e, 0xb6, 0xd5, 0xda, 0x24, 0xc0, 0x12 } };
+// Performance degrades and quality improves as we move from P1 to P7. Presets P3 to P7 for H264 and Presets P2 to P7 for HEVC have B frames enabled by default
+// for HIGH_QUALITY and LOSSLESS tuning info, and will not work with Weighted Prediction enabled. In case Weighted Prediction is required, disable B frames by
+// setting frameIntervalP = 1
+// {FC0A8D3E-45F8-4CF8-80C7-298871590EBF}
+static const GUID NV_ENC_PRESET_P1_GUID =
+{ 0xfc0a8d3e, 0x45f8, 0x4cf8, { 0x80, 0xc7, 0x29, 0x88, 0x71, 0x59, 0xe, 0xbf } };
-// {82E3E450-BDBB-4e40-989C-82A90DF9EF32}
-static const GUID NV_ENC_PRESET_BD_GUID =
-{ 0x82e3e450, 0xbdbb, 0x4e40, { 0x98, 0x9c, 0x82, 0xa9, 0xd, 0xf9, 0xef, 0x32 } };
+// {F581CFB8-88D6-4381-93F0-DF13F9C27DAB}
+static const GUID NV_ENC_PRESET_P2_GUID =
+{ 0xf581cfb8, 0x88d6, 0x4381, { 0x93, 0xf0, 0xdf, 0x13, 0xf9, 0xc2, 0x7d, 0xab } };
-// {49DF21C5-6DFA-4feb-9787-6ACC9EFFB726}
-static const GUID NV_ENC_PRESET_LOW_LATENCY_DEFAULT_GUID =
-{ 0x49df21c5, 0x6dfa, 0x4feb, { 0x97, 0x87, 0x6a, 0xcc, 0x9e, 0xff, 0xb7, 0x26 } };
+// {36850110-3A07-441F-94D5-3670631F91F6}
+static const GUID NV_ENC_PRESET_P3_GUID =
+{ 0x36850110, 0x3a07, 0x441f, { 0x94, 0xd5, 0x36, 0x70, 0x63, 0x1f, 0x91, 0xf6 } };
-// {C5F733B9-EA97-4cf9-BEC2-BF78A74FD105}
-static const GUID NV_ENC_PRESET_LOW_LATENCY_HQ_GUID =
-{ 0xc5f733b9, 0xea97, 0x4cf9, { 0xbe, 0xc2, 0xbf, 0x78, 0xa7, 0x4f, 0xd1, 0x5 } };
+// {90A7B826-DF06-4862-B9D2-CD6D73A08681}
+static const GUID NV_ENC_PRESET_P4_GUID =
+{ 0x90a7b826, 0xdf06, 0x4862, { 0xb9, 0xd2, 0xcd, 0x6d, 0x73, 0xa0, 0x86, 0x81 } };
-// {67082A44-4BAD-48FA-98EA-93056D150A58}
-static const GUID NV_ENC_PRESET_LOW_LATENCY_HP_GUID =
-{ 0x67082a44, 0x4bad, 0x48fa, { 0x98, 0xea, 0x93, 0x5, 0x6d, 0x15, 0xa, 0x58 } };
+// {21C6E6B4-297A-4CBA-998F-B6CBDE72ADE3}
+static const GUID NV_ENC_PRESET_P5_GUID =
+{ 0x21c6e6b4, 0x297a, 0x4cba, { 0x99, 0x8f, 0xb6, 0xcb, 0xde, 0x72, 0xad, 0xe3 } };
-// {D5BFB716-C604-44e7-9BB8-DEA5510FC3AC}
-static const GUID NV_ENC_PRESET_LOSSLESS_DEFAULT_GUID =
-{ 0xd5bfb716, 0xc604, 0x44e7, { 0x9b, 0xb8, 0xde, 0xa5, 0x51, 0xf, 0xc3, 0xac } };
+// {8E75C279-6299-4AB6-8302-0B215A335CF5}
+static const GUID NV_ENC_PRESET_P6_GUID =
+{ 0x8e75c279, 0x6299, 0x4ab6, { 0x83, 0x2, 0xb, 0x21, 0x5a, 0x33, 0x5c, 0xf5 } };
-// {149998E7-2364-411d-82EF-179888093409}
-static const GUID NV_ENC_PRESET_LOSSLESS_HP_GUID =
-{ 0x149998e7, 0x2364, 0x411d, { 0x82, 0xef, 0x17, 0x98, 0x88, 0x9, 0x34, 0x9 } };
+// {84848C12-6F71-4C13-931B-53E283F57974}
+static const GUID NV_ENC_PRESET_P7_GUID =
+{ 0x84848c12, 0x6f71, 0x4c13, { 0x93, 0x1b, 0x53, 0xe2, 0x83, 0xf5, 0x79, 0x74 } };
/**
* \addtogroup ENCODER_STRUCTURE NvEncodeAPI Data structures
@@ -253,11 +269,34 @@ typedef enum _NV_ENC_PARAMS_RC_MODE
NV_ENC_PARAMS_RC_CONSTQP = 0x0, /**< Constant QP mode */
NV_ENC_PARAMS_RC_VBR = 0x1, /**< Variable bitrate mode */
NV_ENC_PARAMS_RC_CBR = 0x2, /**< Constant bitrate mode */
- NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ = 0x8, /**< low-delay CBR, high quality */
- NV_ENC_PARAMS_RC_CBR_HQ = 0x10, /**< CBR, high quality (slower) */
- NV_ENC_PARAMS_RC_VBR_HQ = 0x20 /**< VBR, high quality (slower) */
} NV_ENC_PARAMS_RC_MODE;
+/**
+ * Multi Pass encoding
+ */
+typedef enum _NV_ENC_MULTI_PASS
+{
+ NV_ENC_MULTI_PASS_DISABLED = 0x0, /**< Single Pass */
+ NV_ENC_TWO_PASS_QUARTER_RESOLUTION = 0x1, /**< Two Pass encoding is enabled where first Pass is quarter resolution */
+ NV_ENC_TWO_PASS_FULL_RESOLUTION = 0x2, /**< Two Pass encoding is enabled where first Pass is full resolution */
+} NV_ENC_MULTI_PASS;
+
+typedef enum _NV_ENC_STATE_RESTORE_TYPE
+{
+ NV_ENC_STATE_RESTORE_FULL = 0x01, /**< Restore full encoder state */
+ NV_ENC_STATE_RESTORE_RATE_CONTROL = 0x02, /**< Restore only rate control state */
+ NV_ENC_STATE_RESTORE_ENCODE = 0x03, /**< Restore full encoder state except for rate control state */
+} NV_ENC_STATE_RESTORE_TYPE;
+
+typedef enum _NV_ENC_OUTPUT_STATS_LEVEL
+{
+ NV_ENC_OUTPUT_STATS_NONE = 0, /** No output stats */
+ NV_ENC_OUTPUT_STATS_BLOCK_LEVEL = 1, /** Output stats for every block.
+ Block represents a CTB for HEVC, macroblock for H.264, super block for AV1 */
+ NV_ENC_OUTPUT_STATS_ROW_LEVEL = 2, /** Output stats for every row.
+ Row represents a CTB row for HEVC, macroblock row for H.264, super block row for AV1 */
+} NV_ENC_OUTPUT_STATS_LEVEL;
+
/**
* Emphasis Levels
*/
@@ -277,16 +316,11 @@ typedef enum _NV_ENC_EMPHASIS_MAP_LEVEL
typedef enum _NV_ENC_QP_MAP_MODE
{
NV_ENC_QP_MAP_DISABLED = 0x0, /**< Value in NV_ENC_PIC_PARAMS::qpDeltaMap have no effect. */
- NV_ENC_QP_MAP_EMPHASIS = 0x1, /**< Value in NV_ENC_PIC_PARAMS::qpDeltaMap will be treated as Empasis level. Currently this is only supported for H264 */
+ NV_ENC_QP_MAP_EMPHASIS = 0x1, /**< Value in NV_ENC_PIC_PARAMS::qpDeltaMap will be treated as Emphasis level. Currently this is only supported for H264 */
NV_ENC_QP_MAP_DELTA = 0x2, /**< Value in NV_ENC_PIC_PARAMS::qpDeltaMap will be treated as QP delta map. */
NV_ENC_QP_MAP = 0x3, /**< Currently This is not supported. Value in NV_ENC_PIC_PARAMS::qpDeltaMap will be treated as QP value. */
} NV_ENC_QP_MAP_MODE;
-#define NV_ENC_PARAMS_RC_VBR_MINQP (NV_ENC_PARAMS_RC_MODE)0x4 /**< Deprecated */
-#define NV_ENC_PARAMS_RC_2_PASS_QUALITY NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ /**< Deprecated */
-#define NV_ENC_PARAMS_RC_2_PASS_FRAMESIZE_CAP NV_ENC_PARAMS_RC_CBR_HQ /**< Deprecated */
-#define NV_ENC_PARAMS_RC_2_PASS_VBR NV_ENC_PARAMS_RC_VBR_HQ /**< Deprecated */
-#define NV_ENC_PARAMS_RC_CBR2 NV_ENC_PARAMS_RC_CBR /**< Deprecated */
/**
* Input picture structure
@@ -298,6 +332,20 @@ typedef enum _NV_ENC_PIC_STRUCT
NV_ENC_PIC_STRUCT_FIELD_BOTTOM_TOP = 0x03 /**< Field encoding bottom field first */
} 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
*/
@@ -310,6 +358,8 @@ typedef enum _NV_ENC_PIC_TYPE
NV_ENC_PIC_TYPE_BI = 0x04, /**< Bi-directionally predicted with only Intra MBs */
NV_ENC_PIC_TYPE_SKIPPED = 0x05, /**< Picture is skipped */
NV_ENC_PIC_TYPE_INTRA_REFRESH = 0x06, /**< First picture in intra refresh cycle */
+ NV_ENC_PIC_TYPE_NONREF_P = 0x07, /**< Non reference P picture */
+ NV_ENC_PIC_TYPE_SWITCH = 0x08, /**< Switch frame (AV1 only) */
NV_ENC_PIC_TYPE_UNKNOWN = 0xFF /**< Picture type unknown */
} NV_ENC_PIC_TYPE;
@@ -318,10 +368,10 @@ typedef enum _NV_ENC_PIC_TYPE
*/
typedef enum _NV_ENC_MV_PRECISION
{
- NV_ENC_MV_PRECISION_DEFAULT = 0x0, /** (if lookahead is enabled, input frames must remain available to the encoder until encode completion) */
uint32_t disableIadapt :1; /**< [in]: Set this to 1 to disable adaptive I-frame insertion at scene cuts (only has an effect when lookahead is enabled) */
uint32_t disableBadapt :1; /**< [in]: Set this to 1 to disable adaptive B-frame decision (only has an effect when lookahead is enabled) */
- uint32_t enableTemporalAQ :1; /**< [in]: Set this to 1 to enable temporal AQ for H.264 */
+ uint32_t enableTemporalAQ :1; /**< [in]: Set this to 1 to enable temporal AQ */
uint32_t zeroReorderDelay :1; /**< [in]: Set this to 1 to indicate zero latency operation (no reordering delay, num_reorder_frames=0) */
uint32_t enableNonRefP :1; /**< [in]: Set this to 1 to enable automatic insertion of non-reference P-frames (no effect if enablePTD=0) */
uint32_t strictGOPTarget :1; /**< [in]: Set this to 1 to minimize GOP-to-GOP rate fluctuations */
- uint32_t aqStrength :4; /**< [in]: When AQ (Spatial) is enabled (i.e. NV_ENC_RC_PARAMS::enableAQ is set), this field is used to specify AQ strength. AQ strength scale is from 1 (low) - 15 (aggressive). If not set, strength is autoselected by driver. */
- uint32_t reservedBitFields :16; /**< [in]: Reserved bitfields and must be set to 0 */
+ uint32_t aqStrength :4; /**< [in]: When AQ (Spatial) is enabled (i.e. NV_ENC_RC_PARAMS::enableAQ is set), this field is used to specify AQ strength. AQ strength scale is from 1 (low) - 15 (aggressive).
+ If not set, strength is auto selected by driver. */
+ uint32_t enableExtLookahead :1; /**< [in]: Set this to 1 to enable lookahead externally.
+ Application must call NvEncLookahead() for NV_ENC_RC_PARAMS::lookaheadDepth number of frames,
+ before calling NvEncEncodePicture() for the first frame */
+ uint32_t reservedBitFields :15; /**< [in]: Reserved bitfields and must be set to 0 */
NV_ENC_QP minQP; /**< [in]: Specifies the minimum QP used for rate control. Client must set NV_ENC_CONFIG::enableMinQP to 1. */
NV_ENC_QP maxQP; /**< [in]: Specifies the maximum QP used for rate control. Client must set NV_ENC_CONFIG::enableMaxQP to 1. */
- NV_ENC_QP initialRCQP; /**< [in]: Specifies the initial QP used for rate control. Client must set NV_ENC_CONFIG::enableInitialRCQP to 1. */
- uint32_t temporallayerIdxMask; /**< [in]: Specifies the temporal layers (as a bitmask) whose QPs have changed. Valid max bitmask is [2^NV_ENC_CAPS_NUM_MAX_TEMPORAL_LAYERS - 1] */
- uint8_t temporalLayerQP[8]; /**< [in]: Specifies the temporal layer QPs used for rate control. Temporal layer index is used as as the array index */
- uint8_t targetQuality; /**< [in]: Target CQ (Constant Quality) level for VBR mode (range 0-51 with 0-automatic) */
+ NV_ENC_QP initialRCQP; /**< [in]: Specifies the initial QP hint used for rate control. The parameter is just used as hint to influence the QP difference between I,P and B frames.
+ Client must set NV_ENC_CONFIG::enableInitialRCQP to 1. */
+ uint32_t temporallayerIdxMask; /**< [in]: Specifies the temporal layers (as a bitmask) whose QPs have changed. Valid max bitmask is [2^NV_ENC_CAPS_NUM_MAX_TEMPORAL_LAYERS - 1].
+ Applicable only for constant QP mode (NV_ENC_RC_PARAMS::rateControlMode = NV_ENC_PARAMS_RC_CONSTQP). */
+ uint8_t temporalLayerQP[8]; /**< [in]: Specifies the temporal layer QPs used for rate control. Temporal layer index is used as the array index.
+ Applicable only for constant QP mode (NV_ENC_RC_PARAMS::rateControlMode = NV_ENC_PARAMS_RC_CONSTQP). */
+ uint8_t targetQuality; /**< [in]: Target CQ (Constant Quality) level for VBR mode (range 0-51 for H264/HEVC, 0-63 for AV1 with 0-automatic) */
uint8_t targetQualityLSB; /**< [in]: Fractional part of target quality (as 8.8 fixed point format) */
- uint16_t lookaheadDepth; /**< [in]: Maximum depth of lookahead with range 0-32 (only used if enableLookahead=1) */
- uint32_t reserved1;
- NV_ENC_QP_MAP_MODE qpMapMode; /**< [in]: This flag is used to interpret values in array pecified 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.
- Emphasis Level can be assigned any value specified in enum NV_ENC_EMPHASIS_MAP_LEVEL.
- Emphasis Level Map is used to specify regions to be encoded at varying levels of quality.
+ uint16_t lookaheadDepth; /**< [in]: Maximum depth of lookahead with range 0-(31 - number of B frames).
+ 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,
+ is set to 2 by default for low latency tuning info and 1 by default for ultra low latency tuning info */
+ 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.
+ 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 Map is used to specify regions to be encoded at varying levels of quality.
The hardware encoder adjusts the quantization within the image as per the provided emphasis map,
- by adjusting the quantization parameter (QP) assigned to each macroblock. This adjustment is commonly called “Delta QPâ€.
- The adjustment depends on the absolute QP decided by the rate control algorithm, and is applied after the rate control has decided each macroblock’s QP.
- Since the Delta QP overrides rate control, enabling emphasis level map may violate bitrate and VBV buffersize constraints.
- Emphasis level map is useful in situations when client has a priori knowledge of the image complexity (e.g. via use of NVFBC's Classification feature) and encoding those high-complexity areas at higher quality (lower QP) is important, even at the possible cost of violating bitrate/VBV buffersize constraints
+ by adjusting the quantization parameter (QP) assigned to each macroblock. This adjustment is commonly called "Delta QP".
+ The adjustment depends on the absolute QP decided by the rate control algorithm, and is applied after the rate control has decided each macroblock's QP.
+ Since the Delta QP overrides rate control, enabling Emphasis Level Map may violate bitrate and VBV buffer size constraints.
+ Emphasis Level Map is useful in situations where client has a priori knowledge of the image complexity (e.g. via use of NVFBC's Classification feature) and encoding those high-complexity areas at higher quality (lower QP) is important, even at the possible cost of violating bitrate/VBV buffer size constraints
This feature is not supported when AQ( Spatial/Temporal) is enabled.
This feature is only supported for H264 codec currently.
-
- Set this to NV_ENC_QP_MAP_DELTA to treat values specified by NV_ENC_PIC_PARAMS::qpDeltaMap as QPDelta. This specify QP modifier to be applied on top of the QP chosen by rate control
-
+
+ Set this to NV_ENC_QP_MAP_DELTA to treat values specified by NV_ENC_PIC_PARAMS::qpDeltaMap as QP Delta. This specifies QP modifier to be applied on top of the QP chosen by rate control
+
Set this to NV_ENC_QP_MAP_DISABLED to ignore NV_ENC_PIC_PARAMS::qpDeltaMap values. In this case, qpDeltaMap should be set to NULL.
-
+
Other values are reserved for future use.*/
- uint32_t reserved[7];
+ 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.
+ 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 / '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;
+ NV_ENC_LOOKAHEAD_LEVEL lookaheadLevel; /**< [in]: Specifies the lookahead level. Higher level may improve quality at the expense of performance. */
+ uint8_t viewBitrateRatios[MAX_NUM_VIEWS_MINUS_1]; /**< [in]: Specifies the bit rate ratio for each view of MV-HEVC except the base view.
+ The base view bit rate ratio = 100 - (sum of bit rate ratio of all other views). */
+ uint8_t reserved3;
+ uint32_t reserved1;
} 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 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 */
+ uint32_t skipClockTimestampInsertion; /**< [in] 0 : Inserts Clock Timestamp if NV_ENC_CONFIG_H264::enableTimeCode (H264) or
+ NV_ENC_CONFIG_HEVC::outputTimeCodeSEI (HEVC) is specified
+ 1 : Skips insertion of Clock Timestamp for current frame */
+} NV_ENC_TIME_CODE;
+
+#define MULTIVIEW_MAX_NUM_REF_DISPLAY 32
+
+/**
+ * G.14.2.3 3D reference displays information SEI message syntax elements
+ */
+typedef struct _HEVC_3D_REFERENCE_DISPLAY_INFO
+{
+ uint32_t refViewingDistanceFlag : 1; /**< [in] Specifies the presence of reference viewing distance.*/
+ uint32_t threeDimensionalReferenceDisplaysExtensionFlag : 1; /**< [in] Should be set to 0 for this version of specs. Saved for future use.*/
+ uint32_t reserved : 30; /**< [in] Reserved and must be set to 0 */
+ int32_t precRefDisplayWidth; /**< [in] Specifies the exponent of the maximum allowable truncation error for refDisplayWidth[i]. Range 0-31, inclusive.*/
+ int32_t precRefViewingDist; /**< [in] Specifies the exponent of the maximum allowable truncation error for refViewingDist[i]. Range 0-31, inclusive.*/
+ int32_t numRefDisplaysMinus1; /**< [in] Plus 1 specifies the number of reference displays that are signalled in this SEI message. Range 0-31, inclusive.*/
+ int32_t leftViewId[MULTIVIEW_MAX_NUM_REF_DISPLAY]; /**< [in] Indicates the ViewId of the left view of a stereo pair corresponding to the i-th reference display.*/
+ int32_t rightViewId[MULTIVIEW_MAX_NUM_REF_DISPLAY]; /**< [in] Indicates the ViewId of the right view of a stereo-pair corresponding to the i-th reference display.*/
+ int32_t exponentRefDisplayWidth[MULTIVIEW_MAX_NUM_REF_DISPLAY]; /**< [in] Specifies the exponent part of the reference display width of the i-th reference display.*/
+ int32_t mantissaRefDisplayWidth[MULTIVIEW_MAX_NUM_REF_DISPLAY]; /**< [in] Specifies the mantissa part of the reference display width of the i-th reference display.*/
+ int32_t exponentRefViewingDistance[MULTIVIEW_MAX_NUM_REF_DISPLAY]; /**< [in] Specifies the exponent part of the reference viewing distance of the i-th reference display.*/
+ int32_t mantissaRefViewingDistance[MULTIVIEW_MAX_NUM_REF_DISPLAY]; /**< [in] Specifies the mantissa part of the reference viewing distance of the i-th reference display.*/
+ int32_t numSampleShiftPlus512[MULTIVIEW_MAX_NUM_REF_DISPLAY]; /**< [in] Indicates the recommended additional horizontal shift for a stereo pair corresponding to the i-th reference baseline and the i-th reference display.*/
+ uint8_t additionalShiftPresentFlag[MULTIVIEW_MAX_NUM_REF_DISPLAY]; /**< [in] Equal to 1 indicates that the information about additional horizontal shift of the left and right views for the i-th reference display is present in this SEI message.*/
+ uint32_t reserved2[4]; /**< [in] Reserved and must be set to 0 */
+} HEVC_3D_REFERENCE_DISPLAY_INFO;
+
+/**
+ * Struct for storing x and y chroma points
+ */
+typedef struct _CHROMA_POINTS {
+ uint16_t x;
+ uint16_t y;
+} CHROMA_POINTS;
+
+/**
+ * Struct for storing mastering-display information
+ * Refer to the AV1 spec 6.7.4 Metadata high dynamic range mastering display color volume semantics OR
+ * HEVC spec D.2.28 Mastering display colour volume SEI message syntax
+ */
+typedef struct _MASTERING_DISPLAY_INFO {
+ CHROMA_POINTS g;
+ CHROMA_POINTS b;
+ CHROMA_POINTS r;
+ CHROMA_POINTS whitePoint;
+ uint32_t maxLuma;
+ uint32_t minLuma;
+} MASTERING_DISPLAY_INFO;
+
+/*
+* Refer to Av1 spec 6.7.3 Metadata high dynamic range content light level semantics OR
+* HEVC spec D.2.35 Content light level information SEI message syntax
+*/
+typedef struct _CONTENT_LIGHT_LEVEL
+{
+ uint16_t maxContentLightLevel;
+ uint16_t maxPicAverageLightLevel;
+} CONTENT_LIGHT_LEVEL;
/**
@@ -1206,20 +1719,24 @@ typedef struct _NV_ENC_QP
*/
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;
typedef NV_ENC_CONFIG_H264_VUI_PARAMETERS NV_ENC_CONFIG_HEVC_VUI_PARAMETERS;
@@ -1227,22 +1744,23 @@ typedef NV_ENC_CONFIG_H264_VUI_PARAMETERS NV_ENC_CONFIG_HEVC_VUI_PARAMETERS;
/**
* \struct _NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE
* 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
{
- uint32_t numCandsPerBlk16x16 : 4; /**< [in]: Supported for H264,HEVC.It Specifies the number of candidates per 16x16 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 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 numCandsPerBlk16x16 : 4; /**< [in]: Supported for H264, HEVC. It Specifies the number of candidates per 16x16 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 numCandsPerBlk8x8 : 4; /**< [in]: Supported for H264, HEVC. Specifies the number of candidates per 8x8 block. */
+ 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. */
} NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE;
/**
* \struct _NVENC_EXTERNAL_ME_HINT
- * External Motion Vector hint structure.
+ * External Motion Vector hint structure for H264 and HEVC.
*/
typedef struct _NVENC_EXTERNAL_ME_HINT
{
@@ -1255,6 +1773,26 @@ typedef struct _NVENC_EXTERNAL_ME_HINT
int32_t lastOfMB : 1; /**< [in]: Set to 1 for the last MV of macroblock. */
} 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. Permissible value range: [-4092,4092]. */
+ 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. Permissible value range: [-2044,2044]. */
+ 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
@@ -1264,20 +1802,21 @@ typedef struct _NV_ENC_CONFIG_H264
{
uint32_t enableTemporalSVC :1; /**< [in]: Set to 1 to enable SVC temporal*/
uint32_t enableStereoMVC :1; /**< [in]: Set to 1 to enable stereo MVC*/
- uint32_t hierarchicalPFrames :1; /**< [in]: Set to 1 to enable hierarchical PFrames */
- uint32_t hierarchicalBFrames :1; /**< [in]: Set to 1 to enable hierarchical BFrames */
+ 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 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 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 outputRecoveryPointSEI :1; /**< [in]: Set to 1 to enable writing of recovery point SEI message */
uint32_t enableIntraRefresh :1; /**< [in]: Set to 1 to enable gradual decoder refresh or intra refresh. If the GOP structure uses B frames this will be ignored */
- uint32_t enableConstrainedEncoding :1; /**< [in]: Set this to 1 to enable constrainedFrame encoding where each slice in the constarined picture is independent of other slices
+ uint32_t enableConstrainedEncoding :1; /**< [in]: Set this to 1 to enable constrainedFrame encoding where each slice in the constrained picture is independent of other slices.
+ Constrained encoding works only with rectangular slices.
Check support for constrained encoding using ::NV_ENC_CAPS_SUPPORT_CONSTRAINED_ENCODING caps. */
uint32_t repeatSPSPPS :1; /**< [in]: Set to 1 to enable writing of Sequence and Picture parameter for every IDR frame */
- uint32_t enableVFR :1; /**< [in]: Set to 1 to enable variable frame rate. */
+ uint32_t enableVFR :1; /**< [in]: Setting enableVFR=1 currently only sets the fixed_frame_rate_flag=0 in the VUI but otherwise
+ has no impact on the encoder behavior. For more details please refer to E.1 VUI syntax of H.264 standard. Note, however, that NVENC does not support VFR encoding and rate control. */
uint32_t enableLTR :1; /**< [in]: Set to 1 to enable LTR (Long Term Reference) frame support. LTR can be used in two modes: "LTR Trust" mode and "LTR Per Picture" mode.
LTR Trust mode: In this mode, ltrNumFrames pictures after IDR are automatically marked as LTR. This mode is enabled by setting ltrTrustMode = 1.
Use of LTR Trust mode is strongly discouraged as this mode may be deprecated in future.
@@ -1288,23 +1827,43 @@ typedef struct _NV_ENC_CONFIG_H264
uint32_t qpPrimeYZeroTransformBypassFlag :1; /**< [in]: To enable lossless encode set this to 1, set QP to 0 and RC_mode to NV_ENC_PARAMS_RC_CONSTQP and profile to HIGH_444_PREDICTIVE_PROFILE.
Check support for lossless encoding using ::NV_ENC_CAPS_SUPPORT_LOSSLESS_ENCODE caps. */
uint32_t useConstrainedIntraPred :1; /**< [in]: Set 1 to enable constrained intra prediction. */
- uint32_t reservedBitFields :15; /**< [in]: Reserved bitfields and must be set to 0 */
+ uint32_t enableFillerDataInsertion :1; /**< [in]: Set to 1 to enable insertion of filler data in the bitstream.
+ This flag will take effect only when CBR rate control mode is in use and both
+ NV_ENC_INITIALIZE_PARAMS::frameRateNum and
+ NV_ENC_INITIALIZE_PARAMS::frameRateDen are set to non-zero
+ values. Setting this field when
+ NV_ENC_INITIALIZE_PARAMS::enableOutputInVidmem is also set
+ is currently not supported and will make ::NvEncInitializeEncoder()
+ return an error. */
+ uint32_t disableSVCPrefixNalu :1; /**< [in]: Set to 1 to disable writing of SVC Prefix NALU preceding each slice in bitstream.
+ 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
+ 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.
+ 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. */
+ 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 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 disableDeblockingFilterIDC; /**< [in]: Specifies the deblocking filter mode. Permissible value range: [0,2] */
- uint32_t numTemporalLayers; /**< [in]: Specifies max temporal layers to be used for hierarchical coding. Valid value range is [1,::NV_ENC_CAPS_NUM_MAX_TEMPORAL_LAYERS] */
+ uint32_t disableDeblockingFilterIDC; /**< [in]: Specifies the deblocking filter mode. Permissible value range: [0,2]. This flag corresponds
+ to the flag disable_deblocking_filter_idc specified in section 7.4.3 of H.264 specification,
+ which specifies whether the operation of the deblocking filter shall be disabled across some
+ block edges of the slice and specifies for which edges the filtering is disabled. See section
+ 7.4.3 of H.264 specification for more details.*/
+ uint32_t numTemporalLayers; /**< [in]: Specifies number of temporal layers to be used for hierarchical coding / temporal SVC. Valid value range is [1,::NV_ENC_CAPS_NUM_MAX_TEMPORAL_LAYERS] */
uint32_t spsId; /**< [in]: Specifies the SPS id of the sequence header */
uint32_t ppsId; /**< [in]: Specifies the PPS id of the picture header */
NV_ENC_H264_ADAPTIVE_TRANSFORM_MODE adaptiveTransformMode; /**< [in]: Specifies the AdaptiveTransform Mode. Check support for AdaptiveTransform mode using ::NV_ENC_CAPS_SUPPORT_ADAPTIVE_TRANSFORM caps. */
NV_ENC_H264_FMO_MODE fmoMode; /**< [in]: Specified the FMO Mode. Check support for FMO using ::NV_ENC_CAPS_SUPPORT_FMO caps. */
NV_ENC_H264_BDIRECT_MODE bdirectMode; /**< [in]: Specifies the BDirect mode. Check support for BDirect mode using ::NV_ENC_CAPS_SUPPORT_BDIRECT_MODE caps.*/
NV_ENC_H264_ENTROPY_CODING_MODE entropyCodingMode; /**< [in]: Specifies the entropy coding mode. Check support for CABAC mode using ::NV_ENC_CAPS_SUPPORT_CABAC caps. */
- NV_ENC_STEREO_PACKING_MODE stereoMode; /**< [in]: Specifies the stereo frame packing mode which is to be signalled in frame packing arrangement SEI */
+ NV_ENC_STEREO_PACKING_MODE stereoMode; /**< [in]: Specifies the stereo frame packing mode which is to be signaled in frame packing arrangement SEI */
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 maxNumRefFrames; /**< [in]: Specifies the DPB size used for encoding. Setting it to 0 will let driver use the default dpb size.
+ uint32_t maxNumRefFrames; /**< [in]: Specifies the DPB size used for encoding. Setting it to 0 will let driver use the default DPB size.
The low latency application which wants to invalidate reference frame as an error resilience tool
is recommended to use a large DPB size so that the encoder can keep old reference frames which can be used if recent
frames are invalidated. */
@@ -1317,19 +1876,31 @@ typedef struct _NV_ENC_CONFIG_H264
sliceMode = 1, sliceModeData specifies maximum # of bytes in each slice (except last slice)
sliceMode = 2, sliceModeData specifies # of MB rows in each slice (except last slice)
sliceMode = 3, sliceModeData specifies number of slices in the picture. Driver will divide picture into slices optimally */
- NV_ENC_CONFIG_H264_VUI_PARAMETERS h264VUIParameters; /**< [in]: Specifies the H264 video usability info pamameters */
+ NV_ENC_CONFIG_H264_VUI_PARAMETERS h264VUIParameters; /**< [in]: Specifies the H264 video usability info parameters */
uint32_t ltrNumFrames; /**< [in]: Specifies the number of LTR frames. 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 Per Picture" mode (ltrTrustMode = 0 and ltrMarkFrame = 1), ltrNumFrames specifies maximum number of LTR frames in DPB. */
uint32_t ltrTrustMode; /**< [in]: Specifies the LTR operating mode. See comments near NV_ENC_CONFIG_H264::enableLTR for description of the two modes.
- Set to 1 to use "LTR Trust" mode of LTR operation. Clients are discouraged to use "LTR Trust" mode as this mode may
+ Set to 1 to use "LTR Trust" mode of LTR operation. Clients are discouraged to use "LTR Trust" mode as this mode may
be deprecated in future releases.
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.
Check support for YUV444 encoding using ::NV_ENC_CAPS_SUPPORT_YUV444_ENCODE caps.*/
- uint32_t maxTemporalLayers; /**< [in]: Specifies the max temporal layer used for 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
+ 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.*/
- uint32_t reserved1[269]; /**< [in]: Reserved and must be set to 0 */
+ NV_ENC_NUM_REF_FRAMES numRefL0; /**< [in]: Specifies max number of reference frames in reference picture list L0, that can be used by hardware for prediction of a frame.
+ 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.
+ Check support for numRefL1 using ::NV_ENC_CAPS_SUPPORT_MULTIPLE_REF_FRAMES caps. */
+ NV_ENC_BIT_DEPTH outputBitDepth; /**< [in]: Specifies pixel bit depth of encoded video. Should be set to NV_ENC_BIT_DEPTH_8 for 8 bit, NV_ENC_BIT_DEPTH_10 for 10 bit. */
+ NV_ENC_BIT_DEPTH inputBitDepth; /**< [in]: Specifies pixel bit depth of video input. Should be set to NV_ENC_BIT_DEPTH_8 for 8 bit input, NV_ENC_BIT_DEPTH_10 for 10 bit input. */
+ NV_ENC_TEMPORAL_FILTER_LEVEL tfLevel; /**< [in]: Specifies the strength of temporal filtering. Check support for temporal filter using ::NV_ENC_CAPS_SUPPORT_TEMPORAL_FILTER caps.
+ Temporal filter feature is supported only if frameIntervalP >= 5.
+ If ZeroReorderDelay or enableStereoMVC is enabled, the temporal filter feature is not supported.
+ Temporal filter is recommended for natural contents. */
+ uint32_t reserved1[264]; /**< [in]: Reserved and must be set to 0 */
void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */
} NV_ENC_CONFIG_H264;
@@ -1355,20 +1926,48 @@ typedef struct _NV_ENC_CONFIG_HEVC
ltrTrustMode = 0 and ltrMarkFrame = 1 for the picture to be marked as LTR. This is the preferred mode
for using LTR.
Note that LTRs are not supported if encoding session is configured with B-frames */
- uint32_t disableSPSPPS :1; /**< [in]: Set 1 to disable VPS,SPS and PPS signalling in the bitstream. */
+ uint32_t disableSPSPPS :1; /**< [in]: Set 1 to disable VPS, SPS and PPS signaling in the bitstream. */
uint32_t repeatSPSPPS :1; /**< [in]: Set 1 to output VPS,SPS and PPS for every IDR 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, 3 for yuv444 input.*/
- uint32_t pixelBitDepthMinus8 :3; /**< [in]: Specifies pixel bit depth minus 8. Should be set to 0 for 8 bit input, 2 for 10 bit input.*/
- uint32_t reserved :18; /**< [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 reserved3 :3; /**< [in]: Reserved and must be set to 0.*/
+ uint32_t enableFillerDataInsertion :1; /**< [in]: Set to 1 to enable insertion of filler data in the bitstream.
+ This flag will take effect only when CBR rate control mode is in use and both
+ NV_ENC_INITIALIZE_PARAMS::frameRateNum and
+ NV_ENC_INITIALIZE_PARAMS::frameRateDen are set to non-zero
+ values. Setting this field when
+ NV_ENC_INITIALIZE_PARAMS::enableOutputInVidmem is also set
+ is currently not supported and will make ::NvEncInitializeEncoder()
+ return an error. */
+ uint32_t enableConstrainedEncoding :1; /**< [in]: Set this to 1 to enable constrainedFrame encoding where each slice in the constrained picture is independent of other slices.
+ Constrained encoding works only with rectangular slices.
+ 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 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.
+ This flag will be ignored if the value returned for ::NV_ENC_CAPS_SINGLE_SLICE_INTRA_REFRESH caps is false. */
+ 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 enableTemporalSVC :1; /**< [in]: Set to 1 to enable SVC temporal */
+ uint32_t enableMVHEVC :1; /**< [in]: Set to 1 to enable stereo MVHEVC. This feature currently supports only 2 views.
+ This feature is disabled for LTR, Alpha Layer Encoding, UniDirectionalB,
+ PyramidalME, Lookahead, Temporal Filter, Split encoding, 2 pass encoding and for NV_ENC_TUNING_INFO other than
+ NV_ENC_TUNING_INFO_HIGH_QUALITY. */
+ uint32_t outputHevc3DReferenceDisplayInfo :1; /**< [in]: Set to 1 to write 3D reference displays information SEI message for MVHEVC */
+ uint32_t outputMaxCll :1; /**< [in]: Set to 1 to write Content Light Level information SEI message for HEVC */
+ uint32_t outputMasteringDisplay :1; /**< [in]: Set to 1 to write Mastering displays information SEI message for HEVC */
+ uint32_t reserved :7; /**< [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 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 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 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 spsId; /**< [in]: Specifies the SPS id of the sequence header */
uint32_t ppsId; /**< [in]: Specifies the PPS id of the picture header */
@@ -1381,27 +1980,164 @@ typedef struct _NV_ENC_CONFIG_HEVC
sliceMode = 2, sliceModeData specifies # of CTU rows in each slice (except last slice)
sliceMode = 3, sliceModeData specifies number of slices in the picture. Driver will divide picture into slices optimally */
uint32_t maxTemporalLayersMinus1; /**< [in]: Specifies the max temporal layer used for hierarchical coding. */
- NV_ENC_CONFIG_HEVC_VUI_PARAMETERS hevcVUIParameters; /**< [in]: Specifies the HEVC video usability info pamameters */
+ NV_ENC_CONFIG_HEVC_VUI_PARAMETERS hevcVUIParameters; /**< [in]: Specifies the HEVC video usability info parameters */
uint32_t ltrTrustMode; /**< [in]: Specifies the LTR operating mode. See comments near NV_ENC_CONFIG_HEVC::enableLTR for description of the two modes.
- Set to 1 to use "LTR Trust" mode of LTR operation. Clients are discouraged to use "LTR Trust" mode as this mode may
+ Set to 1 to use "LTR Trust" mode of LTR operation. Clients are discouraged to use "LTR Trust" mode as this mode may
be deprecated in future releases.
Set to 0 when using "LTR Per Picture" mode of LTR operation. */
- uint32_t reserved1[217]; /**< [in]: Reserved and must be set to 0.*/
- void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */
+ 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_NUM_REF_FRAMES numRefL0; /**< [in]: Specifies max number of reference frames in reference picture list L0, that can be used by hardware for prediction of a frame.
+ 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.
+ Check support for numRefL1 using ::NV_ENC_CAPS_SUPPORT_MULTIPLE_REF_FRAMES caps. */
+ NV_ENC_TEMPORAL_FILTER_LEVEL tfLevel; /**< [in]: Specifies the strength of the temporal filtering. Check support for temporal filtering using ::NV_ENC_CAPS_SUPPORT_TEMPORAL_FILTER caps.
+ Temporal filter feature is supported only if frameIntervalP >= 5.
+ Temporal filter feature is not supported with ZeroReorderDelay/enableStereoMVC/AlphaLayerEncoding.
+ Temporal filter is recommended for natural contents. */
+ uint32_t disableDeblockingFilterIDC; /**< [in]: Specifies the deblocking filter mode. Permissible value range: [0,2]. This flag corresponds
+ to the flag pps_deblocking_filter_disabled_flag specified in section 7.4.3.3 of H.265 specification,
+ which specifies whether the operation of the deblocking filter shall be disabled across some
+ block edges of the slice and specifies for which edges the filtering is disabled. See section
+ 7.4.3.3 of H.265 specification for more details.*/
+ NV_ENC_BIT_DEPTH outputBitDepth; /**< [in]: Specifies pixel bit depth of encoded video. Should be set to NV_ENC_BIT_DEPTH_8 for 8 bit, NV_ENC_BIT_DEPTH_10 for 10 bit.
+ SW will do the bitdepth conversion internally from inputBitDepth -> outputBitDepth if bit depths differ
+ Support for 8 bit input to 10 bit encode conversion only*/
+ NV_ENC_BIT_DEPTH inputBitDepth; /**< [in]: Specifies pixel bit depth of video input. Should be set to NV_ENC_BIT_DEPTH_8 for 8 bit input, NV_ENC_BIT_DEPTH_10 for 10 bit input.*/
+ uint32_t numTemporalLayers; /**< [in]: Specifies the number of temporal layers to be used for hierarchical coding.*/
+ uint32_t numViews; /**< [in]: Specifies number of views for MVHEVC */
+ uint32_t reserved1[208]; /**< [in]: Reserved and must be set to 0.*/
+ void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */
} 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 enableLTR : 1; /**< [in]: Set to 1 to enable LTR (Long Term Reference) frame support. LTR can be used in "LTR Per Picture" mode.
+ In this mode, client can control whether the current picture should be marked as LTR.
+ use ltrMarkFrame = 1 for the picture to be marked as LTR.
+ Note that LTRs are not supported if encoding session is configured with B-frames */
+ uint32_t enableTemporalSVC : 1; /**< [in]: Set to 1 to enable SVC temporal */
+ uint32_t outputMaxCll : 1; /**< [in]: Set to 1 to write Content Light Level metadata for Av1 */
+ uint32_t outputMasteringDisplay : 1; /**< [in]: Set to 1 to write Mastering displays metadata for Av1 */
+ uint32_t reserved4 : 2; /**< [in]: Reserved and must be set to 0.*/
+ 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 reserved2; /**< [in]: Reserved and must be set to 0.*/
+ 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. Cannot be reconfigured and must be specified during encoder creation if temporal layer is considered. */
+ 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. */
+ NV_ENC_BIT_DEPTH outputBitDepth; /**< [in]: Specifies pixel bit depth of encoded video. Should be set to NV_ENC_BIT_DEPTH_8 for 8 bit, NV_ENC_BIT_DEPTH_10 for 10 bit.
+ HW will do the bitdepth conversion internally from inputBitDepth -> outputBitDepth if bit depths differ
+ Support for 8 bit input to 10 bit encode conversion only */
+ NV_ENC_BIT_DEPTH inputBitDepth; /**< [in]: Specifies pixel bit depth of video input. Should be set to NV_ENC_BIT_DEPTH_8 for 8 bit input, NV_ENC_BIT_DEPTH_10 for 10 bit input. */
+ uint32_t ltrNumFrames; /**< [in]: In "LTR Per Picture" mode (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 numTemporalLayers; /**< [in]: Specifies the number of temporal layers to be used for hierarchical coding.*/
+ NV_ENC_TEMPORAL_FILTER_LEVEL tfLevel; /**< [in]: Specifies the strength of temporal filtering. Check support for temporal filter using ::NV_ENC_CAPS_SUPPORT_TEMPORAL_FILTER caps.
+ Temporal filter feature is supported only if frameIntervalP >= 5.
+ If ZeroReorderDelay or enableStereoMVC is enabled, the temporal filter feature is not supported.
+ Temporal filter is recommended for natural contents. */
+ uint32_t reserved1[230]; /**< [in]: Reserved and must be set to 0.*/
+ void* reserved3[62]; /**< [in]: Reserved and must be set to NULL */
+} NV_ENC_CONFIG_AV1;
+
/**
* \struct _NV_ENC_CONFIG_H264_MEONLY
* H264 encoder configuration parameters for ME only Mode
- *
+ *
*/
typedef struct _NV_ENC_CONFIG_H264_MEONLY
{
- uint32_t disablePartition16x16 :1; /**< [in]: Disable MotionEstimation on 16x16 blocks*/
- uint32_t disablePartition8x16 :1; /**< [in]: Disable MotionEstimation on 8x16 blocks*/
- uint32_t disablePartition16x8 :1; /**< [in]: Disable MotionEstimation on 16x8 blocks*/
- uint32_t disablePartition8x8 :1; /**< [in]: Disable MotionEstimation on 8x8 blocks*/
- uint32_t disableIntraSearch :1; /**< [in]: Disable Intra search during MotionEstimation*/
+ uint32_t disablePartition16x16 :1; /**< [in]: Disable Motion Estimation on 16x16 blocks*/
+ uint32_t disablePartition8x16 :1; /**< [in]: Disable Motion Estimation on 8x16 blocks*/
+ uint32_t disablePartition16x8 :1; /**< [in]: Disable Motion Estimation on 16x8 blocks*/
+ uint32_t disablePartition8x8 :1; /**< [in]: Disable Motion Estimation on 8x8 blocks*/
+ uint32_t disableIntraSearch :1; /**< [in]: Disable Intra search during Motion Estimation*/
uint32_t bStereoEnable :1; /**< [in]: Enable Stereo Mode for Motion Estimation where each view is independently executed*/
uint32_t reserved :26; /**< [in]: Reserved and must be set to 0 */
uint32_t reserved1 [255]; /**< [in]: Reserved and must be set to 0 */
@@ -1412,11 +2148,11 @@ typedef struct _NV_ENC_CONFIG_H264_MEONLY
/**
* \struct _NV_ENC_CONFIG_HEVC_MEONLY
* HEVC encoder configuration parameters for ME only Mode
- *
+ *
*/
typedef struct _NV_ENC_CONFIG_HEVC_MEONLY
{
- uint32_t reserved [256]; /**< [in]: Reserved and must be set to 0 */
+ uint32_t reserved [256]; /**< [in]: Reserved and must be set to 0 */
void* reserved1[64]; /**< [in]: Reserved and must be set to NULL */
} NV_ENC_CONFIG_HEVC_MEONLY;
@@ -1428,6 +2164,7 @@ typedef union _NV_ENC_CODEC_CONFIG
{
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_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_HEVC_MEONLY hevcMeOnlyConfig; /**< [in]: Specifies the HEVC-specific ME only encoder configuration. */
uint32_t reserved[320]; /**< [in]: Reserved and must be set to 0 */
@@ -1441,7 +2178,7 @@ typedef union _NV_ENC_CODEC_CONFIG
typedef struct _NV_ENC_CONFIG
{
uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_CONFIG_VER. */
- GUID profileGUID; /**< [in]: Specifies the codec profile guid. If client specifies \p NV_ENC_CODEC_PROFILE_AUTOSELECT_GUID the NvEncodeAPI interface will select the appropriate codec profile. */
+ GUID profileGUID; /**< [in]: Specifies the codec profile GUID. If client specifies \p NV_ENC_CODEC_PROFILE_AUTOSELECT_GUID the NvEncodeAPI interface will select the appropriate codec profile. */
uint32_t gopLength; /**< [in]: Specifies the number of pictures in one GOP. Low latency application client can set goplength to NVENC_INFINITE_GOPLENGTH so that keyframes are not inserted automatically. */
int32_t frameIntervalP; /**< [in]: Specifies the GOP pattern as follows: \p frameIntervalP = 0: I, 1: IPP, 2: IBP, 3: IBBP If goplength is set to NVENC_INFINITE_GOPLENGTH \p frameIntervalP should be set to 1. */
uint32_t monoChromeEncoding; /**< [in]: Set this to 1 to enable monochrome encoding for this session. */
@@ -1456,8 +2193,34 @@ typedef struct _NV_ENC_CONFIG
} NV_ENC_CONFIG;
/** macro for constructing the version field of ::_NV_ENC_CONFIG */
-#define NV_ENC_CONFIG_VER (NVENCAPI_STRUCT_VERSION(7) | ( 1<<31 ))
+#define NV_ENC_CONFIG_VER (NVENCAPI_STRUCT_VERSION(9) | ( 1<<31 ))
+
+/**
+ * Tuning information of NVENC encoding (TuningInfo is not applicable to H264 and HEVC MEOnly mode).
+ */
+typedef enum NV_ENC_TUNING_INFO
+{
+ NV_ENC_TUNING_INFO_UNDEFINED = 0, /**< Undefined tuningInfo. Invalid value for encoding. */
+ NV_ENC_TUNING_INFO_HIGH_QUALITY = 1, /**< Tune presets for latency tolerant encoding.*/
+ NV_ENC_TUNING_INFO_LOW_LATENCY = 2, /**< Tune presets for low latency streaming.*/
+ NV_ENC_TUNING_INFO_ULTRA_LOW_LATENCY = 3, /**< Tune presets for ultra low latency streaming.*/
+ NV_ENC_TUNING_INFO_LOSSLESS = 4, /**< Tune presets for lossless encoding.*/
+ NV_ENC_TUNING_INFO_ULTRA_HIGH_QUALITY = 5, /**< Tune presets for latency tolerant encoding for higher quality. Only supported for HEVC and AV1 on Turing+ architectures */
+ NV_ENC_TUNING_INFO_COUNT /**< Count number of tuningInfos. Invalid value. */
+}NV_ENC_TUNING_INFO;
+/**
+ * Split Encoding Modes (Split Encoding is not applicable to H264).
+ */
+typedef enum _NV_ENC_SPLIT_ENCODE_MODE
+{
+ NV_ENC_SPLIT_AUTO_MODE = 0, /**< Default value, implicit mode. Split frame will not always be enabled, even if NVENC number > 1. It will be decided by the driver based on preset, tuning information and video resolution. */
+ NV_ENC_SPLIT_AUTO_FORCED_MODE = 1, /**< Split frame forced mode enabled with number of strips automatically selected by driver to best fit configuration. If NVENC number > 1, split frame will be forced. */
+ NV_ENC_SPLIT_TWO_FORCED_MODE = 2, /**< Forced 2-strip split frame encoding (if NVENC number > 1, 1-strip encode otherwise) */
+ NV_ENC_SPLIT_THREE_FORCED_MODE = 3, /**< Forced 3-strip split frame encoding (if NVENC number > 2, NVENC number of strips otherwise) */
+ NV_ENC_SPLIT_FOUR_FORCED_MODE = 4, /**< Forced 4-strip split frame encoding (if NVENC number > 3, NVENC number of strips otherwise) */
+ NV_ENC_SPLIT_DISABLE_MODE = 15, /**< Both split frame auto mode and forced mode are disabled */
+} NV_ENC_SPLIT_ENCODE_MODE;
/**
* \struct _NV_ENC_INITIALIZE_PARAMS
@@ -1470,37 +2233,62 @@ typedef struct _NV_ENC_INITIALIZE_PARAMS
GUID presetGUID; /**< [in]: Specifies the preset for encoding. If the preset GUID is set then , the preset configuration will be applied before any other parameter. */
uint32_t encodeWidth; /**< [in]: Specifies the encode width. If not set ::NvEncInitializeEncoder() API will fail. */
uint32_t encodeHeight; /**< [in]: Specifies the encode height. If not set ::NvEncInitializeEncoder() API will fail. */
- uint32_t darWidth; /**< [in]: Specifies the display aspect ratio Width. */
- uint32_t darHeight; /**< [in]: Specifies the display aspect ratio height. */
+ uint32_t darWidth; /**< [in]: Specifies the display aspect ratio width (H264/HEVC) or the render width (AV1). */
+ uint32_t darHeight; /**< [in]: Specifies the display aspect ratio height (H264/HEVC) or the render height (AV1). */
uint32_t frameRateNum; /**< [in]: Specifies the numerator for frame rate used for encoding in frames per second ( Frame rate = frameRateNum / frameRateDen ). */
uint32_t frameRateDen; /**< [in]: Specifies the denominator for frame rate used for encoding in frames per second ( Frame rate = frameRateNum / frameRateDen ). */
uint32_t enableEncodeAsync; /**< [in]: Set this to 1 to enable asynchronous mode and is expected to use events to get picture completion notification. */
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 enableSubFrameWrite :1; /**< [in]: Set this to 1 to write out available bitstream to memory at subframe intervals */
- 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 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 (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. */
+ 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. */
uint32_t enableMEOnlyMode :1; /**< [in]: Set to 1 to enable ME Only Mode .*/
- uint32_t enableWeightedPrediction :1; /**< [in]: Set this to 1 to enable weighted prediction. Not supported if encode session is configured for B-Frames( 'frameIntervalP' in NV_ENC_CONFIG is greater than 1).*/
- uint32_t reservedBitFields :27; /**< [in]: Reserved bitfields and must be set to 0 */
+ uint32_t enableWeightedPrediction :1; /**< [in]: Set this to 1 to enable weighted prediction. Not supported if encode session is configured for B-Frames (i.e. NV_ENC_CONFIG::frameIntervalP > 1 or preset >=P3 when tuningInfo = ::NV_ENC_TUNING_INFO_HIGH_QUALITY or
+ tuningInfo = ::NV_ENC_TUNING_INFO_LOSSLESS. This is because preset >=p3 internally enables B frames when tuningInfo = ::NV_ENC_TUNING_INFO_HIGH_QUALITY or ::NV_ENC_TUNING_INFO_LOSSLESS). */
+ uint32_t splitEncodeMode :4; /**< [in]: Split Encoding mode in NVENC (Split Encoding is not applicable to H264).
+ Not supported if any of the following features: weighted prediction, alpha layer encoding,
+ subframe mode, output into video memory buffer, picture timing/buffering period SEI message
+ insertion with DX12 interface are enabled in case of HEVC.
+ For AV1, split encoding is not supported when output into video memory buffer is enabled.
+ For valid values see ::NV_ENC_SPLIT_ENCODE_MODE enum.*/
+ uint32_t enableOutputInVidmem :1; /**< [in]: Set this to 1 to enable output of NVENC in video memory buffer created by application. This feature is not supported for HEVC ME only mode. */
+ uint32_t enableReconFrameOutput :1; /**< [in]: Set this to 1 to enable reconstructed frame output. */
+ uint32_t enableOutputStats :1; /**< [in]: Set this to 1 to enable encoded frame output stats. Client must allocate buffer of size equal to number of blocks multiplied by the size of
+ NV_ENC_OUTPUT_STATS_BLOCK struct in system memory and assign to NV_ENC_LOCK_BITSTREAM::encodedOutputStatsPtr to receive the encoded frame output stats.*/
+ uint32_t enableUniDirectionalB :1; /**< [in]: Set this to 1 to enable uni directional B-frame(both reference will be from past). It will give better compression
+ efficiency for LowLatency/UltraLowLatency use case. Value of parameter is ignored when regular B frames are used. */
+ uint32_t reservedBitFields :19; /**< [in]: Reserved bitfields and must be set to 0 */
uint32_t privDataSize; /**< [in]: Reserved private data buffer size and must be set to 0 */
+ uint32_t reserved; /**< [in]: Reserved and must be set to 0 */
void* privData; /**< [in]: Reserved private data buffer and must be set to NULL */
NV_ENC_CONFIG* encodeConfig; /**< [in]: Specifies the advanced codec specific structure. If client has sent a valid codec config structure, it will override parameters set by the NV_ENC_INITIALIZE_PARAMS::presetGUID parameter. If set to NULL the NvEncodeAPI interface will use the NV_ENC_INITIALIZE_PARAMS::presetGUID to set the codec specific parameters.
- Client can also optionally query the NvEncodeAPI interface to get codec specific parameters for a presetGUID using ::NvEncGetEncodePresetConfig() API. It can then modify (if required) some of the codec config parameters and send down a custom config structure as part of ::_NV_ENC_INITIALIZE_PARAMS.
- Even in this case client is recommended to pass the same preset guid it has used in ::NvEncGetEncodePresetConfig() API to query the config structure; as NV_ENC_INITIALIZE_PARAMS::presetGUID. This will not override the custom config structure but will be used to determine other Encoder HW specific parameters not exposed in the API. */
+ Client can also optionally query the NvEncodeAPI interface to get codec specific parameters for a presetGUID using ::NvEncGetEncodePresetConfigEx() API. It can then modify (if required) some of the codec config parameters and send down a custom config structure as part of ::_NV_ENC_INITIALIZE_PARAMS.
+ Even in this case client is recommended to pass the same preset guid it has used in ::NvEncGetEncodePresetConfigEx() API to query the config structure; as NV_ENC_INITIALIZE_PARAMS::presetGUID. This will not override the custom config structure but will be used to determine other Encoder HW specific parameters not exposed in the API. */
uint32_t maxEncodeWidth; /**< [in]: Maximum encode width to be used for current Encode session.
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.
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.
This client must also set NV_ENC_INITIALIZE_PARAMS::enableExternalMEHints to 1. */
- uint32_t reserved [289]; /**< [in]: Reserved and must be set to 0 */
+ 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]: Input buffer format. Used only when DX12 interface type is used */
+ uint32_t numStateBuffers; /**< [in]: Number of state buffers to allocate to save encoder state. Set this to value greater than zero to enable encoding without advancing the encoder state. */
+ NV_ENC_OUTPUT_STATS_LEVEL outputStatsLevel; /**< [in]: Specifies the level for encoded frame output stats, when NV_ENC_INITIALIZE_PARAMS::enableOutputStats is set to 1.
+ Client should allocate buffer of size equal to number of blocks multiplied by the size of NV_ENC_OUTPUT_STATS_BLOCK struct
+ if NV_ENC_INITIALIZE_PARAMS::outputStatsLevel is set to NV_ENC_OUTPUT_STATS_BLOCK or number of rows multiplied by the size of
+ NV_ENC_OUTPUT_STATS_ROW struct if NV_ENC_INITIALIZE_PARAMS::outputStatsLevel is set to NV_ENC_OUTPUT_STATS_ROW
+ in system memory and assign to NV_ENC_LOCK_BITSTREAM::encodedOutputStatsPtr to receive the encoded frame output stats. */
+ uint32_t reserved1 [284]; /**< [in]: Reserved and must be set to 0 */
void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */
} 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) | ( 1<<31 ))
+#define NV_ENC_INITIALIZE_PARAMS_VER (NVENCAPI_STRUCT_VERSION(7) | ( 1<<31 ))
/**
@@ -1510,6 +2298,7 @@ typedef struct _NV_ENC_INITIALIZE_PARAMS
typedef struct _NV_ENC_RECONFIGURE_PARAMS
{
uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_RECONFIGURE_PARAMS_VER. */
+ uint32_t reserved; /**< [in]: Reserved and must be set to 0 */
NV_ENC_INITIALIZE_PARAMS reInitEncodeParams; /**< [in]: Encoder session re-initialization parameters.
If reInitEncodeParams.encodeConfig is NULL and
reInitEncodeParams.presetGUID is the same as the preset
@@ -1529,29 +2318,59 @@ typedef struct _NV_ENC_RECONFIGURE_PARAMS
If NV_ENC_INITIALIZE_PARAMS::enablePTD is set to 1, encoder will force the frame type to IDR */
uint32_t forceIDR :1; /**< [in]: Encode the current picture as an IDR picture. This flag is only valid when Picture type decision is taken by the Encoder
[_NV_ENC_INITIALIZE_PARAMS::enablePTD == 1]. */
- uint32_t reserved :30;
+ uint32_t reserved1 :30;
+ uint32_t reserved2; /**< [in]: Reserved and must be set to 0 */
}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) | ( 1<<31 ))
+#define NV_ENC_RECONFIGURE_PARAMS_VER (NVENCAPI_STRUCT_VERSION(2) | ( 1<<31 ))
/**
* \struct _NV_ENC_PRESET_CONFIG
* Encoder preset config
- */
+ */
typedef struct _NV_ENC_PRESET_CONFIG
{
uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_PRESET_CONFIG_VER. */
+ uint32_t reserved; /**< [in]: Reserved and must be set to 0 */
NV_ENC_CONFIG presetCfg; /**< [out]: preset config returned by the Nvidia Video Encoder interface. */
- uint32_t reserved1[255]; /**< [in]: Reserved and must be set to 0 */
+ uint32_t reserved1[256]; /**< [in]: Reserved and must be set to 0 */
void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */
}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) | ( 1<<31 ))
+#define NV_ENC_PRESET_CONFIG_VER (NVENCAPI_STRUCT_VERSION(5) | ( 1<<31 ))
+/**
+ * \struct _NV_ENC_PIC_PARAMS_MVC
+ * MVC-specific parameters to be sent on a per-frame basis.
+ */
+typedef struct _NV_ENC_PIC_PARAMS_MVC
+{
+ uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_PIC_PARAMS_MVC_VER. */
+ uint32_t viewID; /**< [in]: Specifies the view ID associated with the current input view. */
+ uint32_t temporalID; /**< [in]: Specifies the temporal ID associated with the current input view. */
+ uint32_t priorityID; /**< [in]: Specifies the priority ID associated with the current input view. Reserved and ignored by the NvEncodeAPI interface. */
+ uint32_t reserved1[12]; /**< [in]: Reserved and must be set to 0. */
+ void* reserved2[8]; /**< [in]: Reserved and must be set to NULL. */
+}NV_ENC_PIC_PARAMS_MVC;
+
+/** macro for constructing the version field of ::_NV_ENC_PIC_PARAMS_MVC */
+#define NV_ENC_PIC_PARAMS_MVC_VER NVENCAPI_STRUCT_VERSION(1)
+
+
+/**
+ * \union _NV_ENC_PIC_PARAMS_H264_EXT
+ * H264 extension picture parameters
+ */
+typedef union _NV_ENC_PIC_PARAMS_H264_EXT
+{
+ NV_ENC_PIC_PARAMS_MVC mvcPicParams; /**< [in]: Specifies the MVC picture parameters. */
+ uint32_t reserved1[32]; /**< [in]: Reserved and must be set to 0. */
+}NV_ENC_PIC_PARAMS_H264_EXT;
+
/**
* \struct _NV_ENC_SEI_PAYLOAD
* User SEI message
@@ -1568,17 +2387,17 @@ typedef struct _NV_ENC_SEI_PAYLOAD
/**
* \struct _NV_ENC_PIC_PARAMS_H264
* H264 specific enc pic params. sent on a per frame basis.
- */
+ */
typedef struct _NV_ENC_PIC_PARAMS_H264
{
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 reserved3; /**< [in]: Reserved and must be set to 0 */
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 colourPlaneId; /**< [in]: Specifies the colour plane ID associated with the current input. */
- uint32_t forceIntraRefreshWithFrameCnt; /**< [in]: Forces an intra refresh with duration equal to intraRefreshFrameCnt.
- When outputRecoveryPointSEI is set this is value is used for recovery_frame_cnt in recovery point SEI message
+ uint32_t forceIntraRefreshWithFrameCnt; /**< [in]: Forces an intra refresh with duration equal to intraRefreshFrameCnt.
+ When outputRecoveryPointSEI is set this is value is used for recovery_frame_cnt in recovery point SEI message
forceIntraRefreshWithFrameCnt cannot be used if B frames are used in the GOP structure specified */
- uint32_t constrainedFrame :1; /**< [in]: Set to 1 if client wants to encode this frame with each slice completely independent of other slices in the frame.
+ uint32_t constrainedFrame :1; /**< [in]: Set to 1 if client wants to encode this frame with each slice completely independent of other slices in the frame.
NV_ENC_INITIALIZE_PARAMS::enableConstrainedEncoding should be set to 1 */
uint32_t sliceModeDataUpdate :1; /**< [in]: Set to 1 if client wants to change the sliceModeData field to specify new sliceSize Parameter
When forceIntraRefreshWithFrameCnt is set it will have priority over sliceMode setting */
@@ -1599,10 +2418,16 @@ typedef struct _NV_ENC_PIC_PARAMS_H264
sliceMode = 2, sliceModeData specifies # of MB rows in each slice (except last slice)
sliceMode = 3, sliceModeData specifies number of slices in the picture. Driver will divide picture into slices optimally */
uint32_t ltrMarkFrameIdx; /**< [in]: Specifies the long term referenceframe index to use for marking this frame as LTR.*/
- uint32_t ltrUseFrameBitmap; /**< [in]: Specifies the the associated bitmap of LTR frame indices to use when encoding this frame. */
+ uint32_t ltrUseFrameBitmap; /**< [in]: Specifies the associated bitmap of LTR frame indices to use when encoding this frame. */
uint32_t ltrUsageMode; /**< [in]: Not supported. Reserved for future use and must be set to 0. */
- uint32_t reserved [243]; /**< [in]: Reserved and must be set to 0. */
- void* reserved2[62]; /**< [in]: Reserved and must be set to NULL. */
+ uint32_t forceIntraSliceCount; /**< [in]: Specifies the number of slices to be forced to Intra in the current picture.
+ This option along with forceIntraSliceIdx[] array needs to be used with sliceMode = 3 only */
+ 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 */
+ NV_ENC_PIC_PARAMS_H264_EXT h264ExtPicParams; /**< [in]: Specifies the H264 extension config parameters using this config. */
+ 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 [202]; /**< [in]: Reserved and must be set to 0. */
+ void* reserved2[61]; /**< [in]: Reserved and must be set to NULL. */
} NV_ENC_PIC_PARAMS_H264;
/**
@@ -1614,18 +2439,20 @@ typedef struct _NV_ENC_PIC_PARAMS_HEVC
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.
- When outputRecoveryPointSEI is set this is value is used for recovery_frame_cnt in recovery point SEI message
+ uint32_t forceIntraRefreshWithFrameCnt; /**< [in]: Forces an intra refresh with duration equal to intraRefreshFrameCnt.
+ When outputRecoveryPointSEI is set this is value is used for recovery_frame_cnt in recovery point SEI message
forceIntraRefreshWithFrameCnt cannot be used if B frames are used in the GOP structure specified */
- uint32_t constrainedFrame :1; /**< [in]: Set to 1 if client wants to encode this frame with each slice completely independent of other slices in the frame.
+ uint32_t constrainedFrame :1; /**< [in]: Set to 1 if client wants to encode this frame with each slice completely independent of other slices in the frame.
NV_ENC_INITIALIZE_PARAMS::enableConstrainedEncoding should be set to 1 */
uint32_t sliceModeDataUpdate :1; /**< [in]: Set to 1 if client wants to change the sliceModeData field to specify new sliceSize Parameter
When forceIntraRefreshWithFrameCnt is set it will have priority over sliceMode setting */
uint32_t ltrMarkFrame :1; /**< [in]: Set to 1 if client wants to mark this frame as LTR */
uint32_t ltrUseFrames :1; /**< [in]: Set to 1 if client allows encoding this frame using the LTR frames specified in ltrFrameBitmap */
- uint32_t reservedBitFields :28; /**< [in]: Reserved bit fields and must be set to 0 */
- uint8_t* sliceTypeData; /**< [in]: Array which specifies the slice type used to force intra slice for a particular slice. Currently supported only for NV_ENC_CONFIG_H264::sliceMode == 3.
- Client should allocate array of size sliceModeData where sliceModeData is specified in field of ::_NV_ENC_CONFIG_H264
+ uint32_t temporalConfigUpdate :1; /**< [in]: Set to 1 if client wants to change the number of temporal layers in temporal SVC encoding */
+ uint32_t reservedBitFields :27; /**< [in]: Reserved bit fields and must be set to 0 */
+ uint32_t reserved1; /**< [in]: Reserved and must be set to 0. */
+ uint8_t* sliceTypeData; /**< [in]: Array which specifies the slice type used to force intra slice for a particular slice. Currently supported only for NV_ENC_CONFIG_H264::sliceMode == 3.
+ Client should allocate array of size sliceModeData where sliceModeData is specified in field of ::_NV_ENC_CONFIG_H264
Array element with index n corresponds to nth slice. To force a particular slice to intra client should set corresponding array element to NV_ENC_SLICE_TYPE_I
all other array elements should be set to NV_ENC_SLICE_TYPE_DEFAULT */
uint32_t sliceTypeArrayCnt; /**< [in]: Client should set this to the number of elements allocated in sliceTypeData array. If sliceTypeData is NULL then this should be set to 0 */
@@ -1644,10 +2471,76 @@ typedef struct _NV_ENC_PIC_PARAMS_HEVC
uint32_t seiPayloadArrayCnt; /**< [in]: Specifies the number of elements allocated in seiPayloadArray array. */
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. */
- uint32_t reserved2 [244]; /**< [in]: Reserved and must be set to 0. */
- void* reserved3[61]; /**< [in]: Reserved and must be set to NULL. */
+ 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 numTemporalLayers; /**< [in]: Specifies the number of temporal layers to be used for hierarchical coding. The set only takes place when temporalConfigUpdate == 1.*/
+ uint32_t viewId; /**< [in]: Specifies the view id of the picture */
+ HEVC_3D_REFERENCE_DISPLAY_INFO *p3DReferenceDisplayInfo; /**< [in]: Specifies the 3D reference displays information SEI message.
+ Applicable only when NV_ENC_CONFIG_HEVC::outputHevc3DReferenceDisplayInfo is set to 1. */
+ CONTENT_LIGHT_LEVEL *pMaxCll; /**< [in]: Specifies the Content light level information SEI syntax*/
+ MASTERING_DISPLAY_INFO *pMasteringDisplay; /**< [in]: Specifies the Mastering display colour volume SEI syntax*/
+ uint32_t reserved2[234]; /**< [in]: Reserved and must be set to 0. */
+ void* reserved3[58]; /**< [in]: Reserved and must be set to NULL. */
} 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 ltrMarkFrame : 1; /**< [in]: Set to 1 if client wants to mark this frame as LTR */
+ uint32_t ltrUseFrames : 1; /**< [in]: Set to 1 if client allows encoding this frame using the LTR frames specified in ltrFrameBitmap */
+ uint32_t temporalConfigUpdate : 1; /**< [in]: Set to 1 if client wants to change the number of temporal layers in temporal SVC encoding */
+ uint32_t reservedBitFields : 19; /**< [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 reserved; /**< [in]: Reserved and must be set to 0. */
+ 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 reserved1; /**< [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 ltrMarkFrameIdx; /**< [in]: Specifies the long term reference frame index to use for marking this frame as LTR.*/
+ uint32_t ltrUseFrameBitmap; /**< [in]: Specifies the associated bitmap of LTR frame indices to use when encoding this frame. */
+ uint32_t numTemporalLayers; /**< [in]: Specifies the number of temporal layers to be used for hierarchical coding. The set only takes place when temporalConfigUpdate == 1.*/
+ uint32_t reserved4; /**< [in]: Reserved and must be set to 0. */
+ CONTENT_LIGHT_LEVEL *pMaxCll; /**< [in]: Specifies the Content light level metadata syntax*/
+ MASTERING_DISPLAY_INFO *pMasteringDisplay; /**< [in]: Specifies the Mastering display colour volume metadata syntax*/
+ uint32_t reserved2[242]; /**< [in]: Reserved and must be set to 0. */
+ void* reserved3[59]; /**< [in]: Reserved and must be set to NULL. */
+} NV_ENC_PIC_PARAMS_AV1;
+
/**
* Codec specific per-picture encoding parameters.
*/
@@ -1655,9 +2548,11 @@ typedef union _NV_ENC_CODEC_PIC_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_AV1 av1PicParams; /**< [in]: AV1 encode picture params. */
uint32_t reserved[256]; /**< [in]: Reserved and must be set to 0. */
} NV_ENC_CODEC_PIC_PARAMS;
+
/**
* \struct _NV_ENC_PIC_PARAMS
* Encoding parameters that need to be sent on a per frame basis.
@@ -1665,42 +2560,68 @@ typedef union _NV_ENC_CODEC_PIC_PARAMS
typedef struct _NV_ENC_PIC_PARAMS
{
uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_PIC_PARAMS_VER. */
- uint32_t inputWidth; /**< [in]: Specifies the input buffer width */
- uint32_t inputHeight; /**< [in]: Specifies the input buffer height */
+ uint32_t inputWidth; /**< [in]: Specifies the input frame width */
+ uint32_t inputHeight; /**< [in]: Specifies the input frame height */
uint32_t inputPitch; /**< [in]: Specifies the input buffer pitch. If pitch value is not known, set this to inputWidth. */
- uint32_t encodePicFlags; /**< [in]: Specifies bit-wise OR`ed encode pic flags. See ::NV_ENC_PIC_FLAGS enum. */
- uint32_t frameIdx; /**< [in]: Specifies the frame index associated with the input frame [optional]. */
- uint64_t inputTimeStamp; /**< [in]: Specifies presentation timestamp associated with the input picture. */
+ uint32_t encodePicFlags; /**< [in]: Specifies bit-wise OR of encode picture flags. See ::NV_ENC_PIC_FLAGS enum. */
+ uint32_t frameIdx; /**< [in]: Specifies the frame index associated with the input frame. It is necessary to pass this as monotonically increasing starting 0 when lookaheadLevel, UHQ Tuning Info
+ or encoding same frames multiple times without advancing encoder state feature are enabled */
+ uint64_t inputTimeStamp; /**< [in]: Specifies opaque data which is associated with the encoded frame, but not actually encoded in the output bitstream.
+ This opaque data can be used later to uniquely refer to the corresponding encoded frame. For example, it can be used
+ for identifying the frame to be invalidated in the reference picture buffer, if lost at the client. */
uint64_t inputDuration; /**< [in]: Specifies duration of the input picture */
NV_ENC_INPUT_PTR inputBuffer; /**< [in]: Specifies the input buffer pointer. Client must use a pointer obtained from ::NvEncCreateInputBuffer() or ::NvEncMapInputResource() APIs.*/
- NV_ENC_OUTPUT_PTR outputBitstream; /**< [in]: Specifies the pointer to output buffer. Client should use a pointer obtained from ::NvEncCreateBitstreamBuffer() API. */
- void* completionEvent; /**< [in]: Specifies an event to be signalled on completion of encoding of this Frame [only if operating in Asynchronous mode]. Each output buffer should be associated with a distinct event pointer. */
+ NV_ENC_OUTPUT_PTR outputBitstream; /**< [in]: Specifies the output buffer pointer.
+ If NV_ENC_INITIALIZE_PARAMS::enableOutputInVidmem is set to 0, specifies the pointer to output buffer. Client should use a pointer obtained from ::NvEncCreateBitstreamBuffer() API.
+ If NV_ENC_INITIALIZE_PARAMS::enableOutputInVidmem is set to 1, client should allocate buffer in video memory for NV_ENC_ENCODE_OUT_PARAMS struct and encoded bitstream data. Client
+ should use a pointer obtained from ::NvEncMapInputResource() API, when mapping this output buffer and assign it to NV_ENC_PIC_PARAMS::outputBitstream.
+ First 256 bytes of this buffer should be interpreted as NV_ENC_ENCODE_OUT_PARAMS struct followed by encoded bitstream data. Recommended size for output buffer is sum of size of
+ NV_ENC_ENCODE_OUT_PARAMS struct and twice the input frame size for lower resolution eg. CIF and 1.5 times the input frame size for higher resolutions. If encoded bitstream size is
+ greater than the allocated buffer size for encoded bitstream, then the output buffer will have encoded bitstream data equal to buffer size. All CUDA operations on this buffer must use
+ the default stream. */
+ void* completionEvent; /**< [in]: Specifies an event to be signaled on completion of encoding of this Frame [only if operating in Asynchronous mode]. Each output buffer should be associated with a distinct event pointer. */
NV_ENC_BUFFER_FORMAT bufferFmt; /**< [in]: Specifies the input buffer format. */
NV_ENC_PIC_STRUCT pictureStruct; /**< [in]: Specifies structure of the input picture. */
NV_ENC_PIC_TYPE pictureType; /**< [in]: Specifies input picture type. Client required to be set explicitly by the client if the client has not set NV_ENC_INITALIZE_PARAMS::enablePTD to 1 while calling NvInitializeEncoder. */
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]: 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 intialization. */
- NVENC_EXTERNAL_ME_HINT *meExternalHints; /**< [in]: 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
+ 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. */
+ 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
+ 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 */
- 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 in raster scan order for the current picture, which will be Interperated depending on NV_ENC_RC_PARAMS::qpMapMode.
- If NV_ENC_RC_PARAMS::qpMapMode is NV_ENC_QP_MAP_DELTA , This specify QP modifier to be applied on top of the QP chosen by rate control.
- If NV_ENC_RC_PARAMS::qpMapMode is NV_ENC_QP_MAP_EMPHASIS, it specifies emphasis level map per MB. 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.
- 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 */
+ uint32_t reserved2[7]; /**< [in]: Reserved and must be set to 0 */
+ void* reserved5[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, 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
+ 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.*/
+ 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 */
- 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 */
- uint32_t reserved3[286]; /**< [in]: Reserved and must be set to 0 */
- void* reserved4[60]; /**< [in]: Reserved and must be set to NULL */
+ uint32_t reserved4; /**< [in]: Reserved and must be set to 0 */
+ 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. */
+ 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 stateBufferIdx; /**< [in]: Specifies the buffer index in which the encoder state will be saved for current frame encode. It must be in the
+ range 0 to NV_ENC_INITIALIZE_PARAMS::numStateBuffers - 1. */
+ NV_ENC_OUTPUT_PTR outputReconBuffer; /**< [in]: Specifies the reconstructed frame buffer pointer to output reconstructed frame, if enabled by setting NV_ENC_INITIALIZE_PARAMS::enableReconFrameOutput.
+ Client must allocate buffers for writing the reconstructed frames and register them with the Nvidia Video Encoder Interface with NV_ENC_REGISTER_RESOURCE::bufferUsage
+ set to NV_ENC_OUTPUT_RECON.
+ Client must use the pointer obtained from ::NvEncMapInputResource() API and assign it to NV_ENC_PIC_PARAMS::outputReconBuffer.
+ Reconstructed output will be in NV_ENC_BUFFER_FORMAT_NV12 format when chromaFormatIDC is set to 1.
+ chromaFormatIDC = 3 is not supported. */
+ uint32_t reserved3[284]; /**< [in]: Reserved and must be set to 0 */
+ void* reserved6[57]; /**< [in]: Reserved and must be set to NULL */
} 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) | ( 1<<31 ))
+#define NV_ENC_PIC_PARAMS_VER (NVENCAPI_STRUCT_VERSION(7) | ( 1<<31 ))
/**
@@ -1711,29 +2632,36 @@ typedef struct _NV_ENC_PIC_PARAMS
typedef struct _NV_ENC_MEONLY_PARAMS
{
uint32_t version; /**< [in]: Struct version. Must be set to NV_ENC_MEONLY_PARAMS_VER.*/
- uint32_t inputWidth; /**< [in]: Specifies the input buffer width */
- uint32_t inputHeight; /**< [in]: Specifies the input buffer height */
+ uint32_t inputWidth; /**< [in]: Specifies the input frame width */
+ uint32_t inputHeight; /**< [in]: Specifies the input frame height */
+ uint32_t reserved; /**< [in]: Reserved and must be set to 0 */
NV_ENC_INPUT_PTR inputBuffer; /**< [in]: Specifies the input buffer pointer. Client must use a pointer obtained from NvEncCreateInputBuffer() or NvEncMapInputResource() APIs. */
NV_ENC_INPUT_PTR referenceFrame; /**< [in]: Specifies the reference frame pointer */
- NV_ENC_OUTPUT_PTR mvBuffer; /**< [in]: Specifies the pointer to motion vector data buffer allocated by NvEncCreateMVBuffer. Client must lock mvBuffer using ::NvEncLockBitstream() API to get the motion vector data. */
+ NV_ENC_OUTPUT_PTR mvBuffer; /**< [in]: Specifies the output buffer pointer.
+ If NV_ENC_INITIALIZE_PARAMS::enableOutputInVidmem is set to 0, specifies the pointer to motion vector data buffer allocated by NvEncCreateMVBuffer.
+ Client must lock mvBuffer using ::NvEncLockBitstream() API to get the motion vector data.
+ If NV_ENC_INITIALIZE_PARAMS::enableOutputInVidmem is set to 1, client should allocate buffer in video memory for storing the motion vector data. The size of this buffer must
+ be equal to total number of macroblocks multiplied by size of NV_ENC_H264_MV_DATA struct. Client should use a pointer obtained from ::NvEncMapInputResource() API, when mapping this
+ output buffer and assign it to NV_ENC_MEONLY_PARAMS::mvBuffer. All CUDA operations on this buffer must use the default stream. */
+ uint32_t reserved2; /**< [in]: Reserved and must be set to 0 */
NV_ENC_BUFFER_FORMAT bufferFmt; /**< [in]: Specifies the input buffer format. */
- void* completionEvent; /**< [in]: Specifies an event to be signalled on completion of motion estimation
- of this Frame [only if operating in Asynchronous mode].
+ void* completionEvent; /**< [in]: Specifies an event to be signaled on completion of motion estimation
+ of this Frame [only if operating in Asynchronous mode].
Each output buffer should be associated with a distinct event pointer. */
- uint32_t viewID; /**< [in]: Specifies left,right viewID if NV_ENC_CONFIG_H264_MEONLY::bStereoEnable is set.
+ uint32_t viewID; /**< [in]: Specifies left or right viewID if NV_ENC_CONFIG_H264_MEONLY::bStereoEnable is set.
viewID can be 0,1 if bStereoEnable is set, 0 otherwise. */
- NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE
+ NVENC_EXTERNAL_ME_HINT_COUNTS_PER_BLOCKTYPE
meHintCountsPerBlock[2]; /**< [in]: Specifies the number of hint candidates per block for the current frame. meHintCountsPerBlock[0] is for L0 predictors.
- The candidate count in NV_ENC_PIC_PARAMS::meHintCountsPerBlock[lx] must never exceed NV_ENC_INITIALIZE_PARAMS::maxMEHintCountsPerBlock[lx] provided during encoder intialization. */
+ 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]: 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) */
- uint32_t reserved1[243]; /**< [in]: Reserved and must be set to 0 */
- void* reserved2[59]; /**< [in]: Reserved and must be set to NULL */
+ uint32_t reserved1[241]; /**< [in]: Reserved and must be set to 0 */
+ void* reserved3[59]; /**< [in]: Reserved and must be set to NULL */
} NV_ENC_MEONLY_PARAMS;
/** NV_ENC_MEONLY_PARAMS struct version*/
-#define NV_ENC_MEONLY_PARAMS_VER NVENCAPI_STRUCT_VERSION(3)
+#define NV_ENC_MEONLY_PARAMS_VER NVENCAPI_STRUCT_VERSION(4)
/**
@@ -1741,20 +2669,23 @@ typedef struct _NV_ENC_MEONLY_PARAMS
* Bitstream buffer lock parameters.
*/
typedef struct _NV_ENC_LOCK_BITSTREAM
-{
+{
uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_LOCK_BITSTREAM_VER. */
uint32_t doNotWait :1; /**< [in]: If this flag is set, the NvEncodeAPI interface will return buffer pointer even if operation is not completed. If not set, the call will block until operation completes. */
uint32_t ltrFrame :1; /**< [out]: Flag indicating this frame is marked as LTR frame */
- uint32_t reservedBitFields :30; /**< [in]: Reserved bit fields and must be set to 0 */
+ 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 */
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 frameIdx; /**< [out]: Frame no. for which the bitstream is being retrieved. */
+ 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 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 bitstreamSizeInBytes; /**< [out]: Actual number of bytes generated and copied to the memory pointed by bitstreamBufferPtr. */
+ 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.
+ 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 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.
For MEOnly mode _NV_ENC_LOCK_BITSTREAM::bitstreamBufferPtr should be typecast to
NV_ENC_H264_MV_DATA/NV_ENC_HEVC_MV_DATA pointer respectively for H264/HEVC */
NV_ENC_PIC_TYPE pictureType; /**< [out]: Picture type of the encoded picture. */
@@ -1763,13 +2694,22 @@ typedef struct _NV_ENC_LOCK_BITSTREAM
uint32_t frameSatd; /**< [out]: Total SATD cost for whole 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 reserved [236]; /**< [in]: Reserved and must be set to 0 */
- void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */
+ uint32_t temporalId; /**< [out]: TemporalId value of the frame when using temporalSVC encoding */
+ 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 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 outputStatsPtrSize; /**< [in]: Size of the buffer pointed by NV_ENC_LOCK_BITSTREAM::outputStatsPtr. */
+ uint32_t reserved; /**< [in]: Reserved and must be set to 0 */
+ void* outputStatsPtr; /**< [in, out]: Buffer which receives the encoded frame output stats, if NV_ENC_INITIALIZE_PARAMS::enableOutputStats is set to 1. */
+ uint32_t frameIdxDisplay; /**< [out]: Frame index in display order */
+ uint32_t reserved1[219]; /**< [in]: Reserved and must be set to 0 */
+ void* reserved2[63]; /**< [in]: Reserved and must be set to NULL */
+ uint32_t reservedInternal[8]; /**< [in]: Reserved and must be set to 0 */
} 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) | ( 1<<31 ))
/**
* \struct _NV_ENC_LOCK_INPUT_BUFFER
@@ -1821,6 +2761,60 @@ typedef struct _NV_ENC_INPUT_RESOURCE_OPENGL_TEX
uint32_t target; /**< [in]: Accepted values are GL_TEXTURE_RECTANGLE and GL_TEXTURE_2D. */
} NV_ENC_INPUT_RESOURCE_OPENGL_TEX;
+/** \struct NV_ENC_FENCE_POINT_D3D12
+* Fence and fence value for synchronization.
+*/
+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. */
+ 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;
+
+#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
+ */
+typedef struct _NV_ENC_INPUT_RESOURCE_D3D12
+{
+ 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;
+
+#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
+ */
+typedef struct _NV_ENC_OUTPUT_RESOURCE_D3D12
+{
+ 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;
+
+#define NV_ENC_OUTPUT_RESOURCE_D3D12_VER NVENCAPI_STRUCT_VERSION(1)
+
/**
* \struct _NV_ENC_REGISTER_RESOURCE
* Register a resource for future use with the Nvidia Video Encoder Interface.
@@ -1833,19 +2827,45 @@ typedef struct _NV_ENC_REGISTER_RESOURCE
::NV_ENC_INPUT_RESOURCE_TYPE_DIRECTX,
::NV_ENC_INPUT_RESOURCE_TYPE_CUDADEVICEPTR,
::NV_ENC_INPUT_RESOURCE_TYPE_OPENGL_TEX */
- uint32_t width; /**< [in]: Input buffer Width. */
- uint32_t height; /**< [in]: Input buffer Height. */
- uint32_t pitch; /**< [in]: Input buffer Pitch. */
+ uint32_t width; /**< [in]: Input frame width. */
+ uint32_t height; /**< [in]: Input frame height. */
+ uint32_t pitch; /**< [in]: Input buffer pitch.
+ For ::NV_ENC_INPUT_RESOURCE_TYPE_DIRECTX resources, set this to 0.
+ For ::NV_ENC_INPUT_RESOURCE_TYPE_CUDADEVICEPTR resources, set this to
+ the pitch as obtained from cuMemAllocPitch(), or to the width in
+ bytes (if this resource was created by using cuMemAlloc()). This
+ value must be a multiple of 4.
+ For ::NV_ENC_INPUT_RESOURCE_TYPE_CUDAARRAY resources, set this to the
+ width of the allocation in bytes (i.e.
+ CUDA_ARRAY3D_DESCRIPTOR::Width * CUDA_ARRAY3D_DESCRIPTOR::NumChannels).
+ For ::NV_ENC_INPUT_RESOURCE_TYPE_OPENGL_TEX resources, set this to the
+ texture width multiplied by the number of components in the texture
+ format. */
uint32_t subResourceIndex; /**< [in]: Subresource Index of the DirectX resource to be registered. Should be set to 0 for other interfaces. */
void* resourceToRegister; /**< [in]: Handle to the resource that is being registered. */
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. */
- uint32_t reserved1[248]; /**< [in]: Reserved and must be set to 0. */
- void* reserved2[62]; /**< [in]: Reserved and must be set to NULL. */
+ NV_ENC_BUFFER_USAGE bufferUsage; /**< [in]: Usage of resource to be registered. */
+ 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
+ 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 chromaOffset[2]; /**< [out]: Chroma offset for the reconstructed output buffer when NV_ENC_BUFFER_USAGE::bufferUsage is set
+ to NV_ENC_OUTPUT_RECON and D3D11 interface is used.
+ When chroma components are interleaved, 'chromaOffset[0]' will contain chroma offset.
+ chromaOffset[1] is reserved for future use. */
+ uint32_t chromaOffsetIn[2]; /**< [in]: Chroma offset for input buffer when NV_ENC_BUFFER_USAGE::bufferUsage is set to NV_ENC_INPUT_IMAGE
+ and NVCUVID interface is used. This is required only when luma and chroma allocations are not continuous,
+ and the planes are padded. */
+ uint32_t reserved1[244]; /**< [in]: Reserved and must be set to 0. */
+ void* reserved2[61]; /**< [in]: Reserved and must be set to NULL. */
} 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(5)
/**
* \struct _NV_ENC_STAT
@@ -1855,18 +2875,26 @@ typedef struct _NV_ENC_STAT
{
uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_STAT_VER. */
uint32_t reserved; /**< [in]: Reserved and must be set to 0 */
- NV_ENC_OUTPUT_PTR outputBitStream; /**< [out]: Specifies the pointer to output bitstream. */
+ NV_ENC_OUTPUT_PTR outputBitStream; /**< [in]: Specifies the pointer to output bitstream. */
uint32_t bitStreamSize; /**< [out]: Size of generated bitstream in bytes. */
uint32_t picType; /**< [out]: Picture type of encoded picture. See ::NV_ENC_PIC_TYPE. */
uint32_t lastValidByteOffset; /**< [out]: Offset of last valid bytes of completed bitstream */
uint32_t sliceOffsets[16]; /**< [out]: Offsets of each slice */
uint32_t picIdx; /**< [out]: Picture number */
- uint32_t reserved1[233]; /**< [in]: Reserved and must be set to 0 */
+ uint32_t frameAvgQP; /**< [out]: Average QP of the frame. */
+ uint32_t ltrFrame :1; /**< [out]: Flag indicating this frame is marked as LTR frame */
+ uint32_t reservedBitFields :31; /**< [in]: Reserved bit fields and must be set to 0 */
+ uint32_t ltrFrameIdx; /**< [out]: Frame index associated with this LTR frame. */
+ uint32_t intraMBCount; /**< [out]: For H264, Number of Intra MBs in the encoded frame. For HEVC, Number of Intra CTBs in the encoded frame. */
+ 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. */
+ int32_t averageMVX; /**< [out]: Average Motion Vector in X direction for the encoded frame. */
+ int32_t averageMVY; /**< [out]: Average Motion Vector in y direction for the encoded frame. */
+ uint32_t reserved1[227]; /**< [in]: Reserved and must be set to 0 */
void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */
} NV_ENC_STAT;
/** Macro for constructing the version field of ::_NV_ENC_STAT */
-#define NV_ENC_STAT_VER NVENCAPI_STRUCT_VERSION(1)
+#define NV_ENC_STAT_VER NVENCAPI_STRUCT_VERSION(2)
/**
@@ -1876,11 +2904,12 @@ typedef struct _NV_ENC_STAT
typedef struct _NV_ENC_SEQUENCE_PARAM_PAYLOAD
{
uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_INITIALIZE_PARAMS_VER. */
- uint32_t inBufferSize; /**< [in]: Specifies the size of the spsppsBuffer provied by the client */
+ uint32_t inBufferSize; /**< [in]: Specifies the size of the spsppsBuffer provided by the client */
uint32_t spsId; /**< [in]: Specifies the SPS id to be used in sequence header. Default value is 0. */
uint32_t ppsId; /**< [in]: Specifies the PPS id to be used in picture header. Default value is 0. */
- void* spsppsBuffer; /**< [in]: Specifies bitstream header pointer of size NV_ENC_SEQUENCE_PARAM_PAYLOAD::inBufferSize. It is the client's responsibility to manage this memory. */
- uint32_t* outSPSPPSPayloadSize; /**< [out]: Size of the sequence and picture header in bytes written by the NvEncodeAPI interface to the SPSPPSBuffer. */
+ void* spsppsBuffer; /**< [in]: Specifies bitstream header pointer of size NV_ENC_SEQUENCE_PARAM_PAYLOAD::inBufferSize.
+ It is the client's responsibility to manage this memory. */
+ uint32_t* outSPSPPSPayloadSize; /**< [out]: Size of the sequence and picture header in bytes. */
uint32_t reserved [250]; /**< [in]: Reserved and must be set to 0 */
void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */
} NV_ENC_SEQUENCE_PARAM_PAYLOAD;
@@ -1897,12 +2926,12 @@ typedef struct _NV_ENC_EVENT_PARAMS
uint32_t version; /**< [in]: Struct version. Must be set to ::NV_ENC_EVENT_PARAMS_VER. */
uint32_t reserved; /**< [in]: Reserved and must be set to 0 */
void* completionEvent; /**< [in]: Handle to event to be registered/unregistered with the NvEncodeAPI interface. */
- uint32_t reserved1[253]; /**< [in]: Reserved and must be set to 0 */
+ uint32_t reserved1[254]; /**< [in]: Reserved and must be set to 0 */
void* reserved2[64]; /**< [in]: Reserved and must be set to NULL */
} NV_ENC_EVENT_PARAMS;
/** Macro for constructing the version field of ::_NV_ENC_EVENT_PARAMS */
-#define NV_ENC_EVENT_PARAMS_VER NVENCAPI_STRUCT_VERSION(1)
+#define NV_ENC_EVENT_PARAMS_VER NVENCAPI_STRUCT_VERSION(2)
/**
* Encoder Session Creation parameters
@@ -1931,7 +2960,7 @@ typedef struct _NV_ENC_OPEN_ENCODE_SESSIONEX_PARAMS
// NvEncOpenEncodeSession
/**
* \brief Opens an encoding session.
- *
+ *
* Deprecated.
*
* \return
@@ -1944,12 +2973,12 @@ NVENCSTATUS NVENCAPI NvEncOpenEncodeSession (void* device, u
/**
* \brief Retrieves the number of supported encode GUIDs.
*
- * The function returns the number of codec guids supported by the NvEncodeAPI
+ * The function returns the number of codec GUIDs supported by the NvEncodeAPI
* interface.
- *
- * \param [in] encoder
+ *
+ * \param [in] encoder
* Pointer to the NvEncodeAPI interface.
- * \param [out] encodeGUIDCount
+ * \param [out] encodeGUIDCount
* Number of supported encode GUIDs.
*
* \return
@@ -1970,12 +2999,12 @@ NVENCSTATUS NVENCAPI NvEncGetEncodeGUIDCount (void* encoder,
/**
* \brief Retrieves an array of supported encoder codec GUIDs.
*
- * The function returns an array of codec guids supported by the NvEncodeAPI interface.
+ * The function returns an array of codec GUIDs supported by the NvEncodeAPI interface.
* The client must allocate an array where the NvEncodeAPI interface can
- * fill the supported guids and pass the pointer in \p *GUIDs parameter.
+ * fill the supported GUIDs and pass the pointer in \p *GUIDs parameter.
* The size of the array can be determined by using ::NvEncGetEncodeGUIDCount() API.
- * The Nvidia Encoding interface returns the number of codec guids it has actually
- * filled in the guid array in the \p GUIDCount parameter.
+ * The Nvidia Encoding interface returns the number of codec GUIDs it has actually
+ * filled in the GUID array in the \p GUIDCount parameter.
*
* \param [in] encoder
* Pointer to the NvEncodeAPI interface.
@@ -2005,16 +3034,16 @@ NVENCSTATUS NVENCAPI NvEncGetEncodeGUIDs (void* encoder,
/**
* \brief Retrieves the number of supported profile GUIDs.
*
- * The function returns the number of profile GUIDs supported for a given codec.
- * The client must first enumerate the codec guids supported by the NvEncodeAPI
- * interface. After determining the codec guid, it can query the NvEncodeAPI
- * interface to determine the number of profile guids supported for a particular
- * codec guid.
+ * The function returns the number of profile GUIDs supported for a given codec.
+ * The client must first enumerate the codec GUIDs supported by the NvEncodeAPI
+ * interface. After determining the codec GUID, it can query the NvEncodeAPI
+ * interface to determine the number of profile GUIDs supported for a particular
+ * codec GUID.
*
- * \param [in] encoder
+ * \param [in] encoder
* Pointer to the NvEncodeAPI interface.
- * \param [in] encodeGUID
- * The codec guid for which the profile guids are being enumerated.
+ * \param [in] encodeGUID
+ * The codec GUID for which the profile GUIDs are being enumerated.
* \param [out] encodeProfileGUIDCount
* Number of encode profiles supported for the given encodeGUID.
*
@@ -2036,9 +3065,9 @@ NVENCSTATUS NVENCAPI NvEncGetEncodeProfileGUIDCount (void* en
/**
* \brief Retrieves an array of supported encode profile GUIDs.
*
- * The function returns an array of supported profile guids for a particular
- * codec guid. The client must allocate an array where the NvEncodeAPI interface
- * can populate the profile guids. The client can determine the array size using
+ * The function returns an array of supported profile GUIDs for a particular
+ * codec GUID. The client must allocate an array where the NvEncodeAPI interface
+ * can populate the profile GUIDs. The client can determine the array size using
* ::NvEncGetEncodeProfileGUIDCount() API. The client must also validiate that the
* NvEncodeAPI interface supports the GUID the client wants to pass as \p encodeGUID
* parameter.
@@ -2046,9 +3075,9 @@ NVENCSTATUS NVENCAPI NvEncGetEncodeProfileGUIDCount (void* en
* \param [in] encoder
* Pointer to the NvEncodeAPI interface.
* \param [in] encodeGUID
- * The encode guid whose profile guids are being enumerated.
+ * The encode GUID whose profile GUIDs are being enumerated.
* \param [in] guidArraySize
- * Number of GUIDs to be retrieved. Should be set to the number retrieved using
+ * Number of GUIDs to be retrieved. Should be set to the number retrieved using
* ::NvEncGetEncodeProfileGUIDCount.
* \param [out] profileGUIDs
* Array of supported Encode Profile GUIDs
@@ -2079,7 +3108,7 @@ NVENCSTATUS NVENCAPI NvEncGetEncodeProfileGUIDs (v
* \param [in] encoder
* Pointer to the NvEncodeAPI interface.
* \param [in] encodeGUID
- * Encode GUID, corresponding to which the number of supported input formats
+ * Encode GUID, corresponding to which the number of supported input formats
* is to be retrieved.
* \param [out] inputFmtCount
* Number of input formats supported for specified Encode GUID.
@@ -2101,13 +3130,13 @@ NVENCSTATUS NVENCAPI NvEncGetInputFormatCount (void* encoder,
/**
* \brief Retrieves an array of supported Input formats
*
- * Returns an array of supported input formats The client must use the input
+ * Returns an array of supported input formats The client must use the input
* format to create input surface using ::NvEncCreateInputBuffer() API.
- *
- * \param [in] encoder
+ *
+ * \param [in] encoder
* Pointer to the NvEncodeAPI interface.
* \param [in] encodeGUID
- * Encode GUID, corresponding to which the number of supported input formats
+ * Encode GUID, corresponding to which the number of supported input formats
* is to be retrieved.
*\param [in] inputFmtArraySize
* Size input format count array passed in \p inputFmts.
@@ -2135,9 +3164,9 @@ NVENCSTATUS NVENCAPI NvEncGetInputFormats (void* encoder,
/**
* \brief Retrieves the capability value for a specified encoder attribute.
*
- * The function returns the capability value for a given encoder attribute. The
- * client must validate the encodeGUID using ::NvEncGetEncodeGUIDs() API before
- * calling this function. The encoder attribute being queried are enumerated in
+ * The function returns the capability value for a given encoder attribute. The
+ * client must validate the encodeGUID using ::NvEncGetEncodeGUIDs() API before
+ * calling this function. The encoder attribute being queried are enumerated in
* ::NV_ENC_CAPS_PARAM enum.
*
* \param [in] encoder
@@ -2145,7 +3174,7 @@ NVENCSTATUS NVENCAPI NvEncGetInputFormats (void* encoder,
* \param [in] encodeGUID
* Encode GUID, corresponding to which the capability attribute is to be retrieved.
* \param [in] capsParam
- * Used to specify attribute being queried. Refer ::NV_ENC_CAPS_PARAM for more
+ * Used to specify attribute being queried. Refer ::NV_ENC_CAPS_PARAM for more
* details.
* \param [out] capsVal
* The value corresponding to the capability attribute being queried.
@@ -2167,14 +3196,14 @@ NVENCSTATUS NVENCAPI NvEncGetEncodeCaps (void* encoder, GUID
/**
* \brief Retrieves the number of supported preset GUIDs.
*
- * The function returns the number of preset GUIDs available for a given codec.
- * The client must validate the codec guid using ::NvEncGetEncodeGUIDs() API
+ * The function returns the number of preset GUIDs available for a given codec.
+ * The client must validate the codec GUID using ::NvEncGetEncodeGUIDs() API
* before calling this function.
*
* \param [in] encoder
* Pointer to the NvEncodeAPI interface.
* \param [in] encodeGUID
- * Encode GUID, corresponding to which the number of supported presets is to
+ * Encode GUID, corresponding to which the number of supported presets is to
* be retrieved.
* \param [out] encodePresetGUIDCount
* Receives the number of supported preset GUIDs.
@@ -2197,30 +3226,30 @@ NVENCSTATUS NVENCAPI NvEncGetEncodePresetCount (void* encoder, GUID
/**
* \brief Receives an array of supported encoder preset GUIDs.
*
- * The function returns an array of encode preset guids available for a given codec.
- * The client can directly use one of the preset guids based upon the use case
- * or target device. The preset guid chosen can be directly used in
- * NV_ENC_INITIALIZE_PARAMS::presetGUID parameter to ::NvEncEncodePicture() API.
- * Alternately client can also use the preset guid to retrieve the encoding config
+ * The function returns an array of encode preset GUIDs available for a given codec.
+ * The client can directly use one of the preset GUIDs based upon the use case
+ * or target device. The preset GUID chosen can be directly used in
+ * NV_ENC_INITIALIZE_PARAMS::presetGUID parameter to ::NvEncEncodePicture() API.
+ * Alternately client can also use the preset GUID to retrieve the encoding config
* parameters being used by NvEncodeAPI interface for that given preset, using
* ::NvEncGetEncodePresetConfig() API. It can then modify preset config parameters
- * as per its use case and send it to NvEncodeAPI interface as part of
+ * as per its use case and send it to NvEncodeAPI interface as part of
* NV_ENC_INITIALIZE_PARAMS::encodeConfig parameter for NvEncInitializeEncoder()
* API.
*
*
- * \param [in] encoder
+ * \param [in] encoder
* Pointer to the NvEncodeAPI interface.
* \param [in] encodeGUID
* Encode GUID, corresponding to which the list of supported presets is to be
* retrieved.
* \param [in] guidArraySize
- * Size of array of preset guids passed in \p preset GUIDs
+ * Size of array of preset GUIDs passed in \p preset GUIDs
* \param [out] presetGUIDs
- * Array of supported Encode preset GUIDs from the NvEncodeAPI interface
+ * Array of supported Encode preset GUIDs from the NvEncodeAPI interface
* to client.
* \param [out] encodePresetGUIDCount
- * Receives the number of preset GUIDs returned by the NvEncodeAPI
+ * Receives the number of preset GUIDs returned by the NvEncodeAPI
* interface.
*
* \return
@@ -2241,21 +3270,22 @@ NVENCSTATUS NVENCAPI NvEncGetEncodePresetGUIDs (void* encoder,
/**
* \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
- * 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
- * wants to modify the NvEncodeAPI preset configuration, otherwise it can
- * directly use the preset guid.
- *
+ * 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
+ * wants to modify the NvEncodeAPI preset configuration, otherwise it can
+ * directly use the preset GUID.
+ *
* \param [in] encoder
- * Pointer to the NvEncodeAPI interface.
+ * Pointer to the NvEncodeAPI interface.
* \param [in] encodeGUID
* Encode GUID, corresponding to which the list of supported presets is to be
* retrieved.
* \param [in] presetGUID
- * Preset GUID, corresponding to which the Encoding configurations is to be
+ * Preset GUID, corresponding to which the Encoding configurations is to be
* retrieved.
* \param [out] presetConfig
* The requested Preset Encoder Attribute set. Refer ::_NV_ENC_CONFIG for
@@ -2275,6 +3305,48 @@ NVENCSTATUS NVENCAPI NvEncGetEncodePresetGUIDs (void* encoder,
*/
NVENCSTATUS NVENCAPI NvEncGetEncodePresetConfig (void* encoder, GUID encodeGUID, GUID presetGUID, NV_ENC_PRESET_CONFIG* presetConfig);
+// NvEncGetEncodePresetConfigEx
+/**
+ * \brief Returns a preset config structure supported for given preset GUID.
+ *
+ * The function returns a preset config structure for a given preset GUID and tuning info.
+ * NvEncGetEncodePresetConfigEx() API is not applicable to H264 and HEVC meonly mode.
+ * 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
+ * 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
+ * wants to modify the NvEncodeAPI preset configuration, otherwise it can
+ * directly use the preset GUID.
+ *
+ * \param [in] encoder
+ * Pointer to the NvEncodeAPI interface.
+ * \param [in] encodeGUID
+ * Encode GUID, corresponding to which the list of supported presets is to be
+ * retrieved.
+ * \param [in] presetGUID
+ * Preset GUID, corresponding to which the Encoding configurations is to be
+ * retrieved.
+ * \param [in] tuningInfo
+ * tuning info, corresponding to which the Encoding configurations is to be
+ * retrieved.
+ * \param [out] presetConfig
+ * The requested Preset Encoder Attribute set. Refer ::_NV_ENC_CONFIG for
+ * more details.
+ *
+ * \return
+ * ::NV_ENC_SUCCESS \n
+ * ::NV_ENC_ERR_INVALID_PTR \n
+ * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n
+ * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n
+ * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n
+ * ::NV_ENC_ERR_OUT_OF_MEMORY \n
+ * ::NV_ENC_ERR_INVALID_PARAM \n
+ * ::NV_ENC_ERR_INVALID_VERSION \n
+ * ::NV_ENC_ERR_GENERIC \n
+ *
+ */
+NVENCSTATUS NVENCAPI NvEncGetEncodePresetConfigEx (void* encoder, GUID encodeGUID, GUID presetGUID, NV_ENC_TUNING_INFO tuningInfo, NV_ENC_PRESET_CONFIG* presetConfig);
+
// NvEncInitializeEncoder
/**
* \brief Initialize the encoder.
@@ -2285,16 +3357,16 @@ NVENCSTATUS NVENCAPI NvEncGetEncodePresetConfig (void* encoder, GU
* - NV_ENC_INITIALIZE_PARAMS::encodeGUID
* - NV_ENC_INITIALIZE_PARAMS::encodeWidth
* - NV_ENC_INITIALIZE_PARAMS::encodeHeight
- *
- * The client can pass a preset guid directly to the NvEncodeAPI interface using
- * NV_ENC_INITIALIZE_PARAMS::presetGUID field. If the client doesn't pass
+ *
+ * The client can pass a preset GUID directly to the NvEncodeAPI interface using
+ * NV_ENC_INITIALIZE_PARAMS::presetGUID field. If the client doesn't pass
* NV_ENC_INITIALIZE_PARAMS::encodeConfig structure, the codec specific parameters
- * will be selected based on the preset guid. The preset guid must have been
+ * will be selected based on the preset GUID. The preset GUID must have been
* validated by the client using ::NvEncGetEncodePresetGUIDs() API.
* If the client passes a custom ::_NV_ENC_CONFIG structure through
* NV_ENC_INITIALIZE_PARAMS::encodeConfig , it will override the codec specific parameters
- * based on the preset guid. It is recommended that even if the client passes a custom config,
- * it should also send a preset guid. In this case, the preset guid passed by the client
+ * based on the preset GUID. It is recommended that even if the client passes a custom config,
+ * it should also send a preset GUID. In this case, the preset GUID passed by the client
* will not override any of the custom config parameters programmed by the client,
* it is only used as a hint by the NvEncodeAPI interface to determine certain encoder parameters
* which are not exposed to the client.
@@ -2310,9 +3382,9 @@ NVENCSTATUS NVENCAPI NvEncGetEncodePresetConfig (void* encoder, GU
* The client operating in asynchronous mode must allocate completion event object
* for each output buffer and pass the completion event object in the
* ::NvEncEncodePicture() API. The client can create another thread and wait on
- * the event object to be signalled by NvEncodeAPI interface on completion of the
+ * the event object to be signaled by NvEncodeAPI interface on completion of the
* encoding process for the output frame. This should unblock the main thread from
- * submitting work to the encoder. When the event is signalled the client can call
+ * submitting work to the encoder. When the event is signaled the client can call
* NvEncodeAPI interfaces to copy the bitstream data using ::NvEncLockBitstream()
* API. This is the preferred mode of operation.
*
@@ -2323,7 +3395,7 @@ NVENCSTATUS NVENCAPI NvEncGetEncodePresetConfig (void* encoder, GU
* The client working in synchronous mode can work in a single threaded or multi
* threaded mode. The client need not allocate any event objects. The client can
* only lock the bitstream data after NvEncodeAPI interface has returned
- * ::NV_ENC_SUCCESS from encode picture. The NvEncodeAPI interface can return
+ * ::NV_ENC_SUCCESS from encode picture. The NvEncodeAPI interface can return
* ::NV_ENC_ERR_NEED_MORE_INPUT error code from ::NvEncEncodePicture() API. The
* client must not lock the output buffer in such case but should send the next
* frame for encoding. The client must keep on calling ::NvEncEncodePicture() API
@@ -2334,16 +3406,16 @@ NVENCSTATUS NVENCAPI NvEncGetEncodePresetConfig (void* encoder, GU
*\par Picture type decision:
* If the client is taking the picture type decision and it must disable the picture
* type decision module in NvEncodeAPI by setting NV_ENC_INITIALIZE_PARAMS::enablePTD
- * to 0. In this case the client is required to send the picture in encoding
+ * to 0. In this case the client is required to send the picture in encoding
* order to NvEncodeAPI by doing the re-ordering for B frames. \n
- * If the client doesn't want to take the picture type decision it can enable
- * picture type decision module in the NvEncodeAPI interface by setting
- * NV_ENC_INITIALIZE_PARAMS::enablePTD to 1 and send the input pictures in display
+ * If the client doesn't want to take the picture type decision it can enable
+ * picture type decision module in the NvEncodeAPI interface by setting
+ * NV_ENC_INITIALIZE_PARAMS::enablePTD to 1 and send the input pictures in display
* order.
- *
+ *
* \param [in] encoder
* Pointer to the NvEncodeAPI interface.
- * \param [in] createEncodeParams
+ * \param [in] createEncodeParams
* Refer ::_NV_ENC_INITIALIZE_PARAMS for details.
*
* \return
@@ -2366,10 +3438,10 @@ NVENCSTATUS NVENCAPI NvEncInitializeEncoder (void* encoder,
* \brief Allocates Input buffer.
*
* This function is used to allocate an input buffer. The client must enumerate
- * the input buffer format before allocating the input buffer resources. The
- * NV_ENC_INPUT_PTR returned by the NvEncodeAPI interface in the
+ * the input buffer format before allocating the input buffer resources. The
+ * NV_ENC_INPUT_PTR returned by the NvEncodeAPI interface in the
* NV_ENC_CREATE_INPUT_BUFFER::inputBuffer field can be directly used in
- * ::NvEncEncodePicture() API. The number of input buffers to be allocated by the
+ * ::NvEncEncodePicture() API. The number of input buffers to be allocated by the
* client must be at least 4 more than the number of B frames being used for encoding.
*
* \param [in] encoder
@@ -2387,7 +3459,7 @@ NVENCSTATUS NVENCAPI NvEncInitializeEncoder (void* encoder,
* ::NV_ENC_ERR_INVALID_PARAM \n
* ::NV_ENC_ERR_INVALID_VERSION \n
* ::NV_ENC_ERR_GENERIC \n
- *
+ *
*/
NVENCSTATUS NVENCAPI NvEncCreateInputBuffer (void* encoder, NV_ENC_CREATE_INPUT_BUFFER* createInputBufferParams);
@@ -2403,7 +3475,7 @@ NVENCSTATUS NVENCAPI NvEncCreateInputBuffer (void* encoder,
*
* \param [in] encoder
* Pointer to the NvEncodeAPI interface.
- * \param [in] inputBuffer
+ * \param [in] inputBuffer
* Pointer to the input buffer to be released.
*
* \return
@@ -2420,19 +3492,54 @@ NVENCSTATUS NVENCAPI NvEncCreateInputBuffer (void* encoder,
*/
NVENCSTATUS NVENCAPI NvEncDestroyInputBuffer (void* encoder, NV_ENC_INPUT_PTR inputBuffer);
+// NvEncSetIOCudaStreams
+/**
+ * \brief Set input and output CUDA stream for specified encoder attribute.
+ *
+ * Encoding may involve CUDA pre-processing on the input and post-processing on encoded output.
+ * This function is used to set input and output CUDA streams to pipeline the CUDA pre-processing
+ * and post-processing tasks. Clients should call this function before the call to
+ * NvEncUnlockInputBuffer(). If this function is not called, the default CUDA stream is used for
+ * input and output processing. After a successful call to this function, the streams specified
+ * in that call will replace the previously-used streams.
+ * This API is supported for NVCUVID interface only.
+ *
+ * \param [in] encoder
+ * Pointer to the NvEncodeAPI interface.
+ * \param [in] inputStream
+ * Pointer to CUstream which is used to process ::NV_ENC_PIC_PARAMS::inputFrame for encode.
+ * In case of ME-only mode, inputStream is used to process ::NV_ENC_MEONLY_PARAMS::inputBuffer and
+ * ::NV_ENC_MEONLY_PARAMS::referenceFrame
+ * \param [in] outputStream
+ * Pointer to CUstream which is used to process ::NV_ENC_PIC_PARAMS::outputBuffer for encode.
+ * In case of ME-only mode, outputStream is used to process ::NV_ENC_MEONLY_PARAMS::mvBuffer
+ *
+ * \return
+ * ::NV_ENC_SUCCESS \n
+ * ::NV_ENC_ERR_INVALID_PTR \n
+ * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n
+ * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n
+ * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n
+ * ::NV_ENC_ERR_OUT_OF_MEMORY \n
+ * ::NV_ENC_ERR_INVALID_PARAM \n
+ * ::NV_ENC_ERR_INVALID_VERSION \n
+ * ::NV_ENC_ERR_GENERIC \n
+ */
+NVENCSTATUS NVENCAPI NvEncSetIOCudaStreams (void* encoder, NV_ENC_CUSTREAM_PTR inputStream, NV_ENC_CUSTREAM_PTR outputStream);
+
// NvEncCreateBitstreamBuffer
/**
- * \brief Allocates an output bitstream buffer
+ * \brief Allocates an output bitstream buffer
*
- * This function is used to allocate an output bitstream buffer and returns a
- * NV_ENC_OUTPUT_PTR to bitstream buffer to the client in the
+ * This function is used to allocate an output bitstream buffer and returns a
+ * NV_ENC_OUTPUT_PTR to bitstream buffer to the client in the
* NV_ENC_CREATE_BITSTREAM_BUFFER::bitstreamBuffer field.
- * The client can only call this function after the encoder session has been
- * initialized using ::NvEncInitializeEncoder() API. The minimum number of output
+ * The client can only call this function after the encoder session has been
+ * initialized using ::NvEncInitializeEncoder() API. The minimum number of output
* buffers allocated by the client must be at least 4 more than the number of B
- * B frames being used for encoding. The client can only access the output
- * bitsteam data by locking the \p bitstreamBuffer using the ::NvEncLockBitstream()
+ * B frames being used for encoding. The client can only access the output
+ * bitstream data by locking the \p bitstreamBuffer using the ::NvEncLockBitstream()
* function.
*
* \param [in] encoder
@@ -2458,7 +3565,7 @@ NVENCSTATUS NVENCAPI NvEncCreateBitstreamBuffer (void* encoder,
// NvEncDestroyBitstreamBuffer
/**
- * \brief Release a bitstream buffer.
+ * \brief Release a bitstream buffer.
*
* This function is used to release the output bitstream buffer allocated using
* the ::NvEncCreateBitstreamBuffer() function. The client must release the output
@@ -2488,7 +3595,7 @@ NVENCSTATUS NVENCAPI NvEncDestroyBitstreamBuffer (void* encoder,
/**
* \brief Submit an input picture for encoding.
*
- * This function is used to submit an input picture buffer for encoding. The
+ * This function is used to submit an input picture buffer for encoding. The
* encoding parameters are passed using \p *encodePicParams which is a pointer
* to the ::_NV_ENC_PIC_PARAMS structure.
*
@@ -2499,57 +3606,73 @@ NVENCSTATUS NVENCAPI NvEncDestroyBitstreamBuffer (void* encoder,
* - NV_ENC_PIC_PARAMS_H264::frameNumSyntax(H264 only)
* - NV_ENC_PIC_PARAMS_H264::refPicFlag(H264 only)
*
+ *\par MVC Encoding:
+ * For MVC encoding the client must call encode picture API for each view separately
+ * and must pass valid view id in NV_ENC_PIC_PARAMS_MVC::viewID field. Currently
+ * NvEncodeAPI only support stereo MVC so client must send viewID as 0 for base
+ * view and view ID as 1 for dependent view.
*
*\par Asynchronous Encoding
- * If the client has enabled asynchronous mode of encoding by setting
+ * If the client has enabled asynchronous mode of encoding by setting
* NV_ENC_INITIALIZE_PARAMS::enableEncodeAsync to 1 in the ::NvEncInitializeEncoder()
* API ,then the client must send a valid NV_ENC_PIC_PARAMS::completionEvent.
* Incase of asynchronous mode of operation, client can queue the ::NvEncEncodePicture()
- * API commands from the main thread and then queue output buffers to be processed
- * to a secondary worker thread. Before the locking the output buffers in the
+ * API commands from the main thread and then queue output buffers to be processed
+ * to a secondary worker thread. Before the locking the output buffers in the
* secondary thread , the client must wait on NV_ENC_PIC_PARAMS::completionEvent
* it has queued in ::NvEncEncodePicture() API call. The client must always process
* completion event and the output buffer in the same order in which they have been
- * submitted for encoding. The NvEncodeAPI interface is responsible for any
+ * submitted for encoding. The NvEncodeAPI interface is responsible for any
* re-ordering required for B frames and will always ensure that encoded bitstream
* data is written in the same order in which output buffer is submitted.
+ * The NvEncodeAPI interface may return ::NV_ENC_ERR_NEED_MORE_INPUT error code for
+ * some ::NvEncEncodePicture() API calls but the client must not treat it as a fatal error.
+ * The NvEncodeAPI interface might not be able to submit an input picture buffer for encoding
+ * immediately due to re-ordering for B frames.
*\code
The below example shows how asynchronous encoding in case of 1 B frames
------------------------------------------------------------------------
- Suppose the client allocated 4 input buffers(I1,I2..), 4 output buffers(O1,O2..)
- and 4 completion events(E1, E2, ...). The NvEncodeAPI interface will need to
- keep a copy of the input buffers for re-ordering and it allocates following
+ Suppose the client allocated 4 input buffers(I1,I2..), 4 output buffers(O1,O2..)
+ and 4 completion events(E1, E2, ...). The NvEncodeAPI interface will need to
+ keep a copy of the input buffers for re-ordering and it allocates following
internal buffers (NvI1, NvI2...). These internal buffers are managed by NvEncodeAPI
- and the client is not responsible for the allocating or freeing the memory of
+ and the client is not responsible for the allocating or freeing the memory of
the internal buffers.
- a) The client main thread will queue the following encode frame calls.
- Note the picture type is unknown to the client, the decision is being taken by
- NvEncodeAPI interface. The client should pass ::_NV_ENC_PIC_PARAMS parameter
- consisting of allocated input buffer, output buffer and output events in successive
+ a) The client main thread will queue the following encode frame calls.
+ Note the picture type is unknown to the client, the decision is being taken by
+ NvEncodeAPI interface. The client should pass ::_NV_ENC_PIC_PARAMS parameter
+ consisting of allocated input buffer, output buffer and output events in successive
::NvEncEncodePicture() API calls along with other required encode picture params.
For example:
1st EncodePicture parameters - (I1, O1, E1)
2nd EncodePicture parameters - (I2, O2, E2)
3rd EncodePicture parameters - (I3, O3, E3)
- b) NvEncodeAPI SW will receive the following encode Commands from the client.
- The left side shows input from client in the form (Input buffer, Output Buffer,
+ b) NvEncodeAPI SW will receive the following encode Commands from the client.
+ The left side shows input from client in the form (Input buffer, Output Buffer,
Output Event). The right hand side shows a possible picture type decision take by
the NvEncodeAPI interface.
(I1, O1, E1) ---P1 Frame
(I2, O2, E2) ---B2 Frame
(I3, O3, E3) ---P3 Frame
- c) NvEncodeAPI interface will make a copy of the input buffers to its internal
- buffersfor re-ordering. These copies are done as part of nvEncEncodePicture
- function call from the client and NvEncodeAPI interface is responsible for
+ c) NvEncodeAPI interface will make a copy of the input buffers to its internal
+ buffers for re-ordering. These copies are done as part of nvEncEncodePicture
+ function call from the client and NvEncodeAPI interface is responsible for
synchronization of copy operation with the actual encoding operation.
- I1 --> NvI1
- I2 --> NvI2
+ I1 --> NvI1
+ I2 --> NvI2
I3 --> NvI3
- d) After returning from ::NvEncEncodePicture() call , the client must queue the output
+ d) The NvEncodeAPI encodes I1 as P frame and submits I1 to encoder HW and returns ::NV_ENC_SUCCESS.
+ The NvEncodeAPI tries to encode I2 as B frame and fails with ::NV_ENC_ERR_NEED_MORE_INPUT error code.
+ The error is not fatal and it notifies client that I2 is not submitted to encoder immediately.
+ The NvEncodeAPI encodes I3 as P frame and submits I3 for encoding which will be used as backward
+ reference frame for I2. The NvEncodeAPI then submits I2 for encoding and returns ::NV_ENC_SUCESS.
+ Both the submission are part of the same ::NvEncEncodePicture() function call.
+
+ e) After returning from ::NvEncEncodePicture() call , the client must queue the output
bitstream processing work to the secondary thread. The output bitstream processing
for asynchronous mode consist of first waiting on completion event(E1, E2..)
and then locking the output bitstream buffer(O1, O2..) for reading the encoded
@@ -2557,80 +3680,80 @@ NVENCSTATUS NVENCAPI NvEncDestroyBitstreamBuffer (void* encoder,
(I1, O1, E1)
(I2, O2, E2)
(I3, O3, E3)
- Note they are in the same order in which client calls ::NvEncEncodePicture() API
+ Note they are in the same order in which client calls ::NvEncEncodePicture() API
in \p step a).
- e) NvEncodeAPI interface will do the re-ordering such that Encoder HW will receive
+ f) NvEncodeAPI interface will do the re-ordering such that Encoder HW will receive
the following encode commands:
(NvI1, O1, E1) ---P1 Frame
(NvI3, O2, E2) ---P3 Frame
(NvI2, O3, E3) ---B2 frame
- f) After the encoding operations are completed, the events will be signalled
+ g) After the encoding operations are completed, the events will be signaled
by NvEncodeAPI interface in the following order :
- (O1, E1) ---P1 Frame ,output bitstream copied to O1 and event E1 signalled.
- (O2, E2) ---P3 Frame ,output bitstream copied to O2 and event E2 signalled.
- (O3, E3) ---B2 Frame ,output bitstream copied to O3 and event E3 signalled.
+ (O1, E1) ---P1 Frame ,output bitstream copied to O1 and event E1 signaled.
+ (O2, E2) ---P3 Frame ,output bitstream copied to O2 and event E2 signaled.
+ (O3, E3) ---B2 Frame ,output bitstream copied to O3 and event E3 signaled.
- g) The client must lock the bitstream data using ::NvEncLockBitstream() API in
+ h) The client must lock the bitstream data using ::NvEncLockBitstream() API in
the order O1,O2,O3 to read the encoded data, after waiting for the events
- to be signalled in the same order i.e E1, E2 and E3.The output processing is
+ to be signaled in the same order i.e E1, E2 and E3.The output processing is
done in the secondary thread in the following order:
Waits on E1, copies encoded bitstream from O1
Waits on E2, copies encoded bitstream from O2
Waits on E3, copies encoded bitstream from O3
- -Note the client will receive the events signalling and output buffer in the
+ -Note the client will receive the events signaling and output buffer in the
same order in which they have submitted for encoding.
- -Note the LockBitstream will have picture type field which will notify the
+ -Note the LockBitstream will have picture type field which will notify the
output picture type to the clients.
- -Note the input, output buffer and the output completion event are free to be
- reused once NvEncodeAPI interfaced has signalled the event and the client has
+ -Note the input, output buffer and the output completion event are free to be
+ reused once NvEncodeAPI interfaced has signaled the event and the client has
copied the data from the output buffer.
* \endcode
*
*\par Synchronous Encoding
- * The client can enable synchronous mode of encoding by setting
+ * The client can enable synchronous mode of encoding by setting
* NV_ENC_INITIALIZE_PARAMS::enableEncodeAsync to 0 in ::NvEncInitializeEncoder() API.
* The NvEncodeAPI interface may return ::NV_ENC_ERR_NEED_MORE_INPUT error code for
- * some ::NvEncEncodePicture() API calls when NV_ENC_INITIALIZE_PARAMS::enablePTD
- * is set to 1, but the client must not treat it as a fatal error. The NvEncodeAPI
- * interface might not be able to submit an input picture buffer for encoding
- * immediately due to re-ordering for B frames. The NvEncodeAPI interface cannot
- * submit the input picture which is decided to be encoded as B frame as it waits
+ * some ::NvEncEncodePicture() API calls when NV_ENC_INITIALIZE_PARAMS::enablePTD
+ * is set to 1, but the client must not treat it as a fatal error. The NvEncodeAPI
+ * interface might not be able to submit an input picture buffer for encoding
+ * immediately due to re-ordering for B frames. The NvEncodeAPI interface cannot
+ * submit the input picture which is decided to be encoded as B frame as it waits
* for backward reference from temporally subsequent frames. This input picture
* is buffered internally and waits for more input picture to arrive. The client
- * must not call ::NvEncLockBitstream() API on the output buffers whose
- * ::NvEncEncodePicture() API returns ::NV_ENC_ERR_NEED_MORE_INPUT. The client must
- * wait for the NvEncodeAPI interface to return ::NV_ENC_SUCCESS before locking the
+ * must not call ::NvEncLockBitstream() API on the output buffers whose
+ * ::NvEncEncodePicture() API returns ::NV_ENC_ERR_NEED_MORE_INPUT. The client must
+ * wait for the NvEncodeAPI interface to return ::NV_ENC_SUCCESS before locking the
* output bitstreams to read the encoded bitstream data. The following example
* explains the scenario with synchronous encoding with 2 B frames.
*\code
The below example shows how synchronous encoding works in case of 1 B frames
-----------------------------------------------------------------------------
- Suppose the client allocated 4 input buffers(I1,I2..), 4 output buffers(O1,O2..)
- and 4 completion events(E1, E2, ...). The NvEncodeAPI interface will need to
- keep a copy of the input buffers for re-ordering and it allocates following
+ Suppose the client allocated 4 input buffers(I1,I2..), 4 output buffers(O1,O2..)
+ and 4 completion events(E1, E2, ...). The NvEncodeAPI interface will need to
+ keep a copy of the input buffers for re-ordering and it allocates following
internal buffers (NvI1, NvI2...). These internal buffers are managed by NvEncodeAPI
- and the client is not responsible for the allocating or freeing the memory of
+ and the client is not responsible for the allocating or freeing the memory of
the internal buffers.
The client calls ::NvEncEncodePicture() API with input buffer I1 and output buffer O1.
The NvEncodeAPI decides to encode I1 as P frame and submits it to encoder
- HW and returns ::NV_ENC_SUCCESS.
+ HW and returns ::NV_ENC_SUCCESS.
The client can now read the encoded data by locking the output O1 by calling
NvEncLockBitstream API.
The client calls ::NvEncEncodePicture() API with input buffer I2 and output buffer O2.
The NvEncodeAPI decides to encode I2 as B frame and buffers I2 by copying it
to internal buffer and returns ::NV_ENC_ERR_NEED_MORE_INPUT.
- The error is not fatal and it notifies client that it cannot read the encoded
+ The error is not fatal and it notifies client that it cannot read the encoded
data by locking the output O2 by calling ::NvEncLockBitstream() API without submitting
more work to the NvEncodeAPI interface.
-
+
The client calls ::NvEncEncodePicture() with input buffer I3 and output buffer O3.
- The NvEncodeAPI decides to encode I3 as P frame and it first submits I3 for
+ The NvEncodeAPI decides to encode I3 as P frame and it first submits I3 for
encoding which will be used as backward reference frame for I2.
The NvEncodeAPI then submits I2 for encoding and returns ::NV_ENC_SUCESS. Both
the submission are part of the same ::NvEncEncodePicture() function call.
@@ -2670,16 +3793,16 @@ NVENCSTATUS NVENCAPI NvEncEncodePicture (void* encoder,
* \brief Lock output bitstream buffer
*
* This function is used to lock the bitstream buffer to read the encoded data.
- * The client can only access the encoded data by calling this function.
- * The pointer to client accessible encoded data is returned in the
+ * The client can only access the encoded data by calling this function.
+ * The pointer to client accessible encoded data is returned in the
* NV_ENC_LOCK_BITSTREAM::bitstreamBufferPtr field. The size of the encoded data
* in the output buffer is returned in the NV_ENC_LOCK_BITSTREAM::bitstreamSizeInBytes
- * The NvEncodeAPI interface also returns the output picture type and picture structure
+ * The NvEncodeAPI interface also returns the output picture type and picture structure
* of the encoded frame in NV_ENC_LOCK_BITSTREAM::pictureType and
* NV_ENC_LOCK_BITSTREAM::pictureStruct fields respectively. If the client has
* set NV_ENC_LOCK_BITSTREAM::doNotWait to 1, the function might return
- * ::NV_ENC_ERR_LOCK_BUSY if client is operating in synchronous mode. This is not
- * a fatal failure if NV_ENC_LOCK_BITSTREAM::doNotWait is set to 1. In the above case the client can
+ * ::NV_ENC_ERR_LOCK_BUSY if client is operating in synchronous mode. This is not
+ * a fatal failure if NV_ENC_LOCK_BITSTREAM::doNotWait is set to 1. In the above case the client can
* retry the function after few milliseconds.
*
* \param [in] encoder
@@ -2733,6 +3856,34 @@ NVENCSTATUS NVENCAPI NvEncLockBitstream (void* encoder,
*/
NVENCSTATUS NVENCAPI NvEncUnlockBitstream (void* encoder, NV_ENC_OUTPUT_PTR bitstreamBuffer);
+// NvEncRestoreEncoderState
+/**
+ * \brief Restore state of encoder
+ *
+ * This function is used to restore the state of encoder with state saved internally in
+ * state buffer corresponding to index equal to 'NV_ENC_RESTORE_ENCODER_STATE_PARAMS::bfrIndex'.
+ * Client can specify the state type to be updated by specifying appropriate value in
+ * 'NV_ENC_RESTORE_ENCODER_STATE_PARAMS::state'. The client must call this
+ * function after all previous encodes have finished.
+ *
+ * \param [in] encoder
+ * Pointer to the NvEncodeAPI interface.
+ * \param [in] restoreState
+ * Pointer to the ::_NV_ENC_RESTORE_ENCODER_STATE_PARAMS structure
+ *
+ * \return
+ * ::NV_ENC_SUCCESS \n
+ * ::NV_ENC_ERR_INVALID_PTR \n
+ * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n
+ * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n
+ * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n
+ * ::NV_ENC_ERR_OUT_OF_MEMORY \n
+ * ::NV_ENC_ERR_INVALID_PARAM \n
+ * ::NV_ENC_ERR_ENCODER_NOT_INITIALIZED \n
+ * ::NV_ENC_ERR_GENERIC \n
+ *
+ */
+NVENCSTATUS NVENCAPI NvEncRestoreEncoderState (void* encoder, NV_ENC_RESTORE_ENCODER_STATE_PARAMS* restoreState);
// NvLockInputBuffer
/**
@@ -2741,9 +3892,9 @@ NVENCSTATUS NVENCAPI NvEncUnlockBitstream (void* encoder,
* This function is used to lock the input buffer to load the uncompressed YUV
* pixel data into input buffer memory. The client must pass the NV_ENC_INPUT_PTR
* it had previously allocated using ::NvEncCreateInputBuffer()in the
- * NV_ENC_LOCK_INPUT_BUFFER::inputBuffer field.
- * The NvEncodeAPI interface returns pointer to client accessible input buffer
- * memory in NV_ENC_LOCK_INPUT_BUFFER::bufferDataPtr field.
+ * NV_ENC_LOCK_INPUT_BUFFER::inputBuffer field.
+ * The NvEncodeAPI interface returns pointer to client accessible input buffer
+ * memory in NV_ENC_LOCK_INPUT_BUFFER::bufferDataPtr field.
*
* \param [in] encoder
* Pointer to the NvEncodeAPI interface.
@@ -2804,6 +3955,8 @@ NVENCSTATUS NVENCAPI NvEncUnlockInputBuffer (void* encoder,
*
* This function is used to retrieve the encoding statistics.
* 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
* Pointer to the NvEncodeAPI interface.
@@ -2829,16 +3982,16 @@ NVENCSTATUS NVENCAPI NvEncGetEncodeStats (void* encoder,
/**
* \brief Get encoded sequence and picture header.
*
- * This function can be used to retrieve the sequence and picture header out of
- * band. The client must call this function only after the encoder has been
- * initialized using ::NvEncInitializeEncoder() function. The client must
+ * This function can be used to retrieve the sequence and picture header out of
+ * band. The client must call this function only after the encoder has been
+ * initialized using ::NvEncInitializeEncoder() function. The client must
* allocate the memory where the NvEncodeAPI interface can copy the bitstream
- * header and pass the pointer to the memory in NV_ENC_SEQUENCE_PARAM_PAYLOAD::spsppsBuffer.
+ * header and pass the pointer to the memory in NV_ENC_SEQUENCE_PARAM_PAYLOAD::spsppsBuffer.
* The size of buffer is passed in the field NV_ENC_SEQUENCE_PARAM_PAYLOAD::inBufferSize.
- * The NvEncodeAPI interface will copy the bitstream header payload and returns
+ * The NvEncodeAPI interface will copy the bitstream header payload and returns
* the actual size of the bitstream header in the field
* NV_ENC_SEQUENCE_PARAM_PAYLOAD::outSPSPPSPayloadSize.
- * The client must call ::NvEncGetSequenceParams() function from the same thread which is
+ * The client must call ::NvEncGetSequenceParams() function from the same thread which is
* being used to call ::NvEncEncodePicture() function.
*
* \param [in] encoder
@@ -2856,22 +4009,60 @@ NVENCSTATUS NVENCAPI NvEncGetEncodeStats (void* encoder,
* ::NV_ENC_ERR_INVALID_VERSION \n
* ::NV_ENC_ERR_INVALID_PARAM \n
* ::NV_ENC_ERR_ENCODER_NOT_INITIALIZED \n
- * ::NV_ENC_ERR_GENERIC \n
+ * ::NV_ENC_ERR_GENERIC \n
*
*/
NVENCSTATUS NVENCAPI NvEncGetSequenceParams (void* encoder, NV_ENC_SEQUENCE_PARAM_PAYLOAD* sequenceParamPayload);
+// NvEncGetSequenceParamEx
+/**
+ * \brief Get sequence and picture header.
+ *
+ * This function can be used to retrieve the sequence and picture header out of band, even when
+ * encoder has not been initialized using ::NvEncInitializeEncoder() function.
+ * The client must allocate the memory where the NvEncodeAPI interface can copy the bitstream
+ * header and pass the pointer to the memory in NV_ENC_SEQUENCE_PARAM_PAYLOAD::spsppsBuffer.
+ * The size of buffer is passed in the field NV_ENC_SEQUENCE_PARAM_PAYLOAD::inBufferSize.
+ * If encoder has not been initialized using ::NvEncInitializeEncoder() function, client must
+ * send NV_ENC_INITIALIZE_PARAMS as input. The NV_ENC_INITIALIZE_PARAMS passed must be same as the
+ * one which will be used for initializing encoder using ::NvEncInitializeEncoder() function later.
+ * If encoder is already initialized using ::NvEncInitializeEncoder() function, the provided
+ * NV_ENC_INITIALIZE_PARAMS structure is ignored. The NvEncodeAPI interface will copy the bitstream
+ * header payload and returns the actual size of the bitstream header in the field
+ * NV_ENC_SEQUENCE_PARAM_PAYLOAD::outSPSPPSPayloadSize. The client must call ::NvEncGetSequenceParamsEx()
+ * function from the same thread which is being used to call ::NvEncEncodePicture() function.
+ *
+ * \param [in] encoder
+ * Pointer to the NvEncodeAPI interface.
+ * \param [in] encInitParams
+ * Pointer to the _NV_ENC_INITIALIZE_PARAMS structure.
+ * \param [in,out] sequenceParamPayload
+ * Pointer to the ::_NV_ENC_SEQUENCE_PARAM_PAYLOAD structure.
+ *
+ * \return
+ * ::NV_ENC_SUCCESS \n
+ * ::NV_ENC_ERR_INVALID_PTR \n
+ * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n
+ * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n
+ * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n
+ * ::NV_ENC_ERR_OUT_OF_MEMORY \n
+ * ::NV_ENC_ERR_INVALID_VERSION \n
+ * ::NV_ENC_ERR_INVALID_PARAM \n
+ * ::NV_ENC_ERR_GENERIC \n
+ *
+ */
+NVENCSTATUS NVENCAPI NvEncGetSequenceParamEx (void* encoder, NV_ENC_INITIALIZE_PARAMS* encInitParams, NV_ENC_SEQUENCE_PARAM_PAYLOAD* sequenceParamPayload);
// NvEncRegisterAsyncEvent
/**
* \brief Register event for notification to encoding completion.
*
- * This function is used to register the completion event with NvEncodeAPI
- * interface. The event is required when the client has configured the encoder to
+ * This function is used to register the completion event with NvEncodeAPI
+ * interface. The event is required when the client has configured the encoder to
* work in asynchronous mode. In this mode the client needs to send a completion
- * event with every output buffer. The NvEncodeAPI interface will signal the
- * completion of the encoding process using this event. Only after the event is
- * signalled the client can get the encoded data using ::NvEncLockBitstream() function.
+ * event with every output buffer. The NvEncodeAPI interface will signal the
+ * completion of the encoding process using this event. Only after the event is
+ * signaled the client can get the encoded data using ::NvEncLockBitstream() function.
*
* \param [in] encoder
* Pointer to the NvEncodeAPI interface.
@@ -2923,7 +4114,7 @@ NVENCSTATUS NVENCAPI NvEncRegisterAsyncEvent (void* encoder,
NVENCSTATUS NVENCAPI NvEncUnregisterAsyncEvent (void* encoder, NV_ENC_EVENT_PARAMS* eventParams);
-// NvEncMapInputResource
+// NvEncMapInputResource
/**
* \brief Map an externally created input resource pointer for encoding.
*
@@ -2932,9 +4123,12 @@ NVENCSTATUS NVENCAPI NvEncUnregisterAsyncEvent (void* encoder,
* mapped resource is returned in the field NV_ENC_MAP_INPUT_RESOURCE::outputResourcePtr.
* The NvEncodeAPI interface also returns the buffer format of the mapped resource
* in the field NV_ENC_MAP_INPUT_RESOURCE::outbufferFmt.
- * This function provides synchronization guarantee that any graphics or compute
- * work submitted on the input buffer is completed before the buffer is used for encoding.
+ * This function provides synchronization guarantee that any graphics work submitted
+ * on the input buffer is completed before the buffer is used for encoding. This is
+ * also true for compute (i.e. CUDA) work, provided that the previous workload using
+ * the input resource was submitted to the default stream.
* The client should not access any input buffer while they are mapped by the encoder.
+ * For D3D12 interface type, this function does not provide synchronization guarantee.
*
* \param [in] encoder
* Pointer to the NvEncodeAPI interface.
@@ -2959,7 +4153,7 @@ NVENCSTATUS NVENCAPI NvEncUnregisterAsyncEvent (void* encoder,
NVENCSTATUS NVENCAPI NvEncMapInputResource (void* encoder, NV_ENC_MAP_INPUT_RESOURCE* mapInputResParams);
-// NvEncUnmapInputResource
+// NvEncUnmapInputResource
/**
* \brief UnMaps a NV_ENC_INPUT_PTR which was mapped for encoding
*
@@ -2967,7 +4161,7 @@ NVENCSTATUS NVENCAPI NvEncMapInputResource (void* encode
* UnMaps an input buffer which was previously mapped using ::NvEncMapInputResource()
* API. The mapping created using ::NvEncMapInputResource() should be invalidated
* using this API before the external resource is destroyed by the client. The client
- * must unmap the buffer after ::NvEncLockBitstream() API returns succuessfully for encode
+ * must unmap the buffer after ::NvEncLockBitstream() API returns successfully for encode
* work submitted using the mapped input buffer.
*
*
@@ -2998,14 +4192,14 @@ NVENCSTATUS NVENCAPI NvEncUnmapInputResource (void* enco
* \brief Destroy Encoding Session
*
* Destroys the encoder session previously created using ::NvEncOpenEncodeSession()
- * function. The client must flush the encoder before freeing any resources. In order
- * to flush the encoder the client must pass a NULL encode picture packet and either
- * wait for the ::NvEncEncodePicture() function to return in synchronous mode or wait
+ * function. The client must flush the encoder before freeing any resources. In order
+ * to flush the encoder the client must pass a NULL encode picture packet and either
+ * wait for the ::NvEncEncodePicture() function to return in synchronous mode or wait
* for the flush event to be signaled by the encoder in asynchronous mode.
* The client must free all the input and output resources created using the
* NvEncodeAPI interface before destroying the encoder. If the client is operating
* in asynchronous mode, it must also unregister the completion events previously
- * registered.
+ * registered.
*
* \param [in] encoder
* Pointer to the NvEncodeAPI interface.
@@ -3025,15 +4219,15 @@ NVENCSTATUS NVENCAPI NvEncDestroyEncoder (void* encoder);
// NvEncInvalidateRefFrames
/**
- * \brief Invalidate reference frames
+ * \brief Invalidate reference frames
*
- * 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
* 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.
- * 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
+ * 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
* that encoder can keep a backup of older reference frames in the DPB and can use them
* for motion estimation when the newer reference frames have been invalidated.
* This API can be called multiple times.
@@ -3059,14 +4253,14 @@ NVENCSTATUS NVENCAPI NvEncInvalidateRefFrames(void* encoder, uint64_t invalidRef
// NvEncOpenEncodeSessionEx
/**
* \brief Opens an encoding session.
- *
+ *
* Opens an encoding session and returns a pointer to the encoder interface in
* the \p **encoder parameter. The client should start encoding process by calling
- * this API first.
+ * this API first.
* The client must pass a pointer to IDirect3DDevice9 device or CUDA context in the \p *device parameter.
* For the OpenGL interface, \p device must be NULL. An OpenGL context must be current when
* calling all NvEncodeAPI functions.
- * If the creation of encoder session fails, the client must call ::NvEncDestroyEncoder API
+ * If the creation of encoder session fails, the client must call ::NvEncDestroyEncoder API
* before exiting.
*
* \param [in] openSessionExParams
@@ -3089,7 +4283,7 @@ NVENCSTATUS NVENCAPI NvEncOpenEncodeSessionEx (NV_ENC_OPEN_ENC
// NvEncRegisterResource
/**
* \brief Registers a resource with the Nvidia Video Encoder Interface.
- *
+ *
* Registers a resource with the Nvidia Video Encoder Interface for book keeping.
* The client is expected to pass the registered resource handle as well, while calling ::NvEncMapInputResource API.
*
@@ -3098,7 +4292,7 @@ NVENCSTATUS NVENCAPI NvEncOpenEncodeSessionEx (NV_ENC_OPEN_ENC
*
* \param [in] registerResParams
* Pointer to a ::_NV_ENC_REGISTER_RESOURCE structure
- *
+ *
* \return
* ::NV_ENC_SUCCESS \n
* ::NV_ENC_ERR_INVALID_PTR \n
@@ -3119,9 +4313,9 @@ NVENCSTATUS NVENCAPI NvEncRegisterResource (void* encoder,
// NvEncUnregisterResource
/**
* \brief Unregisters a resource previously registered with the Nvidia Video Encoder Interface.
- *
+ *
* Unregisters a resource previously registered with the Nvidia Video Encoder Interface.
- * The client is expected to unregister any resource that it has registered with the
+ * The client is expected to unregister any resource that it has registered with the
* Nvidia Video Encoder Interface before destroying the resource.
*
* \param [in] encoder
@@ -3150,16 +4344,16 @@ NVENCSTATUS NVENCAPI NvEncUnregisterResource (void* encoder,
// NvEncReconfigureEncoder
/**
* \brief Reconfigure an existing encoding session.
- *
+ *
* Reconfigure an existing encoding session.
- * The client should call this API to change/reconfigure the parameter passed during
+ * The client should call this API to change/reconfigure the parameter passed during
* NvEncInitializeEncoder API call.
* Currently Reconfiguration of following are not supported.
* Change in GOP structure.
* Change in sync-Async mode.
* Change in MaxWidth & MaxHeight.
- * Change in PTDmode.
- *
+ * Change in PTD mode.
+ *
* Resolution change is possible only if maxEncodeWidth & maxEncodeHeight of NV_ENC_INITIALIZE_PARAMS
* is set while creating encoder session.
*
@@ -3290,9 +4484,51 @@ NVENCSTATUS NVENCAPI NvEncRunMotionEstimationOnly (void* encoder,
NVENCSTATUS NVENCAPI NvEncodeAPIGetMaxSupportedVersion (uint32_t* version);
+// NvEncGetLastErrorString
+/**
+ * \brief Get the description of the last error reported by the API.
+ *
+ * This function returns a null-terminated string that can be used by clients to better understand the reason
+ * for failure of a previous API call.
+ *
+ * \param [in] encoder
+ * Pointer to the NvEncodeAPI interface.
+ *
+ * \return
+ * Pointer to buffer containing the details of the last error encountered by the API.
+ */
+const char * NVENCAPI NvEncGetLastErrorString (void* encoder);
+
+// NvEncLookaheadPicture
+/**
+ * \brief Submit an input picture for lookahead.
+ *
+ * This function can be used by clients to submit input frame for lookahead. Client could call this function
+ * NV_ENC_INITIALIZE_PARAMS::lookaheadDepth plus one number of frames, before calling NvEncEncodePicture() for the first frame.
+ *
+ * \param [in] encoder
+ * Pointer to the NvEncodeAPI interface.
+ * \param [in] lookaheadParams
+ * Pointer to the ::_NV_ENC_LOOKAHEAD_PIC_PARAMS structure.
+ *
+ * \return
+ * ::NV_ENC_SUCCESS \n
+ * ::NV_ENC_NEED_MORE_INPUT \n should we return this error is lookahead queue is not full?
+ * ::NV_ENC_ERR_INVALID_PTR \n
+ * ::NV_ENC_ERR_ENCODER_NOT_INITIALIZED \n
+ * ::NV_ENC_ERR_GENERIC \n
+ * ::NV_ENC_ERR_INVALID_ENCODERDEVICE \n
+ * ::NV_ENC_ERR_DEVICE_NOT_EXIST \n
+ * ::NV_ENC_ERR_UNSUPPORTED_PARAM \n
+ * ::NV_ENC_ERR_OUT_OF_MEMORY \n
+ * ::NV_ENC_ERR_INVALID_PARAM \n
+ * ::NV_ENC_ERR_INVALID_VERSION \n
+ */
+NVENCSTATUS NVENCAPI NvEncLookaheadPicture (void* encoder, NV_ENC_LOOKAHEAD_PIC_PARAMS *lookaheadParamas);
+
/// \cond API PFN
/*
- * Defines API function pointers
+ * Defines API function pointers
*/
typedef NVENCSTATUS (NVENCAPI* PNVENCOPENENCODESESSION) (void* device, uint32_t deviceType, void** encoder);
typedef NVENCSTATUS (NVENCAPI* PNVENCGETENCODEGUIDCOUNT) (void* encoder, uint32_t* encodeGUIDCount);
@@ -3305,6 +4541,7 @@ typedef NVENCSTATUS (NVENCAPI* PNVENCGETENCODECAPS) (void* encoder,
typedef NVENCSTATUS (NVENCAPI* PNVENCGETENCODEPRESETCOUNT) (void* encoder, GUID encodeGUID, uint32_t* encodePresetGUIDCount);
typedef NVENCSTATUS (NVENCAPI* PNVENCGETENCODEPRESETGUIDS) (void* encoder, GUID encodeGUID, GUID* presetGUIDs, uint32_t guidArraySize, uint32_t* encodePresetGUIDCount);
typedef NVENCSTATUS (NVENCAPI* PNVENCGETENCODEPRESETCONFIG) (void* encoder, GUID encodeGUID, GUID presetGUID, NV_ENC_PRESET_CONFIG* presetConfig);
+typedef NVENCSTATUS (NVENCAPI* PNVENCGETENCODEPRESETCONFIGEX) (void* encoder, GUID encodeGUID, GUID presetGUID, NV_ENC_TUNING_INFO tuningInfo, NV_ENC_PRESET_CONFIG* presetConfig);
typedef NVENCSTATUS (NVENCAPI* PNVENCINITIALIZEENCODER) (void* encoder, NV_ENC_INITIALIZE_PARAMS* createEncodeParams);
typedef NVENCSTATUS (NVENCAPI* PNVENCCREATEINPUTBUFFER) (void* encoder, NV_ENC_CREATE_INPUT_BUFFER* createInputBufferParams);
typedef NVENCSTATUS (NVENCAPI* PNVENCDESTROYINPUTBUFFER) (void* encoder, NV_ENC_INPUT_PTR inputBuffer);
@@ -3331,6 +4568,11 @@ typedef NVENCSTATUS (NVENCAPI* PNVENCRECONFIGUREENCODER) (void* encoder,
typedef NVENCSTATUS (NVENCAPI* PNVENCCREATEMVBUFFER) (void* encoder, NV_ENC_CREATE_MV_BUFFER* createMVBufferParams);
typedef NVENCSTATUS (NVENCAPI* PNVENCDESTROYMVBUFFER) (void* encoder, NV_ENC_OUTPUT_PTR mvBuffer);
typedef NVENCSTATUS (NVENCAPI* PNVENCRUNMOTIONESTIMATIONONLY) (void* encoder, NV_ENC_MEONLY_PARAMS* meOnlyParams);
+typedef const char * (NVENCAPI* PNVENCGETLASTERROR) (void* encoder);
+typedef NVENCSTATUS (NVENCAPI* PNVENCSETIOCUDASTREAMS) (void* encoder, NV_ENC_CUSTREAM_PTR inputStream, NV_ENC_CUSTREAM_PTR outputStream);
+typedef NVENCSTATUS (NVENCAPI* PNVENCGETSEQUENCEPARAMEX) (void* encoder, NV_ENC_INITIALIZE_PARAMS* encInitParams, NV_ENC_SEQUENCE_PARAM_PAYLOAD* sequenceParamPayload);
+typedef NVENCSTATUS (NVENCAPI* PNVENCRESTOREENCODERSTATE) (void* encoder, NV_ENC_RESTORE_ENCODER_STATE_PARAMS* restoreState);
+typedef NVENCSTATUS (NVENCAPI* PNVENCLOOKAHEADPICTURE) (void* encoder, NV_ENC_LOOKAHEAD_PIC_PARAMS* lookaheadParams);
/// \endcond
@@ -3348,8 +4590,8 @@ typedef struct _NV_ENCODE_API_FUNCTION_LIST
uint32_t reserved; /**< [in]: Reserved and should be set to 0. */
PNVENCOPENENCODESESSION nvEncOpenEncodeSession; /**< [out]: Client should access ::NvEncOpenEncodeSession() API through this pointer. */
PNVENCGETENCODEGUIDCOUNT nvEncGetEncodeGUIDCount; /**< [out]: Client should access ::NvEncGetEncodeGUIDCount() API through this pointer. */
- PNVENCGETENCODEPRESETCOUNT nvEncGetEncodeProfileGUIDCount; /**< [out]: Client should access ::NvEncGetEncodeProfileGUIDCount() API through this pointer.*/
- PNVENCGETENCODEPRESETGUIDS nvEncGetEncodeProfileGUIDs; /**< [out]: Client should access ::NvEncGetEncodeProfileGUIDs() API through this pointer. */
+ PNVENCGETENCODEPROFILEGUIDCOUNT nvEncGetEncodeProfileGUIDCount; /**< [out]: Client should access ::NvEncGetEncodeProfileGUIDCount() API through this pointer.*/
+ PNVENCGETENCODEPROFILEGUIDS nvEncGetEncodeProfileGUIDs; /**< [out]: Client should access ::NvEncGetEncodeProfileGUIDs() API through this pointer. */
PNVENCGETENCODEGUIDS nvEncGetEncodeGUIDs; /**< [out]: Client should access ::NvEncGetEncodeGUIDs() API through this pointer. */
PNVENCGETINPUTFORMATCOUNT nvEncGetInputFormatCount; /**< [out]: Client should access ::NvEncGetInputFormatCount() API through this pointer. */
PNVENCGETINPUTFORMATS nvEncGetInputFormats; /**< [out]: Client should access ::NvEncGetInputFormats() API through this pointer. */
@@ -3383,7 +4625,13 @@ typedef struct _NV_ENCODE_API_FUNCTION_LIST
PNVENCCREATEMVBUFFER nvEncCreateMVBuffer; /**< [out]: Client should access ::NvEncCreateMVBuffer API through this pointer. */
PNVENCDESTROYMVBUFFER nvEncDestroyMVBuffer; /**< [out]: Client should access ::NvEncDestroyMVBuffer API through this pointer. */
PNVENCRUNMOTIONESTIMATIONONLY nvEncRunMotionEstimationOnly; /**< [out]: Client should access ::NvEncRunMotionEstimationOnly API through this pointer. */
- void* reserved2[281]; /**< [in]: Reserved and must be set to NULL */
+ PNVENCGETLASTERROR nvEncGetLastErrorString; /**< [out]: Client should access ::nvEncGetLastErrorString API through this pointer. */
+ PNVENCSETIOCUDASTREAMS nvEncSetIOCudaStreams; /**< [out]: Client should access ::nvEncSetIOCudaStreams API through this pointer. */
+ PNVENCGETENCODEPRESETCONFIGEX nvEncGetEncodePresetConfigEx; /**< [out]: Client should access ::NvEncGetEncodePresetConfigEx() API through this pointer. */
+ PNVENCGETSEQUENCEPARAMEX nvEncGetSequenceParamEx; /**< [out]: Client should access ::NvEncGetSequenceParamEx() API through this pointer. */
+ PNVENCRESTOREENCODERSTATE nvEncRestoreEncoderState; /**< [out]: Client should access ::NvEncRestoreEncoderState() API through this pointer. */
+ PNVENCLOOKAHEADPICTURE nvEncLookaheadPicture; /**< [out]: Client should access ::NvEncLookaheadPicture() API through this pointer. */
+ void* reserved2[275]; /**< [in]: Reserved and must be set to NULL */
} NV_ENCODE_API_FUNCTION_LIST;
/** Macro for constructing the version field of ::_NV_ENCODEAPI_FUNCTION_LIST. */
@@ -3393,7 +4641,7 @@ typedef struct _NV_ENCODE_API_FUNCTION_LIST
/**
* \ingroup ENCODE_FUNC
* Entry Point to the NvEncodeAPI interface.
- *
+ *
* Creates an instance of the NvEncodeAPI interface, and populates the
* pFunctionList with function pointers to the API routines implemented by the
* NvEncodeAPI interface.
diff --git a/alvr/server/cpp/alvr_server/nvencoderclioptions.h b/alvr/server/cpp/alvr_server/nvencoderclioptions.h
deleted file mode 100644
index 27872cbbdb..0000000000
--- a/alvr/server/cpp/alvr_server/nvencoderclioptions.h
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
-* Copyright 2017-2018 NVIDIA Corporation. All rights reserved.
-*
-* Please refer to the NVIDIA end user license agreement (EULA) associated
-* with this source code for terms and conditions that govern your use of
-* this software. Any use, reproduction, disclosure, or distribution of
-* this software and related documentation outside the terms of the EULA
-* is strictly prohibited.
-*
-*/
-
-#pragma once
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include "Logger.h"
-
-#ifndef _WIN32
-#include
-inline bool operator==(const GUID &guid1, const GUID &guid2) {
- return !memcmp(&guid1, &guid2, sizeof(GUID));
-}
-
-inline bool operator!=(const GUID &guid1, const GUID &guid2) {
- return !(guid1 == guid2);
-}
-#endif
-
-class NvEncoderInitParam {
-public:
- NvEncoderInitParam(const char *szParam = "",
- std::function *pfuncInit = NULL, bool _bLowLatency = false)
- : strParam(szParam), bLowLatency(_bLowLatency)
- {
- if (pfuncInit) {
- funcInit = *pfuncInit;
- }
-
- std::transform(strParam.begin(), strParam.end(), strParam.begin(), tolower);
- std::istringstream ss(strParam);
- tokens = std::vector {
- std::istream_iterator(ss),
- std::istream_iterator()
- };
-
- for (unsigned i = 0; i < tokens.size(); i++)
- {
- if (tokens[i] == "-codec" && ++i != tokens.size())
- {
- ParseString("-codec", tokens[i], vCodec, szCodecNames, &guidCodec);
- continue;
- }
- if (bLowLatency)
- {
- if (tokens[i] == "-preset" && ++i != tokens.size()) {
- ParseString("-preset", tokens[i], vLowLatencyPreset, szLowLatencyPresetNames, &guidPreset);
- continue;
- }
- }
- else
- {
- if (tokens[i] == "-preset" && ++i != tokens.size()) {
- ParseString("-preset", tokens[i], vPreset, szPresetNames, &guidPreset);
- continue;
- }
- }
- }
-
- if (bLowLatency) guidPreset = NV_ENC_PRESET_LOW_LATENCY_DEFAULT_GUID;
- }
- virtual ~NvEncoderInitParam() {}
- virtual bool IsCodecH264() {
- return GetEncodeGUID() == NV_ENC_CODEC_H264_GUID;
- }
-
- virtual bool IsCodecHEVC() {
- return GetEncodeGUID() == NV_ENC_CODEC_HEVC_GUID;
- }
- std::string GetHelpMessage(bool bMeOnly = false, bool bUnbuffered = false, bool bHide444 = false)
- {
- std::ostringstream oss;
- oss << "-codec Codec: " << szCodecNames << std::endl
- << "-preset Preset: " << (bLowLatency ? szLowLatencyPresetNames : szPresetNames) << std::endl
- << "-profile H264: " << szH264ProfileNames << "; HEVC: " << szHevcProfileNames << std::endl;
- if (!bHide444 && !bLowLatency)
- {
- oss << "-444 (Only for RGB input) YUV444 encode" << std::endl;
- }
- if (bMeOnly) return oss.str();
- oss << "-rc Rate control mode: " << szRcModeNames << std::endl
- << "-fps Frame rate" << std::endl
- << "-gop Length of GOP (Group of Pictures)" << std::endl;
- if (!bUnbuffered && !bLowLatency)
- {
- oss << "-bf Number of consecutive B-frames" << std::endl;
- }
- oss << "-bitrate Average bit rate, can be in unit of 1, K, M" << std::endl
- << "-maxbitrate Max bit rate, can be in unit of 1, K, M" << std::endl
- << "-vbvbufsize VBV buffer size in bits, can be in unit of 1, K, M" << std::endl
- << "-vbvinit VBV initial delay in bits, can be in unit of 1, K, M" << std::endl;
- if (!bLowLatency)
- {
- oss << "-aq Enable spatial AQ and set its stength (range 1-15, 0-auto)" << std::endl
- << "-temporalaq (No value) Enable temporal AQ" << std::endl;
- }
- if (!bUnbuffered && !bLowLatency)
- {
- oss << "-lookahead Maximum depth of lookahead (range 0-32)" << std::endl;
- }
- oss << "-cq Target constant quality level for VBR mode (range 1-51, 0-auto)" << std::endl
- << "-qmin Min QP value" << std::endl
- << "-qmax Max QP value" << std::endl
- << "-initqp Initial QP value" << std::endl;
- if (!bLowLatency)
- {
- oss << "-constqp QP value for constqp rate control mode" << std::endl
- << "Note: QP value can be in the form of qp_of_P_B_I or qp_P,qp_B,qp_I (no space)" << std::endl;
- }
- if (bUnbuffered && !bLowLatency)
- {
- oss << "Note: Options -bf and -lookahead are unavailable for this app" << std::endl;
- }
- return oss.str();
- }
-
- std::string MainParamToString(const NV_ENC_INITIALIZE_PARAMS *pParams) {
- std::ostringstream os;
- os
- << "Encoding Parameters:"
- << std::endl << "\tcodec : " << ConvertValueToString(vCodec, szCodecNames, pParams->encodeGUID)
- << std::endl << "\tpreset : " << ConvertValueToString(vPreset, szPresetNames, pParams->presetGUID)
- << std::endl << "\tprofile : " << ConvertValueToString(vProfile, szProfileNames, pParams->encodeConfig->profileGUID)
- << std::endl << "\tchroma : " << ConvertValueToString(vChroma, szChromaNames, (pParams->encodeGUID == NV_ENC_CODEC_H264_GUID) ? pParams->encodeConfig->encodeCodecConfig.h264Config.chromaFormatIDC : pParams->encodeConfig->encodeCodecConfig.hevcConfig.chromaFormatIDC)
- << std::endl << "\tbitdepth : " << ((pParams->encodeGUID == NV_ENC_CODEC_H264_GUID) ? 0 : pParams->encodeConfig->encodeCodecConfig.hevcConfig.pixelBitDepthMinus8) + 8
- << std::endl << "\trc : " << ConvertValueToString(vRcMode, szRcModeNames, pParams->encodeConfig->rcParams.rateControlMode)
- ;
- if (pParams->encodeConfig->rcParams.rateControlMode == NV_ENC_PARAMS_RC_CONSTQP) {
- os << " (P,B,I=" << pParams->encodeConfig->rcParams.constQP.qpInterP << "," << pParams->encodeConfig->rcParams.constQP.qpInterB << "," << pParams->encodeConfig->rcParams.constQP.qpIntra << ")";
- }
- os
- << std::endl << "\tfps : " << pParams->frameRateNum << "/" << pParams->frameRateDen
- << std::endl << "\tgop : " << (pParams->encodeConfig->gopLength == NVENC_INFINITE_GOPLENGTH ? "INF" : std::to_string(pParams->encodeConfig->gopLength))
- << std::endl << "\tbf : " << pParams->encodeConfig->frameIntervalP - 1
- << std::endl << "\tsize : " << pParams->encodeWidth << "x" << pParams->encodeHeight
- << std::endl << "\tbitrate : " << pParams->encodeConfig->rcParams.averageBitRate
- << std::endl << "\tmaxbitrate : " << pParams->encodeConfig->rcParams.maxBitRate
- << std::endl << "\tvbvbufsize : " << pParams->encodeConfig->rcParams.vbvBufferSize
- << std::endl << "\tvbvinit : " << pParams->encodeConfig->rcParams.vbvInitialDelay
- << std::endl << "\taq : " << (pParams->encodeConfig->rcParams.enableAQ ? (pParams->encodeConfig->rcParams.aqStrength ? std::to_string(pParams->encodeConfig->rcParams.aqStrength) : "auto") : "disabled")
- << std::endl << "\ttemporalaq : " << (pParams->encodeConfig->rcParams.enableTemporalAQ ? "enabled" : "disabled")
- << std::endl << "\tlookahead : " << (pParams->encodeConfig->rcParams.enableLookahead ? std::to_string(pParams->encodeConfig->rcParams.lookaheadDepth) : "disabled")
- << std::endl << "\tcq : " << (int)pParams->encodeConfig->rcParams.targetQuality
- << std::endl << "\tqmin : P,B,I=" << pParams->encodeConfig->rcParams.minQP.qpInterP << "," << pParams->encodeConfig->rcParams.minQP.qpInterB << "," << pParams->encodeConfig->rcParams.minQP.qpIntra
- << std::endl << "\tqmax : P,B,I=" << pParams->encodeConfig->rcParams.maxQP.qpInterP << "," << pParams->encodeConfig->rcParams.maxQP.qpInterB << "," << pParams->encodeConfig->rcParams.maxQP.qpIntra
- << std::endl << "\tinitqp : P,B,I=" << pParams->encodeConfig->rcParams.initialRCQP.qpInterP << "," << pParams->encodeConfig->rcParams.initialRCQP.qpInterB << "," << pParams->encodeConfig->rcParams.initialRCQP.qpIntra
- ;
- return os.str();
- }
-
-public:
- virtual GUID GetEncodeGUID() { return guidCodec; }
- virtual GUID GetPresetGUID() { return guidPreset; }
- virtual void SetInitParams(NV_ENC_INITIALIZE_PARAMS *pParams, NV_ENC_BUFFER_FORMAT eBufferFormat)
- {
- NV_ENC_CONFIG &config = *pParams->encodeConfig;
- for (unsigned i = 0; i < tokens.size(); i++)
- {
- if (
- tokens[i] == "-codec" && ++i ||
- tokens[i] == "-preset" && ++i ||
- tokens[i] == "-profile" && ++i != tokens.size() && (IsCodecH264() ?
- ParseString("-profile", tokens[i], vH264Profile, szH264ProfileNames, &config.profileGUID) :
- ParseString("-profile", tokens[i], vHevcProfile, szHevcProfileNames, &config.profileGUID)) ||
- tokens[i] == "-rc" && ++i != tokens.size() && ParseString("-rc", tokens[i], vRcMode, szRcModeNames, &config.rcParams.rateControlMode) ||
- tokens[i] == "-fps" && ++i != tokens.size() && ParseInt("-fps", tokens[i], &pParams->frameRateNum) ||
- tokens[i] == "-bf" && ++i != tokens.size() && ParseInt("-bf", tokens[i], &config.frameIntervalP) && ++config.frameIntervalP ||
- tokens[i] == "-bitrate" && ++i != tokens.size() && ParseBitRate("-bitrate", tokens[i], &config.rcParams.averageBitRate) ||
- tokens[i] == "-maxbitrate" && ++i != tokens.size() && ParseBitRate("-maxbitrate", tokens[i], &config.rcParams.maxBitRate) ||
- tokens[i] == "-vbvbufsize" && ++i != tokens.size() && ParseBitRate("-vbvbufsize", tokens[i], &config.rcParams.vbvBufferSize) ||
- tokens[i] == "-vbvinit" && ++i != tokens.size() && ParseBitRate("-vbvinit", tokens[i], &config.rcParams.vbvInitialDelay) ||
- tokens[i] == "-lookahead" && ++i != tokens.size() && ParseInt("-lookahead", tokens[i], &config.rcParams.lookaheadDepth) && (config.rcParams.enableLookahead = true) ||
- tokens[i] == "-cq" && ++i != tokens.size() && ParseInt("-cq", tokens[i], &config.rcParams.targetQuality) ||
- tokens[i] == "-initqp" && ++i != tokens.size() && ParseQp("-initqp", tokens[i], &config.rcParams.initialRCQP) && (config.rcParams.enableInitialRCQP = true) ||
- tokens[i] == "-qmin" && ++i != tokens.size() && ParseQp("-qmin", tokens[i], &config.rcParams.minQP) && (config.rcParams.enableMinQP = true) ||
- tokens[i] == "-qmax" && ++i != tokens.size() && ParseQp("-qmax", tokens[i], &config.rcParams.maxQP) && (config.rcParams.enableMaxQP = true) ||
- tokens[i] == "-constqp" && ++i != tokens.size() && ParseQp("-constqp", tokens[i], &config.rcParams.constQP) ||
- tokens[i] == "-temporalaq" && (config.rcParams.enableTemporalAQ = true)
- )
- {
- continue;
- }
- int aqStrength;
- if (tokens[i] == "-aq" && ++i != tokens.size() && ParseInt("-aq", tokens[i], &aqStrength)) {
- config.rcParams.enableAQ = true;
- config.rcParams.aqStrength = aqStrength;
- continue;
- }
-
- if (tokens[i] == "-gop" && ++i != tokens.size() && ParseInt("-gop", tokens[i], &config.gopLength))
- {
- if (IsCodecH264())
- {
- config.encodeCodecConfig.h264Config.idrPeriod = config.gopLength;
- }
- else
- {
- config.encodeCodecConfig.hevcConfig.idrPeriod = config.gopLength;
- }
- continue;
- }
-
- if (tokens[i] == "-444")
- {
- if (IsCodecH264())
- {
- config.encodeCodecConfig.h264Config.chromaFormatIDC = 3;
- } else
- {
- config.encodeCodecConfig.hevcConfig.chromaFormatIDC = 3;
- }
- continue;
- }
-
- std::ostringstream errmessage;
- errmessage << "Incorrect parameter: " << tokens[i] << std::endl;
- errmessage << "Re-run the application with the -h option to get a list of the supported options.";
- errmessage << std::endl;
-
- throw std::invalid_argument(errmessage.str());
- }
-
- if (IsCodecHEVC())
- {
- if (eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV420_10BIT || eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV444_10BIT)
- {
- config.encodeCodecConfig.hevcConfig.pixelBitDepthMinus8 = 2;
- }
- }
-
- funcInit(pParams);
- //LOG(INFO) << NvEncoderInitParam().MainParamToString(pParams);
- //LOG(TRACE) << NvEncoderInitParam().FullParamToString(pParams);
- }
-
-private:
- template
- bool ParseString(const std::string &strName, const std::string &strValue, const std::vector &vValue, const std::string &strValueNames, T *pValue) {
- std::vector vstrValueName = split(strValueNames, ' ');
- auto it = std::find(vstrValueName.begin(), vstrValueName.end(), strValue);
- if (it == vstrValueName.end()) {
- //LOG(ERROR) << strName << " options: " << strValueNames;
- return false;
- }
- *pValue = vValue[it - vstrValueName.begin()];
- return true;
- }
- template
- std::string ConvertValueToString(const std::vector &vValue, const std::string &strValueNames, T value) {
- auto it = std::find(vValue.begin(), vValue.end(), value);
- if (it == vValue.end()) {
- //LOG(ERROR) << "Invalid value. Can't convert to one of " << strValueNames;
- return std::string();
- }
- return split(strValueNames, ' ')[it - vValue.begin()];
- }
- bool ParseBitRate(const std::string &strName, const std::string &strValue, unsigned *pBitRate) {
- try {
- size_t l;
- double r = std::stod(strValue, &l);
- char c = strValue[l];
- if (c != 0 && c != 'k' && c != 'm') {
- //LOG(ERROR) << strName << " units: 1, K, M (lower case also allowed)";
- }
- *pBitRate = (unsigned)((c == 'm' ? 1000000 : (c == 'k' ? 1000 : 1)) * r);
- } catch (std::invalid_argument) {
- return false;
- }
- return true;
- }
- template
- bool ParseInt(const std::string &strName, const std::string &strValue, T *pInt) {
- try {
- *pInt = std::stoi(strValue);
- } catch (std::invalid_argument) {
- //LOG(ERROR) << strName << " need a value of positive number";
- return false;
- }
- return true;
- }
- bool ParseQp(const std::string &strName, const std::string &strValue, NV_ENC_QP *pQp) {
- std::vector vQp = split(strValue, ',');
- try {
- if (vQp.size() == 1) {
- unsigned qp = (unsigned)std::stoi(vQp[0]);
- *pQp = {qp, qp, qp};
- } else if (vQp.size() == 3) {
- *pQp = {(unsigned)std::stoi(vQp[0]), (unsigned)std::stoi(vQp[1]), (unsigned)std::stoi(vQp[2])};
- } else {
- //LOG(ERROR) << strName << " qp_for_P_B_I or qp_P,qp_B,qp_I (no space is allowed)";
- return false;
- }
- } catch (std::invalid_argument) {
- return false;
- }
- return true;
- }
- std::vector split(const std::string &s, char delim) {
- std::stringstream ss(s);
- std::string token;
- std::vector tokens;
- while (getline(ss, token, delim)) {
- tokens.push_back(token);
- }
- return tokens;
- }
-
-private:
- std::string strParam;
- std::function funcInit = [](NV_ENC_INITIALIZE_PARAMS *pParams){};
- std::vector tokens;
- GUID guidCodec = NV_ENC_CODEC_H264_GUID;
- GUID guidPreset = NV_ENC_PRESET_DEFAULT_GUID;
- bool bLowLatency = false;
-
- const char *szCodecNames = "h264 hevc";
- std::vector vCodec = std::vector {
- NV_ENC_CODEC_H264_GUID,
- NV_ENC_CODEC_HEVC_GUID
- };
-
- const char *szChromaNames = "yuv420 yuv444";
- std::vector vChroma = std::vector
- {
- 1, 3
- };
-
- const char *szPresetNames = "default hp hq bd ll ll_hp ll_hq lossless lossless_hp";
- const char *szLowLatencyPresetNames = "ll ll_hp ll_hq";
- std::vector vPreset = std::vector {
- NV_ENC_PRESET_DEFAULT_GUID,
- NV_ENC_PRESET_HP_GUID,
- NV_ENC_PRESET_HQ_GUID,
- NV_ENC_PRESET_BD_GUID,
- NV_ENC_PRESET_LOW_LATENCY_DEFAULT_GUID,
- NV_ENC_PRESET_LOW_LATENCY_HP_GUID,
- NV_ENC_PRESET_LOW_LATENCY_HQ_GUID,
- NV_ENC_PRESET_LOSSLESS_DEFAULT_GUID,
- NV_ENC_PRESET_LOSSLESS_HP_GUID
- };
-
- std::vector vLowLatencyPreset = std::vector {
- NV_ENC_PRESET_LOW_LATENCY_DEFAULT_GUID,
- NV_ENC_PRESET_LOW_LATENCY_HP_GUID,
- NV_ENC_PRESET_LOW_LATENCY_HQ_GUID,
- };
-
- const char *szH264ProfileNames = "baseline main high high444";
- std::vector vH264Profile = std::vector {
- NV_ENC_H264_PROFILE_BASELINE_GUID,
- NV_ENC_H264_PROFILE_MAIN_GUID,
- NV_ENC_H264_PROFILE_HIGH_GUID,
- NV_ENC_H264_PROFILE_HIGH_444_GUID,
- };
- const char *szHevcProfileNames = "main main10 frext";
- std::vector vHevcProfile = std::vector {
- NV_ENC_HEVC_PROFILE_MAIN_GUID,
- NV_ENC_HEVC_PROFILE_MAIN10_GUID,
- NV_ENC_HEVC_PROFILE_FREXT_GUID,
- };
- const char *szProfileNames = "(default) auto baseline(h264) main(h264) high(h264) high444(h264)"
- " stereo(h264) svc_temporal_scalability(h264) progressiv_high(h264) constrained_high(h264)"
- " main(hevc) main10(hevc) frext(hevc)";
- std::vector vProfile = std::vector {
- GUID{},
- NV_ENC_CODEC_PROFILE_AUTOSELECT_GUID,
- NV_ENC_H264_PROFILE_BASELINE_GUID,
- NV_ENC_H264_PROFILE_MAIN_GUID,
- NV_ENC_H264_PROFILE_HIGH_GUID,
- NV_ENC_H264_PROFILE_HIGH_444_GUID,
- NV_ENC_H264_PROFILE_STEREO_GUID,
- NV_ENC_H264_PROFILE_SVC_TEMPORAL_SCALABILTY,
- NV_ENC_H264_PROFILE_PROGRESSIVE_HIGH_GUID,
- NV_ENC_H264_PROFILE_CONSTRAINED_HIGH_GUID,
- NV_ENC_HEVC_PROFILE_MAIN_GUID,
- NV_ENC_HEVC_PROFILE_MAIN10_GUID,
- NV_ENC_HEVC_PROFILE_FREXT_GUID,
- };
-
- const char *szRcModeNames = "constqp vbr cbr cbr_ll_hq cbr_hq vbr_hq";
- std::vector vRcMode = std::vector {
- NV_ENC_PARAMS_RC_CONSTQP,
- NV_ENC_PARAMS_RC_VBR,
- NV_ENC_PARAMS_RC_CBR,
- NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ,
- NV_ENC_PARAMS_RC_CBR_HQ,
- NV_ENC_PARAMS_RC_VBR_HQ,
- };
-
- const char *szQpMapModeNames = "disabled emphasis_level_map delta_qp_map qp_map";
- std::vector vQpMapMode = std::vector {
- NV_ENC_QP_MAP_DISABLED,
- NV_ENC_QP_MAP_EMPHASIS,
- NV_ENC_QP_MAP_DELTA,
- NV_ENC_QP_MAP,
- };
-
-
-public:
- std::string FullParamToString(const NV_ENC_INITIALIZE_PARAMS *pInitializeParams) {
- std::ostringstream os;
- os << "NV_ENC_INITIALIZE_PARAMS:" << std::endl
- << "encodeGUID: " << ConvertValueToString(vCodec, szCodecNames, pInitializeParams->encodeGUID) << std::endl
- << "presetGUID: " << ConvertValueToString(vPreset, szPresetNames, pInitializeParams->presetGUID) << std::endl
- << "encodeWidth: " << pInitializeParams->encodeWidth << std::endl
- << "encodeHeight: " << pInitializeParams->encodeHeight << std::endl
- << "darWidth: " << pInitializeParams->darWidth << std::endl
- << "darHeight: " << pInitializeParams->darHeight << std::endl
- << "frameRateNum: " << pInitializeParams->frameRateNum << std::endl
- << "frameRateDen: " << pInitializeParams->frameRateDen << std::endl
- << "enableEncodeAsync: " << pInitializeParams->enableEncodeAsync << std::endl
- << "reportSliceOffsets: " << pInitializeParams->reportSliceOffsets << std::endl
- << "enableSubFrameWrite: " << pInitializeParams->enableSubFrameWrite << std::endl
- << "enableExternalMEHints: " << pInitializeParams->enableExternalMEHints << std::endl
- << "enableMEOnlyMode: " << pInitializeParams->enableMEOnlyMode << std::endl
- << "enableWeightedPrediction: " << pInitializeParams->enableWeightedPrediction << std::endl
- << "maxEncodeWidth: " << pInitializeParams->maxEncodeWidth << std::endl
- << "maxEncodeHeight: " << pInitializeParams->maxEncodeHeight << std::endl
- << "maxMEHintCountsPerBlock: " << pInitializeParams->maxMEHintCountsPerBlock << std::endl
- ;
- NV_ENC_CONFIG *pConfig = pInitializeParams->encodeConfig;
- os << "NV_ENC_CONFIG:" << std::endl
- << "profile: " << ConvertValueToString(vProfile, szProfileNames, pConfig->profileGUID) << std::endl
- << "gopLength: " << pConfig->gopLength << std::endl
- << "frameIntervalP: " << pConfig->frameIntervalP << std::endl
- << "monoChromeEncoding: " << pConfig->monoChromeEncoding << std::endl
- << "frameFieldMode: " << pConfig->frameFieldMode << std::endl
- << "mvPrecision: " << pConfig->mvPrecision << std::endl
- << "NV_ENC_RC_PARAMS:" << std::endl
- << " rateControlMode: 0x" << std::hex << pConfig->rcParams.rateControlMode << std::dec << std::endl
- << " constQP: " << pConfig->rcParams.constQP.qpInterP << ", " << pConfig->rcParams.constQP.qpInterB << ", " << pConfig->rcParams.constQP.qpIntra << std::endl
- << " averageBitRate: " << pConfig->rcParams.averageBitRate << std::endl
- << " maxBitRate: " << pConfig->rcParams.maxBitRate << std::endl
- << " vbvBufferSize: " << pConfig->rcParams.vbvBufferSize << std::endl
- << " vbvInitialDelay: " << pConfig->rcParams.vbvInitialDelay << std::endl
- << " enableMinQP: " << pConfig->rcParams.enableMinQP << std::endl
- << " enableMaxQP: " << pConfig->rcParams.enableMaxQP << std::endl
- << " enableInitialRCQP: " << pConfig->rcParams.enableInitialRCQP << std::endl
- << " enableAQ: " << pConfig->rcParams.enableAQ << std::endl
- << " qpMapMode: " << ConvertValueToString(vQpMapMode, szQpMapModeNames, pConfig->rcParams.qpMapMode) << std::endl
- << " enableLookahead: " << pConfig->rcParams.enableLookahead << std::endl
- << " disableIadapt: " << pConfig->rcParams.disableIadapt << std::endl
- << " disableBadapt: " << pConfig->rcParams.disableBadapt << std::endl
- << " enableTemporalAQ: " << pConfig->rcParams.enableTemporalAQ << std::endl
- << " zeroReorderDelay: " << pConfig->rcParams.zeroReorderDelay << std::endl
- << " enableNonRefP: " << pConfig->rcParams.enableNonRefP << std::endl
- << " strictGOPTarget: " << pConfig->rcParams.strictGOPTarget << std::endl
- << " aqStrength: " << pConfig->rcParams.aqStrength << std::endl
- << " minQP: " << pConfig->rcParams.minQP.qpInterP << ", " << pConfig->rcParams.minQP.qpInterB << ", " << pConfig->rcParams.minQP.qpIntra << std::endl
- << " maxQP: " << pConfig->rcParams.maxQP.qpInterP << ", " << pConfig->rcParams.maxQP.qpInterB << ", " << pConfig->rcParams.maxQP.qpIntra << std::endl
- << " initialRCQP: " << pConfig->rcParams.initialRCQP.qpInterP << ", " << pConfig->rcParams.initialRCQP.qpInterB << ", " << pConfig->rcParams.initialRCQP.qpIntra << std::endl
- << " temporallayerIdxMask: " << pConfig->rcParams.temporallayerIdxMask << std::endl
- << " temporalLayerQP: " << (int)pConfig->rcParams.temporalLayerQP[0] << ", " << (int)pConfig->rcParams.temporalLayerQP[1] << ", " << (int)pConfig->rcParams.temporalLayerQP[2] << ", " << (int)pConfig->rcParams.temporalLayerQP[3] << ", " << (int)pConfig->rcParams.temporalLayerQP[4] << ", " << (int)pConfig->rcParams.temporalLayerQP[5] << ", " << (int)pConfig->rcParams.temporalLayerQP[6] << ", " << (int)pConfig->rcParams.temporalLayerQP[7] << std::endl
- << " targetQuality: " << (int)pConfig->rcParams.targetQuality << std::endl
- << " lookaheadDepth: " << pConfig->rcParams.lookaheadDepth << std::endl;
- if (pInitializeParams->encodeGUID == NV_ENC_CODEC_H264_GUID) {
- os
- << "NV_ENC_CODEC_CONFIG (H264):" << std::endl
- << " enableTemporalSVC: " << pConfig->encodeCodecConfig.h264Config.enableTemporalSVC << std::endl
- << " enableStereoMVC: " << pConfig->encodeCodecConfig.h264Config.enableStereoMVC << std::endl
- << " hierarchicalPFrames: " << pConfig->encodeCodecConfig.h264Config.hierarchicalPFrames << std::endl
- << " hierarchicalBFrames: " << pConfig->encodeCodecConfig.h264Config.hierarchicalBFrames << std::endl
- << " outputBufferingPeriodSEI: " << pConfig->encodeCodecConfig.h264Config.outputBufferingPeriodSEI << std::endl
- << " outputPictureTimingSEI: " << pConfig->encodeCodecConfig.h264Config.outputPictureTimingSEI << std::endl
- << " outputAUD: " << pConfig->encodeCodecConfig.h264Config.outputAUD << std::endl
- << " disableSPSPPS: " << pConfig->encodeCodecConfig.h264Config.disableSPSPPS << std::endl
- << " outputFramePackingSEI: " << pConfig->encodeCodecConfig.h264Config.outputFramePackingSEI << std::endl
- << " outputRecoveryPointSEI: " << pConfig->encodeCodecConfig.h264Config.outputRecoveryPointSEI << std::endl
- << " enableIntraRefresh: " << pConfig->encodeCodecConfig.h264Config.enableIntraRefresh << std::endl
- << " enableConstrainedEncoding: " << pConfig->encodeCodecConfig.h264Config.enableConstrainedEncoding << std::endl
- << " repeatSPSPPS: " << pConfig->encodeCodecConfig.h264Config.repeatSPSPPS << std::endl
- << " enableVFR: " << pConfig->encodeCodecConfig.h264Config.enableVFR << std::endl
- << " enableLTR: " << pConfig->encodeCodecConfig.h264Config.enableLTR << std::endl
- << " qpPrimeYZeroTransformBypassFlag: " << pConfig->encodeCodecConfig.h264Config.qpPrimeYZeroTransformBypassFlag << std::endl
- << " useConstrainedIntraPred: " << pConfig->encodeCodecConfig.h264Config.useConstrainedIntraPred << std::endl
- << " level: " << pConfig->encodeCodecConfig.h264Config.level << std::endl
- << " idrPeriod: " << pConfig->encodeCodecConfig.h264Config.idrPeriod << std::endl
- << " separateColourPlaneFlag: " << pConfig->encodeCodecConfig.h264Config.separateColourPlaneFlag << std::endl
- << " disableDeblockingFilterIDC: " << pConfig->encodeCodecConfig.h264Config.disableDeblockingFilterIDC << std::endl
- << " numTemporalLayers: " << pConfig->encodeCodecConfig.h264Config.numTemporalLayers << std::endl
- << " enableTemporalSVC: " << pConfig->encodeCodecConfig.h264Config.enableTemporalSVC << std::endl
- << " spsId: " << pConfig->encodeCodecConfig.h264Config.spsId << std::endl
- << " ppsId: " << pConfig->encodeCodecConfig.h264Config.ppsId << std::endl
- << " adaptiveTransformMode: " << pConfig->encodeCodecConfig.h264Config.adaptiveTransformMode << std::endl
- << " fmoMode: " << pConfig->encodeCodecConfig.h264Config.fmoMode << std::endl
- << " bdirectMode: " << pConfig->encodeCodecConfig.h264Config.bdirectMode << std::endl
- << " entropyCodingMode: " << pConfig->encodeCodecConfig.h264Config.entropyCodingMode << std::endl
- << " stereoMode: " << pConfig->encodeCodecConfig.h264Config.stereoMode << std::endl
- << " intraRefreshPeriod: " << pConfig->encodeCodecConfig.h264Config.intraRefreshPeriod << std::endl
- << " intraRefreshCnt: " << pConfig->encodeCodecConfig.h264Config.intraRefreshCnt << std::endl
- << " maxNumRefFrames: " << pConfig->encodeCodecConfig.h264Config.maxNumRefFrames << std::endl
- << " sliceMode: " << pConfig->encodeCodecConfig.h264Config.sliceMode << std::endl
- << " sliceModeData: " << pConfig->encodeCodecConfig.h264Config.sliceModeData << std::endl
- << " NV_ENC_CONFIG_H264_VUI_PARAMETERS:" << std::endl
- << " overscanInfoPresentFlag: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.overscanInfoPresentFlag << std::endl
- << " overscanInfo: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.overscanInfo << std::endl
- << " videoSignalTypePresentFlag: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.videoSignalTypePresentFlag << std::endl
- << " videoFormat: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.videoFormat << std::endl
- << " videoFullRangeFlag: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.videoFullRangeFlag << std::endl
- << " colourDescriptionPresentFlag: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.colourDescriptionPresentFlag << std::endl
- << " colourPrimaries: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.colourPrimaries << std::endl
- << " transferCharacteristics: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.transferCharacteristics << std::endl
- << " colourMatrix: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.colourMatrix << std::endl
- << " chromaSampleLocationFlag: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.chromaSampleLocationFlag << std::endl
- << " chromaSampleLocationTop: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.chromaSampleLocationTop << std::endl
- << " chromaSampleLocationBot: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.chromaSampleLocationBot << std::endl
- << " bitstreamRestrictionFlag: " << pConfig->encodeCodecConfig.h264Config.h264VUIParameters.bitstreamRestrictionFlag << std::endl
- << " ltrNumFrames: " << pConfig->encodeCodecConfig.h264Config.ltrNumFrames << std::endl
- << " ltrTrustMode: " << pConfig->encodeCodecConfig.h264Config.ltrTrustMode << std::endl
- << " chromaFormatIDC: " << pConfig->encodeCodecConfig.h264Config.chromaFormatIDC << std::endl
- << " maxTemporalLayers: " << pConfig->encodeCodecConfig.h264Config.maxTemporalLayers << std::endl;
- } else if (pInitializeParams->encodeGUID == NV_ENC_CODEC_HEVC_GUID) {
- os
- << "NV_ENC_CODEC_CONFIG (HEVC):" << std::endl
- << " level: " << pConfig->encodeCodecConfig.hevcConfig.level << std::endl
- << " tier: " << pConfig->encodeCodecConfig.hevcConfig.tier << std::endl
- << " minCUSize: " << pConfig->encodeCodecConfig.hevcConfig.minCUSize << std::endl
- << " maxCUSize: " << pConfig->encodeCodecConfig.hevcConfig.maxCUSize << std::endl
- << " useConstrainedIntraPred: " << pConfig->encodeCodecConfig.hevcConfig.useConstrainedIntraPred << std::endl
- << " disableDeblockAcrossSliceBoundary: " << pConfig->encodeCodecConfig.hevcConfig.disableDeblockAcrossSliceBoundary << std::endl
- << " outputBufferingPeriodSEI: " << pConfig->encodeCodecConfig.hevcConfig.outputBufferingPeriodSEI << std::endl
- << " outputPictureTimingSEI: " << pConfig->encodeCodecConfig.hevcConfig.outputPictureTimingSEI << std::endl
- << " outputAUD: " << pConfig->encodeCodecConfig.hevcConfig.outputAUD << std::endl
- << " enableLTR: " << pConfig->encodeCodecConfig.hevcConfig.enableLTR << std::endl
- << " disableSPSPPS: " << pConfig->encodeCodecConfig.hevcConfig.disableSPSPPS << std::endl
- << " repeatSPSPPS: " << pConfig->encodeCodecConfig.hevcConfig.repeatSPSPPS << std::endl
- << " enableIntraRefresh: " << pConfig->encodeCodecConfig.hevcConfig.enableIntraRefresh << std::endl
- << " chromaFormatIDC: " << pConfig->encodeCodecConfig.hevcConfig.chromaFormatIDC << std::endl
- << " pixelBitDepthMinus8: " << pConfig->encodeCodecConfig.hevcConfig.pixelBitDepthMinus8 << std::endl
- << " idrPeriod: " << pConfig->encodeCodecConfig.hevcConfig.idrPeriod << std::endl
- << " intraRefreshPeriod: " << pConfig->encodeCodecConfig.hevcConfig.intraRefreshPeriod << std::endl
- << " intraRefreshCnt: " << pConfig->encodeCodecConfig.hevcConfig.intraRefreshCnt << std::endl
- << " maxNumRefFramesInDPB: " << pConfig->encodeCodecConfig.hevcConfig.maxNumRefFramesInDPB << std::endl
- << " ltrNumFrames: " << pConfig->encodeCodecConfig.hevcConfig.ltrNumFrames << std::endl
- << " vpsId: " << pConfig->encodeCodecConfig.hevcConfig.vpsId << std::endl
- << " spsId: " << pConfig->encodeCodecConfig.hevcConfig.spsId << std::endl
- << " ppsId: " << pConfig->encodeCodecConfig.hevcConfig.ppsId << std::endl
- << " sliceMode: " << pConfig->encodeCodecConfig.hevcConfig.sliceMode << std::endl
- << " sliceModeData: " << pConfig->encodeCodecConfig.hevcConfig.sliceModeData << std::endl
- << " maxTemporalLayersMinus1: " << pConfig->encodeCodecConfig.hevcConfig.maxTemporalLayersMinus1 << std::endl
- << " NV_ENC_CONFIG_HEVC_VUI_PARAMETERS:" << std::endl
- << " overscanInfoPresentFlag: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.overscanInfoPresentFlag << std::endl
- << " overscanInfo: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.overscanInfo << std::endl
- << " videoSignalTypePresentFlag: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.videoSignalTypePresentFlag << std::endl
- << " videoFormat: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.videoFormat << std::endl
- << " videoFullRangeFlag: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.videoFullRangeFlag << std::endl
- << " colourDescriptionPresentFlag: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.colourDescriptionPresentFlag << std::endl
- << " colourPrimaries: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.colourPrimaries << std::endl
- << " transferCharacteristics: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.transferCharacteristics << std::endl
- << " colourMatrix: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.colourMatrix << std::endl
- << " chromaSampleLocationFlag: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.chromaSampleLocationFlag << std::endl
- << " chromaSampleLocationTop: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.chromaSampleLocationTop << std::endl
- << " chromaSampleLocationBot: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.chromaSampleLocationBot << std::endl
- << " bitstreamRestrictionFlag: " << pConfig->encodeCodecConfig.hevcConfig.hevcVUIParameters.bitstreamRestrictionFlag << std::endl
- << " ltrTrustMode: " << pConfig->encodeCodecConfig.hevcConfig.ltrTrustMode << std::endl;
- }
- return os.str();
- }
-};
diff --git a/alvr/server/cpp/bin/windows/openvr_api.dll b/alvr/server/cpp/bin/windows/openvr_api.dll
index e0113cd389..5c70fd194a 100644
Binary files a/alvr/server/cpp/bin/windows/openvr_api.dll and b/alvr/server/cpp/bin/windows/openvr_api.dll differ
diff --git a/alvr/server/cpp/bin/windows/vcruntime140_1.dll b/alvr/server/cpp/bin/windows/vcruntime140_1.dll
index 70dcc8633e..7e2611997a 100644
Binary files a/alvr/server/cpp/bin/windows/vcruntime140_1.dll and b/alvr/server/cpp/bin/windows/vcruntime140_1.dll differ
diff --git a/alvr/server/cpp/openvr/headers/openvr.h b/alvr/server/cpp/openvr/headers/openvr.h
index ff6d1fe235..336094b0ce 100644
--- a/alvr/server/cpp/openvr/headers/openvr.h
+++ b/alvr/server/cpp/openvr/headers/openvr.h
@@ -15,9 +15,9 @@
namespace vr
{
- static const uint32_t k_nSteamVRVersionMajor = 1;
- static const uint32_t k_nSteamVRVersionMinor = 16;
- static const uint32_t k_nSteamVRVersionBuild = 8;
+ static const uint32_t k_nSteamVRVersionMajor = 2;
+ static const uint32_t k_nSteamVRVersionMinor = 5;
+ static const uint32_t k_nSteamVRVersionBuild = 1;
} // namespace vr
// public_vrtypes.h
@@ -29,6 +29,8 @@ namespace vr
{
#pragma pack( push, 8 )
+typedef uint32_t PropertyTypeTag_t;
+
// right-handed system
// +y is up
// +x is to the right
@@ -102,40 +104,6 @@ struct VRBoneTransform_t
HmdQuaternionf_t orientation;
};
-#pragma pack( pop )
-
-} // namespace vr
-
-#endif
-
-// vrtypes.h
-
-#ifndef _INCLUDE_VRTYPES_H
-#define _INCLUDE_VRTYPES_H
-
-// Forward declarations to avoid requiring vulkan.h
-struct VkDevice_T;
-struct VkPhysicalDevice_T;
-struct VkInstance_T;
-struct VkQueue_T;
-
-// Forward declarations to avoid requiring d3d12.h
-struct ID3D12Resource;
-struct ID3D12CommandQueue;
-
-namespace vr
-{
-#pragma pack( push, 8 )
-
-/** A handle for a spatial anchor. This handle is only valid during the session it was created in.
-* Anchors that live beyond one session should be saved by their string descriptors. */
-typedef uint32_t SpatialAnchorHandle_t;
-
-typedef void* glSharedTextureHandle_t;
-typedef int32_t glInt_t;
-typedef uint32_t glUInt_t;
-
-
/** Used to return the post-distortion UVs for each color channel.
* UVs range from 0 to 1 with 0,0 in the upper left corner of the
* source render target. The 0,0 to 1,1 range covers a single eye. */
@@ -162,9 +130,11 @@ enum ETextureType
TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure
TextureType_DXGISharedHandle = 5, // Handle is a HANDLE DXGI share handle, only supported for Overlay render targets.
// this texture is used directly by our renderer, so only perform atomic (copyresource or resolve) on it
- TextureType_Metal = 6, // Handle is a MTLTexture conforming to the MTLSharedTexture protocol. Textures submitted to IVRCompositor::Submit which
- // are of type MTLTextureType2DArray assume layer 0 is the left eye texture (vr::EVREye::Eye_left), layer 1 is the right
- // eye texture (vr::EVREye::Eye_Right)
+ TextureType_Metal = 6, // Handle is a MTLTexture conforming to the MTLSharedTexture protocol. Textures submitted to IVRCompositor::Submit which
+ // are of type MTLTextureType2DArray assume layer 0 is the left eye texture (vr::EVREye::Eye_left), layer 1 is the right
+ // eye texture (vr::EVREye::Eye_Right)
+
+ TextureType_Reserved = 7,
};
enum EColorSpace
@@ -181,6 +151,81 @@ struct Texture_t
EColorSpace eColorSpace;
};
+/** Allows the application to control what part of the provided texture will be used in the
+* frame buffer. */
+struct VRTextureBounds_t
+{
+ float uMin, vMin;
+ float uMax, vMax;
+};
+
+/** Allows specifying pose used to render provided scene texture (if different from value returned by WaitGetPoses). */
+struct VRTextureWithPose_t : public Texture_t
+{
+ HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures.
+};
+
+struct VRTextureDepthInfo_t
+{
+ void* handle; // See ETextureType definition above
+ HmdMatrix44_t mProjection;
+ HmdVector2_t vRange; // 0..1
+};
+
+struct VRTextureWithDepth_t : public Texture_t
+{
+ VRTextureDepthInfo_t depth;
+};
+
+struct VRTextureWithPoseAndDepth_t : public VRTextureWithPose_t
+{
+ VRTextureDepthInfo_t depth;
+};
+
+// 64-bit types that are part of public structures
+// that are replicated in shared memory.
+#if defined(__linux__) || defined(__APPLE__)
+typedef uint64_t vrshared_uint64_t __attribute__ ((aligned(8)));
+typedef double vrshared_double __attribute__ ((aligned(8)));
+#else
+typedef uint64_t vrshared_uint64_t;
+typedef double vrshared_double;
+#endif
+
+#pragma pack( pop )
+
+} // namespace vr
+
+#endif
+
+// vrtypes.h
+
+#ifndef _INCLUDE_VRTYPES_H
+#define _INCLUDE_VRTYPES_H
+
+// Forward declarations to avoid requiring vulkan.h
+struct VkDevice_T;
+struct VkPhysicalDevice_T;
+struct VkInstance_T;
+struct VkQueue_T;
+
+// Forward declarations to avoid requiring d3d12.h
+struct ID3D12Resource;
+struct ID3D12CommandQueue;
+
+namespace vr
+{
+#pragma pack( push, 8 )
+
+/** A handle for a spatial anchor. This handle is only valid during the session it was created in.
+* Anchors that live beyond one session should be saved by their string descriptors. */
+typedef uint32_t SpatialAnchorHandle_t;
+
+typedef void* glSharedTextureHandle_t;
+typedef int32_t glInt_t;
+typedef uint32_t glUInt_t;
+
+
// Handle to a shared texture (HANDLE on Windows obtained using OpenSharedResource).
typedef uint64_t SharedTextureHandle_t;
#define INVALID_SHARED_TEXTURE_HANDLE ((vr::SharedTextureHandle_t)0)
@@ -387,6 +432,9 @@ enum ETrackedDeviceProperty
Prop_ManufacturerSerialNumber_String = 1049,
Prop_ComputedSerialNumber_String = 1050,
Prop_EstimatedDeviceFirstUseTime_Int32 = 1051,
+ Prop_DevicePowerUsage_Float = 1052,
+ Prop_IgnoreMotionForStandby_Bool = 1053,
+ Prop_ActualTrackingSystemName_String = 1054, // the literal local driver name in case someone is playing games with prop 1000
// Properties that are unique to TrackedDeviceClass_HMD
Prop_ReportsTimeSinceVSync_Bool = 2000,
@@ -479,10 +527,30 @@ enum ETrackedDeviceProperty
Prop_CameraGlobalGain_Float = 2089,
// Prop_DashboardLayoutPathName_String = 2090, // DELETED
Prop_DashboardScale_Float = 2091,
+ Prop_PeerButtonInfo_String = 2092,
+ Prop_Hmd_SupportsHDR10_Bool = 2093,
+ Prop_Hmd_EnableParallelRenderCameras_Bool = 2094,
+ Prop_DriverProvidedChaperoneJson_String = 2095, // higher priority than Prop_DriverProvidedChaperonePath_String
+ Prop_ForceSystemLayerUseAppPoses_Bool = 2096,
+
Prop_IpdUIRangeMinMeters_Float = 2100,
Prop_IpdUIRangeMaxMeters_Float = 2101,
Prop_Hmd_SupportsHDCP14LegacyCompat_Bool = 2102,
Prop_Hmd_SupportsMicMonitoring_Bool = 2103,
+ Prop_Hmd_SupportsDisplayPortTrainingMode_Bool = 2104,
+ Prop_Hmd_SupportsRoomViewDirect_Bool = 2105,
+ Prop_Hmd_SupportsAppThrottling_Bool = 2106,
+ Prop_Hmd_SupportsGpuBusMonitoring_Bool = 2107,
+ Prop_DriverDisplaysIPDChanges_Bool = 2108,
+ Prop_Driver_Reserved_01 = 2109,
+
+ Prop_DSCVersion_Int32 = 2110,
+ Prop_DSCSliceCount_Int32 = 2111,
+ Prop_DSCBPPx16_Int32 = 2112,
+
+ Prop_Hmd_MaxDistortedTextureWidth_Int32 = 2113,
+ Prop_Hmd_MaxDistortedTextureHeight_Int32 = 2114,
+ Prop_Hmd_AllowSupersampleFiltering_Bool = 2115,
// Driver requested mura correction properties
Prop_DriverRequestedMuraCorrectionMode_Int32 = 2200,
@@ -495,10 +563,16 @@ enum ETrackedDeviceProperty
Prop_DriverRequestedMuraFeather_OuterTop_Int32 = 2207,
Prop_DriverRequestedMuraFeather_OuterBottom_Int32 = 2208,
- Prop_Audio_DefaultPlaybackDeviceId_String = 2300,
- Prop_Audio_DefaultRecordingDeviceId_String = 2301,
- Prop_Audio_DefaultPlaybackDeviceVolume_Float = 2302,
- Prop_Audio_SupportsDualSpeakerAndJackOutput_Bool = 2303,
+ Prop_Audio_DefaultPlaybackDeviceId_String = 2300,
+ Prop_Audio_DefaultRecordingDeviceId_String = 2301,
+ Prop_Audio_DefaultPlaybackDeviceVolume_Float = 2302,
+ Prop_Audio_SupportsDualSpeakerAndJackOutput_Bool = 2303,
+ Prop_Audio_DriverManagesPlaybackVolumeControl_Bool = 2304,
+ Prop_Audio_DriverPlaybackVolume_Float = 2305,
+ Prop_Audio_DriverPlaybackMute_Bool = 2306,
+ Prop_Audio_DriverManagesRecordingVolumeControl_Bool = 2307,
+ Prop_Audio_DriverRecordingVolume_Float = 2308,
+ Prop_Audio_DriverRecordingMute_Bool = 2309,
// Properties that are unique to TrackedDeviceClass_Controller
Prop_AttachedDeviceId_String = 3000,
@@ -547,7 +621,8 @@ enum ETrackedDeviceProperty
Prop_HasCameraComponent_Bool = 6004,
Prop_HasDriverDirectModeComponent_Bool = 6005,
Prop_HasVirtualDisplayComponent_Bool = 6006,
- Prop_HasSpatialAnchorsSupport_Bool = 6007,
+ Prop_HasSpatialAnchorsSupport_Bool = 6007,
+ Prop_SupportsXrTextureSets_Bool = 6008,
// Properties that are set internally based on other information provided by drivers
Prop_ControllerType_String = 7000,
@@ -604,37 +679,6 @@ static const VRActionSetHandle_t k_ulInvalidActionSetHandle = 0;
static const VRInputValueHandle_t k_ulInvalidInputValueHandle = 0;
-/** Allows the application to control what part of the provided texture will be used in the
-* frame buffer. */
-struct VRTextureBounds_t
-{
- float uMin, vMin;
- float uMax, vMax;
-};
-
-/** Allows specifying pose used to render provided scene texture (if different from value returned by WaitGetPoses). */
-struct VRTextureWithPose_t : public Texture_t
-{
- HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures.
-};
-
-struct VRTextureDepthInfo_t
-{
- void* handle; // See ETextureType definition above
- HmdMatrix44_t mProjection;
- HmdVector2_t vRange; // 0..1
-};
-
-struct VRTextureWithDepth_t : public Texture_t
-{
- VRTextureDepthInfo_t depth;
-};
-
-struct VRTextureWithPoseAndDepth_t : public VRTextureWithPose_t
-{
- VRTextureDepthInfo_t depth;
-};
-
/** Allows the application to control how scene textures are used by the compositor when calling Submit. */
enum EVRSubmitFlags
{
@@ -670,9 +714,12 @@ enum EVRSubmitFlags
// If the texture pointer passed in is an OpenGL Array texture, set this flag
Submit_GlArrayTexture = 0x80,
- // Do not use
- Submit_Reserved2 = 0x8000,
+ // If the texture is an EGL texture and not an glX/wGL texture (Linux only, currently)
+ Submit_IsEgl = 0x100,
+ // Do not use
+ Submit_Reserved2 = 0x08000,
+ Submit_Reserved3 = 0x10000,
};
@@ -741,6 +788,8 @@ enum EVREventType
VREvent_PropertyChanged = 111,
VREvent_WirelessDisconnect = 112,
VREvent_WirelessReconnect = 113,
+ VREvent_Reserved_01 = 114,
+ VREvent_Reserved_02 = 115,
VREvent_ButtonPress = 200, // data is controller
VREvent_ButtonUnpress = 201, // data is controller
@@ -766,15 +815,15 @@ enum EVREventType
VREvent_OverlayFocusChanged = 307, // data is overlay, global event
VREvent_ReloadOverlays = 308,
VREvent_ScrollSmooth = 309, // data is scroll
- VREvent_LockMousePosition = 310,
- VREvent_UnlockMousePosition = 311,
+ VREvent_LockMousePosition = 310, // data is mouse
+ VREvent_UnlockMousePosition = 311, // data is mouse
VREvent_InputFocusCaptured = 400, // data is process DEPRECATED
VREvent_InputFocusReleased = 401, // data is process DEPRECATED
// VREvent_SceneFocusLost = 402, // data is process
// VREvent_SceneFocusGained = 403, // data is process
VREvent_SceneApplicationChanged = 404, // data is process - The App actually drawing the scene changed (usually to or from the compositor)
- VREvent_SceneFocusChanged = 405, // data is process - New app got access to draw the scene
+ // VREvent_SceneFocusChanged = 405, // data is process - This is defunct and will not be called.
VREvent_InputFocusChanged = 406, // data is process
// VREvent_SceneApplicationSecondaryRenderingStarted = 407,
VREvent_SceneApplicationUsingWrongGraphicsAdapter = 408, // data is process
@@ -785,11 +834,13 @@ enum EVREventType
VREvent_SceneApplicationStateChanged = 412, // No data; but query VRApplications()->GetSceneApplicationState();
+ VREvent_SceneAppPipeDisconnected = 413, // data is process - Called when the scene app's pipe has been closed.
+
VREvent_ConsoleOpened = 420,
VREvent_ConsoleClosed = 421,
- VREvent_OverlayShown = 500,
- VREvent_OverlayHidden = 501,
+ VREvent_OverlayShown = 500, // Indicates that an overlay is now visible to someone and should be rendering normally. Reflects IVROverlay::IsOverlayVisible() becoming true.
+ VREvent_OverlayHidden = 501, // Indicates that an overlay is no longer visible to someone and doesn't need to render frames. Reflects IVROverlay::IsOverlayVisible() becoming false.
VREvent_DashboardActivated = 502,
VREvent_DashboardDeactivated = 503,
//VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay - No longer sent
@@ -824,6 +875,21 @@ enum EVREventType
VREvent_DesktopViewUpdating = 530,
VREvent_DesktopViewReady = 531,
+ VREvent_StartDashboard = 532,
+ VREvent_ElevatePrism = 533,
+
+ VREvent_OverlayClosed = 534,
+
+ VREvent_DashboardThumbChanged = 535, // Sent when a dashboard thumbnail image changes
+
+ VREvent_DesktopMightBeVisible = 536, // Sent when any known desktop related overlay is visible
+ VREvent_DesktopMightBeHidden = 537, // Sent when all known desktop related overlays are hidden
+
+ VREvent_MutualSteamCapabilitiesChanged = 538, // Sent when the set of capabilities common between both Steam and SteamVR have changed.
+
+ VREvent_OverlayCreated = 539, // An OpenVR overlay of any sort was created. Data is overlay.
+ VREvent_OverlayDestroyed = 540, // An OpenVR overlay of any sort was destroyed. Data is overlay.
+
VREvent_Notification_Shown = 600,
VREvent_Notification_Hidden = 601,
VREvent_Notification_BeginInteraction = 602,
@@ -835,6 +901,7 @@ enum EVREventType
VREvent_QuitAcknowledged = 703, // data is process
VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down
VREvent_RestartRequested = 705, // A driver or other component wants the user to restart SteamVR
+ VREvent_InvalidateSwapTextureSets = 706,
VREvent_ChaperoneDataHasChanged = 800, // this will never happen with the new chaperone system
VREvent_ChaperoneUniverseHasChanged = 801,
@@ -870,6 +937,7 @@ enum EVREventType
VREvent_GpuSpeedSectionSettingChanged = 869,
VREvent_WindowsMRSectionSettingChanged = 870,
VREvent_OtherSectionSettingChanged = 871,
+ VREvent_AnyDriverSettingsChanged = 872,
VREvent_StatusUpdate = 900,
@@ -880,9 +948,11 @@ enum EVREventType
VREvent_FirmwareUpdateStarted = 1100,
VREvent_FirmwareUpdateFinished = 1101,
- VREvent_KeyboardClosed = 1200,
+ VREvent_KeyboardClosed = 1200, // DEPRECATED: Sent only to the overlay it closed for, or globally if it was closed for a scene app
VREvent_KeyboardCharInput = 1201,
VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard
+ VREvent_KeyboardOpened_Global = 1203, // Sent globally when the keyboard is opened. data.keyboard.overlayHandle is who it was opened for (scene app if k_ulOverlayHandleInvalid)
+ VREvent_KeyboardClosed_Global = 1204, // Sent globally when the keyboard is closed. data.keyboard.overlayHandle is who it was opened for (scene app if k_ulOverlayHandleInvalid)
//VREvent_ApplicationTransitionStarted = 1300,
//VREvent_ApplicationTransitionAborted = 1301,
@@ -905,6 +975,7 @@ enum EVREventType
VREvent_Compositor_OutOfVideoMemory = 1417,
VREvent_Compositor_DisplayModeNotSupported = 1418, // k_pch_SteamVR_PreferredRefreshRate
VREvent_Compositor_StageOverrideReady = 1419,
+ VREvent_Compositor_RequestDisconnectReconnect = 1420,
VREvent_TrackedCamera_StartVideoStream = 1500,
VREvent_TrackedCamera_StopVideoStream = 1501,
@@ -939,6 +1010,11 @@ enum EVREventType
VREvent_Monitor_ShowHeadsetView = 2000, // data is process
VREvent_Monitor_HideHeadsetView = 2001, // data is process
+ VREvent_Audio_SetSpeakersVolume = 2100,
+ VREvent_Audio_SetSpeakersMute = 2101,
+ VREvent_Audio_SetMicrophoneVolume = 2102,
+ VREvent_Audio_SetMicrophoneMute = 2103,
+
// Vendors are free to expose private events in this reserved region
VREvent_VendorSpecific_Reserved_Start = 10000,
VREvent_VendorSpecific_Reserved_End = 19999,
@@ -991,6 +1067,9 @@ enum EVRButtonId
k_EButton_IndexController_B = k_EButton_ApplicationMenu,
k_EButton_IndexController_JoyStick = k_EButton_Axis3,
+ k_EButton_Reserved0 = 50,
+ k_EButton_Reserved1 = 51,
+
k_EButton_Max = 64
};
@@ -1017,6 +1096,10 @@ struct VREvent_Mouse_t
{
float x, y; // co-ords are in GL space, bottom left of the texture is 0,0
uint32_t button; // EVRMouseButton enum
+
+ // if from an event triggered by cursor input on an overlay that supports multiple cursors, this is the index of
+ // which tracked cursor the event is for
+ uint32_t cursorIndex;
};
/** used for simulated mouse wheel scroll */
@@ -1025,6 +1108,10 @@ struct VREvent_Scroll_t
float xdelta, ydelta;
uint32_t unused;
float viewportscale; // For scrolling on an overlay with laser mouse, this is the overlay's vertical size relative to the overlay height. Range: [0,1]
+
+ // if from an event triggered by cursor input on an overlay that supports multiple cursors, this is the index of
+ // which tracked cursor the event is for
+ uint32_t cursorIndex;
};
/** when in mouse input mode you can receive data from the touchpad, these events are only sent if the users finger
@@ -1069,9 +1156,13 @@ struct VREvent_Process_t
/** Used for a few events about overlays */
struct VREvent_Overlay_t
{
- uint64_t overlayHandle;
+ uint64_t overlayHandle; // VROverlayHandle_t
uint64_t devicePath;
uint64_t memoryBlockId;
+
+ // if from an event triggered by cursor input on an overlay that supports multiple cursors, this is the index of
+ // which tracked cursor the event is for
+ uint32_t cursorIndex;
};
@@ -1081,11 +1172,12 @@ struct VREvent_Status_t
uint32_t statusState; // EVRState enum
};
-/** Used for keyboard events **/
+/** Used for keyboard events */
struct VREvent_Keyboard_t
{
- char cNewInput[8]; // Up to 11 bytes of new input
- uint64_t uUserValue; // Possible flags about the new input
+ char cNewInput[8]; // 7 bytes of utf8 + null
+ uint64_t uUserValue; // caller specified opaque token
+ uint64_t overlayHandle; // VROverlayHandle_t
};
struct VREvent_Ipd_t
@@ -1235,6 +1327,16 @@ struct VREvent_HDCPError_t
EHDCPError eCode;
};
+struct VREvent_AudioVolumeControl_t
+{
+ float fVolumeLevel;
+};
+
+struct VREvent_AudioMuteControl_t
+{
+ bool bMute;
+};
+
typedef union
{
VREvent_Reserved_t reserved;
@@ -1266,7 +1368,9 @@ typedef union
VREvent_ShowUI_t showUi;
VREvent_ShowDevTools_t showDevTools;
VREvent_HDCPError_t hdcpError;
- /** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py */
+ VREvent_AudioVolumeControl_t audioVolumeControl;
+ VREvent_AudioMuteControl_t audioMuteControl;
+ /** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py and openvr_api_flat.h.py */
} VREvent_Data_t;
@@ -1484,6 +1588,7 @@ enum EVROverlayError
VROverlayError_TextureAlreadyLocked = 31,
VROverlayError_TextureLockCapacityReached = 32,
VROverlayError_TextureNotLocked = 33,
+ VROverlayError_TimedOut = 34,
};
/** enum values to pass in to VR_Init to identify whether the application will
@@ -1505,6 +1610,7 @@ enum EVRApplicationType
VRApplication_OpenXRScene = 10, // reserved for openxr (started session)
VRApplication_OpenXROverlay = 11, // reserved for openxr (started overlay session)
VRApplication_Prism = 12, // reserved for the vrprismhost process
+ VRApplication_RoomView = 13, // reserved for the RoomView process
VRApplication_Max
};
@@ -1520,6 +1626,15 @@ inline bool IsOpenXRAppType( EVRApplicationType eType )
}
+/** returns true if the specified application type submits eye buffers */
+inline bool BAppTypeSubmitsEyeBuffers( EVRApplicationType eType )
+{
+ return eType == VRApplication_Scene
+ || eType == VRApplication_OpenXRScene
+ || eType == VRApplication_RoomView;
+}
+
+
/** error codes for firmware */
enum EVRFirmwareError
{
@@ -1537,6 +1652,7 @@ enum EVRNotificationError
VRNotificationError_NotificationQueueFull = 101,
VRNotificationError_InvalidOverlayHandle = 102,
VRNotificationError_SystemWithUserValueAlreadyExists = 103,
+ VRNotificationError_ServiceUnavailable = 104,
};
@@ -1641,8 +1757,20 @@ enum EVRInitError
VRInitError_Init_PrismNeedsNewDrivers = 151,
VRInitError_Init_PrismStartupTimedOut = 152,
VRInitError_Init_CouldNotStartPrism = 153,
- VRInitError_Init_CreateDriverDirectDeviceFailed = 154,
- VRInitError_Init_PrismExitedUnexpectedly = 155,
+ VRInitError_Init_PrismClientInitFailed = 154,
+ VRInitError_Init_PrismClientStartFailed = 155,
+ VRInitError_Init_PrismExitedUnexpectedly = 156,
+ VRInitError_Init_BadLuid = 157,
+ VRInitError_Init_NoServerForAppContainer = 158,
+ VRInitError_Init_DuplicateBootstrapper = 159,
+ VRInitError_Init_VRDashboardServicePending = 160,
+ VRInitError_Init_VRDashboardServiceTimeout = 161,
+ VRInitError_Init_VRDashboardServiceStopped = 162,
+ VRInitError_Init_VRDashboardAlreadyStarted = 163,
+ VRInitError_Init_VRDashboardCopyFailed = 164,
+ VRInitError_Init_VRDashboardTokenFailure = 165,
+ VRInitError_Init_VRDashboardEnvironmentFailure = 166,
+ VRInitError_Init_VRDashboardPathFailure = 167,
VRInitError_Driver_Failed = 200,
VRInitError_Driver_Unknown = 201,
@@ -1658,6 +1786,9 @@ enum EVRInitError
VRInitError_Driver_HmdDriverIdOutOfBounds = 211,
VRInitError_Driver_HmdDisplayMirrored = 212,
VRInitError_Driver_HmdDisplayNotFoundLaptop = 213,
+ VRInitError_Driver_PeerDriverNotInstalled = 214,
+ VRInitError_Driver_WirelessHmdNotConnected = 215,
+
// Never make error 259 because we return it from main and it would conflict with STILL_ACTIVE
VRInitError_IPC_ServerInitFailed = 300,
@@ -1766,9 +1897,17 @@ enum EVRInitError
VRInitError_Compositor_WindowInterfaceIsNull = 491,
VRInitError_Compositor_SystemLayerCreateInstance = 492,
VRInitError_Compositor_SystemLayerCreateSession = 493,
+ VRInitError_Compositor_CreateInverseDistortUVs = 494,
+ VRInitError_Compositor_CreateBackbufferDepth = 495,
+ VRInitError_Compositor_CannotDRMLeaseDisplay = 496,
+ VRInitError_Compositor_CannotConnectToDisplayServer = 497,
+ VRInitError_Compositor_GnomeNoDRMLeasing = 498,
+ VRInitError_Compositor_FailedToInitializeEncoder = 499,
+ VRInitError_Compositor_CreateBlurTexture = 500,
VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000,
VRInitError_VendorSpecific_WindowsNotInDevMode = 1001,
+ VRInitError_VendorSpecific_OculusLinkNotEnabled = 1002,
VRInitError_VendorSpecific_HmdFound_CantOpenDevice = 1101,
VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102,
@@ -1784,6 +1923,7 @@ enum EVRInitError
VRInitError_VendorSpecific_HmdFound_UserDataError = 1112,
VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck = 1113,
VRInitError_VendorSpecific_OculusRuntimeBadInstall = 1114,
+ VRInitError_VendorSpecific_HmdFound_UnexpectedConfiguration_1 = 1115,
VRInitError_Steam_SteamInstallationNotFound = 2000,
@@ -1880,28 +2020,31 @@ static const uint32_t k_unScreenshotHandleInvalid = 0;
/** Compositor frame timing reprojection flags. */
const uint32_t VRCompositor_ReprojectionReason_Cpu = 0x01;
const uint32_t VRCompositor_ReprojectionReason_Gpu = 0x02;
-const uint32_t VRCompositor_ReprojectionAsync = 0x04; // This flag indicates the async reprojection mode is active,
+const uint32_t VRCompositor_ReprojectionAsync = 0x04; // This flag indicates the async reprojection mode is active,
// but does not indicate if reprojection actually happened or not.
// Use the ReprojectionReason flags above to check if reprojection
// was actually applied (i.e. scene texture was reused).
// NumFramePresents > 1 also indicates the scene texture was reused,
// and also the number of times that it was presented in total.
-const uint32_t VRCompositor_ReprojectionMotion = 0x08; // This flag indicates whether or not motion smoothing was triggered for this frame
+const uint32_t VRCompositor_ReprojectionMotion = 0x08; // This flag indicates whether or not motion smoothing was triggered for this frame
-const uint32_t VRCompositor_PredictionMask = 0xF0; // The runtime may predict more than one frame (up to four) ahead if
- // it detects the application is taking too long to render. These two
+const uint32_t VRCompositor_PredictionMask = 0xF0; // The runtime may predict more than one frame ahead if
+ // it detects the application is taking too long to render. These
// bits will contain the count of additional frames (normally zero).
// Use the VR_COMPOSITOR_ADDITIONAL_PREDICTED_FRAMES macro to read from
// the latest frame timing entry.
-const uint32_t VRCompositor_ThrottleMask = 0xF00; // Number of frames the compositor is throttling the application.
+const uint32_t VRCompositor_ThrottleMask = 0xF00; // Number of frames the compositor is throttling the application.
// Use the VR_COMPOSITOR_NUMBER_OF_THROTTLED_FRAMES macro to read from
// the latest frame timing entry.
#define VR_COMPOSITOR_ADDITIONAL_PREDICTED_FRAMES( timing ) ( ( ( timing ).m_nReprojectionFlags & vr::VRCompositor_PredictionMask ) >> 4 )
#define VR_COMPOSITOR_NUMBER_OF_THROTTLED_FRAMES( timing ) ( ( ( timing ).m_nReprojectionFlags & vr::VRCompositor_ThrottleMask ) >> 8 )
+#if defined(__linux__) || defined(__APPLE__)
+#pragma pack( push, 4 )
+#endif
/** Provides a single frame's timing information to the app */
struct Compositor_FrameTiming
{
@@ -1944,7 +2087,12 @@ struct Compositor_FrameTiming
uint32_t m_nNumVSyncsReadyForUse;
uint32_t m_nNumVSyncsToFirstView;
+
+ float m_flTransferLatencyMs;
};
+#if defined(__linux__) || defined(__APPLE__)
+#pragma pack( pop )
+#endif
/** Provides compositor benchmark results to the app */
struct Compositor_BenchmarkResults
@@ -2588,6 +2736,7 @@ namespace vr
VRSettingsError_ReadFailed = 3,
VRSettingsError_JsonParseFailed = 4,
VRSettingsError_UnsetSettingHasNoDefault = 5, // This will be returned if the setting does not appear in the appropriate default file and has not been set
+ VRSettingsError_AccessDenied = 6,
};
// The maximum length of a settings key
@@ -2727,6 +2876,9 @@ namespace vr
static const char * const k_pch_SteamVR_MotionSmoothingOverride_Int32 = "motionSmoothingOverride";
static const char * const k_pch_SteamVR_FramesToThrottle_Int32 = "framesToThrottle";
static const char * const k_pch_SteamVR_AdditionalFramesToPredict_Int32 = "additionalFramesToPredict";
+ static const char * const k_pch_SteamVR_WorldScale_Float = "worldScale";
+ static const char * const k_pch_SteamVR_FovScale_Int32 = "fovScale";
+ static const char * const k_pch_SteamVR_FovScaleLetterboxed_Bool = "fovScaleLetterboxed";
static const char * const k_pch_SteamVR_DisableAsyncReprojection_Bool = "disableAsync";
static const char * const k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking";
static const char * const k_pch_SteamVR_DefaultMirrorView_Int32 = "mirrorView";
@@ -2753,7 +2905,6 @@ namespace vr
static const char * const k_pch_SteamVR_ForceWindows32bitVRMonitor = "forceWindows32BitVRMonitor";
static const char * const k_pch_SteamVR_DebugInputBinding = "debugInputBinding";
static const char * const k_pch_SteamVR_DoNotFadeToGrid = "doNotFadeToGrid";
- static const char * const k_pch_SteamVR_RenderCameraMode = "renderCameraMode";
static const char * const k_pch_SteamVR_EnableSharedResourceJournaling = "enableSharedResourceJournaling";
static const char * const k_pch_SteamVR_EnableSafeMode = "enableSafeMode";
static const char * const k_pch_SteamVR_PreferredRefreshRate = "preferredRefreshRate";
@@ -2770,7 +2921,14 @@ namespace vr
static const char * const k_pch_SteamVR_BlockOculusSDKOnOpenVRLaunchOption_Bool = "blockOculusSDKOnOpenVRLaunchOption";
static const char * const k_pch_SteamVR_BlockOculusSDKOnAllLaunches_Bool = "blockOculusSDKOnAllLaunches";
static const char * const k_pch_SteamVR_HDCPLegacyCompatibility_Bool = "hdcp14legacyCompatibility";
+ static const char * const k_pch_SteamVR_DisplayPortTrainingMode_Int = "displayPortTrainingMode";
static const char * const k_pch_SteamVR_UsePrism_Bool = "usePrism";
+ static const char * const k_pch_SteamVR_AllowFallbackMirrorWindowLinux_Bool = "allowFallbackMirrorWindowLinux";
+
+ //-----------------------------------------------------------------------------
+ // openxr keys
+ static const char * const k_pch_OpenXR_Section = "openxr";
+ static const char * const k_pch_OpenXR_MetaUnityPluginCompatibility_Int32 = "metaUnityPluginCompatibility";
//-----------------------------------------------------------------------------
// direct mode keys
@@ -2846,6 +3004,7 @@ namespace vr
static const char * const k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit";
static const char * const k_pch_Perf_TestData_Float = "perfTestData";
static const char * const k_pch_Perf_GPUProfiling_Bool = "GPUProfiling";
+ static const char * const k_pch_Perf_GpuBusMonitoring_Bool = "gpuBusMonitoring";
//-----------------------------------------------------------------------------
// collision bounds keys
@@ -2917,6 +3076,11 @@ namespace vr
static const char * const k_pch_Dashboard_DesktopScale = "desktopScale";
static const char * const k_pch_Dashboard_DashboardScale = "dashboardScale";
static const char * const k_pch_Dashboard_UseStandaloneSystemLayer = "standaloneSystemLayer";
+ static const char * const k_pch_Dashboard_StickyDashboard = "stickyDashboard";
+ static const char * const k_pch_Dashboard_AllowSteamOverlays_Bool = "allowSteamOverlays";
+ static const char * const k_pch_Dashboard_AllowVRGamepadUI_Bool = "allowVRGamepadUI";
+ static const char * const k_pch_Dashboard_AllowVRGamepadUIViaGamescope_Bool = "allowVRGamepadUIViaGamescope";
+ static const char * const k_pch_Dashboard_SteamMatchesHMDFramerate = "steamMatchesHMDFramerate";
//-----------------------------------------------------------------------------
// model skin keys
@@ -2947,7 +3111,8 @@ namespace vr
// per-app keys - the section name for these is the app key itself. Some of these are prefixed by the controller type
static const char* const k_pch_App_BindingAutosaveURLSuffix_String = "AutosaveURL";
static const char* const k_pch_App_BindingLegacyAPISuffix_String = "_legacy";
- static const char* const k_pch_App_BindingSteamVRInputAPISuffix_String = "_steamvrinput";
+ static const char *const k_pch_App_BindingSteamVRInputAPISuffix_String = "_steamvrinput";
+ static const char *const k_pch_App_BindingOpenXRAPISuffix_String = "_openxr";
static const char* const k_pch_App_BindingCurrentURLSuffix_String = "CurrentURL";
static const char* const k_pch_App_BindingPreviousURLSuffix_String = "PreviousURL";
static const char* const k_pch_App_NeedToUpdateAutosaveSuffix_Bool = "NeedToUpdateAutosave";
@@ -2966,7 +3131,8 @@ namespace vr
// Last known keys for righting recovery
static const char * const k_pch_LastKnown_Section = "LastKnown";
static const char* const k_pch_LastKnown_HMDManufacturer_String = "HMDManufacturer";
- static const char* const k_pch_LastKnown_HMDModel_String = "HMDModel";
+ static const char *const k_pch_LastKnown_HMDModel_String = "HMDModel";
+ static const char* const k_pch_LastKnown_ActualHMDDriver_String = "ActualHMDDriver";
//-----------------------------------------------------------------------------
// Dismissed warnings
@@ -3027,12 +3193,16 @@ class IVRChaperone
* Tracking space center (0,0,0) is the center of the Play Area. **/
virtual bool GetPlayAreaSize( float *pSizeX, float *pSizeZ ) = 0;
- /** Returns the 4 corner positions of the Play Area (formerly named Soft Bounds).
- * Corners are in counter-clockwise order.
- * Standing center (0,0,0) is the center of the Play Area.
- * It's a rectangle.
- * 2 sides are parallel to the X axis and 2 sides are parallel to the Z axis.
- * Height of every corner is 0Y (on the floor). **/
+ /** Returns a quad describing the Play Area (formerly named Soft Bounds).
+ * The corners form a rectangle.
+ * Corners are in counter-clockwise order, starting at the front-right.
+ * The positions are given relative to the standing origin.
+ * The center of the rectangle is the center of the user's calibrated play space, not necessarily the standing
+ * origin.
+ * The Play Area's forward direction goes from its center through the mid-point of a line drawn between the
+ * first and second corner.
+ * The quad lies on the XZ plane (height = 0y), with 2 sides parallel to the X-axis and two sides parallel
+ * to the Z-axis of the user's calibrated Play Area. **/
virtual bool GetPlayAreaRect( HmdQuad_t *rect ) = 0;
/** Reload Chaperone data from the .vrchap file on disk. */
@@ -3228,6 +3398,16 @@ struct Compositor_CumulativeStats
uint32_t m_nNumFramePresentsTimedOut;
uint32_t m_nNumDroppedFramesTimedOut;
uint32_t m_nNumReprojectedFramesTimedOut;
+
+ /** For items in this section, divide all the values by m_nNumFrameSubmits. */
+ uint32_t m_nNumFrameSubmits;
+ vrshared_double m_flSumCompositorCPUTimeMS;
+ vrshared_double m_flSumCompositorGPUTimeMS;
+ vrshared_double m_flSumTargetFrameTimes;
+ vrshared_double m_flSumApplicationCPUTimeMS;
+ vrshared_double m_flSumApplicationGPUTimeMS;
+
+ uint32_t m_nNumFramesWithDepth; // total frames submitted with depth by the current application
};
struct Compositor_StageRenderSettings
@@ -3324,6 +3504,8 @@ class IVRCompositor
* - AlreadySubmitted (app has submitted two left textures or two right textures in a single frame - i.e. before calling WaitGetPoses again)
*/
virtual EVRCompositorError Submit( EVREye eEye, const Texture_t *pTexture, const VRTextureBounds_t* pBounds = 0, EVRSubmitFlags nSubmitFlags = Submit_Default ) = 0;
+ virtual EVRCompositorError SubmitWithArrayIndex( EVREye eEye, const Texture_t *pTexture, uint32_t unTextureArrayIndex,
+ const VRTextureBounds_t *pBounds = 0, EVRSubmitFlags nSubmitFlags = Submit_Default ) = 0;
/** Clears the frame that was sent with the last call to Submit. This will cause the
* compositor to show the grid until Submit is called again. */
@@ -3503,7 +3685,7 @@ class IVRCompositor
virtual EVRCompositorError GetPosesForFrame( uint32_t unPosePredictionID, VR_ARRAY_COUNT( unPoseArrayCount ) TrackedDevicePose_t* pPoseArray, uint32_t unPoseArrayCount ) = 0;
};
-static const char * const IVRCompositor_Version = "IVRCompositor_027";
+static const char * const IVRCompositor_Version = "IVRCompositor_028";
} // namespace vr
@@ -3635,8 +3817,7 @@ typedef uint32_t VRNotificationId;
#pragma pack( pop )
-/** Allows notification sources to interact with the VR system
- This current interface is not yet implemented. Do not use yet. */
+/** Allows notification sources to interact with the VR system. */
class IVRNotifications
{
public:
@@ -3688,13 +3869,14 @@ namespace vr
VROverlayTransform_Invalid = -1,
VROverlayTransform_Absolute = 0,
VROverlayTransform_TrackedDeviceRelative = 1,
- VROverlayTransform_SystemOverlay = 2,
+ //VROverlayTransform_SystemOverlay = 2, // Deleted from the SDK.
VROverlayTransform_TrackedComponent = 3,
VROverlayTransform_Cursor = 4,
VROverlayTransform_DashboardTab = 5,
VROverlayTransform_DashboardThumb = 6,
VROverlayTransform_Mountable = 7,
VROverlayTransform_Projection = 8,
+ VROverlayTransform_Subview = 9,
};
/** Overlay control settings */
@@ -3753,6 +3935,32 @@ namespace vr
// If this is set, alpha composition assumes the texture is pre-multiplied
VROverlayFlags_IsPremultiplied = 1 << 21,
+
+ // If this is set, the alpha values of the overlay texture will be ignored
+ VROverlayFlags_IgnoreTextureAlpha = 1 << 22,
+
+ // If this is set, this overlay will have a control bar drawn underneath of it in the dashboard.
+ VROverlayFlags_EnableControlBar = 1 << 23,
+
+ // If this is set, the overlay control bar will provide a button to toggle the keyboard.
+ VROverlayFlags_EnableControlBarKeyboard = 1 << 24,
+
+ // If this is set, the overlay control bar will provide a "close" button which will send a
+ // VREvent_OverlayClosed event to the overlay when pressed. Applications that use this flag are responsible
+ // for responding to the event with something that approximates "closing" behavior, such as destroying their
+ // overlay and/or shutting down their application.
+ VROverlayFlags_EnableControlBarClose = 1 << 25,
+
+ // Do not use
+ VROverlayFlags_Reserved = 1 << 26,
+
+ // If this is set, click stabilization will be applied to the laser interaction so that clicks more reliably
+ // trigger on the user's intended target
+ VROverlayFlags_EnableClickStabilization = 1 << 27,
+
+ // If this is set, laser mouse pointer events may be sent for the secondary laser. These events will have
+ // cursorIndex set to 0 for the primary laser and 1 for the secondary.
+ VROverlayFlags_MultiCursor = 1 << 28,
};
enum VRMessageOverlayResponse
@@ -3832,8 +4040,16 @@ namespace vr
enum EKeyboardFlags
{
- KeyboardFlag_Minimal = 1 << 0, // makes the keyboard send key events immediately instead of accumulating a buffer
- KeyboardFlag_Modal = 2 << 0, // makes the keyboard take all focus and dismiss when clicking off the panel
+ /** Makes the keyboard send key events immediately instead of accumulating a buffer */
+ KeyboardFlag_Minimal = 1 << 0,
+ /** Makes the keyboard take all focus and dismiss when clicking off the panel */
+ KeyboardFlag_Modal = 1 << 1,
+ /** Shows arrow keys on the keyboard when in minimal mode. Buffered (non-minimal) mode always has them. In minimal
+ * mode, when arrow keys are pressed, they send ANSI escape sequences (e.g. "\x1b[D" for left arrow). */
+ KeyboardFlag_ShowArrowKeys = 1 << 2,
+ /** Shows the hide keyboard button instead of a Done button. The Done key sends a VREvent_KeyboardDone when
+ * clicked. Hide only sends the Closed event. */
+ KeyboardFlag_HideDoneKey = 1 << 3,
};
/** Defines the project used in an overlay that is using SetOverlayTransformProjection */
@@ -3929,6 +4145,9 @@ namespace vr
* Within a category overlays are rendered lowest sort order to highest sort order. Overlays with the same
* sort order are rendered back to front base on distance from the HMD.
*
+ * Subview overlays are always drawn immediately on top of their parent overlay, and the sort order is
+ * only relative to their peer subviews for that overlay.
+ *
* Sort order defaults to 0. */
virtual EVROverlayError SetOverlaySortOrder( VROverlayHandle_t ulOverlayHandle, uint32_t unSortOrder ) = 0;
@@ -3948,6 +4167,12 @@ namespace vr
/** Returns the curvature of the overlay as a percentage from (0..1] where 1 is a fully closed cylinder. */
virtual EVROverlayError GetOverlayCurvature( VROverlayHandle_t ulOverlayHandle, float *pfCurvature ) = 0;
+ /** Sets the pitch angle (in radians) of the overlay before curvature is applied -- to form a fan or disk. */
+ virtual EVROverlayError SetOverlayPreCurvePitch( VROverlayHandle_t ulOverlayHandle, float fRadians ) = 0;
+
+ /** Returns the overlay's set pre-curve pitch angle (in radians). */
+ virtual EVROverlayError GetOverlayPreCurvePitch( VROverlayHandle_t ulOverlayHandle, float *pfRadians ) = 0;
+
/** Sets the colorspace the overlay texture's data is in. Defaults to 'auto'.
* If the texture needs to be resolved, you should call SetOverlayTexture with the appropriate colorspace instead. */
virtual EVROverlayError SetOverlayTextureColorSpace( VROverlayHandle_t ulOverlayHandle, EColorSpace eTextureColorSpace ) = 0;
@@ -3983,12 +4208,6 @@ namespace vr
/** Gets the transform information when the overlay is rendering on a component. */
virtual EVROverlayError GetOverlayTransformTrackedDeviceComponent( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punDeviceIndex, VR_OUT_STRING() char *pchComponentName, uint32_t unComponentNameSize ) = 0;
- /** Gets the transform if it is relative to another overlay. Returns an error if the transform is some other type. */
- virtual vr::EVROverlayError GetOverlayTransformOverlayRelative( VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t *ulOverlayHandleParent, HmdMatrix34_t *pmatParentOverlayToOverlayTransform ) = 0;
-
- /** Sets the transform to relative to the transform of the specified overlay. This overlays visibility will also track the parents visibility */
- virtual vr::EVROverlayError SetOverlayTransformOverlayRelative( VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t ulOverlayHandleParent, const HmdMatrix34_t *pmatParentOverlayToOverlayTransform ) = 0;
-
/** Sets the hotspot for the specified overlay when that overlay is used as a cursor. These are in texture space with 0,0 in the upper left corner of
* the texture and 1,1 in the lower right corner of the texture. */
virtual EVROverlayError SetOverlayTransformCursor( VROverlayHandle_t ulCursorOverlayHandle, const HmdVector2_t *pvHotspot ) = 0;
@@ -4001,18 +4220,23 @@ namespace vr
ETrackingUniverseOrigin eTrackingOrigin, const HmdMatrix34_t* pmatTrackingOriginToOverlayTransform,
const VROverlayProjection_t *pProjection, vr::EVREye eEye ) = 0;
- /** Shows the VR overlay. For dashboard overlays, only the Dashboard Manager is allowed to call this. */
+ /** Shows the VR overlay. Not applicable for Dashboard Overlays. */
virtual EVROverlayError ShowOverlay( VROverlayHandle_t ulOverlayHandle ) = 0;
- /** Hides the VR overlay. For dashboard overlays, only the Dashboard Manager is allowed to call this. */
+ /** Hides the VR overlay. Not applicable for Dashboard Overlays. */
virtual EVROverlayError HideOverlay( VROverlayHandle_t ulOverlayHandle ) = 0;
- /** Returns true if the overlay is visible. */
+ /** Returns true if the overlay is currently visible, applicable for all overlay types except Dashboard Thumbnail overlays. VREvent_OverlayShown and VREvent_OverlayHidden reflect changes to this value. */
virtual bool IsOverlayVisible( VROverlayHandle_t ulOverlayHandle ) = 0;
/** Get the transform in 3d space associated with a specific 2d point in the overlay's coordinate space (where 0,0 is the lower left). -Z points out of the overlay */
virtual EVROverlayError GetTransformForOverlayCoordinates( VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, HmdVector2_t coordinatesInOverlay, HmdMatrix34_t *pmatTransform ) = 0;
+ /** This function will block until the top of each frame, and can therefore be used to synchronize with the runtime's update rate.
+ * Note: In non-async mode, some signals may be dropped due to scene app performance, so passing a timeout of 1000/refresh rate
+ * may be useful depending on the overlay app's desired behavior. */
+ virtual EVROverlayError WaitFrameSync( uint32_t nTimeoutMs ) = 0;
+
// ---------------------------------------------
// Overlay input methods
// ---------------------------------------------
@@ -4124,7 +4348,7 @@ namespace vr
/** Shows the dashboard. */
virtual void ShowDashboard( const char *pchOverlayToShow ) = 0;
- /** Returns the tracked device that has the laser pointer in the dashboard */
+ /** Returns the tracked device index that has the laser pointer in the dashboard, or the last one that was used. */
virtual vr::TrackedDeviceIndex_t GetPrimaryDashboardDevice() = 0;
// ---------------------------------------------
@@ -4165,7 +4389,7 @@ namespace vr
virtual void CloseMessageOverlay() = 0;
};
- static const char * const IVROverlay_Version = "IVROverlay_025";
+ static const char * const IVROverlay_Version = "IVROverlay_027";
} // namespace vr
@@ -4252,11 +4476,14 @@ namespace vr
namespace vr
{
-static const char * const k_pch_Controller_Component_GDC2015 = "gdc2015"; // Canonical coordinate system of the gdc 2015 wired controller, provided for backwards compatibility
-static const char * const k_pch_Controller_Component_Base = "base"; // For controllers with an unambiguous 'base'.
-static const char * const k_pch_Controller_Component_Tip = "tip"; // For controllers with an unambiguous 'tip' (used for 'laser-pointing')
-static const char * const k_pch_Controller_Component_HandGrip = "handgrip"; // Neutral, ambidextrous hand-pose when holding controller. On plane between neutrally posed index finger and thumb
-static const char * const k_pch_Controller_Component_Status = "status"; // 1:1 aspect ratio status area, with canonical [0,1] uv mapping
+static const char * const k_pch_Controller_Component_GDC2015 = "gdc2015"; // Canonical coordinate system of the gdc 2015 wired controller, provided for backwards compatibility
+static const char * const k_pch_Controller_Component_Base = "base"; // For controllers with an unambiguous 'base'.
+static const char * const k_pch_Controller_Component_Tip = "tip"; // OpenVR: For controllers with an unambiguous 'tip' (used for 'laser-pointing')
+static const char * const k_pch_Controller_Component_OpenXR_Aim= "openxr_aim"; // OpenXR: For controllers with an unambiguous 'tip' (used for 'laser-pointing')
+static const char * const k_pch_Controller_Component_HandGrip = "handgrip"; // OpenVR: Neutral, ambidextrous hand-pose when holding controller. On plane between neutrally posed index finger and thumb
+static const char * const k_pch_Controller_Component_OpenXR_Grip = "openxr_grip"; // OpenXR: Neutral, ambidextrous hand-pose when holding controller. On plane between neutrally posed index finger and thumb
+static const char * const k_pch_Controller_Component_OpenXR_HandModel = "openxr_handmodel"; // OpenXR: Pose that can be used to place hand models & visuals that aren't reliant on the physical shape of a controller
+static const char * const k_pch_Controller_Component_Status = "status"; // 1:1 aspect ratio status area, with canonical [0,1] uv mapping
#pragma pack( push, 8 )
@@ -4285,7 +4512,8 @@ enum EVRRenderModelTextureFormat
VRRenderModelTextureFormat_BC2,
VRRenderModelTextureFormat_BC4,
VRRenderModelTextureFormat_BC7,
- VRRenderModelTextureFormat_BC7_SRGB
+ VRRenderModelTextureFormat_BC7_SRGB,
+ VRRenderModelTextureFormat_RGBA16_FLOAT,
};
/** A single vertex in a render model */
@@ -4308,6 +4536,7 @@ struct RenderModel_TextureMap_t
uint16_t unWidth, unHeight; // width and height of the texture map in pixels
const uint8_t *rubTextureMapData; // Map texture data.
EVRRenderModelTextureFormat format; // Refer to EVRRenderModelTextureFormat
+ uint16_t unMipLevels;
};
#if defined(__linux__) || defined(__APPLE__)
#pragma pack( pop )
@@ -5010,7 +5239,7 @@ namespace vr
virtual EVRInputError GetOriginTrackedDeviceInfo( VRInputValueHandle_t origin, InputOriginInfo_t *pOriginInfo, uint32_t unOriginInfoSize ) = 0;
/** Retrieves useful information about the bindings for an action */
- virtual EVRInputError GetActionBindingInfo( VRActionHandle_t action, InputBindingInfo_t *pOriginInfo, uint32_t unBindingInfoSize, uint32_t unBindingInfoCount, uint32_t *punReturnedBindingInfoCount ) = 0;
+ virtual EVRInputError GetActionBindingInfo( VRActionHandle_t action, VR_ARRAY_COUNT( unBindingInfoCount ) InputBindingInfo_t *pOriginInfo, uint32_t unBindingInfoSize, uint32_t unBindingInfoCount, uint32_t *punReturnedBindingInfoCount ) = 0;
/** Shows the current binding for the action in-headset */
virtual EVRInputError ShowActionOrigins( VRActionSetHandle_t actionSetHandle, VRActionHandle_t ulActionHandle ) = 0;
@@ -5096,7 +5325,7 @@ static const uint64_t k_ulInvalidIOBufferHandle = 0;
virtual bool HasReaders( vr::IOBufferHandle_t ulBuffer ) = 0;
};
- static const char *IVRIOBuffer_Version = "IVRIOBuffer_002";
+ static const char * const IVRIOBuffer_Version = "IVRIOBuffer_002";
}
// ivrspatialanchors.h
diff --git a/alvr/server/cpp/openvr/headers/openvr_driver.h b/alvr/server/cpp/openvr/headers/openvr_driver.h
index 34b7053d25..257ac6ccb2 100644
--- a/alvr/server/cpp/openvr/headers/openvr_driver.h
+++ b/alvr/server/cpp/openvr/headers/openvr_driver.h
@@ -15,9 +15,9 @@
namespace vr
{
- static const uint32_t k_nSteamVRVersionMajor = 1;
- static const uint32_t k_nSteamVRVersionMinor = 16;
- static const uint32_t k_nSteamVRVersionBuild = 8;
+ static const uint32_t k_nSteamVRVersionMajor = 2;
+ static const uint32_t k_nSteamVRVersionMinor = 5;
+ static const uint32_t k_nSteamVRVersionBuild = 1;
} // namespace vr
// public_vrtypes.h
@@ -29,6 +29,8 @@ namespace vr
{
#pragma pack( push, 8 )
+typedef uint32_t PropertyTypeTag_t;
+
// right-handed system
// +y is up
// +x is to the right
@@ -102,40 +104,6 @@ struct VRBoneTransform_t
HmdQuaternionf_t orientation;
};
-#pragma pack( pop )
-
-} // namespace vr
-
-#endif
-
-// vrtypes.h
-
-#ifndef _INCLUDE_VRTYPES_H
-#define _INCLUDE_VRTYPES_H
-
-// Forward declarations to avoid requiring vulkan.h
-struct VkDevice_T;
-struct VkPhysicalDevice_T;
-struct VkInstance_T;
-struct VkQueue_T;
-
-// Forward declarations to avoid requiring d3d12.h
-struct ID3D12Resource;
-struct ID3D12CommandQueue;
-
-namespace vr
-{
-#pragma pack( push, 8 )
-
-/** A handle for a spatial anchor. This handle is only valid during the session it was created in.
-* Anchors that live beyond one session should be saved by their string descriptors. */
-typedef uint32_t SpatialAnchorHandle_t;
-
-typedef void* glSharedTextureHandle_t;
-typedef int32_t glInt_t;
-typedef uint32_t glUInt_t;
-
-
/** Used to return the post-distortion UVs for each color channel.
* UVs range from 0 to 1 with 0,0 in the upper left corner of the
* source render target. The 0,0 to 1,1 range covers a single eye. */
@@ -162,9 +130,11 @@ enum ETextureType
TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure
TextureType_DXGISharedHandle = 5, // Handle is a HANDLE DXGI share handle, only supported for Overlay render targets.
// this texture is used directly by our renderer, so only perform atomic (copyresource or resolve) on it
- TextureType_Metal = 6, // Handle is a MTLTexture conforming to the MTLSharedTexture protocol. Textures submitted to IVRCompositor::Submit which
- // are of type MTLTextureType2DArray assume layer 0 is the left eye texture (vr::EVREye::Eye_left), layer 1 is the right
- // eye texture (vr::EVREye::Eye_Right)
+ TextureType_Metal = 6, // Handle is a MTLTexture conforming to the MTLSharedTexture protocol. Textures submitted to IVRCompositor::Submit which
+ // are of type MTLTextureType2DArray assume layer 0 is the left eye texture (vr::EVREye::Eye_left), layer 1 is the right
+ // eye texture (vr::EVREye::Eye_Right)
+
+ TextureType_Reserved = 7,
};
enum EColorSpace
@@ -181,6 +151,81 @@ struct Texture_t
EColorSpace eColorSpace;
};
+/** Allows the application to control what part of the provided texture will be used in the
+* frame buffer. */
+struct VRTextureBounds_t
+{
+ float uMin, vMin;
+ float uMax, vMax;
+};
+
+/** Allows specifying pose used to render provided scene texture (if different from value returned by WaitGetPoses). */
+struct VRTextureWithPose_t : public Texture_t
+{
+ HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures.
+};
+
+struct VRTextureDepthInfo_t
+{
+ void* handle; // See ETextureType definition above
+ HmdMatrix44_t mProjection;
+ HmdVector2_t vRange; // 0..1
+};
+
+struct VRTextureWithDepth_t : public Texture_t
+{
+ VRTextureDepthInfo_t depth;
+};
+
+struct VRTextureWithPoseAndDepth_t : public VRTextureWithPose_t
+{
+ VRTextureDepthInfo_t depth;
+};
+
+// 64-bit types that are part of public structures
+// that are replicated in shared memory.
+#if defined(__linux__) || defined(__APPLE__)
+typedef uint64_t vrshared_uint64_t __attribute__ ((aligned(8)));
+typedef double vrshared_double __attribute__ ((aligned(8)));
+#else
+typedef uint64_t vrshared_uint64_t;
+typedef double vrshared_double;
+#endif
+
+#pragma pack( pop )
+
+} // namespace vr
+
+#endif
+
+// vrtypes.h
+
+#ifndef _INCLUDE_VRTYPES_H
+#define _INCLUDE_VRTYPES_H
+
+// Forward declarations to avoid requiring vulkan.h
+struct VkDevice_T;
+struct VkPhysicalDevice_T;
+struct VkInstance_T;
+struct VkQueue_T;
+
+// Forward declarations to avoid requiring d3d12.h
+struct ID3D12Resource;
+struct ID3D12CommandQueue;
+
+namespace vr
+{
+#pragma pack( push, 8 )
+
+/** A handle for a spatial anchor. This handle is only valid during the session it was created in.
+* Anchors that live beyond one session should be saved by their string descriptors. */
+typedef uint32_t SpatialAnchorHandle_t;
+
+typedef void* glSharedTextureHandle_t;
+typedef int32_t glInt_t;
+typedef uint32_t glUInt_t;
+
+
// Handle to a shared texture (HANDLE on Windows obtained using OpenSharedResource).
typedef uint64_t SharedTextureHandle_t;
#define INVALID_SHARED_TEXTURE_HANDLE ((vr::SharedTextureHandle_t)0)
@@ -387,6 +432,9 @@ enum ETrackedDeviceProperty
Prop_ManufacturerSerialNumber_String = 1049,
Prop_ComputedSerialNumber_String = 1050,
Prop_EstimatedDeviceFirstUseTime_Int32 = 1051,
+ Prop_DevicePowerUsage_Float = 1052,
+ Prop_IgnoreMotionForStandby_Bool = 1053,
+ Prop_ActualTrackingSystemName_String = 1054, // the literal local driver name in case someone is playing games with prop 1000
// Properties that are unique to TrackedDeviceClass_HMD
Prop_ReportsTimeSinceVSync_Bool = 2000,
@@ -479,10 +527,30 @@ enum ETrackedDeviceProperty
Prop_CameraGlobalGain_Float = 2089,
// Prop_DashboardLayoutPathName_String = 2090, // DELETED
Prop_DashboardScale_Float = 2091,
+ Prop_PeerButtonInfo_String = 2092,
+ Prop_Hmd_SupportsHDR10_Bool = 2093,
+ Prop_Hmd_EnableParallelRenderCameras_Bool = 2094,
+ Prop_DriverProvidedChaperoneJson_String = 2095, // higher priority than Prop_DriverProvidedChaperonePath_String
+ Prop_ForceSystemLayerUseAppPoses_Bool = 2096,
+
Prop_IpdUIRangeMinMeters_Float = 2100,
Prop_IpdUIRangeMaxMeters_Float = 2101,
Prop_Hmd_SupportsHDCP14LegacyCompat_Bool = 2102,
Prop_Hmd_SupportsMicMonitoring_Bool = 2103,
+ Prop_Hmd_SupportsDisplayPortTrainingMode_Bool = 2104,
+ Prop_Hmd_SupportsRoomViewDirect_Bool = 2105,
+ Prop_Hmd_SupportsAppThrottling_Bool = 2106,
+ Prop_Hmd_SupportsGpuBusMonitoring_Bool = 2107,
+ Prop_DriverDisplaysIPDChanges_Bool = 2108,
+ Prop_Driver_Reserved_01 = 2109,
+
+ Prop_DSCVersion_Int32 = 2110,
+ Prop_DSCSliceCount_Int32 = 2111,
+ Prop_DSCBPPx16_Int32 = 2112,
+
+ Prop_Hmd_MaxDistortedTextureWidth_Int32 = 2113,
+ Prop_Hmd_MaxDistortedTextureHeight_Int32 = 2114,
+ Prop_Hmd_AllowSupersampleFiltering_Bool = 2115,
// Driver requested mura correction properties
Prop_DriverRequestedMuraCorrectionMode_Int32 = 2200,
@@ -495,10 +563,16 @@ enum ETrackedDeviceProperty
Prop_DriverRequestedMuraFeather_OuterTop_Int32 = 2207,
Prop_DriverRequestedMuraFeather_OuterBottom_Int32 = 2208,
- Prop_Audio_DefaultPlaybackDeviceId_String = 2300,
- Prop_Audio_DefaultRecordingDeviceId_String = 2301,
- Prop_Audio_DefaultPlaybackDeviceVolume_Float = 2302,
- Prop_Audio_SupportsDualSpeakerAndJackOutput_Bool = 2303,
+ Prop_Audio_DefaultPlaybackDeviceId_String = 2300,
+ Prop_Audio_DefaultRecordingDeviceId_String = 2301,
+ Prop_Audio_DefaultPlaybackDeviceVolume_Float = 2302,
+ Prop_Audio_SupportsDualSpeakerAndJackOutput_Bool = 2303,
+ Prop_Audio_DriverManagesPlaybackVolumeControl_Bool = 2304,
+ Prop_Audio_DriverPlaybackVolume_Float = 2305,
+ Prop_Audio_DriverPlaybackMute_Bool = 2306,
+ Prop_Audio_DriverManagesRecordingVolumeControl_Bool = 2307,
+ Prop_Audio_DriverRecordingVolume_Float = 2308,
+ Prop_Audio_DriverRecordingMute_Bool = 2309,
// Properties that are unique to TrackedDeviceClass_Controller
Prop_AttachedDeviceId_String = 3000,
@@ -547,7 +621,8 @@ enum ETrackedDeviceProperty
Prop_HasCameraComponent_Bool = 6004,
Prop_HasDriverDirectModeComponent_Bool = 6005,
Prop_HasVirtualDisplayComponent_Bool = 6006,
- Prop_HasSpatialAnchorsSupport_Bool = 6007,
+ Prop_HasSpatialAnchorsSupport_Bool = 6007,
+ Prop_SupportsXrTextureSets_Bool = 6008,
// Properties that are set internally based on other information provided by drivers
Prop_ControllerType_String = 7000,
@@ -604,37 +679,6 @@ static const VRActionSetHandle_t k_ulInvalidActionSetHandle = 0;
static const VRInputValueHandle_t k_ulInvalidInputValueHandle = 0;
-/** Allows the application to control what part of the provided texture will be used in the
-* frame buffer. */
-struct VRTextureBounds_t
-{
- float uMin, vMin;
- float uMax, vMax;
-};
-
-/** Allows specifying pose used to render provided scene texture (if different from value returned by WaitGetPoses). */
-struct VRTextureWithPose_t : public Texture_t
-{
- HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures.
-};
-
-struct VRTextureDepthInfo_t
-{
- void* handle; // See ETextureType definition above
- HmdMatrix44_t mProjection;
- HmdVector2_t vRange; // 0..1
-};
-
-struct VRTextureWithDepth_t : public Texture_t
-{
- VRTextureDepthInfo_t depth;
-};
-
-struct VRTextureWithPoseAndDepth_t : public VRTextureWithPose_t
-{
- VRTextureDepthInfo_t depth;
-};
-
/** Allows the application to control how scene textures are used by the compositor when calling Submit. */
enum EVRSubmitFlags
{
@@ -670,9 +714,12 @@ enum EVRSubmitFlags
// If the texture pointer passed in is an OpenGL Array texture, set this flag
Submit_GlArrayTexture = 0x80,
- // Do not use
- Submit_Reserved2 = 0x8000,
+ // If the texture is an EGL texture and not an glX/wGL texture (Linux only, currently)
+ Submit_IsEgl = 0x100,
+ // Do not use
+ Submit_Reserved2 = 0x08000,
+ Submit_Reserved3 = 0x10000,
};
@@ -741,6 +788,8 @@ enum EVREventType
VREvent_PropertyChanged = 111,
VREvent_WirelessDisconnect = 112,
VREvent_WirelessReconnect = 113,
+ VREvent_Reserved_01 = 114,
+ VREvent_Reserved_02 = 115,
VREvent_ButtonPress = 200, // data is controller
VREvent_ButtonUnpress = 201, // data is controller
@@ -766,15 +815,15 @@ enum EVREventType
VREvent_OverlayFocusChanged = 307, // data is overlay, global event
VREvent_ReloadOverlays = 308,
VREvent_ScrollSmooth = 309, // data is scroll
- VREvent_LockMousePosition = 310,
- VREvent_UnlockMousePosition = 311,
+ VREvent_LockMousePosition = 310, // data is mouse
+ VREvent_UnlockMousePosition = 311, // data is mouse
VREvent_InputFocusCaptured = 400, // data is process DEPRECATED
VREvent_InputFocusReleased = 401, // data is process DEPRECATED
// VREvent_SceneFocusLost = 402, // data is process
// VREvent_SceneFocusGained = 403, // data is process
VREvent_SceneApplicationChanged = 404, // data is process - The App actually drawing the scene changed (usually to or from the compositor)
- VREvent_SceneFocusChanged = 405, // data is process - New app got access to draw the scene
+ // VREvent_SceneFocusChanged = 405, // data is process - This is defunct and will not be called.
VREvent_InputFocusChanged = 406, // data is process
// VREvent_SceneApplicationSecondaryRenderingStarted = 407,
VREvent_SceneApplicationUsingWrongGraphicsAdapter = 408, // data is process
@@ -785,11 +834,13 @@ enum EVREventType
VREvent_SceneApplicationStateChanged = 412, // No data; but query VRApplications()->GetSceneApplicationState();
+ VREvent_SceneAppPipeDisconnected = 413, // data is process - Called when the scene app's pipe has been closed.
+
VREvent_ConsoleOpened = 420,
VREvent_ConsoleClosed = 421,
- VREvent_OverlayShown = 500,
- VREvent_OverlayHidden = 501,
+ VREvent_OverlayShown = 500, // Indicates that an overlay is now visible to someone and should be rendering normally. Reflects IVROverlay::IsOverlayVisible() becoming true.
+ VREvent_OverlayHidden = 501, // Indicates that an overlay is no longer visible to someone and doesn't need to render frames. Reflects IVROverlay::IsOverlayVisible() becoming false.
VREvent_DashboardActivated = 502,
VREvent_DashboardDeactivated = 503,
//VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay - No longer sent
@@ -824,6 +875,21 @@ enum EVREventType
VREvent_DesktopViewUpdating = 530,
VREvent_DesktopViewReady = 531,
+ VREvent_StartDashboard = 532,
+ VREvent_ElevatePrism = 533,
+
+ VREvent_OverlayClosed = 534,
+
+ VREvent_DashboardThumbChanged = 535, // Sent when a dashboard thumbnail image changes
+
+ VREvent_DesktopMightBeVisible = 536, // Sent when any known desktop related overlay is visible
+ VREvent_DesktopMightBeHidden = 537, // Sent when all known desktop related overlays are hidden
+
+ VREvent_MutualSteamCapabilitiesChanged = 538, // Sent when the set of capabilities common between both Steam and SteamVR have changed.
+
+ VREvent_OverlayCreated = 539, // An OpenVR overlay of any sort was created. Data is overlay.
+ VREvent_OverlayDestroyed = 540, // An OpenVR overlay of any sort was destroyed. Data is overlay.
+
VREvent_Notification_Shown = 600,
VREvent_Notification_Hidden = 601,
VREvent_Notification_BeginInteraction = 602,
@@ -835,6 +901,7 @@ enum EVREventType
VREvent_QuitAcknowledged = 703, // data is process
VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down
VREvent_RestartRequested = 705, // A driver or other component wants the user to restart SteamVR
+ VREvent_InvalidateSwapTextureSets = 706,
VREvent_ChaperoneDataHasChanged = 800, // this will never happen with the new chaperone system
VREvent_ChaperoneUniverseHasChanged = 801,
@@ -870,6 +937,7 @@ enum EVREventType
VREvent_GpuSpeedSectionSettingChanged = 869,
VREvent_WindowsMRSectionSettingChanged = 870,
VREvent_OtherSectionSettingChanged = 871,
+ VREvent_AnyDriverSettingsChanged = 872,
VREvent_StatusUpdate = 900,
@@ -880,9 +948,11 @@ enum EVREventType
VREvent_FirmwareUpdateStarted = 1100,
VREvent_FirmwareUpdateFinished = 1101,
- VREvent_KeyboardClosed = 1200,
+ VREvent_KeyboardClosed = 1200, // DEPRECATED: Sent only to the overlay it closed for, or globally if it was closed for a scene app
VREvent_KeyboardCharInput = 1201,
VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard
+ VREvent_KeyboardOpened_Global = 1203, // Sent globally when the keyboard is opened. data.keyboard.overlayHandle is who it was opened for (scene app if k_ulOverlayHandleInvalid)
+ VREvent_KeyboardClosed_Global = 1204, // Sent globally when the keyboard is closed. data.keyboard.overlayHandle is who it was opened for (scene app if k_ulOverlayHandleInvalid)
//VREvent_ApplicationTransitionStarted = 1300,
//VREvent_ApplicationTransitionAborted = 1301,
@@ -905,6 +975,7 @@ enum EVREventType
VREvent_Compositor_OutOfVideoMemory = 1417,
VREvent_Compositor_DisplayModeNotSupported = 1418, // k_pch_SteamVR_PreferredRefreshRate
VREvent_Compositor_StageOverrideReady = 1419,
+ VREvent_Compositor_RequestDisconnectReconnect = 1420,
VREvent_TrackedCamera_StartVideoStream = 1500,
VREvent_TrackedCamera_StopVideoStream = 1501,
@@ -939,6 +1010,11 @@ enum EVREventType
VREvent_Monitor_ShowHeadsetView = 2000, // data is process
VREvent_Monitor_HideHeadsetView = 2001, // data is process
+ VREvent_Audio_SetSpeakersVolume = 2100,
+ VREvent_Audio_SetSpeakersMute = 2101,
+ VREvent_Audio_SetMicrophoneVolume = 2102,
+ VREvent_Audio_SetMicrophoneMute = 2103,
+
// Vendors are free to expose private events in this reserved region
VREvent_VendorSpecific_Reserved_Start = 10000,
VREvent_VendorSpecific_Reserved_End = 19999,
@@ -991,6 +1067,9 @@ enum EVRButtonId
k_EButton_IndexController_B = k_EButton_ApplicationMenu,
k_EButton_IndexController_JoyStick = k_EButton_Axis3,
+ k_EButton_Reserved0 = 50,
+ k_EButton_Reserved1 = 51,
+
k_EButton_Max = 64
};
@@ -1017,6 +1096,10 @@ struct VREvent_Mouse_t
{
float x, y; // co-ords are in GL space, bottom left of the texture is 0,0
uint32_t button; // EVRMouseButton enum
+
+ // if from an event triggered by cursor input on an overlay that supports multiple cursors, this is the index of
+ // which tracked cursor the event is for
+ uint32_t cursorIndex;
};
/** used for simulated mouse wheel scroll */
@@ -1025,6 +1108,10 @@ struct VREvent_Scroll_t
float xdelta, ydelta;
uint32_t unused;
float viewportscale; // For scrolling on an overlay with laser mouse, this is the overlay's vertical size relative to the overlay height. Range: [0,1]
+
+ // if from an event triggered by cursor input on an overlay that supports multiple cursors, this is the index of
+ // which tracked cursor the event is for
+ uint32_t cursorIndex;
};
/** when in mouse input mode you can receive data from the touchpad, these events are only sent if the users finger
@@ -1069,9 +1156,13 @@ struct VREvent_Process_t
/** Used for a few events about overlays */
struct VREvent_Overlay_t
{
- uint64_t overlayHandle;
+ uint64_t overlayHandle; // VROverlayHandle_t
uint64_t devicePath;
uint64_t memoryBlockId;
+
+ // if from an event triggered by cursor input on an overlay that supports multiple cursors, this is the index of
+ // which tracked cursor the event is for
+ uint32_t cursorIndex;
};
@@ -1081,11 +1172,12 @@ struct VREvent_Status_t
uint32_t statusState; // EVRState enum
};
-/** Used for keyboard events **/
+/** Used for keyboard events */
struct VREvent_Keyboard_t
{
- char cNewInput[8]; // Up to 11 bytes of new input
- uint64_t uUserValue; // Possible flags about the new input
+ char cNewInput[8]; // 7 bytes of utf8 + null
+ uint64_t uUserValue; // caller specified opaque token
+ uint64_t overlayHandle; // VROverlayHandle_t
};
struct VREvent_Ipd_t
@@ -1235,6 +1327,16 @@ struct VREvent_HDCPError_t
EHDCPError eCode;
};
+struct VREvent_AudioVolumeControl_t
+{
+ float fVolumeLevel;
+};
+
+struct VREvent_AudioMuteControl_t
+{
+ bool bMute;
+};
+
typedef union
{
VREvent_Reserved_t reserved;
@@ -1266,7 +1368,9 @@ typedef union
VREvent_ShowUI_t showUi;
VREvent_ShowDevTools_t showDevTools;
VREvent_HDCPError_t hdcpError;
- /** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py */
+ VREvent_AudioVolumeControl_t audioVolumeControl;
+ VREvent_AudioMuteControl_t audioMuteControl;
+ /** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py and openvr_api_flat.h.py */
} VREvent_Data_t;
@@ -1484,6 +1588,7 @@ enum EVROverlayError
VROverlayError_TextureAlreadyLocked = 31,
VROverlayError_TextureLockCapacityReached = 32,
VROverlayError_TextureNotLocked = 33,
+ VROverlayError_TimedOut = 34,
};
/** enum values to pass in to VR_Init to identify whether the application will
@@ -1505,6 +1610,7 @@ enum EVRApplicationType
VRApplication_OpenXRScene = 10, // reserved for openxr (started session)
VRApplication_OpenXROverlay = 11, // reserved for openxr (started overlay session)
VRApplication_Prism = 12, // reserved for the vrprismhost process
+ VRApplication_RoomView = 13, // reserved for the RoomView process
VRApplication_Max
};
@@ -1520,6 +1626,15 @@ inline bool IsOpenXRAppType( EVRApplicationType eType )
}
+/** returns true if the specified application type submits eye buffers */
+inline bool BAppTypeSubmitsEyeBuffers( EVRApplicationType eType )
+{
+ return eType == VRApplication_Scene
+ || eType == VRApplication_OpenXRScene
+ || eType == VRApplication_RoomView;
+}
+
+
/** error codes for firmware */
enum EVRFirmwareError
{
@@ -1537,6 +1652,7 @@ enum EVRNotificationError
VRNotificationError_NotificationQueueFull = 101,
VRNotificationError_InvalidOverlayHandle = 102,
VRNotificationError_SystemWithUserValueAlreadyExists = 103,
+ VRNotificationError_ServiceUnavailable = 104,
};
@@ -1641,8 +1757,20 @@ enum EVRInitError
VRInitError_Init_PrismNeedsNewDrivers = 151,
VRInitError_Init_PrismStartupTimedOut = 152,
VRInitError_Init_CouldNotStartPrism = 153,
- VRInitError_Init_CreateDriverDirectDeviceFailed = 154,
- VRInitError_Init_PrismExitedUnexpectedly = 155,
+ VRInitError_Init_PrismClientInitFailed = 154,
+ VRInitError_Init_PrismClientStartFailed = 155,
+ VRInitError_Init_PrismExitedUnexpectedly = 156,
+ VRInitError_Init_BadLuid = 157,
+ VRInitError_Init_NoServerForAppContainer = 158,
+ VRInitError_Init_DuplicateBootstrapper = 159,
+ VRInitError_Init_VRDashboardServicePending = 160,
+ VRInitError_Init_VRDashboardServiceTimeout = 161,
+ VRInitError_Init_VRDashboardServiceStopped = 162,
+ VRInitError_Init_VRDashboardAlreadyStarted = 163,
+ VRInitError_Init_VRDashboardCopyFailed = 164,
+ VRInitError_Init_VRDashboardTokenFailure = 165,
+ VRInitError_Init_VRDashboardEnvironmentFailure = 166,
+ VRInitError_Init_VRDashboardPathFailure = 167,
VRInitError_Driver_Failed = 200,
VRInitError_Driver_Unknown = 201,
@@ -1658,6 +1786,9 @@ enum EVRInitError
VRInitError_Driver_HmdDriverIdOutOfBounds = 211,
VRInitError_Driver_HmdDisplayMirrored = 212,
VRInitError_Driver_HmdDisplayNotFoundLaptop = 213,
+ VRInitError_Driver_PeerDriverNotInstalled = 214,
+ VRInitError_Driver_WirelessHmdNotConnected = 215,
+
// Never make error 259 because we return it from main and it would conflict with STILL_ACTIVE
VRInitError_IPC_ServerInitFailed = 300,
@@ -1766,9 +1897,17 @@ enum EVRInitError
VRInitError_Compositor_WindowInterfaceIsNull = 491,
VRInitError_Compositor_SystemLayerCreateInstance = 492,
VRInitError_Compositor_SystemLayerCreateSession = 493,
+ VRInitError_Compositor_CreateInverseDistortUVs = 494,
+ VRInitError_Compositor_CreateBackbufferDepth = 495,
+ VRInitError_Compositor_CannotDRMLeaseDisplay = 496,
+ VRInitError_Compositor_CannotConnectToDisplayServer = 497,
+ VRInitError_Compositor_GnomeNoDRMLeasing = 498,
+ VRInitError_Compositor_FailedToInitializeEncoder = 499,
+ VRInitError_Compositor_CreateBlurTexture = 500,
VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000,
VRInitError_VendorSpecific_WindowsNotInDevMode = 1001,
+ VRInitError_VendorSpecific_OculusLinkNotEnabled = 1002,
VRInitError_VendorSpecific_HmdFound_CantOpenDevice = 1101,
VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102,
@@ -1784,6 +1923,7 @@ enum EVRInitError
VRInitError_VendorSpecific_HmdFound_UserDataError = 1112,
VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck = 1113,
VRInitError_VendorSpecific_OculusRuntimeBadInstall = 1114,
+ VRInitError_VendorSpecific_HmdFound_UnexpectedConfiguration_1 = 1115,
VRInitError_Steam_SteamInstallationNotFound = 2000,
@@ -1880,28 +2020,31 @@ static const uint32_t k_unScreenshotHandleInvalid = 0;
/** Compositor frame timing reprojection flags. */
const uint32_t VRCompositor_ReprojectionReason_Cpu = 0x01;
const uint32_t VRCompositor_ReprojectionReason_Gpu = 0x02;
-const uint32_t VRCompositor_ReprojectionAsync = 0x04; // This flag indicates the async reprojection mode is active,
+const uint32_t VRCompositor_ReprojectionAsync = 0x04; // This flag indicates the async reprojection mode is active,
// but does not indicate if reprojection actually happened or not.
// Use the ReprojectionReason flags above to check if reprojection
// was actually applied (i.e. scene texture was reused).
// NumFramePresents > 1 also indicates the scene texture was reused,
// and also the number of times that it was presented in total.
-const uint32_t VRCompositor_ReprojectionMotion = 0x08; // This flag indicates whether or not motion smoothing was triggered for this frame
+const uint32_t VRCompositor_ReprojectionMotion = 0x08; // This flag indicates whether or not motion smoothing was triggered for this frame
-const uint32_t VRCompositor_PredictionMask = 0xF0; // The runtime may predict more than one frame (up to four) ahead if
- // it detects the application is taking too long to render. These two
+const uint32_t VRCompositor_PredictionMask = 0xF0; // The runtime may predict more than one frame ahead if
+ // it detects the application is taking too long to render. These
// bits will contain the count of additional frames (normally zero).
// Use the VR_COMPOSITOR_ADDITIONAL_PREDICTED_FRAMES macro to read from
// the latest frame timing entry.
-const uint32_t VRCompositor_ThrottleMask = 0xF00; // Number of frames the compositor is throttling the application.
+const uint32_t VRCompositor_ThrottleMask = 0xF00; // Number of frames the compositor is throttling the application.
// Use the VR_COMPOSITOR_NUMBER_OF_THROTTLED_FRAMES macro to read from
// the latest frame timing entry.
#define VR_COMPOSITOR_ADDITIONAL_PREDICTED_FRAMES( timing ) ( ( ( timing ).m_nReprojectionFlags & vr::VRCompositor_PredictionMask ) >> 4 )
#define VR_COMPOSITOR_NUMBER_OF_THROTTLED_FRAMES( timing ) ( ( ( timing ).m_nReprojectionFlags & vr::VRCompositor_ThrottleMask ) >> 8 )
+#if defined(__linux__) || defined(__APPLE__)
+#pragma pack( push, 4 )
+#endif
/** Provides a single frame's timing information to the app */
struct Compositor_FrameTiming
{
@@ -1944,7 +2087,12 @@ struct Compositor_FrameTiming
uint32_t m_nNumVSyncsReadyForUse;
uint32_t m_nNumVSyncsToFirstView;
+
+ float m_flTransferLatencyMs;
};
+#if defined(__linux__) || defined(__APPLE__)
+#pragma pack( pop )
+#endif
/** Provides compositor benchmark results to the app */
struct Compositor_BenchmarkResults
@@ -2078,6 +2226,7 @@ enum ECameraVideoStreamFormat
CVS_FORMAT_YUYV16 = 5, // 16 bits per pixel
CVS_FORMAT_BAYER16BG = 6, // 16 bits per pixel, 10-bit BG-format Bayer, see https://docs.opencv.org/3.1.0/de/d25/imgproc_color_conversions.html
CVS_FORMAT_MJPEG = 7, // variable-sized MJPEG Open DML format, see https://www.loc.gov/preservation/digital/formats/fdd/fdd000063.shtml
+ CVS_FORMAT_RGBX32 = 8, // Full-sized pixels, 4BPP, LSB = RED
CVS_MAX_FORMATS
};
@@ -2179,6 +2328,7 @@ namespace vr
VRSettingsError_ReadFailed = 3,
VRSettingsError_JsonParseFailed = 4,
VRSettingsError_UnsetSettingHasNoDefault = 5, // This will be returned if the setting does not appear in the appropriate default file and has not been set
+ VRSettingsError_AccessDenied = 6,
};
// The maximum length of a settings key
@@ -2318,6 +2468,9 @@ namespace vr
static const char * const k_pch_SteamVR_MotionSmoothingOverride_Int32 = "motionSmoothingOverride";
static const char * const k_pch_SteamVR_FramesToThrottle_Int32 = "framesToThrottle";
static const char * const k_pch_SteamVR_AdditionalFramesToPredict_Int32 = "additionalFramesToPredict";
+ static const char * const k_pch_SteamVR_WorldScale_Float = "worldScale";
+ static const char * const k_pch_SteamVR_FovScale_Int32 = "fovScale";
+ static const char * const k_pch_SteamVR_FovScaleLetterboxed_Bool = "fovScaleLetterboxed";
static const char * const k_pch_SteamVR_DisableAsyncReprojection_Bool = "disableAsync";
static const char * const k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking";
static const char * const k_pch_SteamVR_DefaultMirrorView_Int32 = "mirrorView";
@@ -2344,7 +2497,6 @@ namespace vr
static const char * const k_pch_SteamVR_ForceWindows32bitVRMonitor = "forceWindows32BitVRMonitor";
static const char * const k_pch_SteamVR_DebugInputBinding = "debugInputBinding";
static const char * const k_pch_SteamVR_DoNotFadeToGrid = "doNotFadeToGrid";
- static const char * const k_pch_SteamVR_RenderCameraMode = "renderCameraMode";
static const char * const k_pch_SteamVR_EnableSharedResourceJournaling = "enableSharedResourceJournaling";
static const char * const k_pch_SteamVR_EnableSafeMode = "enableSafeMode";
static const char * const k_pch_SteamVR_PreferredRefreshRate = "preferredRefreshRate";
@@ -2361,7 +2513,14 @@ namespace vr
static const char * const k_pch_SteamVR_BlockOculusSDKOnOpenVRLaunchOption_Bool = "blockOculusSDKOnOpenVRLaunchOption";
static const char * const k_pch_SteamVR_BlockOculusSDKOnAllLaunches_Bool = "blockOculusSDKOnAllLaunches";
static const char * const k_pch_SteamVR_HDCPLegacyCompatibility_Bool = "hdcp14legacyCompatibility";
+ static const char * const k_pch_SteamVR_DisplayPortTrainingMode_Int = "displayPortTrainingMode";
static const char * const k_pch_SteamVR_UsePrism_Bool = "usePrism";
+ static const char * const k_pch_SteamVR_AllowFallbackMirrorWindowLinux_Bool = "allowFallbackMirrorWindowLinux";
+
+ //-----------------------------------------------------------------------------
+ // openxr keys
+ static const char * const k_pch_OpenXR_Section = "openxr";
+ static const char * const k_pch_OpenXR_MetaUnityPluginCompatibility_Int32 = "metaUnityPluginCompatibility";
//-----------------------------------------------------------------------------
// direct mode keys
@@ -2437,6 +2596,7 @@ namespace vr
static const char * const k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit";
static const char * const k_pch_Perf_TestData_Float = "perfTestData";
static const char * const k_pch_Perf_GPUProfiling_Bool = "GPUProfiling";
+ static const char * const k_pch_Perf_GpuBusMonitoring_Bool = "gpuBusMonitoring";
//-----------------------------------------------------------------------------
// collision bounds keys
@@ -2508,6 +2668,11 @@ namespace vr
static const char * const k_pch_Dashboard_DesktopScale = "desktopScale";
static const char * const k_pch_Dashboard_DashboardScale = "dashboardScale";
static const char * const k_pch_Dashboard_UseStandaloneSystemLayer = "standaloneSystemLayer";
+ static const char * const k_pch_Dashboard_StickyDashboard = "stickyDashboard";
+ static const char * const k_pch_Dashboard_AllowSteamOverlays_Bool = "allowSteamOverlays";
+ static const char * const k_pch_Dashboard_AllowVRGamepadUI_Bool = "allowVRGamepadUI";
+ static const char * const k_pch_Dashboard_AllowVRGamepadUIViaGamescope_Bool = "allowVRGamepadUIViaGamescope";
+ static const char * const k_pch_Dashboard_SteamMatchesHMDFramerate = "steamMatchesHMDFramerate";
//-----------------------------------------------------------------------------
// model skin keys
@@ -2538,7 +2703,8 @@ namespace vr
// per-app keys - the section name for these is the app key itself. Some of these are prefixed by the controller type
static const char* const k_pch_App_BindingAutosaveURLSuffix_String = "AutosaveURL";
static const char* const k_pch_App_BindingLegacyAPISuffix_String = "_legacy";
- static const char* const k_pch_App_BindingSteamVRInputAPISuffix_String = "_steamvrinput";
+ static const char *const k_pch_App_BindingSteamVRInputAPISuffix_String = "_steamvrinput";
+ static const char *const k_pch_App_BindingOpenXRAPISuffix_String = "_openxr";
static const char* const k_pch_App_BindingCurrentURLSuffix_String = "CurrentURL";
static const char* const k_pch_App_BindingPreviousURLSuffix_String = "PreviousURL";
static const char* const k_pch_App_NeedToUpdateAutosaveSuffix_Bool = "NeedToUpdateAutosave";
@@ -2557,7 +2723,8 @@ namespace vr
// Last known keys for righting recovery
static const char * const k_pch_LastKnown_Section = "LastKnown";
static const char* const k_pch_LastKnown_HMDManufacturer_String = "HMDManufacturer";
- static const char* const k_pch_LastKnown_HMDModel_String = "HMDModel";
+ static const char *const k_pch_LastKnown_HMDModel_String = "HMDModel";
+ static const char* const k_pch_LastKnown_ActualHMDDriver_String = "ActualHMDDriver";
//-----------------------------------------------------------------------------
// Dismissed warnings
@@ -2740,9 +2907,12 @@ namespace vr
* the upper left of that eye's viewport and 1,1 in the lower right of that eye's viewport. */
virtual DistortionCoordinates_t ComputeDistortion( EVREye eEye, float fU, float fV ) = 0;
+ /** Computes the result of the inverse distortion function for the specified eye, channel, and input UV.
+ * Operation can fail, returns success/failure, on success result is stored in *pResult */
+ virtual bool ComputeInverseDistortion( HmdVector2_t *pResult, EVREye eEye, uint32_t unChannel, float fU, float fV ) = 0;
};
- static const char *IVRDisplayComponent_Version = "IVRDisplayComponent_002";
+ static const char *IVRDisplayComponent_Version = "IVRDisplayComponent_003";
}
@@ -2809,20 +2979,34 @@ namespace vr
// Hmd pose used to render this layer.
vr::HmdMatrix34_t mHmdPose;
+
+ // Time in seconds from now that mHmdPose was predicted to.
+ float flHmdPosePredictionTimeInSecondsFromNow;
};
virtual void SubmitLayer( const SubmitLayerPerEye_t( &perEye )[ 2 ] ) {}
/** Submits queued layers for display. */
virtual void Present( vr::SharedTextureHandle_t syncTexture ) {}
- /** Called after Present to allow driver to take more time until vsync after they've successfully acquired the sync texture in Present.*/
- virtual void PostPresent() {}
+ /** Called after Present to allow driver to take more time until vsync after they've successfully acquired the sync texture in Present.
+ * Set Prop_Hmd_SupportsAppThrottling_Bool to enable throttling / prediction UI in per-app video settings. */
+ struct Throttling_t
+ {
+ uint32_t nFramesToThrottle;
+ uint32_t nAdditionalFramesToPredict;
+ };
+ virtual void PostPresent( const Throttling_t *pThrottling ) {}
/** Called to get additional frame timing stats from driver. Check m_nSize for versioning (new members will be added to end only). */
- virtual void GetFrameTiming( DriverDirectMode_FrameTiming *pFrameTiming ) {}
+ virtual void GetFrameTiming( DriverDirectMode_FrameTiming *pFrameTiming )
+ {
+ /** VRCompositor_ReprojectionMotion_XXX flags get passed in, and since these overlap with VRCompositor_ThrottleMask, they need
+ * to be cleared out if this function isn't implemented; otherwise, those settings will get interpreted as throttling. */
+ pFrameTiming->m_nReprojectionFlags = 0;
+ }
};
- static const char *IVRDriverDirectModeComponent_Version = "IVRDriverDirectModeComponent_007";
+ static const char *IVRDriverDirectModeComponent_Version = "IVRDriverDirectModeComponent_009";
}
@@ -3049,6 +3233,10 @@ class CVRPropertyHelpers
public:
CVRPropertyHelpers( IVRProperties * pProperties ) : m_pProperties( pProperties ) {}
+ /** Gets the typed property according to the caller's expected return type. */
+ template
+ T GetTypedProperty( vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError );
+
/** Returns a scaler property. If the device index is not valid or the property value type does not match,
* this function will return false. */
bool GetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L );
@@ -3065,7 +3253,6 @@ class CVRPropertyHelpers
* null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */
uint32_t GetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() void *pvBuffer, uint32_t unBufferSize, PropertyTypeTag_t *punTag, ETrackedPropertyError *pError = 0L );
-
/** Returns a string property. If the device index is not valid or the property is not a string type this function will
* return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing
* null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */
@@ -3118,6 +3305,71 @@ class CVRPropertyHelpers
};
+/** Returns a string property as a std::string. If the device index is not valid or the property is not a string type this function will
+* return an empty string. */
+template <>
+inline std::string CVRPropertyHelpers::GetTypedProperty( vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError )
+{
+ return GetStringProperty( ulContainer, prop, peError );
+}
+
+
+template <>
+inline bool CVRPropertyHelpers::GetTypedProperty( vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError )
+{
+ return GetBoolProperty( ulContainer, prop, peError );
+}
+
+
+template <>
+inline float CVRPropertyHelpers::GetTypedProperty( vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError )
+{
+ return GetFloatProperty( ulContainer, prop, peError );
+}
+
+
+template <>
+inline int32_t CVRPropertyHelpers::GetTypedProperty( vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError )
+{
+ return GetInt32Property( ulContainer, prop, peError );
+}
+
+
+template <>
+inline uint64_t CVRPropertyHelpers::GetTypedProperty( vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError )
+{
+ return GetUint64Property( ulContainer, prop, peError );
+}
+
+
+template <>
+inline HmdVector2_t CVRPropertyHelpers::GetTypedProperty( vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError )
+{
+ return GetVec2Property( ulContainer, prop, peError );
+}
+
+
+template <>
+inline HmdVector3_t CVRPropertyHelpers::GetTypedProperty( vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError )
+{
+ return GetVec3Property( ulContainer, prop, peError );
+}
+
+
+template <>
+inline HmdVector4_t CVRPropertyHelpers::GetTypedProperty( vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError )
+{
+ return GetVec4Property( ulContainer, prop, peError );
+}
+
+
+template <>
+inline double CVRPropertyHelpers::GetTypedProperty( vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError )
+{
+ return GetDoubleProperty( ulContainer, prop, peError );
+}
+
+
inline uint32_t CVRPropertyHelpers::GetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() void *pvBuffer, uint32_t unBufferSize, PropertyTypeTag_t *punTag, ETrackedPropertyError *pError )
{
PropertyRead_t batch;
@@ -3287,19 +3539,19 @@ inline uint64_t CVRPropertyHelpers::GetUint64Property( PropertyContainerHandle_t
inline HmdVector2_t CVRPropertyHelpers::GetVec2Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError )
{
- HmdVector2_t defaultval = { 0 };
+ HmdVector2_t defaultval = { { 0, 0 } };
return GetPropertyHelper( ulContainerHandle, prop, pError, defaultval, k_unHmdVector2PropertyTag );
}
inline HmdVector3_t CVRPropertyHelpers::GetVec3Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError )
{
- HmdVector3_t defaultval = { 0 };
+ HmdVector3_t defaultval = { { 0, 0, 0 } };
return GetPropertyHelper( ulContainerHandle, prop, pError, defaultval, k_unHmdVector3PropertyTag );
}
inline HmdVector4_t CVRPropertyHelpers::GetVec4Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError )
{
- HmdVector4_t defaultval = { 0 };
+ HmdVector4_t defaultval = { { 0, 0, 0, 0 } };
return GetPropertyHelper( ulContainerHandle, prop, pError, defaultval, k_unHmdVector4PropertyTag );
}
@@ -3772,7 +4024,7 @@ static const uint64_t k_ulInvalidIOBufferHandle = 0;
virtual bool HasReaders( vr::IOBufferHandle_t ulBuffer ) = 0;
};
- static const char *IVRIOBuffer_Version = "IVRIOBuffer_002";
+ static const char * const IVRIOBuffer_Version = "IVRIOBuffer_002";
}
// ivrdrivermanager.h
@@ -3892,6 +4144,44 @@ namespace vr
} // namespace vr
+// ivripcresourcemanagerclient.h
+
+namespace vr
+{
+
+// -----------------------------------------------------------------------------
+// Purpose: Interact with the IPCResourceManager
+// -----------------------------------------------------------------------------
+class IVRIPCResourceManagerClient
+{
+public:
+ /** Create a new tracked Vulkan Image
+ *
+ * nImageFormat: in VkFormat
+ */
+ virtual bool NewSharedVulkanImage( uint32_t nImageFormat, uint32_t nWidth, uint32_t nHeight, bool bRenderable, bool bMappable, bool bComputeAccess, uint32_t unMipLevels, uint32_t unArrayLayerCount, vr::SharedTextureHandle_t *pSharedHandle ) = 0;
+
+ /** Create a new tracked Vulkan Buffer */
+ virtual bool NewSharedVulkanBuffer( size_t nSize, uint32_t nUsageFlags, vr::SharedTextureHandle_t *pSharedHandle ) = 0;
+
+ /** Create a new tracked Vulkan Semaphore */
+ virtual bool NewSharedVulkanSemaphore( vr::SharedTextureHandle_t *pSharedHandle ) = 0;
+
+ /** Grab a reference to hSharedHandle, and optionally generate a new IPC handle if pNewIpcHandle is not nullptr */
+ virtual bool RefResource( vr::SharedTextureHandle_t hSharedHandle, uint64_t *pNewIpcHandle ) = 0;
+
+ /** Drop a reference to hSharedHandle */
+ virtual bool UnrefResource( vr::SharedTextureHandle_t hSharedHandle ) = 0;
+
+protected:
+ /** Non-deletable */
+ virtual ~IVRIPCResourceManagerClient() {};
+};
+
+static const char *IVRIPCResourceManagerClient_Version = "IVRIPCResourceManagerClient_001";
+
+}
+
namespace vr
@@ -3910,6 +4200,7 @@ namespace vr
IVRDriverManager_Version,
IVRResources_Version,
IVRCompositorPluginProvider_Version,
+ IVRIPCResourceManagerClient_Version,
nullptr
};
@@ -4058,6 +4349,16 @@ namespace vr
return m_pVRDriverSpatialAnchors;
}
+ IVRIPCResourceManagerClient *VRIPCResourceManager()
+ {
+ if ( m_pVRIPCResourceManager == nullptr )
+ {
+ EVRInitError eError;
+ m_pVRIPCResourceManager = ( IVRIPCResourceManagerClient * )VRDriverContext()->GetGenericInterface( IVRIPCResourceManagerClient_Version, &eError );
+ }
+ return m_pVRIPCResourceManager;
+ }
+
private:
CVRPropertyHelpers m_propertyHelpers;
CVRHiddenAreaHelpers m_hiddenAreaHelpers;
@@ -4073,6 +4374,7 @@ namespace vr
IVRDriverInput *m_pVRDriverInput;
IVRIOBuffer *m_pVRIOBuffer;
IVRDriverSpatialAnchors *m_pVRDriverSpatialAnchors;
+ IVRIPCResourceManagerClient *m_pVRIPCResourceManager;
};
inline COpenVRDriverContext &OpenVRInternal_ModuleServerDriverContext()
@@ -4095,6 +4397,7 @@ namespace vr
inline IVRDriverInput *VR_CALLTYPE VRDriverInput() { return OpenVRInternal_ModuleServerDriverContext().VRDriverInput(); }
inline IVRIOBuffer *VR_CALLTYPE VRIOBuffer() { return OpenVRInternal_ModuleServerDriverContext().VRIOBuffer(); }
inline IVRDriverSpatialAnchors *VR_CALLTYPE VRDriverSpatialAnchors() { return OpenVRInternal_ModuleServerDriverContext().VRDriverSpatialAnchors(); }
+ inline IVRIPCResourceManagerClient *VR_CALLTYPE VRIPCResourceManager() { return OpenVRInternal_ModuleServerDriverContext().VRIPCResourceManager(); }
inline void COpenVRDriverContext::Clear()
{
@@ -4109,11 +4412,13 @@ namespace vr
m_pVRDriverInput = nullptr;
m_pVRIOBuffer = nullptr;
m_pVRDriverSpatialAnchors = nullptr;
+ m_pVRIPCResourceManager = nullptr;
}
inline EVRInitError COpenVRDriverContext::InitServer()
{
Clear();
+ // VRIPCResourceManager initialized async.
if ( !VRServerDriverHost()
|| !VRSettings()
|| !VRProperties()
diff --git a/alvr/server/cpp/openvr/lib/libopenvr_api.a b/alvr/server/cpp/openvr/lib/libopenvr_api.a
deleted file mode 100644
index 3bacefb3d8..0000000000
Binary files a/alvr/server/cpp/openvr/lib/libopenvr_api.a and /dev/null differ
diff --git a/alvr/server/cpp/openvr/lib/libopenvr_api.so b/alvr/server/cpp/openvr/lib/libopenvr_api.so
new file mode 100644
index 0000000000..dff2dfa0f4
Binary files /dev/null and b/alvr/server/cpp/openvr/lib/libopenvr_api.so differ
diff --git a/alvr/server/cpp/openvr/lib/openvr_api.lib b/alvr/server/cpp/openvr/lib/openvr_api.lib
index 3b95d6b7db..76523aceca 100644
Binary files a/alvr/server/cpp/openvr/lib/openvr_api.lib and b/alvr/server/cpp/openvr/lib/openvr_api.lib differ
diff --git a/alvr/server/cpp/platform/linux/EncodePipelineNvEnc.cpp b/alvr/server/cpp/platform/linux/EncodePipelineNvEnc.cpp
index 01ad5480af..e9d1e5c40d 100644
--- a/alvr/server/cpp/platform/linux/EncodePipelineNvEnc.cpp
+++ b/alvr/server/cpp/platform/linux/EncodePipelineNvEnc.cpp
@@ -51,6 +51,16 @@ alvr::EncodePipelineNvEnc::EncodePipelineNvEnc(std::vector &input_frame
case ALVR_CODEC_H264:
AVUTIL.av_opt_set(encoder_ctx, "preset", "llhq", 0);
AVUTIL.av_opt_set(encoder_ctx, "zerolatency", "1", 0);
+
+ switch (settings.m_entropyCoding) {
+ case ALVR_CABAC:
+ AVUTIL.av_opt_set(encoder_ctx->priv_data, "coder", "ac", 0);
+ break;
+ case ALVR_CAVLC:
+ AVUTIL.av_opt_set(encoder_ctx->priv_data, "coder", "vlc", 0);
+ break;
+ }
+
break;
case ALVR_CODEC_H265:
AVUTIL.av_opt_set(encoder_ctx, "preset", "llhq", 0);
diff --git a/alvr/server/cpp/platform/linux/EncodePipelineVAAPI.cpp b/alvr/server/cpp/platform/linux/EncodePipelineVAAPI.cpp
index 9550bdf2ba..f429df6170 100644
--- a/alvr/server/cpp/platform/linux/EncodePipelineVAAPI.cpp
+++ b/alvr/server/cpp/platform/linux/EncodePipelineVAAPI.cpp
@@ -130,7 +130,16 @@ alvr::EncodePipelineVAAPI::EncodePipelineVAAPI(std::vector& input_frame
{
case ALVR_CODEC_H264:
encoder_ctx->profile = FF_PROFILE_H264_MAIN;
- AVUTIL.av_opt_set(encoder_ctx, "rc_mode", "2", 0); //CBR
+
+ switch (settings.m_entropyCoding) {
+ case ALVR_CABAC:
+ AVUTIL.av_opt_set(encoder_ctx->priv_data, "coder", "ac", 0);
+ break;
+ case ALVR_CAVLC:
+ AVUTIL.av_opt_set(encoder_ctx->priv_data, "coder", "vlc", 0);
+ break;
+ }
+
break;
case ALVR_CODEC_H265:
encoder_ctx->profile = FF_PROFILE_HEVC_MAIN;
@@ -146,6 +155,32 @@ alvr::EncodePipelineVAAPI::EncodePipelineVAAPI(std::vector& input_frame
encoder_ctx->pix_fmt = AV_PIX_FMT_VAAPI;
encoder_ctx->max_b_frames = 0;
encoder_ctx->bit_rate = settings.mEncodeBitrateMBs * 1000 * 1000;
+ encoder_ctx->rc_min_rate = encoder_ctx->bit_rate;
+ encoder_ctx->rc_max_rate = encoder_ctx->bit_rate;
+ encoder_ctx->rc_buffer_size = encoder_ctx->bit_rate / settings.m_refreshRate;
+
+ vlVaQualityBits quality = {};
+ quality.valid_setting = 1;
+ quality.vbaq_mode = Settings::Instance().m_enableVbaq; //No noticable performance difference and should improve subjective quality by allocating more bits to smooth areas
+ switch (settings.m_encoderQualityPreset)
+ {
+ case ALVR_QUALITY:
+ quality.preset_mode = PRESET_MODE_QUALITY;
+ encoder_ctx->compression_level = quality.quality; // (QUALITY preset, no pre-encoding, vbaq)
+ break;
+ case ALVR_BALANCED:
+ quality.preset_mode = PRESET_MODE_BALANCE;
+ encoder_ctx->compression_level = quality.quality; // (BALANCE preset, no pre-encoding, vbaq)
+ break;
+ case ALVR_SPEED:
+ default:
+ quality.preset_mode = PRESET_MODE_SPEED;
+ encoder_ctx->compression_level = quality.quality; // (speed preset, no pre-encoding, vbaq)
+ break;
+ }
+
+ AVUTIL.av_opt_set_int(encoder_ctx->priv_data, "idr_interval", INT_MAX, 0);
+ AVUTIL.av_opt_set_int(encoder_ctx->priv_data, "async_depth", 1, 0);
set_hwframe_ctx(encoder_ctx, hw_ctx);
diff --git a/alvr/server/cpp/platform/linux/EncodePipelineVAAPI.h b/alvr/server/cpp/platform/linux/EncodePipelineVAAPI.h
index 92f7e9b520..73f2287f6b 100644
--- a/alvr/server/cpp/platform/linux/EncodePipelineVAAPI.h
+++ b/alvr/server/cpp/platform/linux/EncodePipelineVAAPI.h
@@ -11,6 +11,10 @@ extern "C" struct AVFrame;
namespace alvr
{
+#define PRESET_MODE_SPEED (0)
+#define PRESET_MODE_BALANCE (1)
+#define PRESET_MODE_QUALITY (2)
+
class EncodePipelineVAAPI: public EncodePipeline
{
public:
@@ -25,5 +29,17 @@ class EncodePipelineVAAPI: public EncodePipeline
AVFilterGraph *filter_graph = nullptr;
AVFilterContext *filter_in = nullptr;
AVFilterContext *filter_out = nullptr;
+
+ union vlVaQualityBits {
+ unsigned int quality;
+ struct {
+ unsigned int valid_setting: 1;
+ unsigned int preset_mode: 2;
+ unsigned int pre_encode_mode: 1;
+ unsigned int vbaq_mode: 1;
+ unsigned int reservered: 27;
+ };
+ };
+
};
}
diff --git a/alvr/server/cpp/platform/linux/generated/avutil_loader.cpp b/alvr/server/cpp/platform/linux/generated/avutil_loader.cpp
index 7cd668fb88..4f84c06390 100644
--- a/alvr/server/cpp/platform/linux/generated/avutil_loader.cpp
+++ b/alvr/server/cpp/platform/linux/generated/avutil_loader.cpp
@@ -241,6 +241,19 @@ bool avutil::Load(const std::string& library_name) {
return false;
}
+#if defined(LIBRARY_LOADER_AVUTIL_LOADER_H_DLOPEN)
+ av_opt_set_int =
+ reinterpret_castav_opt_set_int)>(
+ dlsym(library_, "av_opt_set_int"));
+#else
+ av_opt_set_int = &::av_opt_set_int;
+#endif
+ if (!av_opt_set_int) {
+ CleanUp(true);
+ return false;
+ }
+
+
#if defined(LIBRARY_LOADER_AVUTIL_LOADER_H_DLOPEN)
av_strdup =
reinterpret_castav_strdup)>(
diff --git a/alvr/server/cpp/platform/linux/generated/avutil_loader.h b/alvr/server/cpp/platform/linux/generated/avutil_loader.h
index b747fb233c..eab27da1c7 100644
--- a/alvr/server/cpp/platform/linux/generated/avutil_loader.h
+++ b/alvr/server/cpp/platform/linux/generated/avutil_loader.h
@@ -45,6 +45,7 @@ class avutil {
decltype(&::av_log_set_callback) av_log_set_callback;
decltype(&::av_log_set_level) av_log_set_level;
decltype(&::av_opt_set) av_opt_set;
+ decltype(&::av_opt_set_int) av_opt_set_int;
decltype(&::av_strdup) av_strdup;
decltype(&::av_strerror) av_strerror;
decltype(&::av_vkfmt_from_pixfmt) av_vkfmt_from_pixfmt;
diff --git a/alvr/server/cpp/platform/win32/ColorCorrectionPixelShader.cso b/alvr/server/cpp/platform/win32/ColorCorrectionPixelShader.cso
index 20869e9d9a..1288779fa8 100644
Binary files a/alvr/server/cpp/platform/win32/ColorCorrectionPixelShader.cso and b/alvr/server/cpp/platform/win32/ColorCorrectionPixelShader.cso differ
diff --git a/alvr/server/cpp/platform/win32/CompressAxisAlignedPixelShader.cso b/alvr/server/cpp/platform/win32/CompressAxisAlignedPixelShader.cso
index d3103b5aa5..15a4a9a1c7 100644
Binary files a/alvr/server/cpp/platform/win32/CompressAxisAlignedPixelShader.cso and b/alvr/server/cpp/platform/win32/CompressAxisAlignedPixelShader.cso differ
diff --git a/alvr/server/cpp/platform/win32/FrameRenderPS.cso b/alvr/server/cpp/platform/win32/FrameRenderPS.cso
index c16bdfd85a..d91ad3e8cb 100644
Binary files a/alvr/server/cpp/platform/win32/FrameRenderPS.cso and b/alvr/server/cpp/platform/win32/FrameRenderPS.cso differ
diff --git a/alvr/server/cpp/platform/win32/FrameRenderVS.cso b/alvr/server/cpp/platform/win32/FrameRenderVS.cso
index 13ed7e2618..37b0a09f83 100644
Binary files a/alvr/server/cpp/platform/win32/FrameRenderVS.cso and b/alvr/server/cpp/platform/win32/FrameRenderVS.cso differ
diff --git a/alvr/server/cpp/platform/win32/NvCodecUtils.h b/alvr/server/cpp/platform/win32/NvCodecUtils.h
index 17b41511c4..43c409e526 100644
--- a/alvr/server/cpp/platform/win32/NvCodecUtils.h
+++ b/alvr/server/cpp/platform/win32/NvCodecUtils.h
@@ -1,13 +1,36 @@
/*
-* Copyright 2017-2018 NVIDIA Corporation. All rights reserved.
-*
-* Please refer to the NVIDIA end user license agreement (EULA) associated
-* with this source code for terms and conditions that govern your use of
-* this software. Any use, reproduction, disclosure, or distribution of
-* this software and related documentation outside the terms of the EULA
-* is strictly prohibited.
-*
-*/
+ * This copyright notice applies to this header file only:
+ *
+ * Copyright (c) 2010-2024 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the software, and to permit persons to whom the
+ * software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+//---------------------------------------------------------------------------
+//! \file NvCodecUtils.h
+//! \brief Miscellaneous classes and error checking functions.
+//!
+//! Used by Transcode/Encode samples apps for reading input files, mutithreading, performance measurement or colorspace conversion while decoding.
+//---------------------------------------------------------------------------
#pragma once
#include
@@ -16,15 +39,21 @@
#include
#include
#include
-#include "alvr_server/Logger.h"
+#include
+#include
+#include
+#include
#include
+#include
+#include
+#include
#ifdef __cuda_cuda_h__
inline bool check(CUresult e, int iLine, const char *szFile) {
if (e != CUDA_SUCCESS) {
const char *szErrName = NULL;
cuGetErrorName(e, &szErrName);
- LogDriver("CUDA driver API error %hs at line %d in file %hs", szErrName, iLine, szFile);
+ //LOG(FATAL) << "CUDA driver API error " << szErrName << " at line " << iLine << " in file " << szFile;
return false;
}
return true;
@@ -34,7 +63,7 @@ inline bool check(CUresult e, int iLine, const char *szFile) {
#ifdef __CUDA_RUNTIME_H__
inline bool check(cudaError_t e, int iLine, const char *szFile) {
if (e != cudaSuccess) {
- LOG(FATAL) << "CUDA runtime API error " << cudaGetErrorName(e) << " at line " << iLine << " in file " << szFile;
+ //LOG(FATAL) << "CUDA runtime API error " << cudaGetErrorName(e) << " at line " << iLine << " in file " << szFile;
return false;
}
return true;
@@ -82,7 +111,9 @@ inline bool check(NVENCSTATUS e, int iLine, const char *szFile) {
#ifdef _WINERROR_
inline bool check(HRESULT e, int iLine, const char *szFile) {
if (e != S_OK) {
- //LOG(FATAL) << "HRESULT error 0x" << (void *)(intptr_t)e << " at line " << iLine << " in file " << szFile;
+ std::stringstream stream;
+ stream << std::hex << std::uppercase << e;
+ //LOG(FATAL) << "HRESULT error 0x" << stream.str() << " at line " << iLine << " in file " << szFile;
return false;
}
return true;
@@ -108,7 +139,41 @@ inline bool check(int e, int iLine, const char *szFile) {
}
#define ck(call) check(call, __LINE__, __FILE__)
+#define CudaCheckError() \
+ do { \
+ cudaError err_ = cudaGetLastError(); \
+ if (err_ != cudaSuccess) { \
+ printf("CudaCheckError() failed at: %s:%d\n", __FILE__, __LINE__); \
+ printf("code: %d ; description: %s\n", err_, cudaGetErrorString(err_)); \
+ exit(1); \
+ } \
+ \
+ err_ = cudaDeviceSynchronize(); \
+ if (cudaSuccess != err_) { \
+ printf("CudaCheckError() failed after sync at: %s:%d;\n", __FILE__, \
+ __LINE__); \
+ printf("code: %d; description: %s\n", err_, cudaGetErrorString(err_)); \
+ exit(1); \
+ } \
+ } while (0)
+#define MAKE_FOURCC( ch0, ch1, ch2, ch3 ) \
+ ( (uint32_t)(uint8_t)(ch0) | ( (uint32_t)(uint8_t)(ch1) << 8 ) | \
+ ( (uint32_t)(uint8_t)(ch2) << 16 ) | ( (uint32_t)(uint8_t)(ch3) << 24 ) )
+
+
+// sleep for milli-seconds
+inline void NvSleep(unsigned int mSec)
+{
+#if defined WIN32 || defined _WIN32
+ Sleep(mSec);
+#else
+ usleep(mSec * 1000);
+#endif
+}
+/**
+* @brief Wrapper class around std::thread
+*/
class NvThread
{
public:
@@ -150,23 +215,30 @@ class NvThread
#ifndef _WIN32
#define _stricmp strcasecmp
+#define _stat64 stat64
#endif
+/**
+* @brief Utility class to allocate buffer memory. Helps avoid I/O during the encode/decode loop in case of performance tests.
+*/
class BufferedFileReader {
public:
+ /**
+ * @brief Constructor function to allocate appropriate memory and copy file contents into it
+ */
BufferedFileReader(const char *szFileName, bool bPartial = false) {
- struct stat st;
+ struct _stat64 st;
- if (stat(szFileName, &st) != 0) {
+ if (_stat64(szFileName, &st) != 0) {
return;
}
nSize = st.st_size;
while (nSize) {
try {
- pBuf = new uint8_t[nSize];
+ pBuf = new uint8_t[(size_t)nSize];
if (nSize != st.st_size) {
- //LOG(WARNING) << "File is too large - only " << std::setprecision(4) << 100.0 * nSize / (uint32_t)st.st_size << "% is loaded";
+ //LOG(WARNING) << "File is too large - only " << std::setprecision(4) << 100.0 * nSize / st.st_size << "% is loaded";
}
break;
} catch(std::bad_alloc) {
@@ -195,7 +267,7 @@ class BufferedFileReader {
delete[] pBuf;
}
}
- bool GetBuffer(uint8_t **ppBuf, uint32_t *pnSize) {
+ bool GetBuffer(uint8_t **ppBuf, uint64_t *pnSize) {
if (!pBuf) {
return false;
}
@@ -207,35 +279,51 @@ class BufferedFileReader {
private:
uint8_t *pBuf = NULL;
- uint32_t nSize = 0;
+ uint64_t nSize = 0;
};
+#ifdef __NVCUVID_H__
+/**
+* @brief Template class to facilitate color space conversion
+*/
template
class YuvConverter {
public:
- YuvConverter(int nWidth, int nHeight) : nWidth(nWidth), nHeight(nHeight) {
- pQuad = new T[nWidth * nHeight / 4];
+ YuvConverter(int nWidth, int nHeight, uint8_t nChromaFormat) :
+ nWidth(nWidth), nHeight(nHeight), nChromaFormat(nChromaFormat)
+ {
+ if (nChromaFormat == cudaVideoChromaFormat_420) {
+ pQuad = new T[((nWidth + 1) / 2) * ((nHeight + 1) / 2)];
+ } else {
+ pQuad = new T[((nWidth + 1) / 2) * nHeight];
+ }
}
~YuvConverter() {
- delete pQuad;
+ delete[] pQuad;
}
void PlanarToUVInterleaved(T *pFrame, int nPitch = 0) {
if (nPitch == 0) {
nPitch = nWidth;
}
- T *puv = pFrame + nPitch * nHeight;
+
+ // sizes of source surface plane
+ int nSizePlaneY = nPitch * nHeight;
+ int nSizePlaneU = ((nPitch + 1) / 2) * ((nHeight + 1) / 2);
+ int nSizePlaneV = nSizePlaneU;
+
+ T *puv = pFrame + nSizePlaneY;
if (nPitch == nWidth) {
- memcpy(pQuad, puv, nWidth * nHeight / 4 * sizeof(T));
+ memcpy(pQuad, puv, nSizePlaneU * sizeof(T));
} else {
- for (int i = 0; i < nHeight / 2; i++) {
- memcpy(pQuad + nWidth / 2 * i, puv + nPitch / 2 * i, nWidth / 2 * sizeof(T));
+ for (int i = 0; i < (nHeight + 1) / 2; i++) {
+ memcpy(pQuad + ((nWidth + 1) / 2) * i, puv + ((nPitch + 1) / 2) * i, ((nWidth + 1) / 2) * sizeof(T));
}
}
- T *pv = puv + (nPitch / 2) * (nHeight / 2);
- for (int y = 0; y < nHeight / 2; y++) {
- for (int x = 0; x < nWidth / 2; x++) {
- puv[y * nPitch + x * 2] = pQuad[y * nWidth / 2 + x];
- puv[y * nPitch + x * 2 + 1] = pv[y * nPitch / 2 + x];
+ T *pv = puv + nSizePlaneU;
+ for (int y = 0; y < (nHeight + 1) / 2; y++) {
+ for (int x = 0; x < (nWidth + 1) / 2; x++) {
+ puv[y * nPitch + x * 2] = pQuad[y * ((nWidth + 1) / 2) + x];
+ puv[y * nPitch + x * 2 + 1] = pv[y * ((nPitch + 1) / 2) + x];
}
}
}
@@ -243,29 +331,97 @@ class YuvConverter {
if (nPitch == 0) {
nPitch = nWidth;
}
- T *puv = pFrame + nPitch * nHeight,
+
+ // sizes of source surface plane
+ int nSizePlaneY = nPitch * nHeight;
+ int nSizePlaneU = (nChromaFormat == cudaVideoChromaFormat_420) ? (((nPitch + 1) / 2) * ((nHeight + 1) / 2)) : (((nPitch + 1) / 2) * nHeight);
+ int nSizePlaneV = nSizePlaneU;
+
+ T *puv = pFrame + nSizePlaneY,
*pu = puv,
- *pv = puv + nPitch * nHeight / 4;
- for (int y = 0; y < nHeight / 2; y++) {
- for (int x = 0; x < nWidth / 2; x++) {
- pu[y * nPitch / 2 + x] = puv[y * nPitch + x * 2];
- pQuad[y * nWidth / 2 + x] = puv[y * nPitch + x * 2 + 1];
+ *pv = puv + nSizePlaneU;
+
+ // split chroma from interleave to planar
+ int nChromaHeight = (nChromaFormat == cudaVideoChromaFormat_420) ? (nHeight + 1) / 2 : nHeight;
+ for (int y = 0; y < nChromaHeight; y++) {
+ for (int x = 0; x < (nWidth + 1) / 2; x++) {
+ pu[y * ((nPitch + 1) / 2) + x] = puv[y * nPitch + x * 2];
+ pQuad[y * ((nWidth + 1) / 2) + x] = puv[y * nPitch + x * 2 + 1];
}
}
if (nPitch == nWidth) {
- memcpy(pv, pQuad, nWidth * nHeight / 4 * sizeof(T));
+ memcpy(pv, pQuad, nSizePlaneV * sizeof(T));
} else {
- for (int i = 0; i < nHeight / 2; i++) {
- memcpy(pv + nPitch / 2 * i, pQuad + nWidth / 2 * i, nWidth / 2 * sizeof(T));
+ for (int i = 0; i < nChromaHeight; i++) {
+ memcpy(pv + ((nPitch + 1) / 2) * i, pQuad + ((nWidth + 1) / 2) * i, ((nWidth + 1) / 2) * sizeof(T));
}
}
}
private:
T *pQuad;
- int nWidth, nHeight;
+ int nWidth, nHeight, nChromaFormat;
};
+#endif
+
+/**
+* @brief Class for writing IVF format header for AV1 codec
+*/
+class IVFUtils {
+public:
+ void WriteFileHeader(std::vector &vPacket, uint32_t nFourCC, uint32_t nWidth, uint32_t nHeight, uint32_t nFrameRateNum, uint32_t nFrameRateDen, uint32_t nFrameCnt)
+ {
+ char header[32];
+
+ header[0] = 'D';
+ header[1] = 'K';
+ header[2] = 'I';
+ header[3] = 'F';
+ mem_put_le16(header + 4, 0); // version
+ mem_put_le16(header + 6, 32); // header size
+ mem_put_le32(header + 8, nFourCC); // fourcc
+ mem_put_le16(header + 12, nWidth); // width
+ mem_put_le16(header + 14, nHeight); // height
+ mem_put_le32(header + 16, nFrameRateNum); // rate
+ mem_put_le32(header + 20, nFrameRateDen); // scale
+ mem_put_le32(header + 24, nFrameCnt); // length
+ mem_put_le32(header + 28, 0); // unused
+
+ vPacket.insert(vPacket.end(), &header[0], &header[32]);
+ }
+
+ void WriteFrameHeader(std::vector &vPacket, size_t nFrameSize, int64_t pts)
+ {
+ char header[12];
+ mem_put_le32(header, (int)nFrameSize);
+ mem_put_le32(header + 4, (int)(pts & 0xFFFFFFFF));
+ mem_put_le32(header + 8, (int)(pts >> 32));
+
+ vPacket.insert(vPacket.end(), &header[0], &header[12]);
+ }
+
+private:
+ static inline void mem_put_le32(void *vmem, int val)
+ {
+ unsigned char *mem = (unsigned char *)vmem;
+ mem[0] = (unsigned char)((val >> 0) & 0xff);
+ mem[1] = (unsigned char)((val >> 8) & 0xff);
+ mem[2] = (unsigned char)((val >> 16) & 0xff);
+ mem[3] = (unsigned char)((val >> 24) & 0xff);
+ }
+
+ static inline void mem_put_le16(void *vmem, int val)
+ {
+ unsigned char *mem = (unsigned char *)vmem;
+ mem[0] = (unsigned char)((val >> 0) & 0xff);
+ mem[1] = (unsigned char)((val >> 8) & 0xff);
+ }
+};
+
+/**
+* @brief Utility class to measure elapsed time in seconds between the block of executed code
+*/
class StopWatch {
public:
void Start() {
@@ -279,6 +435,95 @@ class StopWatch {
std::chrono::high_resolution_clock::time_point t0;
};
+template
+class ConcurrentQueue
+{
+ public:
+
+ ConcurrentQueue() : maxSize(0) {}
+ ConcurrentQueue(size_t size) : maxSize(size) {}
+ ConcurrentQueue(const ConcurrentQueue&) = delete;
+ ConcurrentQueue& operator=(const ConcurrentQueue&) = delete;
+
+ void setSize(size_t s) {
+ maxSize = s;
+ }
+
+ void push_back(const T& value) {
+ // Do not use a std::lock_guard here. We will need to explicitly
+ // unlock before notify_one as the other waiting thread will
+ // automatically try to acquire mutex once it wakes up
+ // (which will happen on notify_one)
+ std::unique_lock lock(m_mutex);
+ auto wasEmpty = m_List.empty();
+
+ while (full()) {
+ m_cond.wait(lock);
+ }
+
+ m_List.push_back(value);
+ if (wasEmpty && !m_List.empty()) {
+ lock.unlock();
+ m_cond.notify_one();
+ }
+ }
+
+ T pop_front() {
+ std::unique_lock lock(m_mutex);
+
+ while (m_List.empty()) {
+ m_cond.wait(lock);
+ }
+ auto wasFull = full();
+ T data = std::move(m_List.front());
+ m_List.pop_front();
+
+ if (wasFull && !full()) {
+ lock.unlock();
+ m_cond.notify_one();
+ }
+
+ return data;
+ }
+
+ T front() {
+ std::unique_lock lock(m_mutex);
+
+ while (m_List.empty()) {
+ m_cond.wait(lock);
+ }
+
+ return m_List.front();
+ }
+
+ size_t size() {
+ std::unique_lock lock(m_mutex);
+ return m_List.size();
+ }
+
+ bool empty() {
+ std::unique_lock lock(m_mutex);
+ return m_List.empty();
+ }
+ void clear() {
+ std::unique_lock lock(m_mutex);
+ m_List.clear();
+ }
+
+private:
+ bool full() {
+ if (maxSize > 0 && m_List.size() == maxSize)
+ return true;
+ return false;
+ }
+
+private:
+ std::list m_List;
+ std::mutex m_mutex;
+ std::condition_variable m_cond;
+ size_t maxSize;
+};
+
inline void CheckInputFile(const char *szInFilePath) {
std::ifstream fpIn(szInFilePath, std::ios::in | std::ios::binary);
if (fpIn.fail()) {
@@ -288,16 +533,73 @@ inline void CheckInputFile(const char *szInFilePath) {
}
}
-void Nv12ToBgra32(uint8_t *dpNv12, int nNv12Pitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 0);
-void Nv12ToBgra64(uint8_t *dpNv12, int nNv12Pitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 0);
-
-void P016ToBgra32(uint8_t *dpP016, int nP016Pitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 4);
-void P016ToBgra64(uint8_t *dpP016, int nP016Pitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 4);
-
-void Nv12ToBgrPlanar(uint8_t *dpNv12, int nNv12Pitch, uint8_t *dpBgrp, int nBgrpPitch, int nWidth, int nHeight, int iMatrix = 0);
-void P016ToBgrPlanar(uint8_t *dpP016, int nP016Pitch, uint8_t *dpBgrp, int nBgrpPitch, int nWidth, int nHeight, int iMatrix = 4);
+inline void ValidateResolution(int nWidth, int nHeight) {
+
+ if (nWidth <= 0 || nHeight <= 0) {
+ std::ostringstream err;
+ err << "Please specify positive non zero resolution as -s WxH. Current resolution is " << nWidth << "x" << nHeight << std::endl;
+ throw std::invalid_argument(err.str());
+ }
+}
-void Bgra64ToP016(uint8_t *dpBgra, int nBgraPitch, uint8_t *dpP016, int nP016Pitch, int nWidth, int nHeight, int iMatrix = 4);
+template
+void Nv12ToColor32(uint8_t *dpNv12, int nNv12Pitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 0, bool video_full_range = 0);
+template
+void Nv12ToColor24(uint8_t *dpNv12, int nNv12Pitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 0, bool video_full_range = 0);
+template
+void Nv12ToColor64(uint8_t *dpNv12, int nNv12Pitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 0, bool video_full_range = 0);
+
+template
+void P016ToColor32(uint8_t *dpP016, int nP016Pitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 4, bool video_full_range = 0);
+template
+void P016ToColor24(uint8_t *dpP016, int nP016Pitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 4, bool video_full_range = 0);
+template
+void P016ToColor64(uint8_t *dpP016, int nP016Pitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 4, bool video_full_range = 0);
+
+template
+void Nv16ToColor32(uint8_t *dpNv16, int nNv16Pitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 0, bool video_full_range = 0);
+template
+void Nv16ToColor24(uint8_t *dpNv16, int nNv16Pitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 0, bool video_full_range = 0);
+template
+void Nv16ToColor64(uint8_t *dpNv16, int nNv16Pitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 0, bool video_full_range = 0);
+
+template
+void P216ToColor32(uint8_t *dpP216, int nP216Pitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 4, bool video_full_range = 0);
+template
+void P216ToColor64(uint8_t *dpP216, int nP216Pitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 4, bool video_full_range = 0);
+template
+void P216ToColor24(uint8_t *dpP216, int nP216Pitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 4, bool video_full_range = 0);
+
+template
+void YUV444ToColor32(uint8_t *dpYUV444, int nPitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 0, bool video_full_range = 0);
+template
+void YUV444ToColor24(uint8_t *dpYUV444, int nPitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 0, bool video_full_range = 0);
+template
+void YUV444ToColor64(uint8_t *dpYUV444, int nPitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 0, bool video_full_range = 0);
+
+template
+void YUV444P16ToColor32(uint8_t *dpYUV444, int nPitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 4, bool video_full_range = 0);
+template
+void YUV444P16ToColor24(uint8_t *dpYUV444, int nPitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 4, bool video_full_range = 0);
+template
+void YUV444P16ToColor64(uint8_t *dpYUV444, int nPitch, uint8_t *dpBgra, int nBgraPitch, int nWidth, int nHeight, int iMatrix = 4, bool video_full_range = 0);
+
+template
+void Nv12ToColorPlanar(uint8_t *dpNv12, int nNv12Pitch, uint8_t *dpBgrp, int nBgrpPitch, int nWidth, int nHeight, int iMatrix = 0, bool video_full_range = 0);
+template
+void P016ToColorPlanar(uint8_t *dpP016, int nP016Pitch, uint8_t *dpBgrp, int nBgrpPitch, int nWidth, int nHeight, int iMatrix = 4, bool video_full_range = 0);
+
+template
+void Nv16ToColorPlanar(uint8_t *dpNv16, int nNv16Pitch, uint8_t *dpBgrp, int nBgrpPitch, int nWidth, int nHeight, int iMatrix = 0, bool video_full_range = 0);
+template
+void P216ToColorPlanar(uint8_t *dpP216, int nP216Pitch, uint8_t *dpBgrp, int nBgrpPitch, int nWidth, int nHeight, int iMatrix = 4, bool video_full_range = 0);
+
+template
+void YUV444ToColorPlanar(uint8_t *dpYUV444, int nPitch, uint8_t *dpBgrp, int nBgrpPitch, int nWidth, int nHeight, int iMatrix = 0, bool video_full_range = 0);
+template
+void YUV444P16ToColorPlanar(uint8_t *dpYUV444, int nPitch, uint8_t *dpBgrp, int nBgrpPitch, int nWidth, int nHeight, int iMatrix = 4, bool video_full_range = 0);
+
+void Bgra64ToP016(uint8_t *dpBgra, int nBgraPitch, uint8_t *dpP016, int nP016Pitch, int nWidth, int nHeight, int iMatrix = 4, bool video_full_range = 0);
void ConvertUInt8ToUInt16(uint8_t *dpUInt8, uint16_t *dpUInt16, int nSrcPitch, int nDestPitch, int nWidth, int nHeight);
void ConvertUInt16ToUInt8(uint16_t *dpUInt16, uint8_t *dpUInt8, int nSrcPitch, int nDestPitch, int nWidth, int nHeight);
@@ -307,3 +609,7 @@ void ResizeP016(unsigned char *dpDstP016, int nDstPitch, int nDstWidth, int nDst
void ScaleYUV420(unsigned char *dpDstY, unsigned char* dpDstU, unsigned char* dpDstV, int nDstPitch, int nDstChromaPitch, int nDstWidth, int nDstHeight,
unsigned char *dpSrcY, unsigned char* dpSrcU, unsigned char* dpSrcV, int nSrcPitch, int nSrcChromaPitch, int nSrcWidth, int nSrcHeight, bool bSemiplanar);
+
+#ifdef __cuda_cuda_h__
+void ComputeCRC(uint8_t *pBuffer, uint32_t *crcValue, CUstream_st *outputCUStream);
+#endif
diff --git a/alvr/server/cpp/platform/win32/NvEncoder.cpp b/alvr/server/cpp/platform/win32/NvEncoder.cpp
index 06f0f98b05..a3e9b6a0b6 100644
--- a/alvr/server/cpp/platform/win32/NvEncoder.cpp
+++ b/alvr/server/cpp/platform/win32/NvEncoder.cpp
@@ -1,13 +1,29 @@
/*
-* Copyright 2017-2018 NVIDIA Corporation. All rights reserved.
-*
-* Please refer to the NVIDIA end user license agreement (EULA) associated
-* with this source code for terms and conditions that govern your use of
-* this software. Any use, reproduction, disclosure, or distribution of
-* this software and related documentation outside the terms of the EULA
-* is strictly prohibited.
-*
-*/
+ * This copyright notice applies to this header file only:
+ *
+ * Copyright (c) 2010-2024 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the software, and to permit persons to whom the
+ * software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
#include "NvEncoder.h"
@@ -23,7 +39,7 @@ static inline bool operator!=(const GUID &guid1, const GUID &guid2) {
#endif
NvEncoder::NvEncoder(NV_ENC_DEVICE_TYPE eDeviceType, void *pDevice, uint32_t nWidth, uint32_t nHeight, NV_ENC_BUFFER_FORMAT eBufferFormat,
- uint32_t nExtraOutputDelay, bool bMotionEstimationOnly) :
+ uint32_t nExtraOutputDelay, bool bMotionEstimationOnly, bool bOutputInVideoMemory, bool bDX12Encode, bool bUseIVFContainer) :
m_pDevice(pDevice),
m_eDeviceType(eDeviceType),
m_nWidth(nWidth),
@@ -32,6 +48,9 @@ NvEncoder::NvEncoder(NV_ENC_DEVICE_TYPE eDeviceType, void *pDevice, uint32_t nWi
m_nMaxEncodeHeight(nHeight),
m_eBufferFormat(eBufferFormat),
m_bMotionEstimationOnly(bMotionEstimationOnly),
+ m_bOutputInVideoMemory(bOutputInVideoMemory),
+ m_bIsDX12Encode(bDX12Encode),
+ m_bUseIVFContainer(bUseIVFContainer),
m_nExtraOutputDelay(nExtraOutputDelay),
m_hEncoder(nullptr)
{
@@ -49,7 +68,6 @@ NvEncoder::NvEncoder(NV_ENC_DEVICE_TYPE eDeviceType, void *pDevice, uint32_t nWi
encodeSessionExParams.apiVersion = NVENCAPI_VERSION;
void *hEncoder = NULL;
NVENC_API_CALL(m_nvenc.nvEncOpenEncodeSessionEx(&encodeSessionExParams, &hEncoder));
-
m_hEncoder = hEncoder;
}
@@ -82,7 +100,6 @@ void NvEncoder::LoadNvEncApi()
uint32_t version = 0;
uint32_t currentVersion = (NVENCAPI_MAJOR_VERSION << 4) | NVENCAPI_MINOR_VERSION;
NVENC_API_CALL(NvEncodeAPIGetMaxSupportedVersion(&version));
-
if (currentVersion > version)
{
NVENC_THROW_ERROR("Current Driver Version does not support this NvEncodeAPI version, please upgrade driver", NV_ENC_ERR_INVALID_VERSION);
@@ -118,7 +135,7 @@ NvEncoder::~NvEncoder()
}
}
-void NvEncoder::CreateDefaultEncoderParams(NV_ENC_INITIALIZE_PARAMS* pIntializeParams, GUID codecGuid, GUID presetGuid)
+void NvEncoder::CreateDefaultEncoderParams(NV_ENC_INITIALIZE_PARAMS* pIntializeParams, GUID codecGuid, GUID presetGuid, NV_ENC_TUNING_INFO tuningInfo)
{
if (!m_hEncoder)
{
@@ -154,43 +171,73 @@ void NvEncoder::CreateDefaultEncoderParams(NV_ENC_INITIALIZE_PARAMS* pIntializeP
pIntializeParams->maxEncodeWidth = m_nWidth;
pIntializeParams->maxEncodeHeight = m_nHeight;
pIntializeParams->enableMEOnlyMode = m_bMotionEstimationOnly;
+ pIntializeParams->enableOutputInVidmem = m_bOutputInVideoMemory;
#if defined(_WIN32)
- pIntializeParams->enableEncodeAsync = true;
+ if (!m_bOutputInVideoMemory)
+ {
+ pIntializeParams->enableEncodeAsync = GetCapabilityValue(codecGuid, NV_ENC_CAPS_ASYNC_ENCODE_SUPPORT);
+ }
#endif
- NV_ENC_PRESET_CONFIG presetConfig = { NV_ENC_PRESET_CONFIG_VER, { NV_ENC_CONFIG_VER } };
- m_nvenc.nvEncGetEncodePresetConfig(m_hEncoder, codecGuid, presetGuid, &presetConfig);
+ pIntializeParams->tuningInfo = tuningInfo;
+ pIntializeParams->encodeConfig->rcParams.rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
+
+ //There are changes in the structure layout, therefore users are recommended to be careful while moving their application to the new header.
+ //Following initialization has changed for the same reason.
+ NV_ENC_PRESET_CONFIG presetConfig = { NV_ENC_PRESET_CONFIG_VER, 0, { NV_ENC_CONFIG_VER } };
+ m_nvenc.nvEncGetEncodePresetConfigEx(m_hEncoder, codecGuid, presetGuid, tuningInfo, &presetConfig);
memcpy(pIntializeParams->encodeConfig, &presetConfig.presetCfg, sizeof(NV_ENC_CONFIG));
- pIntializeParams->encodeConfig->frameIntervalP = 1;
- pIntializeParams->encodeConfig->gopLength = NVENC_INFINITE_GOPLENGTH;
- pIntializeParams->encodeConfig->rcParams.rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
- if (pIntializeParams->presetGUID != NV_ENC_PRESET_LOSSLESS_DEFAULT_GUID
- && pIntializeParams->presetGUID != NV_ENC_PRESET_LOSSLESS_HP_GUID)
+ if(m_bMotionEstimationOnly)
{
- pIntializeParams->encodeConfig->rcParams.constQP = { 28, 31, 25 };
+ m_encodeConfig.version = NV_ENC_CONFIG_VER;
+ m_encodeConfig.rcParams.rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
+ m_encodeConfig.rcParams.constQP = { 28, 31, 25 };
}
-
+
if (pIntializeParams->encodeGUID == NV_ENC_CODEC_H264_GUID)
{
if (m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV444 || m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV444_10BIT)
{
pIntializeParams->encodeConfig->encodeCodecConfig.h264Config.chromaFormatIDC = 3;
}
+ else if (m_eBufferFormat == NV_ENC_BUFFER_FORMAT_NV16 || m_eBufferFormat == NV_ENC_BUFFER_FORMAT_P210)
+ {
+ pIntializeParams->encodeConfig->encodeCodecConfig.h264Config.chromaFormatIDC = 2;
+ }
pIntializeParams->encodeConfig->encodeCodecConfig.h264Config.idrPeriod = pIntializeParams->encodeConfig->gopLength;
}
else if (pIntializeParams->encodeGUID == NV_ENC_CODEC_HEVC_GUID)
{
- pIntializeParams->encodeConfig->encodeCodecConfig.hevcConfig.pixelBitDepthMinus8 =
- (m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV420_10BIT || m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV444_10BIT ) ? 2 : 0;
+ pIntializeParams->encodeConfig->encodeCodecConfig.hevcConfig.inputBitDepth = pIntializeParams->encodeConfig->encodeCodecConfig.hevcConfig.outputBitDepth =
+ (m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV420_10BIT || m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV444_10BIT ) ? NV_ENC_BIT_DEPTH_10 : NV_ENC_BIT_DEPTH_8;
if (m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV444 || m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV444_10BIT)
{
pIntializeParams->encodeConfig->encodeCodecConfig.hevcConfig.chromaFormatIDC = 3;
}
+ else if (m_eBufferFormat == NV_ENC_BUFFER_FORMAT_NV16 || m_eBufferFormat == NV_ENC_BUFFER_FORMAT_P210)
+ {
+ pIntializeParams->encodeConfig->encodeCodecConfig.hevcConfig.chromaFormatIDC = 2;
+ }
pIntializeParams->encodeConfig->encodeCodecConfig.hevcConfig.idrPeriod = pIntializeParams->encodeConfig->gopLength;
}
+ else if (pIntializeParams->encodeGUID == NV_ENC_CODEC_AV1_GUID)
+ {
+ pIntializeParams->encodeConfig->encodeCodecConfig.av1Config.inputBitDepth = (m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV420_10BIT) ? NV_ENC_BIT_DEPTH_10 : NV_ENC_BIT_DEPTH_8;
+ pIntializeParams->encodeConfig->encodeCodecConfig.av1Config.chromaFormatIDC = 1;
+ pIntializeParams->encodeConfig->encodeCodecConfig.av1Config.idrPeriod = pIntializeParams->encodeConfig->gopLength;
+ if (m_bOutputInVideoMemory)
+ {
+ pIntializeParams->encodeConfig->frameIntervalP = 1;
+ }
+ }
+ if (m_bIsDX12Encode)
+ {
+ pIntializeParams->bufferFormat = m_eBufferFormat;
+ }
+
return;
}
@@ -211,22 +258,34 @@ void NvEncoder::CreateEncoder(const NV_ENC_INITIALIZE_PARAMS* pEncoderParams)
NVENC_THROW_ERROR("Invalid encoder width and height", NV_ENC_ERR_INVALID_PARAM);
}
- if (pEncoderParams->encodeGUID != NV_ENC_CODEC_H264_GUID && pEncoderParams->encodeGUID != NV_ENC_CODEC_HEVC_GUID)
+ if (pEncoderParams->encodeGUID != NV_ENC_CODEC_H264_GUID && pEncoderParams->encodeGUID != NV_ENC_CODEC_HEVC_GUID && pEncoderParams->encodeGUID != NV_ENC_CODEC_AV1_GUID)
{
NVENC_THROW_ERROR("Invalid codec guid", NV_ENC_ERR_INVALID_PARAM);
}
- if (pEncoderParams->encodeGUID == NV_ENC_CODEC_H264_GUID)
+ if (pEncoderParams->encodeGUID == NV_ENC_CODEC_AV1_GUID)
{
- if (m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV420_10BIT || m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV444_10BIT)
+ if (m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV444 || m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV444_10BIT)
{
- NVENC_THROW_ERROR("10-bit format isn't supported by H264 encoder", NV_ENC_ERR_INVALID_PARAM);
+ NVENC_THROW_ERROR("YUV444 format isn't supported by AV1 encoder", NV_ENC_ERR_INVALID_PARAM);
}
}
// set other necessary params if not set yet
if (pEncoderParams->encodeGUID == NV_ENC_CODEC_H264_GUID)
{
+ bool yuv10BitFormat = (m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV420_10BIT || m_eBufferFormat == NV_ENC_BUFFER_FORMAT_P210 || m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV444_10BIT) ? true : false;
+ if (yuv10BitFormat && pEncoderParams->encodeConfig->encodeCodecConfig.h264Config.inputBitDepth != NV_ENC_BIT_DEPTH_10)
+ {
+ NVENC_THROW_ERROR("Invalid PixelBitdepth", NV_ENC_ERR_INVALID_PARAM);
+ }
+
+ if ((m_eBufferFormat == NV_ENC_BUFFER_FORMAT_NV16 || m_eBufferFormat == NV_ENC_BUFFER_FORMAT_P210) &&
+ (pEncoderParams->encodeConfig->encodeCodecConfig.h264Config.chromaFormatIDC != 2))
+ {
+ NVENC_THROW_ERROR("Invalid ChromaFormatIDC", NV_ENC_ERR_INVALID_PARAM);
+ }
+
if ((m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV444) &&
(pEncoderParams->encodeConfig->encodeCodecConfig.h264Config.chromaFormatIDC != 3))
{
@@ -236,12 +295,18 @@ void NvEncoder::CreateEncoder(const NV_ENC_INITIALIZE_PARAMS* pEncoderParams)
if (pEncoderParams->encodeGUID == NV_ENC_CODEC_HEVC_GUID)
{
- bool yuv10BitFormat = (m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV420_10BIT || m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV444_10BIT) ? true : false;
- if (yuv10BitFormat && pEncoderParams->encodeConfig->encodeCodecConfig.hevcConfig.pixelBitDepthMinus8 != 2)
+ bool yuv10BitFormat = (m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV420_10BIT || m_eBufferFormat == NV_ENC_BUFFER_FORMAT_P210 || m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV444_10BIT) ? true : false;
+ if (yuv10BitFormat && pEncoderParams->encodeConfig->encodeCodecConfig.hevcConfig.inputBitDepth != NV_ENC_BIT_DEPTH_10)
{
NVENC_THROW_ERROR("Invalid PixelBitdepth", NV_ENC_ERR_INVALID_PARAM);
}
+ if ((m_eBufferFormat == NV_ENC_BUFFER_FORMAT_NV16 || m_eBufferFormat == NV_ENC_BUFFER_FORMAT_P210) &&
+ (pEncoderParams->encodeConfig->encodeCodecConfig.hevcConfig.chromaFormatIDC != 2))
+ {
+ NVENC_THROW_ERROR("Invalid ChromaFormatIDC", NV_ENC_ERR_INVALID_PARAM);
+ }
+
if ((m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV444 || m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV444_10BIT) &&
(pEncoderParams->encodeConfig->encodeCodecConfig.hevcConfig.chromaFormatIDC != 3))
{
@@ -249,6 +314,25 @@ void NvEncoder::CreateEncoder(const NV_ENC_INITIALIZE_PARAMS* pEncoderParams)
}
}
+ if (pEncoderParams->encodeGUID == NV_ENC_CODEC_AV1_GUID)
+ {
+ bool yuv10BitFormat = (m_eBufferFormat == NV_ENC_BUFFER_FORMAT_YUV420_10BIT) ? true : false;
+ if (yuv10BitFormat && pEncoderParams->encodeConfig->encodeCodecConfig.av1Config.inputBitDepth != NV_ENC_BIT_DEPTH_10)
+ {
+ NVENC_THROW_ERROR("Invalid PixelBitdepth", NV_ENC_ERR_INVALID_PARAM);
+ }
+
+ if (pEncoderParams->encodeConfig->encodeCodecConfig.av1Config.chromaFormatIDC != 1)
+ {
+ NVENC_THROW_ERROR("Invalid ChromaFormatIDC", NV_ENC_ERR_INVALID_PARAM);
+ }
+
+ if (m_bOutputInVideoMemory && pEncoderParams->encodeConfig->frameIntervalP > 1)
+ {
+ NVENC_THROW_ERROR("Alt Ref frames not supported for AV1 in case of OutputInVideoMemory", NV_ENC_ERR_INVALID_PARAM);
+ }
+ }
+
memcpy(&m_initializeParams, pEncoderParams, sizeof(m_initializeParams));
m_initializeParams.version = NV_ENC_INITIALIZE_PARAMS_VER;
@@ -259,13 +343,31 @@ void NvEncoder::CreateEncoder(const NV_ENC_INITIALIZE_PARAMS* pEncoderParams)
}
else
{
- NV_ENC_PRESET_CONFIG presetConfig = { NV_ENC_PRESET_CONFIG_VER, { NV_ENC_CONFIG_VER } };
- m_nvenc.nvEncGetEncodePresetConfig(m_hEncoder, pEncoderParams->encodeGUID, NV_ENC_PRESET_DEFAULT_GUID, &presetConfig);
- memcpy(&m_encodeConfig, &presetConfig.presetCfg, sizeof(NV_ENC_CONFIG));
- m_encodeConfig.version = NV_ENC_CONFIG_VER;
- m_encodeConfig.rcParams.rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
- m_encodeConfig.rcParams.constQP = { 28, 31, 25 };
+ //There are changes in the structure layout, therefore users are recommended to be careful while moving their application to the new header.
+ //Following initialization has changed for the same reason.
+ NV_ENC_PRESET_CONFIG presetConfig = { NV_ENC_PRESET_CONFIG_VER, 0, { NV_ENC_CONFIG_VER } };
+ if (!m_bMotionEstimationOnly)
+ {
+ m_nvenc.nvEncGetEncodePresetConfigEx(m_hEncoder, pEncoderParams->encodeGUID, pEncoderParams->presetGUID, pEncoderParams->tuningInfo, &presetConfig);
+ memcpy(&m_encodeConfig, &presetConfig.presetCfg, sizeof(NV_ENC_CONFIG));
+ if (m_bOutputInVideoMemory && pEncoderParams->encodeGUID == NV_ENC_CODEC_AV1_GUID)
+ {
+ m_encodeConfig.frameIntervalP = 1;
+ }
+ }
+ else
+ {
+ m_encodeConfig.version = NV_ENC_CONFIG_VER;
+ m_encodeConfig.rcParams.rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
+ m_encodeConfig.rcParams.constQP = { 28, 31, 25 };
+ }
}
+
+ if (((uint32_t)m_encodeConfig.frameIntervalP) > m_encodeConfig.gopLength)
+ {
+ m_encodeConfig.frameIntervalP = m_encodeConfig.gopLength;
+ }
+
m_initializeParams.encodeConfig = &m_encodeConfig;
NVENC_API_CALL(m_nvenc.nvEncInitializeEncoder(m_hEncoder, &m_initializeParams));
@@ -277,32 +379,55 @@ void NvEncoder::CreateEncoder(const NV_ENC_INITIALIZE_PARAMS* pEncoderParams)
m_nMaxEncodeHeight = m_initializeParams.maxEncodeHeight;
m_nEncoderBuffer = m_encodeConfig.frameIntervalP + m_encodeConfig.rcParams.lookaheadDepth + m_nExtraOutputDelay;
+
+ if (pEncoderParams->encodeGUID == NV_ENC_CODEC_HEVC_GUID)
+ {
+ m_enableStereoMVHEVC = m_initializeParams.encodeConfig->encodeCodecConfig.hevcConfig.enableMVHEVC;
+ if (m_enableStereoMVHEVC)
+ {
+ m_nEncoderBuffer = m_nEncoderBuffer * 2;
+ m_outputHevc3DReferenceDisplayInfo = m_initializeParams.encodeConfig->encodeCodecConfig.hevcConfig.outputHevc3DReferenceDisplayInfo;
+ }
+ }
+
m_nOutputDelay = m_nEncoderBuffer - 1;
- m_vMappedInputBuffers.resize(m_nEncoderBuffer, nullptr);
- m_vBitstreamOutputBuffer.resize(m_nEncoderBuffer, nullptr);
- for (int i = 0; i < m_nEncoderBuffer; i++)
+ if (!m_bOutputInVideoMemory)
{
- NV_ENC_CREATE_BITSTREAM_BUFFER createBitstreamBuffer = { NV_ENC_CREATE_BITSTREAM_BUFFER_VER };
- NVENC_API_CALL(m_nvenc.nvEncCreateBitstreamBuffer(m_hEncoder, &createBitstreamBuffer));
- m_vBitstreamOutputBuffer[i] = createBitstreamBuffer.bitstreamBuffer;
+ m_vpCompletionEvent.resize(m_nEncoderBuffer, nullptr);
}
- m_vpCompletionEvent.resize(m_nEncoderBuffer, nullptr);
#if defined(_WIN32)
- for (int i = 0; i < m_nEncoderBuffer; i++)
+ for (uint32_t i = 0; i < m_vpCompletionEvent.size(); i++)
{
m_vpCompletionEvent[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
- NV_ENC_EVENT_PARAMS eventParams = { NV_ENC_EVENT_PARAMS_VER };
- eventParams.completionEvent = m_vpCompletionEvent[i];
- m_nvenc.nvEncRegisterAsyncEvent(m_hEncoder, &eventParams);
+ if (!m_bIsDX12Encode)
+ {
+ NV_ENC_EVENT_PARAMS eventParams = { NV_ENC_EVENT_PARAMS_VER };
+ eventParams.completionEvent = m_vpCompletionEvent[i];
+ m_nvenc.nvEncRegisterAsyncEvent(m_hEncoder, &eventParams);
+ }
}
#endif
+ m_vMappedInputBuffers.resize(m_nEncoderBuffer, nullptr);
+
if (m_bMotionEstimationOnly)
{
m_vMappedRefBuffers.resize(m_nEncoderBuffer, nullptr);
- InitializeMVOutputBuffer();
+
+ if (!m_bOutputInVideoMemory)
+ {
+ InitializeMVOutputBuffer();
+ }
+ }
+ else
+ {
+ if (!m_bOutputInVideoMemory && !m_bIsDX12Encode)
+ {
+ m_vBitstreamOutputBuffer.resize(m_nEncoderBuffer, nullptr);
+ InitializeBitstreamBuffer();
+ }
}
AllocateInputBuffers(m_nEncoderBuffer);
@@ -327,23 +452,17 @@ void NvEncoder::DestroyHWEncoder()
return;
}
- for (uint32_t i = 0; i < m_vBitstreamOutputBuffer.size(); i++)
- {
- if (m_vBitstreamOutputBuffer[i])
- {
- m_nvenc.nvEncDestroyBitstreamBuffer(m_hEncoder, m_vBitstreamOutputBuffer[i]);
- }
- }
- m_vBitstreamOutputBuffer.clear();
-
#if defined(_WIN32)
for (uint32_t i = 0; i < m_vpCompletionEvent.size(); i++)
{
if (m_vpCompletionEvent[i])
{
- NV_ENC_EVENT_PARAMS eventParams = { NV_ENC_EVENT_PARAMS_VER };
- eventParams.completionEvent = m_vpCompletionEvent[i];
- m_nvenc.nvEncUnregisterAsyncEvent(m_hEncoder, &eventParams);
+ if (!m_bIsDX12Encode)
+ {
+ NV_ENC_EVENT_PARAMS eventParams = { NV_ENC_EVENT_PARAMS_VER };
+ eventParams.completionEvent = m_vpCompletionEvent[i];
+ m_nvenc.nvEncUnregisterAsyncEvent(m_hEncoder, &eventParams);
+ }
CloseHandle(m_vpCompletionEvent[i]);
}
}
@@ -354,6 +473,11 @@ void NvEncoder::DestroyHWEncoder()
{
DestroyMVOutputBuffer();
}
+ else
+ {
+ if (!m_bIsDX12Encode)
+ DestroyBitstreamBuffer();
+ }
m_nvenc.nvEncDestroyEncoder(m_hEncoder);
@@ -368,25 +492,57 @@ const NvEncInputFrame* NvEncoder::GetNextInputFrame()
return &m_vInputFrames[i];
}
+const NvEncInputFrame* NvEncoder::GetNextInputFrame(uint32_t frameIdx) // for external lookahead API in Iterative Encoder sample (AppEncQual)
+{
+ int i = frameIdx % m_nEncoderBuffer;
+ return &m_vInputFrames[i];
+}
+
const NvEncInputFrame* NvEncoder::GetNextReferenceFrame()
{
int i = m_iToSend % m_nEncoderBuffer;
return &m_vReferenceFrames[i];
}
-void NvEncoder::EncodeFrame(std::vector> &vPacket, NV_ENC_PIC_PARAMS *pPicParams)
+void NvEncoder::MapResources(uint32_t bfrIdx)
+{
+ NV_ENC_MAP_INPUT_RESOURCE mapInputResource = { NV_ENC_MAP_INPUT_RESOURCE_VER };
+
+ mapInputResource.registeredResource = m_vRegisteredResources[bfrIdx];
+ NVENC_API_CALL(m_nvenc.nvEncMapInputResource(m_hEncoder, &mapInputResource));
+ m_vMappedInputBuffers[bfrIdx] = mapInputResource.mappedResource;
+
+ if (m_bMotionEstimationOnly)
+ {
+ mapInputResource.registeredResource = m_vRegisteredResourcesForReference[bfrIdx];
+ NVENC_API_CALL(m_nvenc.nvEncMapInputResource(m_hEncoder, &mapInputResource));
+ m_vMappedRefBuffers[bfrIdx] = mapInputResource.mappedResource;
+ }
+}
+
+std::size_t NvEncoder::EncodeFrame(std::vector &vPacket, NV_ENC_PIC_PARAMS *pPicParams)
{
- vPacket.clear();
if (!IsHWEncoderInitialized())
{
NVENC_THROW_ERROR("Encoder device not found", NV_ENC_ERR_NO_ENCODE_DEVICE);
}
- int i = m_iToSend % m_nEncoderBuffer;
- NV_ENC_MAP_INPUT_RESOURCE mapInputResource = { NV_ENC_MAP_INPUT_RESOURCE_VER };
- mapInputResource.registeredResource = m_vRegisteredResources[i];
- NVENC_API_CALL(m_nvenc.nvEncMapInputResource(m_hEncoder, &mapInputResource));
- m_vMappedInputBuffers[i] = mapInputResource.mappedResource;
- DoEncode(m_vMappedInputBuffers[i], vPacket, pPicParams);
+
+ int bfrIdx = m_iToSend % m_nEncoderBuffer;
+
+ MapResources(bfrIdx);
+
+ NVENCSTATUS nvStatus = DoEncode(m_vMappedInputBuffers[bfrIdx], m_vBitstreamOutputBuffer[bfrIdx], pPicParams);
+
+ if (nvStatus == NV_ENC_SUCCESS || nvStatus == NV_ENC_ERR_NEED_MORE_INPUT)
+ {
+ m_iToSend++;
+ return GetEncodedPacket(m_vBitstreamOutputBuffer, vPacket, true);
+ }
+ else
+ {
+ NVENC_THROW_ERROR("nvEncEncodePicture API failed", nvStatus);
+ }
+ return 0;
}
void NvEncoder::RunMotionEstimation(std::vector &mvData)
@@ -397,21 +553,27 @@ void NvEncoder::RunMotionEstimation(std::vector &mvData)
return;
}
- const uint32_t i = m_iToSend % m_nEncoderBuffer;
+ const uint32_t bfrIdx = m_iToSend % m_nEncoderBuffer;
- NV_ENC_MAP_INPUT_RESOURCE mapInputResource = { NV_ENC_MAP_INPUT_RESOURCE_VER };
- mapInputResource.registeredResource = m_vRegisteredResources[i];
- NVENC_API_CALL(m_nvenc.nvEncMapInputResource(m_hEncoder, &mapInputResource));
- NV_ENC_INPUT_PTR pDeviceMemoryInputBuffer = mapInputResource.mappedResource;
- m_vMappedInputBuffers[i] = mapInputResource.mappedResource;
+ MapResources(bfrIdx);
+ NVENCSTATUS nvStatus = DoMotionEstimation(m_vMappedInputBuffers[bfrIdx], m_vMappedRefBuffers[bfrIdx], m_vMVDataOutputBuffer[bfrIdx]);
- mapInputResource.registeredResource = m_vRegisteredResourcesForReference[i];
- NVENC_API_CALL(m_nvenc.nvEncMapInputResource(m_hEncoder, &mapInputResource));
- NV_ENC_INPUT_PTR pDeviceMemoryInputBufferForReference = mapInputResource.mappedResource;
- m_vMappedRefBuffers[i] = mapInputResource.mappedResource;
-
- DoMotionEstimation(pDeviceMemoryInputBuffer, pDeviceMemoryInputBufferForReference, mvData);
+ if (nvStatus == NV_ENC_SUCCESS)
+ {
+ m_iToSend++;
+ std::vector vPacket;
+ GetEncodedPacket(m_vMVDataOutputBuffer, vPacket, true);
+ if (vPacket.size() != 1)
+ {
+ NVENC_THROW_ERROR("GetEncodedPacket() doesn't return one (and only one) MVData", NV_ENC_ERR_GENERIC);
+ }
+ mvData = vPacket[0].frame;
+ }
+ else
+ {
+ NVENC_THROW_ERROR("nvEncEncodePicture API failed", nvStatus);
+ }
}
@@ -430,34 +592,79 @@ void NvEncoder::GetSequenceParams(std::vector &seqParams)
seqParams.insert(seqParams.end(), &spsppsData[0], &spsppsData[spsppsSize]);
}
-void NvEncoder::DoEncode(NV_ENC_INPUT_PTR inputBuffer, std::vector> &vPacket, NV_ENC_PIC_PARAMS *pPicParams)
+NVENCSTATUS NvEncoder::DoEncode(NV_ENC_INPUT_PTR inputBuffer, NV_ENC_OUTPUT_PTR outputBuffer, NV_ENC_PIC_PARAMS *pPicParams)
{
NV_ENC_PIC_PARAMS picParams = {};
if (pPicParams)
{
picParams = *pPicParams;
}
+
+ HEVC_3D_REFERENCE_DISPLAY_INFO *p3dReferenceDisplayInfo = NULL;
picParams.version = NV_ENC_PIC_PARAMS_VER;
picParams.pictureStruct = NV_ENC_PIC_STRUCT_FRAME;
+ picParams.inputTimeStamp = m_nInputTimeStamp++;
picParams.inputBuffer = inputBuffer;
picParams.bufferFmt = GetPixelFormat();
picParams.inputWidth = GetEncodeWidth();
picParams.inputHeight = GetEncodeHeight();
- picParams.outputBitstream = m_vBitstreamOutputBuffer[m_iToSend % m_nEncoderBuffer];
- picParams.completionEvent = m_vpCompletionEvent[m_iToSend % m_nEncoderBuffer];
- NVENCSTATUS nvStatus = m_nvenc.nvEncEncodePicture(m_hEncoder, &picParams);
- if (nvStatus == NV_ENC_SUCCESS || nvStatus == NV_ENC_ERR_NEED_MORE_INPUT)
+ picParams.frameIdx = m_iToSend;
+ picParams.outputBitstream = outputBuffer;
+ picParams.completionEvent = GetCompletionEvent(m_iToSend % m_nEncoderBuffer);
+
+ if (m_enableStereoMVHEVC)
{
- m_iToSend++;
- GetEncodedPacket(m_vBitstreamOutputBuffer, vPacket, true);
+ picParams.codecPicParams.hevcPicParams.viewId = m_viewId;
+ m_viewId = m_viewId ^ 1;
+ if (m_outputHevc3DReferenceDisplayInfo == 1)
+ {
+
+ // Example code to insert HEVC_3D_REFERENCE_DISPLAY_INFO
+ // One 3D Reference Displays Information SEI message NAL unit (per G.14.2.3), with
+ // nuh_layer_id equal to 0, and with the following values:
+ // - To indicate the display width value is unspecified by using 0, use:
+ // - prec_ref_display_width = 31
+ // - exponent_ref_display_width = 0
+ // - mantissa_ref_display_width = 0
+ // - ref_viewing_distance_flag = 0
+ // - prec_ref_viewing_dist syntax element skipped
+ // - num_ref_displays_minusl = 0
+ // - left_view_id[ 0 ] is set to reference the texture layer used for the viewer_s left
+ // eye using values in vps_extension (per F.7.3.2.1.1)
+ // - right_view_id[ 0 ] is set to reference the texture layer used for the viewer_s
+ // right eye using values in vps_extension (per F.7.3.2.1.1)
+ // - additional_shift_present_flag[ 0 ] = 0
+ // - exponent_ref_viewing_distancel 0 ], mantissa_ref_viewing_distance[ 0 ],
+ // num_sample_shift_plus512[ 0 ] syntax elements are skipped
+ p3dReferenceDisplayInfo = new HEVC_3D_REFERENCE_DISPLAY_INFO;
+ memset(p3dReferenceDisplayInfo, 0, sizeof(HEVC_3D_REFERENCE_DISPLAY_INFO));
+ p3dReferenceDisplayInfo->precRefDisplayWidth = 31;
+ p3dReferenceDisplayInfo->leftViewId[0] = 0;
+ p3dReferenceDisplayInfo->rightViewId[0] = 1;
+ picParams.codecPicParams.hevcPicParams.p3DReferenceDisplayInfo = p3dReferenceDisplayInfo;
+ }
}
- else
+
+ NVENCSTATUS nvStatus = m_nvenc.nvEncEncodePicture(m_hEncoder, &picParams);
+
+ if (p3dReferenceDisplayInfo)
{
- NVENC_THROW_ERROR("nvEncEncodePicture API failed", nvStatus);
+ delete p3dReferenceDisplayInfo;
+ p3dReferenceDisplayInfo = NULL;
}
+
+ return nvStatus;
+}
+
+void NvEncoder::SendEOS()
+{
+ NV_ENC_PIC_PARAMS picParams = { NV_ENC_PIC_PARAMS_VER };
+ picParams.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
+ picParams.completionEvent = GetCompletionEvent(m_iToSend % m_nEncoderBuffer);
+ NVENC_API_CALL(m_nvenc.nvEncEncodePicture(m_hEncoder, &picParams));
}
-void NvEncoder::EndEncode(std::vector> &vPacket)
+void NvEncoder::EndEncode(std::vector &vPacket)
{
vPacket.clear();
if (!IsHWEncoderInitialized())
@@ -465,16 +672,14 @@ void NvEncoder::EndEncode(std::vector> &vPacket)
NVENC_THROW_ERROR("Encoder device not initialized", NV_ENC_ERR_ENCODER_NOT_INITIALIZED);
}
- NV_ENC_PIC_PARAMS picParams = { NV_ENC_PIC_PARAMS_VER };
- picParams.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
- picParams.completionEvent = m_vpCompletionEvent[m_iToSend % m_nEncoderBuffer];
- NVENC_API_CALL(m_nvenc.nvEncEncodePicture(m_hEncoder, &picParams));
+ SendEOS();
+
GetEncodedPacket(m_vBitstreamOutputBuffer, vPacket, false);
}
-void NvEncoder::GetEncodedPacket(std::vector &vOutputBuffer, std::vector> &vPacket, bool bOutputDelay)
+std::size_t NvEncoder::GetEncodedPacket(std::vector &vOutputBuffer, std::vector &vPacket, bool bOutputDelay)
{
- unsigned i = 0;
+ std::size_t i = 0;
int iEnd = bOutputDelay ? m_iToSend - m_nOutputDelay : m_iToSend;
for (; m_iGot < iEnd; m_iGot++)
{
@@ -487,10 +692,24 @@ void NvEncoder::GetEncodedPacket(std::vector &vOutputBuffer,
uint8_t *pData = (uint8_t *)lockBitstreamData.bitstreamBufferPtr;
if (vPacket.size() < i + 1)
{
- vPacket.push_back(std::vector());
+ NvEncOutputFrame nvEncOutputFrame;
+ vPacket.push_back(nvEncOutputFrame);
+ }
+ vPacket[i].frame.clear();
+
+ if ((m_initializeParams.encodeGUID == NV_ENC_CODEC_AV1_GUID) && (m_bUseIVFContainer))
+ {
+ if (m_bWriteIVFFileHeader)
+ {
+ m_IVFUtils.WriteFileHeader(vPacket[i].frame, MAKE_FOURCC('A', 'V', '0', '1'), m_initializeParams.encodeWidth, m_initializeParams.encodeHeight, m_initializeParams.frameRateNum, m_initializeParams.frameRateDen, 0xFFFF);
+ m_bWriteIVFFileHeader = false;
+ }
+
+ m_IVFUtils.WriteFrameHeader(vPacket[i].frame, lockBitstreamData.bitstreamSizeInBytes, lockBitstreamData.outputTimeStamp);
}
- vPacket[i].clear();
- vPacket[i].insert(vPacket[i].end(), &pData[0], &pData[lockBitstreamData.bitstreamSizeInBytes]);
+ vPacket[i].frame.insert(vPacket[i].frame.end(), &pData[0], &pData[lockBitstreamData.bitstreamSizeInBytes]);
+ vPacket[i].pictureType = lockBitstreamData.pictureType;
+ vPacket[i].timeStamp = lockBitstreamData.outputTimeStamp;
i++;
NVENC_API_CALL(m_nvenc.nvEncUnlockBitstream(m_hEncoder, lockBitstreamData.outputBitstream));
@@ -507,6 +726,7 @@ void NvEncoder::GetEncodedPacket(std::vector &vOutputBuffer,
m_vMappedRefBuffers[m_iGot % m_nEncoderBuffer] = nullptr;
}
}
+ return i;
}
bool NvEncoder::Reconfigure(const NV_ENC_RECONFIGURE_PARAMS *pReconfigureParams)
@@ -527,20 +747,31 @@ bool NvEncoder::Reconfigure(const NV_ENC_RECONFIGURE_PARAMS *pReconfigureParams)
return true;
}
-void NvEncoder::RegisterResources(std::vector inputframes, NV_ENC_INPUT_RESOURCE_TYPE eResourceType,
+NV_ENC_REGISTERED_PTR NvEncoder::RegisterResource(void *pBuffer, NV_ENC_INPUT_RESOURCE_TYPE eResourceType,
+ int width, int height, int pitch, NV_ENC_BUFFER_FORMAT bufferFormat, NV_ENC_BUFFER_USAGE bufferUsage,
+ NV_ENC_FENCE_POINT_D3D12* pInputFencePoint)
+{
+ NV_ENC_REGISTER_RESOURCE registerResource = { NV_ENC_REGISTER_RESOURCE_VER };
+ registerResource.resourceType = eResourceType;
+ registerResource.resourceToRegister = pBuffer;
+ registerResource.width = width;
+ registerResource.height = height;
+ registerResource.pitch = pitch;
+ registerResource.bufferFormat = bufferFormat;
+ registerResource.bufferUsage = bufferUsage;
+ registerResource.pInputFencePoint = pInputFencePoint;
+ NVENC_API_CALL(m_nvenc.nvEncRegisterResource(m_hEncoder, ®isterResource));
+
+ return registerResource.registeredResource;
+}
+
+void NvEncoder::RegisterInputResources(std::vector inputframes, NV_ENC_INPUT_RESOURCE_TYPE eResourceType,
int width, int height, int pitch, NV_ENC_BUFFER_FORMAT bufferFormat, bool bReferenceFrame)
{
for (uint32_t i = 0; i < inputframes.size(); ++i)
{
- NV_ENC_REGISTER_RESOURCE registerResource = { NV_ENC_REGISTER_RESOURCE_VER };
- registerResource.resourceType = eResourceType;
- registerResource.resourceToRegister = (void *)inputframes[i];
- registerResource.width = width;
- registerResource.height = height;
- registerResource.pitch = pitch;
- registerResource.bufferFormat = bufferFormat;
- NVENC_API_CALL(m_nvenc.nvEncRegisterResource(m_hEncoder, ®isterResource));
-
+ NV_ENC_REGISTERED_PTR registeredPtr = RegisterResource(inputframes[i], eResourceType, width, height, pitch, bufferFormat, NV_ENC_INPUT_IMAGE);
+
std::vector _chromaOffsets;
NvEncoder::GetChromaSubPlaneOffsets(bufferFormat, pitch, height, _chromaOffsets);
NvEncInputFrame inputframe = {};
@@ -559,30 +790,39 @@ void NvEncoder::RegisterResources(std::vector inputframes, NV_ENC_INPUT_R
if (bReferenceFrame)
{
- m_vRegisteredResourcesForReference.push_back(registerResource.registeredResource);
+ m_vRegisteredResourcesForReference.push_back(registeredPtr);
m_vReferenceFrames.push_back(inputframe);
}
else
{
- m_vRegisteredResources.push_back(registerResource.registeredResource);
+ m_vRegisteredResources.push_back(registeredPtr);
m_vInputFrames.push_back(inputframe);
}
}
}
-void NvEncoder::UnregisterResources()
+void NvEncoder::FlushEncoder()
{
- // Incase of error it is possible for buffers still mapped to encoder.
- // flush the encoder queue and then unmapped it if any surface is still mapped
- try
- {
- std::vector> vPacket;
- EndEncode(vPacket);
- }
- catch (...)
+ if (!m_bMotionEstimationOnly && !m_bOutputInVideoMemory)
{
+ // Incase of error it is possible for buffers still mapped to encoder.
+ // flush the encoder queue and then unmapped it if any surface is still mapped
+ try
+ {
+ std::vector vPacket;
+ EndEncode(vPacket);
+ }
+ catch (...)
+ {
+ }
}
+}
+
+void NvEncoder::UnregisterInputResources()
+{
+ FlushEncoder();
+
if (m_bMotionEstimationOnly)
{
for (uint32_t i = 0; i < m_vMappedRefBuffers.size(); ++i)
@@ -629,6 +869,16 @@ void NvEncoder::UnregisterResources()
void NvEncoder::WaitForCompletionEvent(int iEvent)
{
#if defined(_WIN32)
+ // Check if we are in async mode. If not, don't wait for event;
+ NV_ENC_CONFIG sEncodeConfig = { 0 };
+ NV_ENC_INITIALIZE_PARAMS sInitializeParams = { 0 };
+ sInitializeParams.encodeConfig = &sEncodeConfig;
+ GetInitializeParams(&sInitializeParams);
+
+ if (0U == sInitializeParams.enableEncodeAsync)
+ {
+ return;
+ }
#ifdef DEBUG
WaitForSingleObject(m_vpCompletionEvent[iEvent], INFINITE);
#else
@@ -647,9 +897,11 @@ uint32_t NvEncoder::GetWidthInBytes(const NV_ENC_BUFFER_FORMAT bufferFormat, con
case NV_ENC_BUFFER_FORMAT_NV12:
case NV_ENC_BUFFER_FORMAT_YV12:
case NV_ENC_BUFFER_FORMAT_IYUV:
+ case NV_ENC_BUFFER_FORMAT_NV16:
case NV_ENC_BUFFER_FORMAT_YUV444:
return width;
case NV_ENC_BUFFER_FORMAT_YUV420_10BIT:
+ case NV_ENC_BUFFER_FORMAT_P210:
case NV_ENC_BUFFER_FORMAT_YUV444_10BIT:
return width * 2;
case NV_ENC_BUFFER_FORMAT_ARGB:
@@ -670,6 +922,8 @@ uint32_t NvEncoder::GetNumChromaPlanes(const NV_ENC_BUFFER_FORMAT bufferFormat)
{
case NV_ENC_BUFFER_FORMAT_NV12:
case NV_ENC_BUFFER_FORMAT_YUV420_10BIT:
+ case NV_ENC_BUFFER_FORMAT_NV16:
+ case NV_ENC_BUFFER_FORMAT_P210:
return 1;
case NV_ENC_BUFFER_FORMAT_YV12:
case NV_ENC_BUFFER_FORMAT_IYUV:
@@ -684,7 +938,7 @@ uint32_t NvEncoder::GetNumChromaPlanes(const NV_ENC_BUFFER_FORMAT bufferFormat)
return 0;
default:
NVENC_THROW_ERROR("Invalid Buffer format", NV_ENC_ERR_INVALID_PARAM);
- return (uint32_t)-1;
+ return -1;
}
}
@@ -694,6 +948,8 @@ uint32_t NvEncoder::GetChromaPitch(const NV_ENC_BUFFER_FORMAT bufferFormat,const
{
case NV_ENC_BUFFER_FORMAT_NV12:
case NV_ENC_BUFFER_FORMAT_YUV420_10BIT:
+ case NV_ENC_BUFFER_FORMAT_NV16:
+ case NV_ENC_BUFFER_FORMAT_P210:
case NV_ENC_BUFFER_FORMAT_YUV444:
case NV_ENC_BUFFER_FORMAT_YUV444_10BIT:
return lumaPitch;
@@ -708,7 +964,7 @@ uint32_t NvEncoder::GetChromaPitch(const NV_ENC_BUFFER_FORMAT bufferFormat,const
return 0;
default:
NVENC_THROW_ERROR("Invalid Buffer format", NV_ENC_ERR_INVALID_PARAM);
- return (uint32_t)-1;
+ return -1;
}
}
@@ -719,6 +975,8 @@ void NvEncoder::GetChromaSubPlaneOffsets(const NV_ENC_BUFFER_FORMAT bufferFormat
{
case NV_ENC_BUFFER_FORMAT_NV12:
case NV_ENC_BUFFER_FORMAT_YUV420_10BIT:
+ case NV_ENC_BUFFER_FORMAT_NV16:
+ case NV_ENC_BUFFER_FORMAT_P210:
chromaOffsets.push_back(pitch * height);
return;
case NV_ENC_BUFFER_FORMAT_YV12:
@@ -752,6 +1010,9 @@ uint32_t NvEncoder::GetChromaHeight(const NV_ENC_BUFFER_FORMAT bufferFormat, con
case NV_ENC_BUFFER_FORMAT_NV12:
case NV_ENC_BUFFER_FORMAT_YUV420_10BIT:
return (lumaHeight + 1)/2;
+ case NV_ENC_BUFFER_FORMAT_NV16:
+ case NV_ENC_BUFFER_FORMAT_P210:
+ return lumaHeight;
case NV_ENC_BUFFER_FORMAT_YUV444:
case NV_ENC_BUFFER_FORMAT_YUV444_10BIT:
return lumaHeight;
@@ -778,6 +1039,10 @@ uint32_t NvEncoder::GetChromaWidthInBytes(const NV_ENC_BUFFER_FORMAT bufferForma
return lumaWidth;
case NV_ENC_BUFFER_FORMAT_YUV420_10BIT:
return 2 * lumaWidth;
+ case NV_ENC_BUFFER_FORMAT_NV16:
+ return lumaWidth;
+ case NV_ENC_BUFFER_FORMAT_P210:
+ return 2 * lumaWidth;
case NV_ENC_BUFFER_FORMAT_YUV444:
return lumaWidth;
case NV_ENC_BUFFER_FORMAT_YUV444_10BIT:
@@ -818,6 +1083,10 @@ int NvEncoder::GetFrameSize() const
return GetEncodeWidth() * (GetEncodeHeight() + (GetEncodeHeight() + 1) / 2);
case NV_ENC_BUFFER_FORMAT_YUV420_10BIT:
return 2 * GetEncodeWidth() * (GetEncodeHeight() + (GetEncodeHeight() + 1) / 2);
+ case NV_ENC_BUFFER_FORMAT_NV16:
+ return 2 * GetEncodeWidth() * GetEncodeHeight();
+ case NV_ENC_BUFFER_FORMAT_P210:
+ return 4 * GetEncodeWidth() * GetEncodeHeight();
case NV_ENC_BUFFER_FORMAT_YUV444:
return GetEncodeWidth() * GetEncodeHeight() * 3;
case NV_ENC_BUFFER_FORMAT_YUV444_10BIT:
@@ -846,6 +1115,29 @@ void NvEncoder::GetInitializeParams(NV_ENC_INITIALIZE_PARAMS *pInitializeParams)
pInitializeParams->encodeConfig = pEncodeConfig;
}
+void NvEncoder::InitializeBitstreamBuffer()
+{
+ for (int i = 0; i < m_nEncoderBuffer; i++)
+ {
+ NV_ENC_CREATE_BITSTREAM_BUFFER createBitstreamBuffer = { NV_ENC_CREATE_BITSTREAM_BUFFER_VER };
+ NVENC_API_CALL(m_nvenc.nvEncCreateBitstreamBuffer(m_hEncoder, &createBitstreamBuffer));
+ m_vBitstreamOutputBuffer[i] = createBitstreamBuffer.bitstreamBuffer;
+ }
+}
+
+void NvEncoder::DestroyBitstreamBuffer()
+{
+ for (uint32_t i = 0; i < m_vBitstreamOutputBuffer.size(); i++)
+ {
+ if (m_vBitstreamOutputBuffer[i])
+ {
+ m_nvenc.nvEncDestroyBitstreamBuffer(m_hEncoder, m_vBitstreamOutputBuffer[i]);
+ }
+ }
+
+ m_vBitstreamOutputBuffer.clear();
+}
+
void NvEncoder::InitializeMVOutputBuffer()
{
for (int i = 0; i < m_nEncoderBuffer; i++)
@@ -869,29 +1161,16 @@ void NvEncoder::DestroyMVOutputBuffer()
m_vMVDataOutputBuffer.clear();
}
-void NvEncoder::DoMotionEstimation(NV_ENC_INPUT_PTR inputBuffer, NV_ENC_INPUT_PTR inputBufferForReference, std::vector &mvData)
+NVENCSTATUS NvEncoder::DoMotionEstimation(NV_ENC_INPUT_PTR inputBuffer, NV_ENC_INPUT_PTR inputBufferForReference, NV_ENC_OUTPUT_PTR outputBuffer)
{
NV_ENC_MEONLY_PARAMS meParams = { NV_ENC_MEONLY_PARAMS_VER };
meParams.inputBuffer = inputBuffer;
meParams.referenceFrame = inputBufferForReference;
meParams.inputWidth = GetEncodeWidth();
meParams.inputHeight = GetEncodeHeight();
- meParams.mvBuffer = m_vMVDataOutputBuffer[m_iToSend % m_nEncoderBuffer];
- meParams.completionEvent = m_vpCompletionEvent[m_iToSend % m_nEncoderBuffer];
+ meParams.mvBuffer = outputBuffer;
+ meParams.completionEvent = GetCompletionEvent(m_iToSend % m_nEncoderBuffer);
NVENCSTATUS nvStatus = m_nvenc.nvEncRunMotionEstimationOnly(m_hEncoder, &meParams);
- if (nvStatus == NV_ENC_SUCCESS || nvStatus == NV_ENC_ERR_NEED_MORE_INPUT)
- {
- m_iToSend++;
- std::vector> vPacket;
- GetEncodedPacket(m_vMVDataOutputBuffer, vPacket, true);
- if (vPacket.size() != 1)
- {
- NVENC_THROW_ERROR("GetEncodedPacket() doesn't return one (and only one) MVData", NV_ENC_ERR_GENERIC);
- }
- mvData = vPacket[0];
- }
- else
- {
- NVENC_THROW_ERROR("nvEncEncodePicture API failed", nvStatus);
- }
+
+ return nvStatus;
}
diff --git a/alvr/server/cpp/platform/win32/NvEncoder.h b/alvr/server/cpp/platform/win32/NvEncoder.h
index 9528b12c3b..9d490f8114 100644
--- a/alvr/server/cpp/platform/win32/NvEncoder.h
+++ b/alvr/server/cpp/platform/win32/NvEncoder.h
@@ -1,13 +1,29 @@
/*
-* Copyright 2017-2018 NVIDIA Corporation. All rights reserved.
-*
-* Please refer to the NVIDIA end user license agreement (EULA) associated
-* with this source code for terms and conditions that govern your use of
-* this software. Any use, reproduction, disclosure, or distribution of
-* this software and related documentation outside the terms of the EULA
-* is strictly prohibited.
-*
-*/
+ * This copyright notice applies to this header file only:
+ *
+ * Copyright (c) 2010-2024 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the software, and to permit persons to whom the
+ * software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
#pragma once
@@ -19,6 +35,7 @@
#include
#include
#include
+#include "NvCodecUtils.h"
/**
* @brief Exception class for error reporting from NvEncodeAPI calls.
@@ -79,6 +96,13 @@ struct NvEncInputFrame
NV_ENC_INPUT_RESOURCE_TYPE resourceType;
};
+struct NvEncOutputFrame
+{
+ std::vector frame;
+ NV_ENC_PIC_TYPE pictureType;
+ uint64_t timeStamp;
+};
+
/**
* @brief Shared base class for different encoder interfaces.
*/
@@ -90,7 +114,7 @@ class NvEncoder
* Application must call this function to initialize the encoder, before
* starting to encode any frames.
*/
- void CreateEncoder(const NV_ENC_INITIALIZE_PARAMS* pEncodeParams);
+ virtual void CreateEncoder(const NV_ENC_INITIALIZE_PARAMS* pEncodeParams);
/**
* @brief This function is used to destroy the encoder session.
@@ -98,7 +122,7 @@ class NvEncoder
* clean up any allocated resources. The application must call EndEncode()
* function to get any queued encoded frames before calling DestroyEncoder().
*/
- void DestroyEncoder();
+ virtual void DestroyEncoder();
/**
* @brief This function is used to reconfigure an existing encoder session.
@@ -115,7 +139,7 @@ class NvEncoder
* input buffer and then call EncodeFrame() function to encode it.
*/
const NvEncInputFrame* GetNextInputFrame();
-
+ const NvEncInputFrame* GetNextInputFrame(uint32_t frameIdx);
/**
* @brief This function is used to encode a frame.
@@ -123,7 +147,7 @@ class NvEncoder
* data, which has been copied to an input buffer obtained from the
* GetNextInputFrame() function.
*/
- void EncodeFrame(std::vector> &vPacket, NV_ENC_PIC_PARAMS *pPicParams = nullptr);
+ virtual std::size_t EncodeFrame(std::vector &vPacket, NV_ENC_PIC_PARAMS *pPicParams = nullptr);
/**
* @brief This function to flush the encoder queue.
@@ -132,7 +156,7 @@ class NvEncoder
* from the encoder. The application must call this function before destroying
* an encoder session.
*/
- void EndEncode(std::vector> &vPacket);
+ virtual void EndEncode(std::vector &vPacket);
/**
* @brief This function is used to query hardware encoder capabilities.
@@ -176,7 +200,7 @@ class NvEncoder
* directly or override them with application-specific settings before
* using them in CreateEncoder() function.
*/
- void CreateDefaultEncoderParams(NV_ENC_INITIALIZE_PARAMS* pIntializeParams, GUID codecGuid, GUID presetGuid);
+ void CreateDefaultEncoderParams(NV_ENC_INITIALIZE_PARAMS* pIntializeParams, GUID codecGuid, GUID presetGuid, NV_ENC_TUNING_INFO tuningInfo = NV_ENC_TUNING_INFO_UNDEFINED);
/**
* @brief This function is used to get the current initialization parameters,
@@ -249,6 +273,21 @@ class NvEncoder
*/
static uint32_t GetWidthInBytes(const NV_ENC_BUFFER_FORMAT bufferFormat, const uint32_t width);
+ /**
+ * @brief This function returns the number of allocated buffers.
+ */
+ uint32_t GetEncoderBufferCount() const { return m_nEncoderBuffer; }
+
+ /*
+ * @brief This function returns initializeParams(width, height, fps etc).
+ */
+ NV_ENC_INITIALIZE_PARAMS GetinitializeParams() const { return m_initializeParams; }
+
+ /**
+ * @brief This function returns mvhevc is enabled or not.
+ */
+ uint32_t IsMVHEVC() const { return m_enableStereoMVHEVC; };
+
protected:
/**
@@ -256,7 +295,8 @@ class NvEncoder
* NvEncoder class constructor cannot be called directly by the application.
*/
NvEncoder(NV_ENC_DEVICE_TYPE eDeviceType, void *pDevice, uint32_t nWidth, uint32_t nHeight,
- NV_ENC_BUFFER_FORMAT eBufferFormat, uint32_t m_nOutputDelay, bool bMotionEstimationOnly);
+ NV_ENC_BUFFER_FORMAT eBufferFormat, uint32_t nOutputDelay, bool bMotionEstimationOnly, bool bOutputInVideoMemory = false, bool bDX12Encode = false,
+ bool bUseIVFContainer = true);
/**
* @brief This function is used to check if hardware encoder is properly initialized.
@@ -268,14 +308,22 @@ class NvEncoder
* This is non public function and is called by derived class for allocating
* and registering input buffers.
*/
- void RegisterResources(std::vector inputframes, NV_ENC_INPUT_RESOURCE_TYPE eResourceType,
+ void RegisterInputResources(std::vector inputframes, NV_ENC_INPUT_RESOURCE_TYPE eResourceType,
int width, int height, int pitch, NV_ENC_BUFFER_FORMAT bufferFormat, bool bReferenceFrame = false);
/**
* @brief This function is used to unregister resources which had been previously registered for encoding
- * using RegisterResources() function.
+ * using RegisterInputResources() function.
*/
- void UnregisterResources();
+ void UnregisterInputResources();
+
+ /**
+ * @brief This function is used to register CUDA, D3D or OpenGL input or output buffers with NvEncodeAPI.
+ */
+ NV_ENC_REGISTERED_PTR RegisterResource(void *pBuffer, NV_ENC_INPUT_RESOURCE_TYPE eResourceType,
+ int width, int height, int pitch, NV_ENC_BUFFER_FORMAT bufferFormat, NV_ENC_BUFFER_USAGE bufferUsage = NV_ENC_INPUT_IMAGE,
+ NV_ENC_FENCE_POINT_D3D12* pInputFencePoint = NULL);
+
/**
* @brief This function returns maximum width used to open the encoder session.
* All encode input buffers are allocated using maximum dimensions.
@@ -288,17 +336,44 @@ class NvEncoder
*/
uint32_t GetMaxEncodeHeight() const { return m_nMaxEncodeHeight; }
+ /**
+ * @brief This function returns the completion event.
+ */
+ void* GetCompletionEvent(uint32_t eventIdx) { return (m_vpCompletionEvent.size() == m_nEncoderBuffer) ? m_vpCompletionEvent[eventIdx] : nullptr; }
+
/**
* @brief This function returns the current pixel format.
*/
NV_ENC_BUFFER_FORMAT GetPixelFormat() const { return m_eBufferFormat; }
-private:
/**
- * @brief This is a private function which is used to wait for completion of encode command.
+ * @brief This function is used to submit the encode commands to the
+ * NVENC hardware.
+ */
+ NVENCSTATUS DoEncode(NV_ENC_INPUT_PTR inputBuffer, NV_ENC_OUTPUT_PTR outputBuffer, NV_ENC_PIC_PARAMS *pPicParams);
+
+ /**
+ * @brief This function is used to submit the encode commands to the
+ * NVENC hardware for ME only mode.
+ */
+ NVENCSTATUS DoMotionEstimation(NV_ENC_INPUT_PTR inputBuffer, NV_ENC_INPUT_PTR inputBufferForReference, NV_ENC_OUTPUT_PTR outputBuffer);
+
+ /**
+ * @brief This function is used to map the input buffers to NvEncodeAPI.
+ */
+ void MapResources(uint32_t bfrIdx);
+
+ /**
+ * @brief This function is used to wait for completion of encode command.
*/
void WaitForCompletionEvent(int iEvent);
+ /**
+ * @brief This function is used to send EOS to HW encoder.
+ */
+ void SendEOS();
+
+private:
/**
* @brief This is a private function which is used to check if there is any
buffering done by encoder.
@@ -313,24 +388,24 @@ class NvEncoder
void LoadNvEncApi();
/**
- * @brief This is a private function which is used to submit the encode
- * commands to the NVENC hardware.
+ * @brief This is a private function which is used to get the output packets
+ * from the encoder HW.
+ * This is called by DoEncode() function. If there is buffering enabled,
+ * this may return without any output data.
*/
- void DoEncode(NV_ENC_INPUT_PTR inputBuffer, std::vector> &vPacket, NV_ENC_PIC_PARAMS *pPicParams);
+ std::size_t GetEncodedPacket(std::vector &vOutputBuffer, std::vector &vPacket, bool bOutputDelay);
/**
- * @brief This is a private function which is used to submit the encode
- * commands to the NVENC hardware for ME only mode.
+ * @brief This is a private function which is used to initialize the bitstream buffers.
+ * This is only used in the encoding mode.
*/
- void DoMotionEstimation(NV_ENC_INPUT_PTR inputBuffer, NV_ENC_INPUT_PTR referenceFrame, std::vector &mvData);
+ void InitializeBitstreamBuffer();
/**
- * @brief This is a private function which is used to get the output packets
- * from the encoder HW.
- * This is called by DoEncode() function. If there is buffering enabled,
- * this may return without any output data.
+ * @brief This is a private function which is used to destroy the bitstream buffers.
+ * This is only used in the encoding mode.
*/
- void GetEncodedPacket(std::vector &vOutputBuffer, std::vector> &vPacket, bool bOutputDelay);
+ void DestroyBitstreamBuffer();
/**
* @brief This is a private function which is used to initialize MV output buffers.
@@ -349,6 +424,11 @@ class NvEncoder
*/
void DestroyHWEncoder();
+ /**
+ * @brief This function is used to flush the encoder queue.
+ */
+ void FlushEncoder();
+
private:
/**
* @brief This is a pure virtual function which is used to allocate input buffers.
@@ -364,32 +444,45 @@ class NvEncoder
protected:
bool m_bMotionEstimationOnly = false;
+ bool m_bOutputInVideoMemory = false;
+ bool m_bIsDX12Encode = false;
void *m_hEncoder = nullptr;
NV_ENCODE_API_FUNCTION_LIST m_nvenc;
+ NV_ENC_INITIALIZE_PARAMS m_initializeParams = {};
std::vector m_vInputFrames;
std::vector m_vRegisteredResources;
std::vector m_vReferenceFrames;
std::vector m_vRegisteredResourcesForReference;
-private:
+ std::vector m_vMappedInputBuffers;
+ std::vector m_vMappedRefBuffers;
+ std::vector m_vpCompletionEvent;
+
+ int32_t m_iToSend = 0;
+ int32_t m_iGot = 0;
+ int32_t m_nEncoderBuffer = 0;
+ int32_t m_nOutputDelay = 0;
+ IVFUtils m_IVFUtils;
+ bool m_bWriteIVFFileHeader = true;
+ bool m_bUseIVFContainer = true;
+ std::vector m_vBitstreamOutputBuffer;
uint32_t m_nWidth;
uint32_t m_nHeight;
NV_ENC_BUFFER_FORMAT m_eBufferFormat;
- void *m_pDevice;
- NV_ENC_DEVICE_TYPE m_eDeviceType;
- NV_ENC_INITIALIZE_PARAMS m_initializeParams = {};
NV_ENC_CONFIG m_encodeConfig = {};
bool m_bEncoderInitialized = false;
- uint32_t m_nExtraOutputDelay = 3;
- std::vector m_vMappedInputBuffers;
- std::vector m_vMappedRefBuffers;
- std::vector m_vBitstreamOutputBuffer;
- std::vector m_vMVDataOutputBuffer;
- std::vector m_vpCompletionEvent;
+ uint32_t m_nExtraOutputDelay = 3; // To ensure encode and graphics can work in parallel, m_nExtraOutputDelay should be set to at least 1
+
+
uint32_t m_nMaxEncodeWidth = 0;
uint32_t m_nMaxEncodeHeight = 0;
+private:
+ uint32_t m_enableStereoMVHEVC = 0;
+ uint32_t m_viewId = 0;
+ uint32_t m_outputHevc3DReferenceDisplayInfo = 0;
+ uint64_t m_nInputTimeStamp = 0;
+ void *m_pDevice;
+ NV_ENC_DEVICE_TYPE m_eDeviceType;
+ std::vector m_vMVDataOutputBuffer;
+
void* m_hModule = nullptr;
- int32_t m_iToSend = 0;
- int32_t m_iGot = 0;
- int32_t m_nEncoderBuffer = 0;
- int32_t m_nOutputDelay = 0;
};
diff --git a/alvr/server/cpp/platform/win32/NvEncoderD3D11.cpp b/alvr/server/cpp/platform/win32/NvEncoderD3D11.cpp
index 3d07f015d8..64e78cc4b1 100644
--- a/alvr/server/cpp/platform/win32/NvEncoderD3D11.cpp
+++ b/alvr/server/cpp/platform/win32/NvEncoderD3D11.cpp
@@ -1,15 +1,34 @@
/*
-* Copyright 2017-2018 NVIDIA Corporation. All rights reserved.
-*
-* Please refer to the NVIDIA end user license agreement (EULA) associated
-* with this source code for terms and conditions that govern your use of
-* this software. Any use, reproduction, disclosure, or distribution of
-* this software and related documentation outside the terms of the EULA
-* is strictly prohibited.
-*
-*/
-
-
+ * This copyright notice applies to this header file only:
+ *
+ * Copyright (c) 2010-2024 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the software, and to permit persons to whom the
+ * software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef _WIN32
+#include
+#endif
#include "NvEncoderD3D11.h"
#include
@@ -35,8 +54,8 @@ DXGI_FORMAT GetD3D11Format(NV_ENC_BUFFER_FORMAT eBufferFormat)
}
NvEncoderD3D11::NvEncoderD3D11(ID3D11Device* pD3D11Device, uint32_t nWidth, uint32_t nHeight,
- NV_ENC_BUFFER_FORMAT eBufferFormat, uint32_t nExtraOutputDelay, bool bMotionEstimationOnly) :
- NvEncoder(NV_ENC_DEVICE_TYPE_DIRECTX, pD3D11Device, nWidth, nHeight, eBufferFormat, nExtraOutputDelay, bMotionEstimationOnly)
+ NV_ENC_BUFFER_FORMAT eBufferFormat, uint32_t nExtraOutputDelay, bool bMotionEstimationOnly, bool bOutputInVideoMemory) :
+ NvEncoder(NV_ENC_DEVICE_TYPE_DIRECTX, pD3D11Device, nWidth, nHeight, eBufferFormat, nExtraOutputDelay, bMotionEstimationOnly, bOutputInVideoMemory)
{
if (!pD3D11Device)
{
@@ -96,7 +115,7 @@ void NvEncoderD3D11::AllocateInputBuffers(int32_t numInputBuffers)
}
inputFrames.push_back(pInputTextures);
}
- RegisterResources(inputFrames, NV_ENC_INPUT_RESOURCE_TYPE_DIRECTX,
+ RegisterInputResources(inputFrames, NV_ENC_INPUT_RESOURCE_TYPE_DIRECTX,
GetMaxEncodeWidth(), GetMaxEncodeHeight(), 0, GetPixelFormat(), count == 1 ? true : false);
}
}
@@ -113,7 +132,7 @@ void NvEncoderD3D11::ReleaseD3D11Resources()
return;
}
- UnregisterResources();
+ UnregisterInputResources();
for (uint32_t i = 0; i < m_vInputFrames.size(); ++i)
{
diff --git a/alvr/server/cpp/platform/win32/NvEncoderD3D11.h b/alvr/server/cpp/platform/win32/NvEncoderD3D11.h
index 7acbdc97b9..1eab46633e 100644
--- a/alvr/server/cpp/platform/win32/NvEncoderD3D11.h
+++ b/alvr/server/cpp/platform/win32/NvEncoderD3D11.h
@@ -1,13 +1,29 @@
/*
-* Copyright 2017-2018 NVIDIA Corporation. All rights reserved.
-*
-* Please refer to the NVIDIA end user license agreement (EULA) associated
-* with this source code for terms and conditions that govern your use of
-* this software. Any use, reproduction, disclosure, or distribution of
-* this software and related documentation outside the terms of the EULA
-* is strictly prohibited.
-*
-*/
+ * This copyright notice applies to this header file only:
+ *
+ * Copyright (c) 2010-2024 NVIDIA Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the software, and to permit persons to whom the
+ * software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
#pragma once
@@ -22,8 +38,16 @@ class NvEncoderD3D11 : public NvEncoder
{
public:
NvEncoderD3D11(ID3D11Device* pD3D11Device, uint32_t nWidth, uint32_t nHeight, NV_ENC_BUFFER_FORMAT eBufferFormat,
- uint32_t nExtraOutputDelay = 3, bool bMotionEstimationOnly = false);
+ uint32_t nExtraOutputDelay = 3, bool bMotionEstimationOnly = false, bool bOPInVideoMemory = false);
virtual ~NvEncoderD3D11();
+
+protected:
+ /**
+ * @brief This function is used to release the input buffers allocated for encoding.
+ * This function is an override of virtual function NvEncoder::ReleaseInputBuffers().
+ */
+ virtual void ReleaseInputBuffers() override;
+
private:
/**
* @brief This function is used to allocate input buffers for encoding.
@@ -33,17 +57,15 @@ class NvEncoderD3D11 : public NvEncoder
*/
virtual void AllocateInputBuffers(int32_t numInputBuffers) override;
- /**
- * @brief This function is used to release the input buffers allocated for encoding.
- * This function is an override of virtual function NvEncoder::ReleaseInputBuffers().
- */
- virtual void ReleaseInputBuffers() override;
private:
/**
* @brief This is a private function to release ID3D11Texture2D textures used for encoding.
*/
void ReleaseD3D11Resources();
-private:
+
+protected:
ID3D11Device *m_pD3D11Device = nullptr;
+
+private:
ID3D11DeviceContext* m_pD3D11DeviceContext = nullptr;
};
diff --git a/alvr/server/cpp/platform/win32/OvrDirectModeComponent.cpp b/alvr/server/cpp/platform/win32/OvrDirectModeComponent.cpp
index 51cf2346db..2642fbb2c6 100644
--- a/alvr/server/cpp/platform/win32/OvrDirectModeComponent.cpp
+++ b/alvr/server/cpp/platform/win32/OvrDirectModeComponent.cpp
@@ -20,19 +20,24 @@ void OvrDirectModeComponent::CreateSwapTextureSet(uint32_t unPid, const SwapText
//HRESULT hr = D3D11CreateDevice(pAdapter, D3D_DRIVER_TYPE_HARDWARE, NULL, creationFlags, NULL, 0, D3D11_SDK_VERSION, &pDevice, &eFeatureLevel, &pContext);
D3D11_TEXTURE2D_DESC SharedTextureDesc = {};
+ DXGI_FORMAT format = (DXGI_FORMAT)pSwapTextureSetDesc->nFormat;
+ SharedTextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
+ if (format == DXGI_FORMAT_R32G8X24_TYPELESS || format == DXGI_FORMAT_R32_TYPELESS) {
+ SharedTextureDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+ }
SharedTextureDesc.ArraySize = 1;
SharedTextureDesc.MipLevels = 1;
- SharedTextureDesc.SampleDesc.Count = pSwapTextureSetDesc->nSampleCount;
+ SharedTextureDesc.SampleDesc.Count
+ = pSwapTextureSetDesc->nSampleCount == 0 ? 1 : pSwapTextureSetDesc->nSampleCount;
SharedTextureDesc.SampleDesc.Quality = 0;
SharedTextureDesc.Usage = D3D11_USAGE_DEFAULT;
- SharedTextureDesc.Format = (DXGI_FORMAT)pSwapTextureSetDesc->nFormat;
+ SharedTextureDesc.Format = format;
// Some(or all?) applications request larger texture than we specified in GetRecommendedRenderTargetSize.
// But, we must create textures in requested size to prevent cropped output. And then we must shrink texture to H.264 movie size.
SharedTextureDesc.Width = pSwapTextureSetDesc->nWidth;
SharedTextureDesc.Height = pSwapTextureSetDesc->nHeight;
- SharedTextureDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
//SharedTextureDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX | D3D11_RESOURCE_MISC_SHARED_NTHANDLE;
SharedTextureDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED;
@@ -42,12 +47,28 @@ void OvrDirectModeComponent::CreateSwapTextureSet(uint32_t unPid, const SwapText
for (int i = 0; i < 3; i++) {
HRESULT hr = m_pD3DRender->GetDevice()->CreateTexture2D(&SharedTextureDesc, NULL, &processResource->textures[i]);
//LogDriver("texture%d %p res:%d %s", i, texture[i], hr, GetDxErrorStr(hr).c_str());
+ if (FAILED(hr)) {
+ Error("CreateSwapTextureSet CreateTexture2D %p %ls\n", hr, GetErrorStr(hr).c_str());
+ delete processResource;
+ break;
+ }
IDXGIResource* pResource;
hr = processResource->textures[i]->QueryInterface(__uuidof(IDXGIResource), (void**)&pResource);
+ if (FAILED(hr)) {
+ Error("CreateSwapTextureSet QueryInterface %p %ls\n", hr, GetErrorStr(hr).c_str());
+ delete processResource;
+ break;
+ }
//LogDriver("QueryInterface %p res:%d %s", pResource, hr, GetDxErrorStr(hr).c_str());
hr = pResource->GetSharedHandle(&processResource->sharedHandles[i]);
+ if (FAILED(hr)) {
+ Error("CreateSwapTextureSet GetSharedHandle %p %ls\n", hr, GetErrorStr(hr).c_str());
+ delete processResource;
+ pResource->Release();
+ break;
+ }
//LogDriver("GetSharedHandle %p res:%d %s", processResource->sharedHandles[i], hr, GetDxErrorStr(hr).c_str());
m_handleMap.insert(std::make_pair(processResource->sharedHandles[i], std::make_pair(processResource, i)));
@@ -140,10 +161,10 @@ void OvrDirectModeComponent::SubmitLayer(const SubmitLayerPerEye_t(&perEye)[2])
m_targetTimestampNs = pose->info.targetTimestampNs;
m_prevFramePoseRotation = m_framePoseRotation;
- m_framePoseRotation.x = pose->info.HeadPose_Pose_Orientation.x;
- m_framePoseRotation.y = pose->info.HeadPose_Pose_Orientation.y;
- m_framePoseRotation.z = pose->info.HeadPose_Pose_Orientation.z;
- m_framePoseRotation.w = pose->info.HeadPose_Pose_Orientation.w;
+ m_framePoseRotation.x = pose->info.headPose.orientation.x;
+ m_framePoseRotation.y = pose->info.headPose.orientation.y;
+ m_framePoseRotation.z = pose->info.headPose.orientation.z;
+ m_framePoseRotation.w = pose->info.headPose.orientation.w;
Debug("Frame pose found. m_prevSubmitFrameIndex=%llu m_submitFrameIndex=%llu\n", m_prevTargetTimestampNs, m_targetTimestampNs);
}
@@ -161,11 +182,6 @@ void OvrDirectModeComponent::SubmitLayer(const SubmitLayerPerEye_t(&perEye)[2])
Warn("Too many layers submitted!\n");
}
- if (Settings::Instance().m_DriverTestMode & 8) {
- // Crash test
- *(char*)0 = 1;
- }
-
//CopyTexture();
}
@@ -230,7 +246,7 @@ void OvrDirectModeComponent::Present(vr::SharedTextureHandle_t syncTexture)
void OvrDirectModeComponent::CopyTexture(uint32_t layerCount) {
- uint64_t presentationTime = GetTimestampUs();
+ const std::uint64_t presentationTime = GetSystemTimestampUs();
ID3D11Texture2D *pTexture[MAX_LAYERS][2];
ComPtr Texture[MAX_LAYERS][2];
@@ -271,7 +287,9 @@ void OvrDirectModeComponent::CopyTexture(uint32_t layerCount) {
}
// This can go away, but is useful to see it as a separate packet on the gpu in traces.
+#ifndef NDEBUG
m_pD3DRender->GetContext()->Flush();
+#endif
if (m_pEncoder) {
Debug("Waiting for finish of previous encode.\n");
@@ -289,6 +307,9 @@ void OvrDirectModeComponent::CopyTexture(uint32_t layerCount) {
// Copy entire texture to staging so we can read the pixels to send to remote device.
m_pEncoder->CopyToStaging(pTexture, bounds, layerCount,false, presentationTime, submitFrameIndex,"", debugText);
+// CopyToStaging invokes RenderFrame which already does a pipeline flush.
+#ifndef NDEBUG
m_pD3DRender->GetContext()->Flush();
+#endif
}
}
diff --git a/alvr/server/cpp/platform/win32/QuadVertexShader.cso b/alvr/server/cpp/platform/win32/QuadVertexShader.cso
index ed98dd5cec..4aff7df528 100644
Binary files a/alvr/server/cpp/platform/win32/QuadVertexShader.cso and b/alvr/server/cpp/platform/win32/QuadVertexShader.cso differ
diff --git a/alvr/server/cpp/platform/win32/VideoEncoder.h b/alvr/server/cpp/platform/win32/VideoEncoder.h
index 96faf71fc1..d4a2a7c146 100644
--- a/alvr/server/cpp/platform/win32/VideoEncoder.h
+++ b/alvr/server/cpp/platform/win32/VideoEncoder.h
@@ -8,6 +8,7 @@
class VideoEncoder
{
public:
+ virtual ~VideoEncoder(){}
virtual void Initialize() = 0;
virtual void Shutdown() = 0;
diff --git a/alvr/server/cpp/platform/win32/VideoEncoderNVENC.cpp b/alvr/server/cpp/platform/win32/VideoEncoderNVENC.cpp
index d4d1ed684e..08e24a8ec7 100644
--- a/alvr/server/cpp/platform/win32/VideoEncoderNVENC.cpp
+++ b/alvr/server/cpp/platform/win32/VideoEncoderNVENC.cpp
@@ -1,7 +1,5 @@
-
#include "VideoEncoderNVENC.h"
#include "NvCodecUtils.h"
-#include "alvr_server/nvencoderclioptions.h"
#include "alvr_server/Statistics.h"
#include "alvr_server/Logger.h"
@@ -12,7 +10,6 @@ VideoEncoderNVENC::VideoEncoderNVENC(std::shared_ptr pD3DRender
, std::shared_ptr listener
, int width, int height)
: m_pD3DRender(pD3DRender)
- , m_nFrame(0)
, m_Listener(listener)
, m_codec(Settings::Instance().m_codec)
, m_refreshRate(Settings::Instance().m_refreshRate)
@@ -51,12 +48,11 @@ void VideoEncoderNVENC::Initialize()
NV_ENC_CONFIG encodeConfig = { NV_ENC_CONFIG_VER };
initializeParams.encodeConfig = &encodeConfig;
- FillEncodeConfig(initializeParams, m_refreshRate, m_renderWidth, m_renderHeight, m_bitrateInMBits * 1'000'000);
+ FillEncodeConfig(initializeParams, m_refreshRate, m_renderWidth, m_renderHeight, m_bitrateInMBits * 1'000'000L);
-
try {
m_NvNecoder->CreateEncoder(&initializeParams);
- }
+ }
catch (NVENCException e) {
if (e.getErrorCode() == NV_ENC_ERR_INVALID_PARAM) {
throw MakeException("This GPU does not support H.265 encoding. (NvEncoderCuda NV_ENC_ERR_INVALID_PARAM)");
@@ -69,16 +65,18 @@ void VideoEncoderNVENC::Initialize()
void VideoEncoderNVENC::Shutdown()
{
- std::vector> vPacket;
+ m_vPacket.clear();
if(m_NvNecoder)
- m_NvNecoder->EndEncode(vPacket);
+ m_NvNecoder->EndEncode(m_vPacket);
- for (std::vector &packet : vPacket)
+#ifndef NDEBUG
+ for (const auto &packet : m_vPacket)
{
if (fpOut) {
- fpOut.write(reinterpret_cast(packet.data()), packet.size());
+ fpOut.write(reinterpret_cast(packet.frame.data()), packet.frame.size());
}
}
+#endif
if (m_NvNecoder) {
m_NvNecoder->DestroyEncoder();
m_NvNecoder.reset();
@@ -99,37 +97,37 @@ void VideoEncoderNVENC::Transmit(ID3D11Texture2D *pTexture, uint64_t presentatio
NV_ENC_INITIALIZE_PARAMS initializeParams = { NV_ENC_INITIALIZE_PARAMS_VER };
NV_ENC_CONFIG encodeConfig = { NV_ENC_CONFIG_VER };
initializeParams.encodeConfig = &encodeConfig;
- FillEncodeConfig(initializeParams, m_refreshRate, m_renderWidth, m_renderHeight, m_bitrateInMBits * 1'000'000);
+ FillEncodeConfig(initializeParams, m_refreshRate, m_renderWidth, m_renderHeight, m_bitrateInMBits * 1'000'000L);
NV_ENC_RECONFIGURE_PARAMS reconfigureParams = { NV_ENC_RECONFIGURE_PARAMS_VER };
reconfigureParams.reInitEncodeParams = initializeParams;
m_NvNecoder->Reconfigure(&reconfigureParams);
}
}
- std::vector> vPacket;
-
const NvEncInputFrame* encoderInputFrame = m_NvNecoder->GetNextInputFrame();
ID3D11Texture2D *pInputTexture = reinterpret_cast(encoderInputFrame->inputPtr);
m_pD3DRender->GetContext()->CopyResource(pInputTexture, pTexture);
- NV_ENC_PIC_PARAMS picParams = {};
+ NV_ENC_PIC_PARAMS picParams = {NV_ENC_PIC_PARAMS_VER};
if (insertIDR) {
Debug("Inserting IDR frame.\n");
picParams.encodePicFlags = NV_ENC_PIC_FLAG_FORCEIDR;
}
- m_NvNecoder->EncodeFrame(vPacket, &picParams);
+ const std::size_t packetCount = m_NvNecoder->EncodeFrame(m_vPacket, &picParams);
if (m_Listener) {
- m_Listener->GetStatistics()->EncodeOutput(GetTimestampUs() - presentationTime);
+ m_Listener->GetStatistics()->EncodeOutput(GetSystemTimestampUs() - presentationTime);
}
- m_nFrame += (int)vPacket.size();
- for (std::vector &packet : vPacket)
+ for (std::size_t packetIndex = 0; packetIndex < packetCount; ++packetIndex)
{
+ const auto& packet = m_vPacket[packetIndex].frame;
+#ifndef NDEBUG
if (fpOut) {
- fpOut.write(reinterpret_cast(packet.data()), packet.size());
+ fpOut.write(reinterpret_cast(packet.data()), packet.size());
}
+#endif
if (m_Listener) {
m_Listener->SendVideo(packet.data(), (int)packet.size(), targetTimestampNs);
}
@@ -139,86 +137,163 @@ void VideoEncoderNVENC::Transmit(ID3D11Texture2D *pTexture, uint64_t presentatio
void VideoEncoderNVENC::FillEncodeConfig(NV_ENC_INITIALIZE_PARAMS &initializeParams, int refreshRate, int renderWidth, int renderHeight, uint64_t bitrateBits)
{
auto &encodeConfig = *initializeParams.encodeConfig;
- GUID EncoderGUID = m_codec == ALVR_CODEC_H264 ? NV_ENC_CODEC_H264_GUID : NV_ENC_CODEC_HEVC_GUID;
-
- // According to the docment, NVIDIA Video Encoder (NVENC) Interface 8.1,
- // following configrations are recommended for low latency application:
- // 1. Low-latency high quality preset
- // 2. Rate control mode = CBR
- // 3. Very low VBV buffer size(single frame)
- // 4. No B Frames
- // 5. Infinite GOP length
- // 6. Long term reference pictures
- // 7. Intra refresh
- // 8. Adaptive quantization(AQ) enabled
+ GUID encoderGUID = m_codec == ALVR_CODEC_H264 ? NV_ENC_CODEC_H264_GUID : NV_ENC_CODEC_HEVC_GUID;
+
+ // See recommended NVENC settings for low-latency encoding.
+ // https://docs.nvidia.com/video-technologies/video-codec-sdk/nvenc-video-encoder-api-prog-guide/#recommended-nvenc-settings
+ GUID qualityPreset = NV_ENC_PRESET_P1_GUID;
+ if (Settings::Instance().m_encoderQualityPreset == ALVR_QUALITY) {
+ qualityPreset = NV_ENC_PRESET_P7_GUID;
+ } else if (Settings::Instance().m_encoderQualityPreset == ALVR_BALANCED) {
+ qualityPreset = NV_ENC_PRESET_P4_GUID;
+ } else if (Settings::Instance().m_encoderQualityPreset == ALVR_SPEED) {
+ qualityPreset = NV_ENC_PRESET_P1_GUID;
+ }
+ NV_ENC_TUNING_INFO tuningPreset = static_cast(Settings::Instance().m_nvencTuningPreset);
- m_NvNecoder->CreateDefaultEncoderParams(&initializeParams, EncoderGUID, NV_ENC_PRESET_LOW_LATENCY_HQ_GUID);
+ m_NvNecoder->CreateDefaultEncoderParams(&initializeParams, encoderGUID, qualityPreset, tuningPreset);
initializeParams.encodeWidth = initializeParams.darWidth = renderWidth;
initializeParams.encodeHeight = initializeParams.darHeight = renderHeight;
initializeParams.frameRateNum = refreshRate;
initializeParams.frameRateDen = 1;
+ initializeParams.splitEncodeMode = NV_ENC_SPLIT_AUTO_MODE;
- // Use reference frame invalidation to faster recovery from frame loss if supported.
- mSupportsReferenceFrameInvalidation = m_NvNecoder->GetCapabilityValue(EncoderGUID, NV_ENC_CAPS_SUPPORT_REF_PIC_INVALIDATION);
- bool supportsIntraRefresh = m_NvNecoder->GetCapabilityValue(EncoderGUID, NV_ENC_CAPS_SUPPORT_INTRA_REFRESH);
- Debug("VideoEncoderNVENC: SupportsReferenceFrameInvalidation: %d\n", mSupportsReferenceFrameInvalidation);
- Debug("VideoEncoderNVENC: SupportsIntraRefresh: %d\n", supportsIntraRefresh);
+ if (Settings::Instance().m_nvencRefreshRate != -1) {
+ initializeParams.frameRateNum = Settings::Instance().m_nvencRefreshRate;
+ }
+
+ initializeParams.enableWeightedPrediction = Settings::Instance().m_nvencEnableWeightedPrediction;
// 16 is recommended when using reference frame invalidation. But it has caused bad visual quality.
// Now, use 0 (use default).
- int maxNumRefFrames = 0;
+ uint32_t maxNumRefFrames = 0;
+ uint32_t gopLength = NVENC_INFINITE_GOPLENGTH;
+
+ if (Settings::Instance().m_nvencMaxNumRefFrames != -1) {
+ maxNumRefFrames = Settings::Instance().m_nvencMaxNumRefFrames;
+ }
+ if (Settings::Instance().m_nvencGopLength != -1) {
+ gopLength = Settings::Instance().m_nvencGopLength;
+ }
+
+ const auto setVUIParameters = [](auto& vuiParams) {
+ const uint32_t colorRangeFull = Settings::Instance().IsColorRangeItuFull();
+ Info("ColorRange-Full: %u", colorRangeFull);
+ vuiParams.videoSignalTypePresentFlag = 1;
+ vuiParams.videoFormat = NV_ENC_VUI_VIDEO_FORMAT_UNSPECIFIED;
+ vuiParams.videoFullRangeFlag = colorRangeFull;
+ vuiParams.colourDescriptionPresentFlag = 1;
+ vuiParams.colourPrimaries = NV_ENC_VUI_COLOR_PRIMARIES_BT709;
+ vuiParams.transferCharacteristics = NV_ENC_VUI_TRANSFER_CHARACTERISTIC_SRGB;
+ vuiParams.colourMatrix = NV_ENC_VUI_MATRIX_COEFFS_BT709;
+ };
if (m_codec == ALVR_CODEC_H264) {
auto &config = encodeConfig.encodeCodecConfig.h264Config;
config.repeatSPSPPS = 1;
- //if (supportsIntraRefresh) {
- // config.enableIntraRefresh = 1;
- // // Do intra refresh every 10sec.
- // config.intraRefreshPeriod = refreshRate * 10;
- // config.intraRefreshCnt = refreshRate;
- //}
+ config.enableIntraRefresh = Settings::Instance().m_nvencEnableIntraRefresh;
+
+ if (Settings::Instance().m_nvencIntraRefreshPeriod != -1) {
+ config.intraRefreshPeriod = Settings::Instance().m_nvencIntraRefreshPeriod;
+ }
+ if (Settings::Instance().m_nvencIntraRefreshCount != -1) {
+ config.intraRefreshCnt = Settings::Instance().m_nvencIntraRefreshCount;
+ }
+
+ switch (Settings::Instance().m_entropyCoding) {
+ case ALVR_CABAC:
+ config.entropyCodingMode = NV_ENC_H264_ENTROPY_CODING_MODE_CABAC;
+ break;
+ case ALVR_CAVLC:
+ config.entropyCodingMode = NV_ENC_H264_ENTROPY_CODING_MODE_CAVLC;
+ break;
+ }
+
config.maxNumRefFrames = maxNumRefFrames;
- config.idrPeriod = NVENC_INFINITE_GOPLENGTH;
- }
+ config.idrPeriod = gopLength;
+
+ if (Settings::Instance().m_fillerData) {
+ config.enableFillerDataInsertion = Settings::Instance().m_rateControlMode == ALVR_CBR;
+ }
+
+ setVUIParameters(config.h264VUIParameters);
+ }
else {
auto &config = encodeConfig.encodeCodecConfig.hevcConfig;
config.repeatSPSPPS = 1;
- //if (supportsIntraRefresh) {
- // config.enableIntraRefresh = 1;
- // // Do intra refresh every 10sec.
- // config.intraRefreshPeriod = refreshRate * 10;
- // config.intraRefreshCnt = refreshRate;
- //}
+ config.enableIntraRefresh = Settings::Instance().m_nvencEnableIntraRefresh;
+
+ if (Settings::Instance().m_nvencIntraRefreshPeriod != -1) {
+ config.intraRefreshPeriod = Settings::Instance().m_nvencIntraRefreshPeriod;
+ }
+ if (Settings::Instance().m_nvencIntraRefreshCount != -1) {
+ config.intraRefreshCnt = Settings::Instance().m_nvencIntraRefreshCount;
+ }
+
config.maxNumRefFramesInDPB = maxNumRefFrames;
- config.idrPeriod = NVENC_INFINITE_GOPLENGTH;
- }
+ config.idrPeriod = gopLength;
- // According to the document, NVIDIA Video Encoder Interface 5.0,
- // following configrations are recommended for low latency application:
- // 1. NV_ENC_PARAMS_RC_2_PASS_FRAMESIZE_CAP rate control mode.
- // 2. Set vbvBufferSize and vbvInitialDelay to maxFrameSize.
- // 3. Inifinite GOP length.
- // NV_ENC_PARAMS_RC_2_PASS_FRAMESIZE_CAP also assures maximum frame size,
- // which introduces lower transport latency and fewer packet losses.
+ if (Settings::Instance().m_use10bitEncoder) {
+ encodeConfig.encodeCodecConfig.hevcConfig.inputBitDepth = encodeConfig.encodeCodecConfig.hevcConfig.outputBitDepth = NV_ENC_BIT_DEPTH_10;
+ }
+
+ if (Settings::Instance().m_fillerData) {
+ config.enableFillerDataInsertion = Settings::Instance().m_rateControlMode == ALVR_CBR;
+ }
+
+ setVUIParameters(config.hevcVUIParameters);
+ }
// Disable automatic IDR insertion by NVENC. We need to manually insert IDR when packet is dropped
// if don't use reference frame invalidation.
- encodeConfig.gopLength = NVENC_INFINITE_GOPLENGTH;
+ encodeConfig.gopLength = gopLength;
encodeConfig.frameIntervalP = 1;
- // NV_ENC_PARAMS_RC_CBR_HQ is equivalent to NV_ENC_PARAMS_RC_2_PASS_FRAMESIZE_CAP.
- //encodeConfig.rcParams.rateControlMode = NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ;// NV_ENC_PARAMS_RC_CBR_HQ;
- encodeConfig.rcParams.rateControlMode = NV_ENC_PARAMS_RC_CBR_LOWDELAY_HQ;
+ if (Settings::Instance().m_nvencPFrameStrategy != -1) {
+ encodeConfig.frameIntervalP = Settings::Instance().m_nvencPFrameStrategy;
+ }
+
+ switch (Settings::Instance().m_rateControlMode) {
+ case ALVR_CBR:
+ encodeConfig.rcParams.rateControlMode = NV_ENC_PARAMS_RC_CBR;
+ break;
+ case ALVR_VBR:
+ encodeConfig.rcParams.rateControlMode = NV_ENC_PARAMS_RC_VBR;
+ break;
+ }
+ encodeConfig.rcParams.multiPass = static_cast(Settings::Instance().m_nvencMultiPass);
+ encodeConfig.rcParams.lowDelayKeyFrameScale = 1;
+
+ if (Settings::Instance().m_nvencLowDelayKeyFrameScale != -1) {
+ encodeConfig.rcParams.lowDelayKeyFrameScale = Settings::Instance().m_nvencLowDelayKeyFrameScale;
+ }
+
uint32_t maxFrameSize = static_cast(bitrateBits / refreshRate);
Debug("VideoEncoderNVENC: maxFrameSize=%d bits\n", maxFrameSize);
- encodeConfig.rcParams.vbvBufferSize = maxFrameSize;
- encodeConfig.rcParams.vbvInitialDelay = maxFrameSize;
+ encodeConfig.rcParams.vbvBufferSize = maxFrameSize * 1.1;
+ encodeConfig.rcParams.vbvInitialDelay = maxFrameSize * 1.1;
encodeConfig.rcParams.maxBitRate = static_cast(bitrateBits);
encodeConfig.rcParams.averageBitRate = static_cast(bitrateBits);
-
- if (Settings::Instance().m_use10bitEncoder) {
+ if (Settings::Instance().m_nvencAdaptiveQuantizationMode == SpatialAQ) {
encodeConfig.rcParams.enableAQ = 1;
- encodeConfig.encodeCodecConfig.hevcConfig.pixelBitDepthMinus8 = 2;
+ } else if (Settings::Instance().m_nvencAdaptiveQuantizationMode == TemporalAQ) {
+ encodeConfig.rcParams.enableTemporalAQ = 1;
+ }
+
+ if (Settings::Instance().m_nvencRateControlMode != -1) {
+ encodeConfig.rcParams.rateControlMode = (NV_ENC_PARAMS_RC_MODE)Settings::Instance().m_nvencRateControlMode;
+ }
+ if (Settings::Instance().m_nvencRcBufferSize != -1) {
+ encodeConfig.rcParams.vbvBufferSize = Settings::Instance().m_nvencRcBufferSize;
+ }
+ if (Settings::Instance().m_nvencRcInitialDelay != -1) {
+ encodeConfig.rcParams.vbvInitialDelay = Settings::Instance().m_nvencRcInitialDelay;
+ }
+ if (Settings::Instance().m_nvencRcMaxBitrate != -1) {
+ encodeConfig.rcParams.maxBitRate = Settings::Instance().m_nvencRcMaxBitrate;
+ }
+ if (Settings::Instance().m_nvencRcAverageBitrate != -1) {
+ encodeConfig.rcParams.averageBitRate = Settings::Instance().m_nvencRcAverageBitrate;
}
}
\ No newline at end of file
diff --git a/alvr/server/cpp/platform/win32/VideoEncoderNVENC.h b/alvr/server/cpp/platform/win32/VideoEncoderNVENC.h
index e25a0ad8f4..4143a5b39c 100644
--- a/alvr/server/cpp/platform/win32/VideoEncoderNVENC.h
+++ b/alvr/server/cpp/platform/win32/VideoEncoderNVENC.h
@@ -6,6 +6,11 @@
#include "VideoEncoder.h"
#include "NvEncoderD3D11.h"
+enum AdaptiveQuantizationMode {
+ SpatialAQ = 1,
+ TemporalAQ = 2
+};
+
// Video encoder for NVIDIA NvEnc.
class VideoEncoderNVENC : public VideoEncoder
{
@@ -27,11 +32,10 @@ class VideoEncoderNVENC : public VideoEncoder
std::shared_ptr m_NvNecoder;
std::shared_ptr m_pD3DRender;
- int m_nFrame;
std::shared_ptr m_Listener;
-
- bool mSupportsReferenceFrameInvalidation = false;
+
+ std::vector m_vPacket{};
int m_codec;
int m_refreshRate;
diff --git a/alvr/server/cpp/platform/win32/VideoEncoderSW.cpp b/alvr/server/cpp/platform/win32/VideoEncoderSW.cpp
index 93b6e5fd20..8cf8697285 100644
--- a/alvr/server/cpp/platform/win32/VideoEncoderSW.cpp
+++ b/alvr/server/cpp/platform/win32/VideoEncoderSW.cpp
@@ -59,7 +59,15 @@ void VideoEncoderSW::Initialize() {
av_dict_set(&opt, "tune", "zerolatency", 0);
switch (m_codec) {
case ALVR_CODEC_H264:
- m_codecContext->profile = Settings::Instance().m_use10bitEncoder ? AV_PROFILE_H264_HIGH_10 : AV_PROFILE_H264_HIGH;
+ m_codecContext->profile = Settings::Instance().m_use10bitEncoder ? AV_PROFILE_H264_HIGH_10_INTRA : (AV_PROFILE_H264_HIGH | AV_PROFILE_H264_INTRA);
+ switch (Settings::Instance().m_entropyCoding) {
+ case ALVR_CABAC:
+ av_dict_set(&opt, "coder", "ac", 0);
+ break;
+ case ALVR_CAVLC:
+ av_dict_set(&opt, "coder", "vlc", 0);
+ break;
+ }
break;
case ALVR_CODEC_H265:
m_codecContext->profile = Settings::Instance().m_use10bitEncoder ? AV_PROFILE_HEVC_MAIN_10 : AV_PROFILE_HEVC_MAIN;
@@ -73,7 +81,21 @@ void VideoEncoderSW::Initialize() {
m_codecContext->sample_aspect_ratio = AVRational{1, 1};
m_codecContext->pix_fmt = Settings::Instance().m_use10bitEncoder ? AV_PIX_FMT_YUV420P10LE : AV_PIX_FMT_YUV420P;
m_codecContext->max_b_frames = 0;
- m_codecContext->bit_rate = Settings::Instance().mEncodeBitrateMBs * 1000 * 1000;
+ m_codecContext->color_range = Settings::Instance().IsColorRangeItuFull() ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
+ m_codecContext->gop_size = 0;
+ m_codecContext->bit_rate = Settings::Instance().mEncodeBitrateMBs * 1'000'000L;
+ m_codecContext->rc_buffer_size = m_codecContext->bit_rate / Settings::Instance().m_refreshRate * 1.1;
+ switch (Settings::Instance().m_rateControlMode) {
+ case ALVR_CBR:
+ if (Settings::Instance().m_fillerData) {
+ av_dict_set(&opt, "nal-hrd", "cbr", 0);
+ }
+ break;
+ case ALVR_VBR:
+ av_dict_set(&opt, "nal-hrd", "vbr", 0);
+ break;
+ }
+ m_codecContext->rc_max_rate = m_codecContext->bit_rate;
m_codecContext->thread_count = Settings::Instance().m_swThreadCount;
if((err = avcodec_open2(m_codecContext, codec, &opt))) throw MakeException("Cannot open video encoder codec: %d", err);
@@ -148,6 +170,8 @@ void VideoEncoderSW::Transmit(ID3D11Texture2D *pTexture, uint64_t presentationTi
if(m_Listener->GetStatistics()->CheckBitrateUpdated()) {
//Debug("Bitrate changed");
m_codecContext->bit_rate = m_Listener->GetStatistics()->GetBitrate() * 1000000L;
+ m_codecContext->rc_buffer_size = m_codecContext->bit_rate / Settings::Instance().m_refreshRate * 1.1;
+ m_codecContext->rc_max_rate = m_codecContext->bit_rate;
}
// Setup staging texture if not defined yet; we can only define it here as we now have the texture's size
@@ -238,7 +262,7 @@ void VideoEncoderSW::Transmit(ID3D11Texture2D *pTexture, uint64_t presentationTi
}
// Send statistics to client
- m_Listener->GetStatistics()->EncodeOutput(GetTimestampUs() - presentationTime);
+ m_Listener->GetStatistics()->EncodeOutput(GetSystemTimestampUs() - presentationTime);
// Unmap the copied texture and delete it
m_d3dRender->GetContext()->Unmap(stagingTex.Get(), 0);
diff --git a/alvr/server/cpp/platform/win32/VideoEncoderVCE.cpp b/alvr/server/cpp/platform/win32/VideoEncoderVCE.cpp
index 6626e3cb6c..2ca83cd912 100644
--- a/alvr/server/cpp/platform/win32/VideoEncoderVCE.cpp
+++ b/alvr/server/cpp/platform/win32/VideoEncoderVCE.cpp
@@ -10,22 +10,140 @@ if(res != AMF_OK){throw MakeException("AMF Error %d. %s", res, L#expr);}}
const wchar_t *VideoEncoderVCE::START_TIME_PROPERTY = L"StartTimeProperty";
const wchar_t *VideoEncoderVCE::FRAME_INDEX_PROPERTY = L"FrameIndexProperty";
+AMFPipe::AMFPipe(amf::AMFComponentPtr src, AMFDataReceiver receiver)
+ : m_amfComponentSrc(src)
+ , m_receiver(receiver)
+{}
+
+AMFPipe::~AMFPipe()
+{
+ Debug("AMFPipe::~AMFPipe() m_amfComponentSrc->Drain\n");
+ m_amfComponentSrc->Drain();
+}
+
+void AMFPipe::doPassthrough(bool hasQueryTimeout, uint32_t timerResolution)
+{
+ amf::AMFDataPtr data = nullptr;
+ if (hasQueryTimeout) {
+ AMF_RESULT res = m_amfComponentSrc->QueryOutput(&data);
+ if (res == AMF_OK && data) {
+ m_receiver(data);
+ } else {
+ Debug("Failed to get AMF component data. Last status: %d.\n", res);
+ }
+ } else {
+ uint16_t timeout = 1000; // 1s timeout
+ AMF_RESULT res = m_amfComponentSrc->QueryOutput(&data);
+
+ timeBeginPeriod(timerResolution);
+ while (!data && --timeout != 0) {
+ amf_sleep(1);
+ res = m_amfComponentSrc->QueryOutput(&data);
+ }
+ timeEndPeriod(timerResolution);
+
+ if (data) {
+ m_receiver(data);
+ } else {
+ Debug("Failed to get AMF component data. Last status: %d.\n", res);
+ }
+ }
+}
+
+AMFSolidPipe::AMFSolidPipe(amf::AMFComponentPtr src, amf::AMFComponentPtr dst)
+ : AMFPipe(src, std::bind(&AMFSolidPipe::Passthrough, this, std::placeholders::_1))
+ , m_amfComponentDst(dst)
+{}
+
+void AMFSolidPipe::Passthrough(AMFDataPtr data)
+{
+ auto res = m_amfComponentDst->SubmitInput(data);
+ switch (res) {
+ case AMF_OK:
+ break;
+ case AMF_INPUT_FULL:
+ Debug("m_amfComponentDst->SubmitInput returns AMF_INPUT_FULL.\n");
+ break;
+ case AMF_NEED_MORE_INPUT:
+ Debug("m_amfComponentDst->SubmitInput returns AMF_NEED_MORE_INPUT.\n");
+ break;
+ default:
+ Debug("m_amfComponentDst->SubmitInput returns code %d.\n", res);
+ break;
+ }
+}
+
+AMFPipeline::AMFPipeline()
+ : m_pipes()
+{
+ TIMECAPS tc;
+ m_timerResolution = timeGetDevCaps(&tc, sizeof(tc)) == TIMERR_NOERROR ? tc.wPeriodMin : 1;
+}
+
+AMFPipeline::~AMFPipeline()
+{
+ for (auto &pipe : m_pipes)
+ {
+ delete pipe;
+ }
+}
+
+void AMFPipeline::Connect(AMFPipePtr pipe)
+{
+ m_pipes.emplace_back(pipe);
+}
+
+void AMFPipeline::Run(bool hasQueryTimeout)
+{
+ for (auto &pipe : m_pipes)
+ {
+ pipe->doPassthrough(hasQueryTimeout, m_timerResolution);
+ }
+}
+
//
-// AMFTextureEncoder
+// VideoEncoderVCE
//
-AMFTextureEncoder::AMFTextureEncoder(const amf::AMFContextPtr &amfContext
- , int codec, int width, int height, int refreshRate, int bitrateInMbits
- , amf::AMF_SURFACE_FORMAT inputFormat
- , AMFTextureReceiver receiver) : m_receiver(receiver)
+VideoEncoderVCE::VideoEncoderVCE(std::shared_ptr d3dRender
+ , std::shared_ptr listener
+ , int width, int height)
+ : m_d3dRender(d3dRender)
+ , m_Listener(listener)
+ , m_codec(Settings::Instance().m_codec)
+ , m_refreshRate(Settings::Instance().m_refreshRate)
+ , m_renderWidth(width)
+ , m_renderHeight(height)
+ , m_bitrateInMBits(Settings::Instance().mEncodeBitrateMBs)
+ , m_surfaceFormat(amf::AMF_SURFACE_RGBA)
+ , m_use10bit(Settings::Instance().m_use10bitEncoder)
+ , m_audByteSequence(nullptr)
+ , m_audNalSize(0)
+ , m_audHeaderSize(0)
+ , m_hasQueryTimeout(false)
+{}
+
+VideoEncoderVCE::~VideoEncoderVCE() {
+ if (m_audByteSequence) {
+ delete[] m_audByteSequence;
+ m_audByteSequence = nullptr;
+ }
+}
+
+amf::AMFComponentPtr VideoEncoderVCE::MakeEncoder(
+ amf::AMF_SURFACE_FORMAT inputFormat, int width, int height, int codec, int refreshRate, int bitrateInMbits
+)
{
const wchar_t *pCodec;
amf_int32 frameRateIn = refreshRate;
- amf_int64 bitRateIn = bitrateInMbits * 1000000L; // in bits
+ amf_int64 bitRateIn = bitrateInMbits * 1'000'000L; // in bits
switch (codec) {
case ALVR_CODEC_H264:
+ if (m_use10bit) {
+ throw MakeException("H.264 10-bit encoding is not supported");
+ }
pCodec = AMFVideoEncoderVCE_AVC;
break;
case ALVR_CODEC_H265:
@@ -35,242 +153,265 @@ AMFTextureEncoder::AMFTextureEncoder(const amf::AMFContextPtr &amfContext
throw MakeException("Unsupported video encoding %d", codec);
}
+ amf::AMFComponentPtr amfEncoder;
// Create encoder component.
- AMF_THROW_IF(g_AMFFactory.GetFactory()->CreateComponent(amfContext, pCodec, &m_amfEncoder));
+ AMF_THROW_IF(g_AMFFactory.GetFactory()->CreateComponent(m_amfContext, pCodec, &amfEncoder));
if (codec == ALVR_CODEC_H264)
{
- m_amfEncoder->SetProperty(AMF_VIDEO_ENCODER_USAGE, AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY);
- m_amfEncoder->SetProperty(AMF_VIDEO_ENCODER_TARGET_BITRATE, bitRateIn);
- m_amfEncoder->SetProperty(AMF_VIDEO_ENCODER_FRAMESIZE, ::AMFConstructSize(width, height));
- m_amfEncoder->SetProperty(AMF_VIDEO_ENCODER_FRAMERATE, ::AMFConstructRate(frameRateIn, 1));
- m_amfEncoder->SetProperty(AMF_VIDEO_ENCODER_B_PIC_PATTERN, 0);
- m_amfEncoder->SetProperty(AMF_VIDEO_ENCODER_PROFILE, AMF_VIDEO_ENCODER_PROFILE_HIGH);
- m_amfEncoder->SetProperty(AMF_VIDEO_ENCODER_PROFILE_LEVEL, 51);
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_USAGE, AMF_VIDEO_ENCODER_USAGE_ULTRA_LOW_LATENCY);
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_PROFILE, AMF_VIDEO_ENCODER_PROFILE_HIGH);
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_PROFILE_LEVEL, 42);
+ switch (Settings::Instance().m_rateControlMode) {
+ case ALVR_CBR:
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD, AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_CBR);
+ // Required for CBR to work correctly
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_FILLER_DATA_ENABLE, Settings::Instance().m_fillerData);
+ break;
+ case ALVR_VBR:
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD, AMF_VIDEO_ENCODER_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR);
+ break;
+ }
- //No noticable visual difference between PRESET_QUALITY and PRESET_SPEED but the latter has better latency when the GPU is under heavy load
- m_amfEncoder->SetProperty(AMF_VIDEO_ENCODER_QUALITY_PRESET, AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED);
+ switch (Settings::Instance().m_entropyCoding) {
+ case ALVR_CABAC:
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_CABAC_ENABLE, AMF_VIDEO_ENCODER_CABAC);
+ break;
+ case ALVR_CAVLC:
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_CABAC_ENABLE, AMF_VIDEO_ENCODER_CALV);
+ break;
+ }
+
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_TARGET_BITRATE, bitRateIn);
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_PEAK_BITRATE, bitRateIn);
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_FRAMESIZE, ::AMFConstructSize(width, height));
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_FRAMERATE, ::AMFConstructRate(frameRateIn, 1));
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_B_PIC_PATTERN, 0);
+
+ switch (Settings::Instance().m_encoderQualityPreset) {
+ case ALVR_QUALITY:
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_QUALITY_PRESET, AMF_VIDEO_ENCODER_QUALITY_PRESET_QUALITY);
+ break;
+ case ALVR_BALANCED:
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_QUALITY_PRESET, AMF_VIDEO_ENCODER_QUALITY_PRESET_BALANCED);
+ break;
+ case ALVR_SPEED:
+ default:
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_QUALITY_PRESET, AMF_VIDEO_ENCODER_QUALITY_PRESET_SPEED);
+ break;
+ }
//No noticable performance difference and should improve subjective quality by allocating more bits to smooth areas
- m_amfEncoder->SetProperty(AMF_VIDEO_ENCODER_ENABLE_VBAQ, true);
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_ENABLE_VBAQ, Settings::Instance().m_enableVbaq);
- //Fixes rythmic pixelation. I-frames were overcompressed on default settings
- m_amfEncoder->SetProperty(AMF_VIDEO_ENCODER_MAX_QP, 30);
+ //Turns Off IDR/I Frames
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_IDR_PERIOD, 0);
- //Does not seem to make a difference but turned on anyway in case it does on other hardware
- m_amfEncoder->SetProperty(AMF_VIDEO_ENCODER_LOWLATENCY_MODE, true);
- }
- else
- {
- m_amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_USAGE, AMF_VIDEO_ENCODER_HEVC_USAGE_ULTRA_LOW_LATENCY);
- m_amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_TARGET_BITRATE, bitRateIn);
- m_amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_FRAMESIZE, ::AMFConstructSize(width, height));
- m_amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_FRAMERATE, ::AMFConstructRate(frameRateIn, 1));
+ // Disable AUD to produce the same stream format as VideoEncoderNVENC.
+ // FIXME: This option doesn't work in 22.10.3, but works in versions prior 22.5.1
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_INSERT_AUD, false);
- //No noticable visual difference between PRESET_QUALITY and PRESET_SPEED but the latter has better latency when the GPU is under heavy load
- m_amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET, AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_SPEED);
-
- //No noticable performance difference and should improve subjective quality by allocating more bits to smooth areas
- m_amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_ENABLE_VBAQ, true);
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_VBV_BUFFER_SIZE, bitRateIn / frameRateIn * 1.1);
- //Fixes rythmic pixelation. I-frames were overcompressed on default settings
- m_amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_MAX_QP_I, 30);
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_MAX_NUM_REFRAMES, 0);
+
+ amf::AMFCapsPtr caps;
+ if (amfEncoder->GetCaps(&caps) == AMF_OK) {
+ caps->GetProperty(AMF_VIDEO_ENCODER_CAPS_QUERY_TIMEOUT_SUPPORT, &m_hasQueryTimeout);
+ }
+ if (m_hasQueryTimeout) {
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_QUERY_TIMEOUT, 1000); // 1s timeout
+ }
- //Does not seem to make a difference but turned on anyway in case it does on other hardware
- m_amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_LOWLATENCY_MODE, true);
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_FULL_RANGE_COLOR, Settings::Instance().IsColorRangeItuFull());
+
+ amfEncoder->SetProperty(
+ AMF_VIDEO_ENCODER_OUTPUT_COLOR_PROFILE,
+ Settings::Instance().IsColorRangeItuFull()
+ ? AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_709
+ : AMF_VIDEO_CONVERTER_COLOR_PROFILE_709
+ );
+ amfEncoder->SetProperty(
+ AMF_VIDEO_ENCODER_OUTPUT_TRANSFER_CHARACTERISTIC,
+ AMF_COLOR_TRANSFER_CHARACTERISTIC_IEC61966_2_1
+ );
+ amfEncoder->SetProperty(
+ AMF_VIDEO_ENCODER_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT709
+ );
}
- AMF_THROW_IF(m_amfEncoder->Init(inputFormat, width, height));
-
- Debug("Initialized AMFTextureEncoder.\n");
-}
-
-AMFTextureEncoder::~AMFTextureEncoder()
-{
-}
-
-void AMFTextureEncoder::Start()
-{
- m_thread = new std::thread(&AMFTextureEncoder::Run, this);
-}
-
-void AMFTextureEncoder::Shutdown()
-{
- Debug("AMFTextureEncoder::Shutdown() m_amfEncoder->Drain\n");
- m_amfEncoder->Drain();
- Debug("AMFTextureEncoder::Shutdown() m_thread->join\n");
- m_thread->join();
- Debug("AMFTextureEncoder::Shutdown() joined.\n");
- delete m_thread;
- m_thread = NULL;
-}
-
-void AMFTextureEncoder::Submit(amf::AMFData *data)
-{
- while (true)
+ else
{
- Debug("AMFTextureEncoder::Submit.\n");
- auto res = m_amfEncoder->SubmitInput(data);
- if (res == AMF_INPUT_FULL)
- {
- return;
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_USAGE, AMF_VIDEO_ENCODER_HEVC_USAGE_ULTRA_LOW_LATENCY);
+ switch (Settings::Instance().m_rateControlMode) {
+ case ALVR_CBR:
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD, AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_CBR);
+ // Required for CBR to work correctly
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_FILLER_DATA_ENABLE, Settings::Instance().m_fillerData);
+ break;
+ case ALVR_VBR:
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD, AMF_VIDEO_ENCODER_HEVC_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR);
+ break;
}
- else
- {
- break;
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_TARGET_BITRATE, bitRateIn);
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_PEAK_BITRATE, bitRateIn);
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_FRAMESIZE, ::AMFConstructSize(width, height));
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_FRAMERATE, ::AMFConstructRate(frameRateIn, 1));
+
+ switch (Settings::Instance().m_encoderQualityPreset) {
+ case ALVR_QUALITY:
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET, AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_QUALITY);
+ break;
+ case ALVR_BALANCED:
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET, AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_BALANCED);
+ break;
+ case ALVR_SPEED:
+ default:
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET, AMF_VIDEO_ENCODER_HEVC_QUALITY_PRESET_SPEED);
+ break;
}
- }
-}
-amf::AMFComponentPtr AMFTextureEncoder::Get()
-{
- return m_amfEncoder;
-}
-
-void AMFTextureEncoder::Run()
-{
- Debug("Start AMFTextureEncoder thread. Thread Id=%d\n", GetCurrentThreadId());
- amf::AMFDataPtr data;
- while (true)
- {
- auto res = m_amfEncoder->QueryOutput(&data);
- if (res == AMF_EOF)
- {
- Warn("m_amfEncoder->QueryOutput returns AMF_EOF.\n");
- return;
+ if (m_use10bit) {
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_COLOR_BIT_DEPTH, AMF_COLOR_BIT_DEPTH_10);
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_PROFILE, AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN_10);
+ } else {
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_COLOR_BIT_DEPTH, AMF_COLOR_BIT_DEPTH_8);
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_PROFILE, AMF_VIDEO_ENCODER_HEVC_PROFILE_MAIN);
}
- if (data != NULL)
- {
- m_receiver(data);
- }
- else
- {
- Sleep(1);
- }
- }
-}
+ //No noticable performance difference and should improve subjective quality by allocating more bits to smooth areas
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_ENABLE_VBAQ, Settings::Instance().m_enableVbaq);
+
+ //Turns Off IDR/I Frames
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_NUM_GOPS_PER_IDR, 0);
+ //Set infinite GOP length
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_GOP_SIZE, 0);
+
+ // Disable AUD to produce the same stream format as VideoEncoderNVENC.
+ // FIXME: This option doesn't work in 22.10.3, but works in versions prior 22.5.1
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_INSERT_AUD, false);
-//
-// AMFTextureConverter
-//
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_VBV_BUFFER_SIZE, bitRateIn / frameRateIn * 1.1);
-AMFTextureConverter::AMFTextureConverter(const amf::AMFContextPtr &amfContext
- , int width, int height
- , amf::AMF_SURFACE_FORMAT inputFormat, amf::AMF_SURFACE_FORMAT outputFormat
- , AMFTextureReceiver receiver) : m_receiver(receiver)
-{
- AMF_THROW_IF(g_AMFFactory.GetFactory()->CreateComponent(amfContext, AMFVideoConverter, &m_amfConverter));
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_MAX_NUM_REFRAMES, 0);
+
+ amf::AMFCapsPtr caps;
+ if (amfEncoder->GetCaps(&caps) == AMF_OK) {
+ caps->GetProperty(AMF_VIDEO_ENCODER_CAPS_HEVC_QUERY_TIMEOUT_SUPPORT, &m_hasQueryTimeout);
+ }
+ if (m_hasQueryTimeout) {
+ amfEncoder->SetProperty(AMF_VIDEO_ENCODER_HEVC_QUERY_TIMEOUT, 1000); // 1s timeout
+ }
- AMF_THROW_IF(m_amfConverter->SetProperty(AMF_VIDEO_CONVERTER_MEMORY_TYPE, amf::AMF_MEMORY_DX11));
- AMF_THROW_IF(m_amfConverter->SetProperty(AMF_VIDEO_CONVERTER_OUTPUT_FORMAT, outputFormat));
- AMF_THROW_IF(m_amfConverter->SetProperty(AMF_VIDEO_CONVERTER_OUTPUT_SIZE, ::AMFConstructSize(width, height)));
+ amfEncoder->SetProperty(
+ AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE,
+ Settings::Instance().IsColorRangeItuFull()
+ ? AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE_FULL
+ : AMF_VIDEO_ENCODER_HEVC_NOMINAL_RANGE_STUDIO
+ );
+
+ amfEncoder->SetProperty(
+ AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PROFILE,
+ Settings::Instance().IsColorRangeItuFull()
+ ? AMF_VIDEO_CONVERTER_COLOR_PROFILE_FULL_709
+ : AMF_VIDEO_CONVERTER_COLOR_PROFILE_709
+ );
+ amfEncoder->SetProperty(
+ AMF_VIDEO_ENCODER_HEVC_OUTPUT_TRANSFER_CHARACTERISTIC,
+ AMF_COLOR_TRANSFER_CHARACTERISTIC_IEC61966_2_1
+ );
+ amfEncoder->SetProperty(
+ AMF_VIDEO_ENCODER_HEVC_OUTPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT709
+ );
+ }
- AMF_THROW_IF(m_amfConverter->Init(inputFormat, width, height));
+ Debug("Configured %s.\n", pCodec);
+ AMF_THROW_IF(amfEncoder->Init(inputFormat, width, height));
- Debug("Initialized AMFTextureConverter.\n");
-}
+ Debug("Initialized %s.\n", pCodec);
-AMFTextureConverter::~AMFTextureConverter()
-{
+ return amfEncoder;
}
-void AMFTextureConverter::Start()
-{
- m_thread = new std::thread(&AMFTextureConverter::Run, this);
-}
+amf::AMFComponentPtr VideoEncoderVCE::MakeConverter(
+ amf::AMF_SURFACE_FORMAT inputFormat, int width, int height, amf::AMF_SURFACE_FORMAT outputFormat
+) {
+ amf::AMFComponentPtr amfConverter;
+ AMF_THROW_IF(g_AMFFactory.GetFactory()->CreateComponent(m_amfContext, AMFVideoConverter, &amfConverter));
+
+ AMF_THROW_IF(amfConverter->SetProperty(AMF_VIDEO_CONVERTER_MEMORY_TYPE, amf::AMF_MEMORY_DX11));
+ AMF_THROW_IF(amfConverter->SetProperty(AMF_VIDEO_CONVERTER_OUTPUT_FORMAT, outputFormat));
+ AMF_THROW_IF(amfConverter->SetProperty(AMF_VIDEO_CONVERTER_OUTPUT_SIZE, ::AMFConstructSize(width, height)));
+
+ if (m_use10bit) {
+ AMF_THROW_IF(amfConverter->SetProperty(AMF_VIDEO_CONVERTER_INPUT_TRANSFER_CHARACTERISTIC, AMF_COLOR_TRANSFER_CHARACTERISTIC_GAMMA28));
+ AMF_THROW_IF(amfConverter->SetProperty(AMF_VIDEO_CONVERTER_INPUT_COLOR_PRIMARIES, AMF_COLOR_PRIMARIES_BT709));
+ AMF_THROW_IF(amfConverter->SetProperty(AMF_VIDEO_CONVERTER_INPUT_COLOR_RANGE, AMF_COLOR_RANGE_FULL));
+ AMF_THROW_IF(amfConverter->SetProperty(AMF_VIDEO_CONVERTER_INPUT_TONEMAPPING, AMF_VIDEO_CONVERTER_TONEMAPPING_COPY));
+ }
-void AMFTextureConverter::Shutdown()
-{
- Debug("AMFTextureConverter::Shutdown() m_amfConverter->Drain\n");
- m_amfConverter->Drain();
- Debug("AMFTextureConverter::Shutdown() m_thread->join\n");
- m_thread->join();
- Debug("AMFTextureConverter::Shutdown() joined.\n");
- delete m_thread;
- m_thread = NULL;
-}
+ AMF_THROW_IF(amfConverter->Init(inputFormat, width, height));
-void AMFTextureConverter::Submit(amf::AMFData *data)
-{
- while (true)
- {
- Debug("AMFTextureConverter::Submit.\n");
- auto res = m_amfConverter->SubmitInput(data);
- if (res == AMF_INPUT_FULL)
- {
- return;
- }
- else
- {
- break;
- }
- }
+ Debug("Initialized %s.\n", AMFVideoConverter);
+ return amfConverter;
}
-void AMFTextureConverter::Run()
-{
- Debug("Start AMFTextureConverter thread. Thread Id=%d\n", GetCurrentThreadId());
- amf::AMFDataPtr data;
- while (true)
- {
- auto res = m_amfConverter->QueryOutput(&data);
- if (res == AMF_EOF)
- {
- Warn("m_amfConverter->QueryOutput returns AMF_EOF.\n");
- return;
- }
+amf::AMFComponentPtr VideoEncoderVCE::MakePreprocessor(
+ amf::AMF_SURFACE_FORMAT inputFormat, int width, int height
+) {
+ amf::AMFComponentPtr amfPreprocessor;
+ AMF_THROW_IF(g_AMFFactory.GetFactory()->CreateComponent(m_amfContext, AMFPreProcessing, &amfPreprocessor));
- if (data != NULL)
- {
- m_receiver(data);
- }
- else
- {
- Sleep(1);
- }
- }
-}
+ AMF_THROW_IF(amfPreprocessor->SetProperty(AMF_PP_ENGINE_TYPE, amf::AMF_MEMORY_DX11));
+ AMF_THROW_IF(amfPreprocessor->SetProperty(AMF_PP_ADAPTIVE_FILTER_STRENGTH, Settings::Instance().m_preProcSigma));
+ AMF_THROW_IF(amfPreprocessor->SetProperty(AMF_PP_ADAPTIVE_FILTER_SENSITIVITY, Settings::Instance().m_preProcTor));
-//
-// VideoEncoderVCE
-//
+ AMF_THROW_IF(amfPreprocessor->Init(inputFormat, width, height));
-VideoEncoderVCE::VideoEncoderVCE(std::shared_ptr d3dRender
- , std::shared_ptr listener
- , int width, int height)
- : m_d3dRender(d3dRender)
- , m_Listener(listener)
- , m_codec(Settings::Instance().m_codec)
- , m_refreshRate(Settings::Instance().m_refreshRate)
- , m_renderWidth(width)
- , m_renderHeight(height)
- , m_bitrateInMBits(Settings::Instance().mEncodeBitrateMBs)
-{
+ Debug("Initialized %s.\n", AMFPreProcessing);
+ return amfPreprocessor;
}
-VideoEncoderVCE::~VideoEncoderVCE()
-{}
-
void VideoEncoderVCE::Initialize()
{
Debug("Initializing VideoEncoderVCE.\n");
AMF_THROW_IF(g_AMFFactory.Init());
- ::amf_increase_timer_precision();
+ LoadAUDByteSequence();
AMF_THROW_IF(g_AMFFactory.GetFactory()->CreateContext(&m_amfContext));
AMF_THROW_IF(m_amfContext->InitDX11(m_d3dRender->GetDevice()));
- m_encoder = std::make_shared(m_amfContext
- , m_codec, m_renderWidth, m_renderHeight, m_refreshRate, m_bitrateInMBits
- , ENCODER_INPUT_FORMAT, std::bind(&VideoEncoderVCE::Receive, this, std::placeholders::_1));
- m_converter = std::make_shared(m_amfContext
- , m_renderWidth, m_renderHeight
- , CONVERTER_INPUT_FORMAT, ENCODER_INPUT_FORMAT
- , std::bind(&AMFTextureEncoder::Submit, m_encoder.get(), std::placeholders::_1));
+ amf::AMF_SURFACE_FORMAT inFormat = m_surfaceFormat;
+ if (m_use10bit) {
+ inFormat = amf::AMF_SURFACE_P010;
+ m_amfComponents.emplace_back(MakeConverter(
+ m_surfaceFormat, m_renderWidth, m_renderHeight, inFormat
+ ));
+ } else {
+ if (Settings::Instance().m_usePreproc) {
+ inFormat = amf::AMF_SURFACE_NV12;
+ m_amfComponents.emplace_back(MakeConverter(
+ m_surfaceFormat, m_renderWidth, m_renderHeight, inFormat
+ ));
+ m_amfComponents.emplace_back(MakePreprocessor(
+ inFormat, m_renderWidth, m_renderHeight
+ ));
+ }
+ }
+ m_amfComponents.emplace_back(MakeEncoder(
+ inFormat, m_renderWidth, m_renderHeight, m_codec, m_refreshRate, m_bitrateInMBits
+ ));
+
+ m_pipeline = new AMFPipeline();
+ for (int i = 0; i < m_amfComponents.size() - 1; i++) {
+ m_pipeline->Connect(new AMFSolidPipe(
+ m_amfComponents[i], m_amfComponents[i + 1]
+ ));
+ }
- m_encoder->Start();
- m_converter->Start();
+ m_pipeline->Connect(new AMFPipe(
+ m_amfComponents.back(), std::bind(&VideoEncoderVCE::Receive, this, std::placeholders::_1)
+ ));
Debug("Successfully initialized VideoEncoderVCE.\n");
}
@@ -279,10 +420,17 @@ void VideoEncoderVCE::Shutdown()
{
Debug("Shutting down VideoEncoderVCE.\n");
- m_encoder->Shutdown();
- m_converter->Shutdown();
+ delete m_pipeline;
+
+ for (auto &component : m_amfComponents) {
+ component->Release();
+ delete component;
+ }
+
+ m_amfContext->Terminate();
+ m_amfContext = NULL;
- amf_restore_timer_precision();
+ g_AMFFactory.Terminate();
if (fpOut) {
fpOut.close();
@@ -298,19 +446,23 @@ void VideoEncoderVCE::Transmit(ID3D11Texture2D *pTexture, uint64_t presentationT
if (m_Listener) {
if (m_Listener->GetStatistics()->CheckBitrateUpdated()) {
m_bitrateInMBits = m_Listener->GetStatistics()->GetBitrate();
- amf_int64 bitRateIn = m_bitrateInMBits * 1000000L; // in bits
+ amf_int64 bitRateIn = m_bitrateInMBits * 1'000'000L; // in bits
if (m_codec == ALVR_CODEC_H264)
{
- m_encoder->Get()->SetProperty(AMF_VIDEO_ENCODER_TARGET_BITRATE, bitRateIn);
+ m_amfComponents.back()->SetProperty(AMF_VIDEO_ENCODER_TARGET_BITRATE, bitRateIn);
+ m_amfComponents.back()->SetProperty(AMF_VIDEO_ENCODER_PEAK_BITRATE, bitRateIn);
+ m_amfComponents.back()->SetProperty(AMF_VIDEO_ENCODER_VBV_BUFFER_SIZE, bitRateIn / m_refreshRate * 1.1);
}
else
{
- m_encoder->Get()->SetProperty(AMF_VIDEO_ENCODER_HEVC_TARGET_BITRATE, bitRateIn);
+ m_amfComponents.back()->SetProperty(AMF_VIDEO_ENCODER_HEVC_TARGET_BITRATE, bitRateIn);
+ m_amfComponents.back()->SetProperty(AMF_VIDEO_ENCODER_HEVC_PEAK_BITRATE, bitRateIn);
+ m_amfComponents.back()->SetProperty(AMF_VIDEO_ENCODER_HEVC_VBV_BUFFER_SIZE, bitRateIn / m_refreshRate * 1.1);
}
}
}
- AMF_THROW_IF(m_amfContext->AllocSurface(amf::AMF_MEMORY_DX11, CONVERTER_INPUT_FORMAT, m_renderWidth, m_renderHeight, &surface));
+ AMF_THROW_IF(m_amfContext->AllocSurface(amf::AMF_MEMORY_DX11, m_surfaceFormat, m_renderWidth, m_renderHeight, &surface));
ID3D11Texture2D *textureDX11 = (ID3D11Texture2D*)surface->GetPlaneAt(0)->GetNative(); // no reference counting - do not Release()
m_d3dRender->GetContext()->CopyResource(textureDX11, pTexture);
@@ -320,10 +472,11 @@ void VideoEncoderVCE::Transmit(ID3D11Texture2D *pTexture, uint64_t presentationT
ApplyFrameProperties(surface, insertIDR);
- m_converter->Submit(surface);
+ m_amfComponents.front()->SubmitInput(surface);
+ m_pipeline->Run(m_hasQueryTimeout);
}
-void VideoEncoderVCE::Receive(amf::AMFData *data)
+void VideoEncoderVCE::Receive(AMFDataPtr data)
{
amf_pts current_time = amf_high_precision_clock();
amf_pts start_time = 0;
@@ -340,20 +493,21 @@ void VideoEncoderVCE::Receive(amf::AMFData *data)
char *p = reinterpret_cast(buffer->GetNative());
int length = static_cast(buffer->GetSize());
+ //Fallback in case AUD was not removed by the encoder
SkipAUD(&p, &length);
if (fpOut) {
fpOut.write(p, length);
}
if (m_Listener) {
- m_Listener->SendVideo(reinterpret_cast(p), length, targetTimestampNs);
+ m_Listener->SendVideo(reinterpret_cast