Add support for HDR streaming

This commit is contained in:
Cameron Gutman 2017-11-05 19:23:15 -08:00
parent e5d9da447c
commit a989bdde80
7 changed files with 64 additions and 8 deletions

View File

@ -15,6 +15,7 @@ public class ConnectionContext {
public int negotiatedWidth, negotiatedHeight; public int negotiatedWidth, negotiatedHeight;
public int negotiatedFps; public int negotiatedFps;
public boolean negotiatedHdr;
public int videoCapabilities; public int videoCapabilities;
} }

View File

@ -100,6 +100,12 @@ public class NvConnection {
return false; return false;
} }
context.negotiatedHdr = context.streamConfig.getEnableHdr();
if ((h.getServerCodecModeSupport(serverInfo) & 0x200) == 0 && context.negotiatedHdr) {
context.connListener.displayTransientMessage("Your GPU does not support streaming HDR. The stream will be SDR.");
context.negotiatedHdr = false;
}
// //
// Decide on negotiated stream parameters now // Decide on negotiated stream parameters now
// //
@ -154,7 +160,7 @@ public class NvConnection {
return false; return false;
} }
} else { } else {
return quitAndLaunch(h, app); return quitAndLaunch(h, context);
} }
} catch (GfeHttpResponseException e) { } catch (GfeHttpResponseException e) {
if (e.getErrorCode() == 470) { if (e.getErrorCode() == 470) {
@ -178,11 +184,11 @@ public class NvConnection {
return true; return true;
} }
else { else {
return launchNotRunningApp(h, app); return launchNotRunningApp(h, context);
} }
} }
protected boolean quitAndLaunch(NvHTTP h, NvApp app) throws IOException, protected boolean quitAndLaunch(NvHTTP h, ConnectionContext context) throws IOException,
XmlPullParserException { XmlPullParserException {
try { try {
if (!h.quitApp()) { if (!h.quitApp()) {
@ -201,13 +207,13 @@ public class NvConnection {
} }
} }
return launchNotRunningApp(h, app); return launchNotRunningApp(h, context);
} }
private boolean launchNotRunningApp(NvHTTP h, NvApp app) private boolean launchNotRunningApp(NvHTTP h, ConnectionContext context)
throws IOException, XmlPullParserException { throws IOException, XmlPullParserException {
// Launch the app since it's not running // Launch the app since it's not running
if (!h.launchApp(context, app.getAppId())) { if (!h.launchApp(context, context.streamConfig.getApp().getAppId(), context.negotiatedHdr)) {
context.connListener.displayMessage("Failed to launch application"); context.connListener.displayMessage("Failed to launch application");
return false; return false;
} }
@ -263,6 +269,7 @@ public class NvConnection {
context.streamConfig.getMaxPacketSize(), context.streamConfig.getMaxPacketSize(),
context.streamConfig.getRemote(), context.streamConfig.getAudioConfiguration(), context.streamConfig.getRemote(), context.streamConfig.getAudioConfiguration(),
context.streamConfig.getHevcSupported(), context.streamConfig.getHevcSupported(),
context.negotiatedHdr,
context.streamConfig.getHevcBitratePercentageMultiplier(), context.streamConfig.getHevcBitratePercentageMultiplier(),
context.riKey.getEncoded(), ib.array(), context.riKey.getEncoded(), ib.array(),
context.videoCapabilities); context.videoCapabilities);

View File

@ -26,6 +26,7 @@ public class StreamConfiguration {
private int audioConfiguration; private int audioConfiguration;
private boolean supportsHevc; private boolean supportsHevc;
private int hevcBitratePercentageMultiplier; private int hevcBitratePercentageMultiplier;
private boolean enableHdr;
public static class Builder { public static class Builder {
private StreamConfiguration config = new StreamConfiguration(); private StreamConfiguration config = new StreamConfiguration();
@ -81,6 +82,11 @@ public class StreamConfiguration {
return this; return this;
} }
public StreamConfiguration.Builder setEnableHdr(boolean enableHdr) {
config.enableHdr = enableHdr;
return this;
}
public StreamConfiguration.Builder setAudioConfiguration(int audioConfig) { public StreamConfiguration.Builder setAudioConfiguration(int audioConfig) {
if (audioConfig == MoonBridge.AUDIO_CONFIGURATION_STEREO) { if (audioConfig == MoonBridge.AUDIO_CONFIGURATION_STEREO) {
config.audioChannelCount = CHANNEL_COUNT_STEREO; config.audioChannelCount = CHANNEL_COUNT_STEREO;
@ -122,6 +128,7 @@ public class StreamConfiguration {
this.audioChannelCount = CHANNEL_COUNT_STEREO; this.audioChannelCount = CHANNEL_COUNT_STEREO;
this.audioChannelMask = CHANNEL_MASK_STEREO; this.audioChannelMask = CHANNEL_MASK_STEREO;
this.supportsHevc = false; this.supportsHevc = false;
this.enableHdr = false;
} }
public int getWidth() { public int getWidth() {
@ -183,4 +190,8 @@ public class StreamConfiguration {
public int getHevcBitratePercentageMultiplier() { public int getHevcBitratePercentageMultiplier() {
return hevcBitratePercentageMultiplier; return hevcBitratePercentageMultiplier;
} }
public boolean getEnableHdr() {
return enableHdr;
}
} }

View File

@ -6,6 +6,7 @@ public class NvApp {
private String appName = ""; private String appName = "";
private int appId; private int appId;
private boolean initialized; private boolean initialized;
private boolean hdrSupported;
public NvApp() {} public NvApp() {}
@ -13,9 +14,10 @@ public class NvApp {
this.appName = appName; this.appName = appName;
} }
public NvApp(String appName, int appId) { public NvApp(String appName, int appId, boolean hdrSupported) {
this.appName = appName; this.appName = appName;
this.appId = appId; this.appId = appId;
this.hdrSupported = hdrSupported;
this.initialized = true; this.initialized = true;
} }
@ -37,6 +39,10 @@ public class NvApp {
this.initialized = true; this.initialized = true;
} }
public void setHdrSupported(boolean hdrSupported) {
this.hdrSupported = hdrSupported;
}
public String getAppName() { public String getAppName() {
return this.appName; return this.appName;
} }
@ -45,6 +51,10 @@ public class NvApp {
return this.appId; return this.appId;
} }
public boolean isHdrSupported() {
return this.hdrSupported;
}
public boolean isInitialized() { public boolean isInitialized() {
return this.initialized; return this.initialized;
} }

View File

@ -371,6 +371,27 @@ public class NvHTTP {
} }
} }
// Possible meaning of bits
// Bit 0: H.264 Baseline
// Bit 1: H.264 High
// ----
// Bit 8: HEVC Main
// Bit 9: HEVC Main10
// Bit 10: HEVC Main10 4:4:4
// Bit 11: ???
public long getServerCodecModeSupport(String serverInfo) throws XmlPullParserException, IOException {
String str = getXmlString(serverInfo, "ServerCodecModeSupport");
if (str != null) {
try {
return Long.parseLong(str);
} catch (NumberFormatException e) {
return 0;
}
} else {
return 0;
}
}
public String getGpuType(String serverInfo) throws XmlPullParserException, IOException { public String getGpuType(String serverInfo) throws XmlPullParserException, IOException {
return getXmlString(serverInfo, "gputype"); return getXmlString(serverInfo, "gputype");
} }
@ -504,6 +525,8 @@ public class NvHTTP {
app.setAppName(xpp.getText().trim()); app.setAppName(xpp.getText().trim());
} else if (currentTag.peek().equals("ID")) { } else if (currentTag.peek().equals("ID")) {
app.setAppId(xpp.getText().trim()); app.setAppId(xpp.getText().trim());
} else if (currentTag.peek().equals("IsHdrSupported")) {
app.setHdrSupported(xpp.getText().trim().equals("1"));
} }
break; break;
} }
@ -601,7 +624,7 @@ public class NvHTTP {
return new String(hexChars); return new String(hexChars);
} }
public boolean launchApp(ConnectionContext context, int appId) throws IOException, XmlPullParserException { public boolean launchApp(ConnectionContext context, int appId, boolean enableHdr) throws IOException, XmlPullParserException {
String xmlStr = openHttpConnectionToString(baseUrlHttps + String xmlStr = openHttpConnectionToString(baseUrlHttps +
"/launch?" + buildUniqueIdUuidString() + "/launch?" + buildUniqueIdUuidString() +
"&appid=" + appId + "&appid=" + appId +
@ -609,6 +632,7 @@ public class NvHTTP {
"&additionalStates=1&sops=" + (context.streamConfig.getSops() ? 1 : 0) + "&additionalStates=1&sops=" + (context.streamConfig.getSops() ? 1 : 0) +
"&rikey="+bytesToHex(context.riKey.getEncoded()) + "&rikey="+bytesToHex(context.riKey.getEncoded()) +
"&rikeyid="+context.riKeyId + "&rikeyid="+context.riKeyId +
(!enableHdr ? "" : "&hdrMode=1&clientHdrCapVersion=0&clientHdrCapSupportedFlagsInUint32=0&clientHdrCapMetaDataId=NV_STATIC_METADATA_TYPE_1&clientHdrCapDisplayData=0x0x0x0x0x0x0x0x0x0x0") +
"&localAudioPlayMode=" + (context.streamConfig.getPlayLocalAudio() ? 1 : 0) + "&localAudioPlayMode=" + (context.streamConfig.getPlayLocalAudio() ? 1 : 0) +
"&surroundAudioInfo=" + ((context.streamConfig.getAudioChannelMask() << 16) + context.streamConfig.getAudioChannelCount()), "&surroundAudioInfo=" + ((context.streamConfig.getAudioChannelMask() << 16) + context.streamConfig.getAudioChannelCount()),
false); false);

View File

@ -160,6 +160,7 @@ public class MoonBridge {
int width, int height, int fps, int width, int height, int fps,
int bitrate, int packetSize, boolean streamingRemotely, int bitrate, int packetSize, boolean streamingRemotely,
int audioConfiguration, boolean supportsHevc, int audioConfiguration, boolean supportsHevc,
boolean enableHdr,
int hevcBitratePercentageMultiplier, int hevcBitratePercentageMultiplier,
byte[] riAesKey, byte[] riAesIv, byte[] riAesKey, byte[] riAesIv,
int videoCapabilities); int videoCapabilities);

View File

@ -382,6 +382,7 @@ Java_com_limelight_nvstream_jni_MoonBridge_startConnection(JNIEnv *env, jobject
jint width, jint height, jint fps, jint width, jint height, jint fps,
jint bitrate, jint packetSize, jboolean streamingRemotely, jint bitrate, jint packetSize, jboolean streamingRemotely,
jint audioConfiguration, jboolean supportsHevc, jint audioConfiguration, jboolean supportsHevc,
jboolean enableHdr,
jint hevcBitratePercentageMultiplier, jint hevcBitratePercentageMultiplier,
jbyteArray riAesKey, jbyteArray riAesIv, jbyteArray riAesKey, jbyteArray riAesIv,
jint videoCapabilities) { jint videoCapabilities) {
@ -399,6 +400,7 @@ Java_com_limelight_nvstream_jni_MoonBridge_startConnection(JNIEnv *env, jobject
.streamingRemotely = streamingRemotely, .streamingRemotely = streamingRemotely,
.audioConfiguration = audioConfiguration, .audioConfiguration = audioConfiguration,
.supportsHevc = supportsHevc, .supportsHevc = supportsHevc,
.enableHdr = enableHdr,
.hevcBitratePercentageMultiplier = hevcBitratePercentageMultiplier, .hevcBitratePercentageMultiplier = hevcBitratePercentageMultiplier,
}; };