Compare commits
246 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 077cb2103d | |||
| cdeda011a4 | |||
| 894c146988 | |||
| 61cc9e151f | |||
| cfe4c9ff21 | |||
| d4bd29b320 | |||
| 7f2f2056c3 | |||
| 4dd3b2cfb7 | |||
| 2e62ad0f00 | |||
| 41ef292b82 | |||
| aa60671c88 | |||
| f1ccba39e8 | |||
| 226e580a30 | |||
| 6f8e719200 | |||
| c127af1e05 | |||
| 648904cc69 | |||
| dc85ddb3f9 | |||
| 23a7d8555f | |||
| bc9e250d34 | |||
| 2203186527 | |||
| 53d3d9ecb8 | |||
| de549f67a1 | |||
| 755c41481a | |||
| aebc2126bc | |||
| f43547fb31 | |||
| 398e4df7cf | |||
| ff68efc3f5 | |||
| 8ba2f51bda | |||
| 87b79b278b | |||
| 121e3ea9be | |||
| ec6ed79ee1 | |||
| ca125826a7 | |||
| dd0aecf108 | |||
| ef5cb2f0cd | |||
| e5a7bb40e9 | |||
| bfdda48fee | |||
| ebea1bb5c1 | |||
| 14bc1552fc | |||
| a5b80d3944 | |||
| 75d0eedc2b | |||
| 29ac7028fa | |||
| 8a63b61495 | |||
| eb9e6443e2 | |||
| 362c466a16 | |||
| 5dac42646b | |||
| c25faf6426 | |||
| 81df1245b4 | |||
| 2bf4d92185 | |||
| ae6073fe80 | |||
| d0463da2a1 | |||
| c0f8001627 | |||
| f39bf61b04 | |||
| 9c8237dab0 | |||
| b88251fa79 | |||
| 208855917e | |||
| 34bdf450e9 | |||
| 998fa1f4e9 | |||
| 5c80f7d58c | |||
| 7552181e24 | |||
| 4b2e26050e | |||
| 530b48de71 | |||
| f4721901f8 | |||
| 8b692269c1 | |||
| 079eca7b4d | |||
| fee40cdbe2 | |||
| 66920bb4cb | |||
| fdbf810aa2 | |||
| 08bfc1de4a | |||
| 76149328fe | |||
| 285f33f3f1 | |||
| b17c1b7588 | |||
| 5b25c90db8 | |||
| 931a0a5168 | |||
| f6a46438bd | |||
| 4a60ec1755 | |||
| ec222413dd | |||
| 5a28239813 | |||
| da45cba2ff | |||
| 54bc34496a | |||
| 294910ac84 | |||
| 71d2c6a5d5 | |||
| 79bf17fe24 | |||
| 31f66031bc | |||
| d3f2284791 | |||
| ec647608c4 | |||
| 597582ddd8 | |||
| c6d9889182 | |||
| 7c58234174 | |||
| ae9282b0af | |||
| 310ba646fc | |||
| d479908939 | |||
| 5cd5d68d22 | |||
| 3e0bf25acb | |||
| f3d277c94a | |||
| 04545ecbb0 | |||
| 5350651d6f | |||
| f2e2e28419 | |||
| b9031785ac | |||
| 91a72474a1 | |||
| b6e7c425c6 | |||
| 834ace4566 | |||
| 54af70005d | |||
| f2bf168925 | |||
| 27ffbd8dec | |||
| eaa82592fe | |||
| 73784585a8 | |||
| 262d562dd9 | |||
| ab4f904dc9 | |||
| fc4fdd5ee2 | |||
| 41c5b62b1a | |||
| 239cb0435c | |||
| c6ccc7a6e2 | |||
| 6cedb9019c | |||
| 8bc64f0438 | |||
| 89e6e39e58 | |||
| 645761f677 | |||
| 0fc60f7855 | |||
| ce38460d87 | |||
| de8e759d3a | |||
| 06f6134538 | |||
| ac352b3a23 | |||
| 9b8e65e552 | |||
| 35999a05f0 | |||
| 86ee30e9b4 | |||
| a81c4a1e23 | |||
| 394ce458a0 | |||
| f187e57899 | |||
| a15335872d | |||
| beb77b4dab | |||
| aa80d8cd0a | |||
| 77d197f14e | |||
| f98fbb778c | |||
| c46a0106f2 | |||
| cbf3db0be0 | |||
| 21f3710083 | |||
| 8ac5768f4f | |||
| 2458b9305c | |||
| a8909ea2a5 | |||
| ac7c35c6c2 | |||
| e4631b5a85 | |||
| e1c50b5dc5 | |||
| c6c5a5cd12 | |||
| bd4854a607 | |||
| cd0181e6f4 | |||
| 287b1d2b4d | |||
| 10c61bb0a7 | |||
| 92215ac34f | |||
| f64d50d8c8 | |||
| b74e0ce48f | |||
| 27cb0029a8 | |||
| ce6f193f06 | |||
| a862ffdde4 | |||
| 3f1cd8a118 | |||
| bb4b5838e3 | |||
| ea98d64184 | |||
| 98f3c56da5 | |||
| 20b7619380 | |||
| 7b1c3f05c7 | |||
| 9166998442 | |||
| e1f6b577bf | |||
| ba0d08b2a6 | |||
| e79c12a038 | |||
| 2ca5182a28 | |||
| 205e627209 | |||
| 425d4f3f63 | |||
| d69843e122 | |||
| d2586d3b59 | |||
| edab84c89b | |||
| dd08754f1f | |||
| 2cdfe85091 | |||
| a11acef36f | |||
| 1e34dbf616 | |||
| b3d4763ef6 | |||
| fe630e9383 | |||
| 826a20785f | |||
| 75932d7621 | |||
| 62d095af4f | |||
| 1594735aa0 | |||
| cbd0bdf9fc | |||
| d3e8e8fb9c | |||
| 66406c5a48 | |||
| 753c600dd2 | |||
| b28b1df348 | |||
| b94649162e | |||
| ee50e19dbd | |||
| cc23f8b831 | |||
| bac7b68bb1 | |||
| f9a622c89b | |||
| c321dc5e81 | |||
| 72f37c9df4 | |||
| 544eac0c8a | |||
| 823593ddae | |||
| 3600e704c4 | |||
| 0c79d756a4 | |||
| eb531a7a88 | |||
| d6634d30dc | |||
| f87806b1b4 | |||
| 2a5afeb5ff | |||
| fc5495f1ec | |||
| 699cc361a2 | |||
| 31bf4f10c0 | |||
| fe704af62f | |||
| e74517543d | |||
| 44acf19742 | |||
| bf20aa253e | |||
| 81c815840d | |||
| e9cd63dc5f | |||
| 1ae8f67d93 | |||
| daa1e10333 | |||
| a8a356e703 | |||
| ca440cc5dd | |||
| 95a9fb4f62 | |||
| 7db9e27112 | |||
| 03bcdbe3f7 | |||
| f0762a6213 | |||
| 67fbc6b3ad | |||
| d9662d7396 | |||
| 5ccbbf259d | |||
| 179c2f8723 | |||
| c76e0a40a7 | |||
| 03407e528f | |||
| 0c41d742cf | |||
| ed2f471a4e | |||
| 04efec101e | |||
| a6c69012cc | |||
| 0045c54d8e | |||
| 45436c006f | |||
| cc183c0da8 | |||
| 523f1df98b | |||
| 5843dff278 | |||
| 7f24f47978 | |||
| b1f9fd459e | |||
| 48988eb785 | |||
| 0045a885b9 | |||
| 0b57f60454 | |||
| f0857c7da2 | |||
| 15faa2e841 | |||
| da103f7197 | |||
| 1d3e42f92e | |||
| 20ced841dd | |||
| 54ebd0a796 | |||
| e636a7171b | |||
| e8f847065b | |||
| 1c806bb572 | |||
| 963133598f | |||
| fedaa74c47 |
@@ -0,0 +1,48 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Follow the troubleshooting guide before reporting a bug
|
||||
|
||||
---
|
||||
**READ ME FIRST!**
|
||||
If you're here because something basic is not working (like gamepad input, video, or similar), it's probably something specific to your setup, so make sure you've gone through the Troubleshooting Guide first: https://github.com/moonlight-stream/moonlight-docs/wiki/Troubleshooting
|
||||
|
||||
If you still have trouble with basic functionality after following the guide, join our Discord server where there are many other volunteers who can help (or direct you back here if it looks like a Moonlight bug after all). https://moonlight-stream.org/discord
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Steps to reproduce**
|
||||
Any special steps that are required for the bug to appear.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem. If the issue is related to video glitching or poor quality, please include screenshots.
|
||||
|
||||
**Affected games**
|
||||
List the games you've tried that exhibit the issue. To see if the issue is game-specific, try streaming Steam Big Picture with Moonlight and see if the issue persists there.
|
||||
|
||||
**Other Moonlight clients**
|
||||
- Does the issue occur when using Moonlight on PC or iOS?
|
||||
|
||||
**Moonlight settings (please complete the following information)**
|
||||
- Have any settings been adjusted from defaults?
|
||||
- If so, which settings have been changed?
|
||||
- Does the problem still occur after reverting settings back to default?
|
||||
|
||||
**Gamepad-related issues (please complete if problem is gamepad-related)**
|
||||
- Do you have any gamepads connected to your host PC directly?
|
||||
- If gamepad input is not working, does it work if you use Moonlight's on-screen controls?
|
||||
- Does the problem still remain if you stream the desktop and use https://html5gamepad.com to test your gamepad?
|
||||
- Instructions for streaming the desktop can be found here: https://github.com/moonlight-stream/moonlight-docs/wiki/Setup-Guide
|
||||
|
||||
**Device details (please complete the following information)**
|
||||
- Android version: [e.g. Android 10]
|
||||
- Device model: [e.g. Samsung Galaxy S21]
|
||||
|
||||
**Server PC details (please complete the following information)**
|
||||
- OS: [e.g. Windows 10 1809]
|
||||
- GeForce Experience version: [e.g. 3.16.0.140]
|
||||
- Nvidia GPU driver: [e.g. 417.35]
|
||||
- Antivirus and firewall software: [e.g. Windows Defender and Windows Firewall]
|
||||
|
||||
**Additional context**
|
||||
Anything else you think may be relevant to the issue or special about your specific setup.
|
||||
@@ -0,0 +1 @@
|
||||
blank_issues_enabled: false
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
language: android
|
||||
dist: trusty
|
||||
|
||||
git:
|
||||
depth: 1
|
||||
|
||||
android:
|
||||
components:
|
||||
- tools
|
||||
- platform-tools
|
||||
- build-tools-30.0.0
|
||||
- android-30
|
||||
|
||||
before_install:
|
||||
- sdkmanager --list
|
||||
|
||||
install:
|
||||
- yes | sdkmanager "ndk;21.0.6113669"
|
||||
@@ -1,15 +1,16 @@
|
||||
# Moonlight Android
|
||||
|
||||
[](https://travis-ci.org/moonlight-stream/moonlight-android)
|
||||
[](https://ci.appveyor.com/project/cgutman/moonlight-android/branch/master)
|
||||
[](https://hosted.weblate.org/projects/moonlight/moonlight-android/)
|
||||
|
||||
[Moonlight for Android](https://moonlight-stream.org) is an open source implementation of NVIDIA's GameStream, as used by the NVIDIA Shield.
|
||||
[Moonlight for Android](https://moonlight-stream.org) is an open source client for NVIDIA GameStream, as used by the NVIDIA Shield.
|
||||
|
||||
Moonlight for Android will allow you to stream your full collection of games from your Windows PC to your Android device,
|
||||
whether in your own home or over the internet.
|
||||
|
||||
Moonlight also has a [PC client](https://github.com/moonlight-stream/moonlight-qt) and [iOS/tvOS client](https://github.com/moonlight-stream/moonlight-ios).
|
||||
|
||||
Check out [the Moonlight wiki](https://github.com/moonlight-stream/moonlight-docs/wiki) for more detailed project information, setup guide, or troubleshooting steps.
|
||||
You can follow development on our [Discord server](https://moonlight-stream.org/discord) and help translate Moonlight into your language on [Weblate](https://hosted.weblate.org/projects/moonlight/moonlight-android/).
|
||||
|
||||
## Downloads
|
||||
* [Google Play Store](https://play.google.com/store/apps/details?id=com.limelight)
|
||||
|
||||
+15
-11
@@ -1,14 +1,16 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 30
|
||||
ndkVersion "23.1.7779620"
|
||||
|
||||
compileSdkVersion 32
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 30
|
||||
targetSdkVersion 32
|
||||
|
||||
versionName "9.8.1"
|
||||
versionCode = 252
|
||||
versionName "10.1"
|
||||
versionCode = 273
|
||||
}
|
||||
|
||||
flavorDimensions "root"
|
||||
@@ -41,9 +43,9 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
lint {
|
||||
disable 'MissingTranslation'
|
||||
lintConfig file("lint.xml")
|
||||
lintConfig file('lint.xml')
|
||||
}
|
||||
|
||||
bundle {
|
||||
@@ -65,7 +67,6 @@ android {
|
||||
applicationIdSuffix ".debug"
|
||||
|
||||
minifyEnabled true
|
||||
useProguard false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
release {
|
||||
@@ -111,13 +112,16 @@ android {
|
||||
path "src/main/jni/Android.mk"
|
||||
}
|
||||
}
|
||||
|
||||
// Generate native debug symbols to allow Google Play to symbolicate our native crashes
|
||||
android.defaultConfig.ndk.debugSymbolLevel = 'FULL'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'org.bouncycastle:bcprov-jdk15on:1.66'
|
||||
implementation 'org.bouncycastle:bcpkix-jdk15on:1.66'
|
||||
implementation 'org.bouncycastle:bcprov-jdk15on:1.70'
|
||||
implementation 'org.bouncycastle:bcpkix-jdk15on:1.70'
|
||||
implementation 'org.jcodec:jcodec:0.2.3'
|
||||
implementation 'com.squareup.okhttp3:okhttp:3.12.12'
|
||||
implementation 'com.squareup.okhttp3:okhttp:3.12.13'
|
||||
implementation 'com.squareup.okio:okio:1.17.5'
|
||||
implementation 'org.jmdns:jmdns:3.5.5'
|
||||
implementation 'org.jmdns:jmdns:3.5.7'
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
android:dataExtractionRules="@xml/backup_rules_s"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:isGame="true"
|
||||
android:banner="@drawable/atv_banner"
|
||||
@@ -64,6 +65,7 @@
|
||||
|
||||
<activity
|
||||
android:name=".PcView"
|
||||
android:exported="true"
|
||||
android:resizeableActivity="true"
|
||||
android:configChanges="mcc|mnc|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection">
|
||||
<intent-filter>
|
||||
@@ -97,6 +99,7 @@
|
||||
<activity
|
||||
android:name=".preferences.StreamSettings"
|
||||
android:resizeableActivity="true"
|
||||
android:configChanges="mcc|mnc|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection"
|
||||
android:label="Streaming Settings">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
@@ -106,6 +109,7 @@
|
||||
android:name=".preferences.AddComputerManually"
|
||||
android:resizeableActivity="true"
|
||||
android:windowSoftInputMode="stateVisible"
|
||||
android:configChanges="mcc|mnc|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection"
|
||||
android:label="Add Computer Manually">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
|
||||
@@ -78,7 +78,6 @@ import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
@@ -118,6 +117,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
private boolean displayedFailureDialog = false;
|
||||
private boolean connecting = false;
|
||||
private boolean connected = false;
|
||||
private boolean autoEnterPip = false;
|
||||
private boolean surfaceCreated = false;
|
||||
private boolean attemptedConnection = false;
|
||||
|
||||
@@ -214,9 +214,9 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
prefConfig = PreferenceConfiguration.readPreferences(this);
|
||||
tombstonePrefs = Game.this.getSharedPreferences("DecoderTombstone", 0);
|
||||
|
||||
if (prefConfig.stretchVideo) {
|
||||
if (prefConfig.stretchVideo || shouldIgnoreInsetsForResolution(prefConfig.width, prefConfig.height)) {
|
||||
// Allow the activity to layout under notches if the fill-screen option
|
||||
// was turned on by the user
|
||||
// was turned on by the user or it's a full-screen native resolution
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
getWindow().getAttributes().layoutInDisplayCutoutMode =
|
||||
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
|
||||
@@ -275,7 +275,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
String uniqueId = Game.this.getIntent().getStringExtra(EXTRA_UNIQUEID);
|
||||
String uuid = Game.this.getIntent().getStringExtra(EXTRA_PC_UUID);
|
||||
String pcName = Game.this.getIntent().getStringExtra(EXTRA_PC_NAME);
|
||||
boolean willStreamHdr = Game.this.getIntent().getBooleanExtra(EXTRA_APP_HDR, false);
|
||||
boolean appSupportsHdr = Game.this.getIntent().getBooleanExtra(EXTRA_APP_HDR, false);
|
||||
byte[] derCertData = Game.this.getIntent().getByteArrayExtra(EXTRA_SERVER_CERT);
|
||||
|
||||
X509Certificate serverCert = null;
|
||||
@@ -301,7 +301,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
shortcutHelper.reportComputerShortcutUsed(computer);
|
||||
if (appName != null) {
|
||||
// This may be null if launched from the "Resume Session" PC context menu item
|
||||
shortcutHelper.reportGameLaunched(computer, new NvApp(appName, appId, willStreamHdr));
|
||||
shortcutHelper.reportGameLaunched(computer, new NvApp(appName, appId, appSupportsHdr));
|
||||
}
|
||||
|
||||
// Initialize the MediaCodec helper before creating the decoder
|
||||
@@ -309,42 +309,33 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
MediaCodecHelper.initialize(this, glPrefs.glRenderer);
|
||||
|
||||
// Check if the user has enabled HDR
|
||||
boolean willStreamHdr = false;
|
||||
if (prefConfig.enableHdr) {
|
||||
// Check if the app supports it
|
||||
if (!willStreamHdr) {
|
||||
Toast.makeText(this, "This game does not support HDR10", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
// It does, so start our HDR checklist
|
||||
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
// We already know the app supports HDR if willStreamHdr is set.
|
||||
// Start our HDR checklist
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
Display display = getWindowManager().getDefaultDisplay();
|
||||
Display.HdrCapabilities hdrCaps = display.getHdrCapabilities();
|
||||
|
||||
// We must now ensure our display is compatible with HDR10
|
||||
boolean foundHdr10 = false;
|
||||
if (hdrCaps != null) {
|
||||
// getHdrCapabilities() returns null on Lenovo Lenovo Mirage Solo (vega), Android 8.0
|
||||
for (int hdrType : hdrCaps.getSupportedHdrTypes()) {
|
||||
if (hdrType == Display.HdrCapabilities.HDR_TYPE_HDR10) {
|
||||
foundHdr10 = true;
|
||||
willStreamHdr = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundHdr10) {
|
||||
if (!willStreamHdr) {
|
||||
// Nope, no HDR for us :(
|
||||
willStreamHdr = false;
|
||||
Toast.makeText(this, "Display does not support HDR10", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
else {
|
||||
Toast.makeText(this, "HDR requires Android 7.0 or later", Toast.LENGTH_LONG).show();
|
||||
willStreamHdr = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
willStreamHdr = false;
|
||||
}
|
||||
|
||||
// Check if the user has enabled performance stats overlay
|
||||
if (prefConfig.enablePerfOverlay) {
|
||||
@@ -377,9 +368,9 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
Toast.makeText(this, "Decoder does not support HEVC Main10HDR10", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
// Display a message to the user if H.265 was forced on but we still didn't find a decoder
|
||||
// Display a message to the user if HEVC was forced on but we still didn't find a decoder
|
||||
if (prefConfig.videoFormat == PreferenceConfiguration.FORCE_H265_ON && !decoderRenderer.isHevcSupported()) {
|
||||
Toast.makeText(this, "No H.265 decoder found.\nFalling back to H.264.", Toast.LENGTH_LONG).show();
|
||||
Toast.makeText(this, "No HEVC decoder found.\nFalling back to H.264.", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
int gamepadMask = ControllerHandler.getAttachedControllerMask(this);
|
||||
@@ -398,52 +389,22 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
float displayRefreshRate = prepareDisplayForRendering();
|
||||
LimeLog.info("Display refresh rate: "+displayRefreshRate);
|
||||
|
||||
// HACK: Despite many efforts to ensure low latency consistent frame
|
||||
// delivery, the best non-lossy mechanism is to buffer 1 extra frame
|
||||
// in the output pipeline. Android does some buffering on its end
|
||||
// in SurfaceFlinger and it's difficult (impossible?) to inspect
|
||||
// the precise state of the buffer queue to the screen after we
|
||||
// release a frame for rendering.
|
||||
//
|
||||
// Since buffering a frame adds latency and we are primarily a
|
||||
// latency-optimized client, rather than one designed for picture-perfect
|
||||
// accuracy, we will synthetically induce a negative pressure on the display
|
||||
// output pipeline by driving the decoder input pipeline under the speed
|
||||
// that the display can refresh. This ensures a constant negative pressure
|
||||
// to keep latency down but does induce a periodic frame loss. However, this
|
||||
// periodic frame loss is *way* less than what we'd already get in Marshmallow's
|
||||
// display pipeline where frames are dropped outside of our control if they land
|
||||
// on the same V-sync.
|
||||
//
|
||||
// Hopefully, we can get rid of this once someone comes up with a better way
|
||||
// to track the state of the pipeline and time frames.
|
||||
// If the user requested frame pacing using a capped FPS, we will need to change our
|
||||
// desired FPS setting here in accordance with the active display refresh rate.
|
||||
int roundedRefreshRate = Math.round(displayRefreshRate);
|
||||
int chosenFrameRate = prefConfig.fps;
|
||||
if (!prefConfig.disableFrameDrop || prefConfig.unlockFps) {
|
||||
if (Build.DEVICE.equals("coral") || Build.DEVICE.equals("flame")) {
|
||||
// HACK: Pixel 4 (XL) ignores the preferred display mode and lowers refresh rate,
|
||||
// causing frame pacing issues. See https://issuetracker.google.com/issues/143401475
|
||||
// To work around this, use frame drop mode if we want to stream at >= 60 FPS.
|
||||
if (prefConfig.fps >= 60) {
|
||||
LimeLog.info("Using Pixel 4 rendering hack");
|
||||
decoderRenderer.enableLegacyFrameDropRendering();
|
||||
}
|
||||
}
|
||||
else if (prefConfig.fps >= roundedRefreshRate) {
|
||||
if (prefConfig.unlockFps) {
|
||||
if (prefConfig.framePacing == PreferenceConfiguration.FRAME_PACING_CAP_FPS) {
|
||||
if (prefConfig.fps >= roundedRefreshRate) {
|
||||
if (prefConfig.fps > roundedRefreshRate + 3) {
|
||||
// Use frame drops when rendering above the screen frame rate
|
||||
decoderRenderer.enableLegacyFrameDropRendering();
|
||||
prefConfig.framePacing = PreferenceConfiguration.FRAME_PACING_BALANCED;
|
||||
LimeLog.info("Using drop mode for FPS > Hz");
|
||||
} else if (roundedRefreshRate <= 49) {
|
||||
// Let's avoid clearly bogus refresh rates and fall back to legacy rendering
|
||||
decoderRenderer.enableLegacyFrameDropRendering();
|
||||
prefConfig.framePacing = PreferenceConfiguration.FRAME_PACING_BALANCED;
|
||||
LimeLog.info("Bogus refresh rate: " + roundedRefreshRate);
|
||||
}
|
||||
// HACK: Avoid crashing on some MTK devices
|
||||
else if (decoderRenderer.isBlacklistedForFrameRate(roundedRefreshRate - 1)) {
|
||||
// Use the old rendering strategy on these broken devices
|
||||
decoderRenderer.enableLegacyFrameDropRendering();
|
||||
} else {
|
||||
else {
|
||||
chosenFrameRate = roundedRefreshRate - 1;
|
||||
LimeLog.info("Adjusting FPS target for screen to " + chosenFrameRate);
|
||||
}
|
||||
@@ -459,7 +420,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
.setResolution(prefConfig.width, prefConfig.height)
|
||||
.setLaunchRefreshRate(prefConfig.fps)
|
||||
.setRefreshRate(chosenFrameRate)
|
||||
.setApp(new NvApp(appName != null ? appName : "app", appId, willStreamHdr))
|
||||
.setApp(new NvApp(appName != null ? appName : "app", appId, appSupportsHdr))
|
||||
.setBitrate(prefConfig.bitrate)
|
||||
.setEnableSops(prefConfig.enableSops)
|
||||
.enableLocalAudioPlayback(prefConfig.playHostAudio)
|
||||
@@ -473,6 +434,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
.setAttachedGamepadMask(gamepadMask)
|
||||
.setClientRefreshRateX100((int)(displayRefreshRate * 100))
|
||||
.setAudioConfiguration(prefConfig.audioConfiguration)
|
||||
.setAudioEncryption(true)
|
||||
.build();
|
||||
|
||||
// Initialize the connection
|
||||
@@ -570,23 +532,49 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
}
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
private PictureInPictureParams getPictureInPictureParams(boolean autoEnter) {
|
||||
PictureInPictureParams.Builder builder =
|
||||
new PictureInPictureParams.Builder()
|
||||
.setAspectRatio(new Rational(prefConfig.width, prefConfig.height))
|
||||
.setSourceRectHint(new Rect(
|
||||
streamView.getLeft(), streamView.getTop(),
|
||||
streamView.getRight(), streamView.getBottom()));
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
builder.setAutoEnterEnabled(autoEnter);
|
||||
builder.setSeamlessResizeEnabled(true);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private void setPipAutoEnter(boolean autoEnter) {
|
||||
if (!prefConfig.enablePip) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
setPictureInPictureParams(getPictureInPictureParams(autoEnter));
|
||||
}
|
||||
else {
|
||||
autoEnterPip = autoEnter;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserLeaveHint() {
|
||||
super.onUserLeaveHint();
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
if (prefConfig.enablePip && connected) {
|
||||
// PiP is only supported on Oreo and later, and we don't need to manually enter PiP on
|
||||
// Android S and later.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
||||
if (autoEnterPip) {
|
||||
try {
|
||||
// This has thrown all sorts of weird exceptions on Samsung devices
|
||||
// running Oreo. Just eat them and close gracefully on leave, rather
|
||||
// than crashing.
|
||||
enterPictureInPictureMode(
|
||||
new PictureInPictureParams.Builder()
|
||||
.setAspectRatio(new Rational(prefConfig.width, prefConfig.height))
|
||||
.setSourceRectHint(new Rect(
|
||||
streamView.getLeft(), streamView.getTop(),
|
||||
streamView.getRight(), streamView.getBottom()))
|
||||
.build());
|
||||
enterPictureInPictureMode(getPictureInPictureParams(false));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -598,23 +586,18 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// Capture is lost when focus is lost, so it must be requested again
|
||||
// when focus is regained.
|
||||
if (inputCaptureProvider.isCapturingEnabled() && hasFocus) {
|
||||
// Recapture the pointer if focus was regained. On Android Q,
|
||||
// we have to delay a bit before requesting capture because otherwise
|
||||
// we'll hit the "requestPointerCapture called for a window that has no focus"
|
||||
// error and it will not actually capture the cursor.
|
||||
Handler h = new Handler();
|
||||
h.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
streamView.requestPointerCapture();
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
// We can't guarantee the state of modifiers keys which may have
|
||||
// lifted while focus was not on us. Clear the modifier state.
|
||||
this.modifierFlags = 0;
|
||||
|
||||
// With Android native pointer capture, capture is lost when focus is lost,
|
||||
// so it must be requested again when focus is regained.
|
||||
inputCaptureProvider.onWindowFocusChanged(hasFocus);
|
||||
}
|
||||
|
||||
private boolean isRefreshRateEqualMatch(float refreshRate) {
|
||||
return refreshRate >= prefConfig.fps &&
|
||||
refreshRate <= prefConfig.fps + 3;
|
||||
}
|
||||
|
||||
private boolean isRefreshRateGoodMatch(float refreshRate) {
|
||||
@@ -622,6 +605,26 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
Math.round(refreshRate) % prefConfig.fps <= 3;
|
||||
}
|
||||
|
||||
private boolean shouldIgnoreInsetsForResolution(int width, int height) {
|
||||
// Never ignore insets for non-native resolutions
|
||||
if (!PreferenceConfiguration.isNativeResolution(width, height)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
Display display = getWindowManager().getDefaultDisplay();
|
||||
for (Display.Mode candidate : display.getSupportedModes()) {
|
||||
// Ignore insets if this is an exact match for the display resolution
|
||||
if ((width == candidate.getPhysicalWidth() && height == candidate.getPhysicalHeight()) ||
|
||||
(height == candidate.getPhysicalWidth() && width == candidate.getPhysicalHeight())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private float prepareDisplayForRendering() {
|
||||
Display display = getWindowManager().getDefaultDisplay();
|
||||
WindowManager.LayoutParams windowLayoutParams = getWindow().getAttributes();
|
||||
@@ -632,6 +635,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
Display.Mode bestMode = display.getMode();
|
||||
boolean isNativeResolutionStream = PreferenceConfiguration.isNativeResolution(prefConfig.width, prefConfig.height);
|
||||
boolean refreshRateIsGood = isRefreshRateGoodMatch(bestMode.getRefreshRate());
|
||||
boolean refreshRateIsEqual = isRefreshRateEqualMatch(bestMode.getRefreshRate());
|
||||
for (Display.Mode candidate : display.getSupportedModes()) {
|
||||
boolean refreshRateReduced = candidate.getRefreshRate() < bestMode.getRefreshRate();
|
||||
boolean resolutionReduced = candidate.getPhysicalWidth() < bestMode.getPhysicalWidth() ||
|
||||
@@ -663,12 +667,30 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (refreshRateIsGood) {
|
||||
// We have a good matching refresh rate, so we're looking for equal or greater
|
||||
// that is also a good matching refresh rate for our stream frame rate.
|
||||
if (refreshRateReduced || !isRefreshRateGoodMatch(candidate.getRefreshRate())) {
|
||||
if (prefConfig.framePacing != PreferenceConfiguration.FRAME_PACING_MIN_LATENCY &&
|
||||
refreshRateIsEqual && !isRefreshRateEqualMatch(candidate.getRefreshRate())) {
|
||||
// If we had an equal refresh rate and this one is not, skip it. In min latency
|
||||
// mode, we want to always prefer the highest frame rate even though it may cause
|
||||
// microstuttering.
|
||||
continue;
|
||||
}
|
||||
else if (refreshRateIsGood) {
|
||||
// We've already got a good match, so if this one isn't also good, it's not
|
||||
// worth considering at all.
|
||||
if (!isRefreshRateGoodMatch(candidate.getRefreshRate())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// We don't want ever reduce our refresh rate unless we found an exact
|
||||
// match and we're not in min latency mode.
|
||||
if (refreshRateReduced) {
|
||||
if (prefConfig.framePacing == PreferenceConfiguration.FRAME_PACING_MIN_LATENCY) {
|
||||
continue;
|
||||
}
|
||||
else if (!isRefreshRateEqualMatch(candidate.getRefreshRate())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!isRefreshRateGoodMatch(candidate.getRefreshRate())) {
|
||||
// We didn't have a good match and this match isn't good either, so just don't
|
||||
@@ -685,6 +707,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
|
||||
bestMode = candidate;
|
||||
refreshRateIsGood = isRefreshRateGoodMatch(candidate.getRefreshRate());
|
||||
refreshRateIsEqual = isRefreshRateEqualMatch(candidate.getRefreshRate());
|
||||
}
|
||||
LimeLog.info("Selected display mode: "+bestMode.getPhysicalWidth()+"x"+
|
||||
bestMode.getPhysicalHeight()+"x"+bestMode.getRefreshRate());
|
||||
@@ -765,9 +788,9 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
return displayRefreshRate;
|
||||
}
|
||||
else {
|
||||
// Use the actual refresh rate of the display, since the preferred refresh rate or mode
|
||||
// may not actually be applied (ex: Pixel 4 with Smooth Display disabled).
|
||||
return getWindowManager().getDefaultDisplay().getRefreshRate();
|
||||
// Use the lower of the current refresh rate and the selected refresh rate.
|
||||
// The preferred refresh rate may not actually be applied (ex: Battery Saver mode).
|
||||
return Math.min(getWindowManager().getDefaultDisplay().getRefreshRate(), displayRefreshRate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -775,6 +798,9 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
private final Runnable hideSystemUi = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// TODO: Do we want to use WindowInsetsController here on R+ instead of
|
||||
// SYSTEM_UI_FLAG_IMMERSIVE_STICKY? They seem to do the same thing as of S...
|
||||
|
||||
// In multi-window mode on N+, we need to drop our layout flags or we'll
|
||||
// be drawing underneath the system UI.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && isInMultiWindowMode()) {
|
||||
@@ -894,10 +920,10 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
// Add the video codec to the post-stream toast
|
||||
if (message != null) {
|
||||
if (videoFormat == MoonBridge.VIDEO_FORMAT_H265_MAIN10) {
|
||||
message += " [H.265 HDR]";
|
||||
message += " [HEVC HDR]";
|
||||
}
|
||||
else if (videoFormat == MoonBridge.VIDEO_FORMAT_H265) {
|
||||
message += " [H.265]";
|
||||
message += " [HEVC]";
|
||||
}
|
||||
else if (videoFormat == MoonBridge.VIDEO_FORMAT_H264) {
|
||||
message += " [H.264]";
|
||||
@@ -996,8 +1022,14 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
return false;
|
||||
}
|
||||
|
||||
private static byte getModifierState(KeyEvent event) {
|
||||
byte modifier = 0;
|
||||
// We cannot simply use modifierFlags for all key event processing, because
|
||||
// some IMEs will not generate real key events for pressing Shift. Instead
|
||||
// they will simply send key events with isShiftPressed() returning true,
|
||||
// and we will need to send the modifier flag ourselves.
|
||||
private byte getModifierState(KeyEvent event) {
|
||||
// Start with the global modifier state to ensure we cover the case
|
||||
// detailed in https://github.com/moonlight-stream/moonlight-android/issues/840
|
||||
byte modifier = getModifierState();
|
||||
if (event.isShiftPressed()) {
|
||||
modifier |= KeyboardPacket.MODIFIER_SHIFT;
|
||||
}
|
||||
@@ -1029,8 +1061,9 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
// Handle a synthetic back button event that some Android OS versions
|
||||
// create as a result of a right-click. This event WILL repeat if
|
||||
// the right mouse button is held down, so we ignore those.
|
||||
if ((event.getSource() == InputDevice.SOURCE_MOUSE ||
|
||||
event.getSource() == InputDevice.SOURCE_MOUSE_RELATIVE) &&
|
||||
int eventSource = event.getSource();
|
||||
if ((eventSource == InputDevice.SOURCE_MOUSE ||
|
||||
eventSource == InputDevice.SOURCE_MOUSE_RELATIVE) &&
|
||||
event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
|
||||
|
||||
// Send the right mouse button event if mouse back and forward
|
||||
@@ -1078,7 +1111,6 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
byte modifiers = getModifierState(event);
|
||||
if (KeyboardTranslator.needsShift(event.getKeyCode())) {
|
||||
modifiers |= KeyboardPacket.MODIFIER_SHIFT;
|
||||
conn.sendKeyboardInput((short) 0x8010, KeyboardPacket.KEY_DOWN, modifiers);
|
||||
}
|
||||
conn.sendKeyboardInput(translated, KeyboardPacket.KEY_DOWN, modifiers);
|
||||
}
|
||||
@@ -1100,8 +1132,9 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
|
||||
// Handle a synthetic back button event that some Android OS versions
|
||||
// create as a result of a right-click.
|
||||
if ((event.getSource() == InputDevice.SOURCE_MOUSE ||
|
||||
event.getSource() == InputDevice.SOURCE_MOUSE_RELATIVE) &&
|
||||
int eventSource = event.getSource();
|
||||
if ((eventSource == InputDevice.SOURCE_MOUSE ||
|
||||
eventSource == InputDevice.SOURCE_MOUSE_RELATIVE) &&
|
||||
event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
|
||||
|
||||
// Send the right mouse button event if mouse back and forward
|
||||
@@ -1144,9 +1177,6 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
modifiers |= KeyboardPacket.MODIFIER_SHIFT;
|
||||
}
|
||||
conn.sendKeyboardInput(translated, KeyboardPacket.KEY_UP, modifiers);
|
||||
if (KeyboardTranslator.needsShift(event.getKeyCode())) {
|
||||
conn.sendKeyboardInput((short) 0x8010, KeyboardPacket.KEY_UP, getModifierState(event));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1177,17 +1207,20 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
|
||||
int eventSource = event.getSource();
|
||||
if ((eventSource & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
|
||||
if (controllerHandler.handleMotionEvent(event)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0 ||
|
||||
event.getSource() == InputDevice.SOURCE_MOUSE_RELATIVE)
|
||||
else if ((eventSource & InputDevice.SOURCE_CLASS_POINTER) != 0 ||
|
||||
(eventSource & InputDevice.SOURCE_CLASS_POSITION) != 0 ||
|
||||
eventSource == InputDevice.SOURCE_MOUSE_RELATIVE)
|
||||
{
|
||||
// This case is for mice and non-finger touch devices
|
||||
if (event.getSource() == InputDevice.SOURCE_MOUSE ||
|
||||
event.getSource() == InputDevice.SOURCE_MOUSE_RELATIVE ||
|
||||
if (eventSource == InputDevice.SOURCE_MOUSE ||
|
||||
(eventSource & InputDevice.SOURCE_CLASS_POSITION) != 0 || // SOURCE_TOUCHPAD
|
||||
eventSource == InputDevice.SOURCE_MOUSE_RELATIVE ||
|
||||
(event.getPointerCount() >= 1 &&
|
||||
(event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE ||
|
||||
event.getToolType(0) == MotionEvent.TOOL_TYPE_STYLUS ||
|
||||
@@ -1214,15 +1247,40 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
conn.sendMouseMove(deltaX, deltaY);
|
||||
}
|
||||
}
|
||||
else if ((eventSource & InputDevice.SOURCE_CLASS_POSITION) != 0) {
|
||||
// If this input device is not associated with the view itself (like a trackpad),
|
||||
// we'll convert the device-specific coordinates to use to send the cursor position.
|
||||
// This really isn't ideal but it's probably better than nothing.
|
||||
//
|
||||
// Trackpad on newer versions of Android (Oreo and later) should be caught by the
|
||||
// relative axes case above. If we get here, we're on an older version that doesn't
|
||||
// support pointer capture.
|
||||
InputDevice device = event.getDevice();
|
||||
if (device != null) {
|
||||
InputDevice.MotionRange xRange = device.getMotionRange(MotionEvent.AXIS_X, eventSource);
|
||||
InputDevice.MotionRange yRange = device.getMotionRange(MotionEvent.AXIS_Y, eventSource);
|
||||
|
||||
// All touchpads coordinate planes should start at (0, 0)
|
||||
if (xRange != null && yRange != null && xRange.getMin() == 0 && yRange.getMin() == 0) {
|
||||
int xMax = (int)xRange.getMax();
|
||||
int yMax = (int)yRange.getMax();
|
||||
|
||||
// Touchpads must be smaller than (65535, 65535)
|
||||
if (xMax <= Short.MAX_VALUE && yMax <= Short.MAX_VALUE) {
|
||||
conn.sendMousePosition((short)event.getX(), (short)event.getY(),
|
||||
(short)xMax, (short)yMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (view != null) {
|
||||
// Otherwise send absolute position
|
||||
// Otherwise send absolute position based on the view for SOURCE_CLASS_POINTER
|
||||
updateMousePosition(view, event);
|
||||
}
|
||||
|
||||
if (event.getActionMasked() == MotionEvent.ACTION_SCROLL) {
|
||||
// Send the vertical scroll packet
|
||||
byte vScrollClicks = (byte) event.getAxisValue(MotionEvent.AXIS_VSCROLL);
|
||||
conn.sendMouseScroll(vScrollClicks);
|
||||
conn.sendMouseHighResScroll((short)(event.getAxisValue(MotionEvent.AXIS_VSCROLL) * 120));
|
||||
}
|
||||
|
||||
if ((changedButtons & MotionEvent.BUTTON_PRIMARY) != 0) {
|
||||
@@ -1510,6 +1568,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
|
||||
private void stopConnection() {
|
||||
if (connecting || connected) {
|
||||
setPipAutoEnter(false);
|
||||
connecting = connected = false;
|
||||
|
||||
controllerHandler.stop();
|
||||
@@ -1608,6 +1667,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
break;
|
||||
|
||||
case MoonBridge.ML_ERROR_UNEXPECTED_EARLY_TERMINATION:
|
||||
case MoonBridge.ML_ERROR_PROTECTED_CONTENT:
|
||||
message = getResources().getString(R.string.early_termination_error);
|
||||
break;
|
||||
|
||||
@@ -1673,6 +1733,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
spinner = null;
|
||||
}
|
||||
|
||||
setPipAutoEnter(true);
|
||||
connected = true;
|
||||
connecting = false;
|
||||
|
||||
@@ -1726,6 +1787,12 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
||||
controllerHandler.handleRumble(controllerNumber, lowFreqMotor, highFreqMotor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHdrMode(boolean enabled) {
|
||||
LimeLog.info("Display HDR mode: " + (enabled ? "enabled" : "disabled"));
|
||||
decoderRenderer.setHdrMode(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
|
||||
if (!surfaceCreated) {
|
||||
|
||||
@@ -155,6 +155,13 @@ public class PcView extends Activity implements AdapterFragmentCallbacks {
|
||||
}
|
||||
});
|
||||
|
||||
// Amazon review didn't like the help button because the wiki was not entirely
|
||||
// navigable via the Fire TV remote (though the relevant parts were). Let's hide
|
||||
// it on Fire TV.
|
||||
if (getPackageManager().hasSystemFeature("amazon.hardware.fire_tv")) {
|
||||
helpButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
getFragmentManager().beginTransaction()
|
||||
.replace(R.id.pcFragmentContainer, new AdapterFragment())
|
||||
.commitAllowingStateLoss();
|
||||
|
||||
@@ -13,11 +13,13 @@ import com.limelight.computers.ComputerManagerService;
|
||||
import com.limelight.nvstream.http.ComputerDetails;
|
||||
import com.limelight.nvstream.http.NvApp;
|
||||
import com.limelight.nvstream.http.PairingManager;
|
||||
import com.limelight.nvstream.wol.WakeOnLanSender;
|
||||
import com.limelight.utils.Dialog;
|
||||
import com.limelight.utils.ServerHelper;
|
||||
import com.limelight.utils.SpinnerDialog;
|
||||
import com.limelight.utils.UiHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -26,6 +28,7 @@ public class ShortcutTrampoline extends Activity {
|
||||
private NvApp app;
|
||||
private ArrayList<Intent> intentStack = new ArrayList<>();
|
||||
|
||||
private int wakeHostTries = 10;
|
||||
private ComputerDetails computer;
|
||||
private SpinnerDialog blockingLoadSpinner;
|
||||
|
||||
@@ -79,6 +82,23 @@ public class ShortcutTrampoline extends Activity {
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to wake the target PC if it's offline (up to some retry limit)
|
||||
if (details.state == ComputerDetails.State.OFFLINE && --wakeHostTries >= 0) {
|
||||
try {
|
||||
// Make a best effort attempt to wake the target PC
|
||||
WakeOnLanSender.sendWolPacket(computer);
|
||||
|
||||
// If we sent at least one WoL packet, reset the computer state
|
||||
// to force ComputerManager to poll it again.
|
||||
managerBinder.invalidateStateForComputer(computer.uuid);
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
// If we got an exception, we couldn't send a single WoL packet,
|
||||
// so fallthrough into the offline error path.
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (details.state != ComputerDetails.State.UNKNOWN) {
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.limelight.binding.input;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.hardware.input.InputManager;
|
||||
@@ -7,9 +8,11 @@ import android.hardware.usb.UsbDevice;
|
||||
import android.hardware.usb.UsbManager;
|
||||
import android.media.AudioAttributes;
|
||||
import android.os.Build;
|
||||
import android.os.CombinedVibration;
|
||||
import android.os.SystemClock;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.os.VibratorManager;
|
||||
import android.util.SparseArray;
|
||||
import android.view.InputDevice;
|
||||
import android.view.InputEvent;
|
||||
@@ -107,6 +110,8 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
defaultContext.rightStickDeadzoneRadius = (float) stickDeadzone;
|
||||
defaultContext.leftTriggerAxis = MotionEvent.AXIS_BRAKE;
|
||||
defaultContext.rightTriggerAxis = MotionEvent.AXIS_GAS;
|
||||
defaultContext.hatXAxis = MotionEvent.AXIS_HAT_X;
|
||||
defaultContext.hatYAxis = MotionEvent.AXIS_HAT_Y;
|
||||
defaultContext.controllerNumber = (short) 0;
|
||||
defaultContext.assignedControllerNumber = true;
|
||||
defaultContext.external = false;
|
||||
@@ -153,11 +158,36 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
}
|
||||
}
|
||||
|
||||
// This can happen when gaining/losing input focus with some devices.
|
||||
// Input devices that have a trackpad may gain/lose AXIS_RELATIVE_X/Y.
|
||||
@Override
|
||||
public void onInputDeviceChanged(int deviceId) {
|
||||
// Remove and re-add
|
||||
onInputDeviceRemoved(deviceId);
|
||||
onInputDeviceAdded(deviceId);
|
||||
InputDevice device = InputDevice.getDevice(deviceId);
|
||||
if (device == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we don't have a context for this device, we don't need to update anything
|
||||
InputDeviceContext existingContext = inputDeviceContexts.get(deviceId);
|
||||
if (existingContext == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
LimeLog.info("Device changed: "+existingContext.name+" ("+deviceId+")");
|
||||
|
||||
// Don't release the controller number, because we will carry it over if it is present.
|
||||
// We also want to make sure the change is invisible to the host PC to avoid an add/remove
|
||||
// cycle for the gamepad which may break some games.
|
||||
existingContext.destroy();
|
||||
|
||||
InputDeviceContext newContext = createInputDeviceContextForDevice(device);
|
||||
|
||||
// Copy over existing controller number state
|
||||
newContext.assignedControllerNumber = existingContext.assignedControllerNumber;
|
||||
newContext.reservedControllerNumber = existingContext.reservedControllerNumber;
|
||||
newContext.controllerNumber = existingContext.controllerNumber;
|
||||
|
||||
inputDeviceContexts.put(deviceId, newContext);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
@@ -194,6 +224,28 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
return true;
|
||||
}
|
||||
|
||||
// HACK for https://issuetracker.google.com/issues/163120692
|
||||
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R) {
|
||||
if (device.getId() == -1) {
|
||||
// This "virtual" device could be input from any of the attached devices.
|
||||
// Look to see if any gamepads are connected.
|
||||
int[] ids = InputDevice.getDeviceIds();
|
||||
for (int id : ids) {
|
||||
InputDevice dev = InputDevice.getDevice(id);
|
||||
if (dev == null) {
|
||||
// This device was removed during enumeration
|
||||
continue;
|
||||
}
|
||||
|
||||
// If there are any gamepad devices connected, we'll
|
||||
// report that this virtual device is a gamepad.
|
||||
if (hasJoystickAxes(dev) || hasGamepadButtons(dev)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, we'll try anything that claims to be a non-alphabetic keyboard
|
||||
return device.getKeyboardType() != InputDevice.KEYBOARD_TYPE_ALPHABETIC;
|
||||
}
|
||||
@@ -463,7 +515,10 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
context.productId = dev.getProductId();
|
||||
}
|
||||
|
||||
if (dev.getVibrator().hasVibrator()) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && hasDualAmplitudeControlledRumbleVibrators(dev.getVibratorManager())) {
|
||||
context.vibratorManager = dev.getVibratorManager();
|
||||
}
|
||||
else if (dev.getVibrator().hasVibrator()) {
|
||||
context.vibrator = dev.getVibrator();
|
||||
}
|
||||
|
||||
@@ -703,6 +758,13 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
return null;
|
||||
}
|
||||
|
||||
// HACK for https://issuetracker.google.com/issues/163120692
|
||||
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.R) {
|
||||
if (event.getDeviceId() == -1) {
|
||||
return defaultContext;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the existing context if it exists
|
||||
InputDeviceContext context = inputDeviceContexts.get(event.getDeviceId());
|
||||
if (context != null) {
|
||||
@@ -864,7 +926,10 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
return KeyEvent.KEYCODE_BUTTON_MODE;
|
||||
}
|
||||
|
||||
if ((context.vendorId == 0x057e && context.productId == 0x2009) || // Switch Pro controller
|
||||
// This mapping was adding in Android 10, then changed based on
|
||||
// kernel changes (adding hid-nintendo) in Android 11. If we're
|
||||
// on anything newer than Pie, just use the built-in mapping.
|
||||
if ((context.vendorId == 0x057e && context.productId == 0x2009 && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) || // Switch Pro controller
|
||||
(context.vendorId == 0x0f0d && context.productId == 0x00c1)) { // HORIPAD for Switch
|
||||
switch (event.getScanCode()) {
|
||||
case 0x130:
|
||||
@@ -1249,7 +1314,58 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
}
|
||||
}
|
||||
|
||||
private void rumbleVibrator(Vibrator vibrator, short lowFreqMotor, short highFreqMotor) {
|
||||
@TargetApi(31)
|
||||
private boolean hasDualAmplitudeControlledRumbleVibrators(VibratorManager vm) {
|
||||
int[] vibratorIds = vm.getVibratorIds();
|
||||
|
||||
// There must be exactly 2 vibrators on this device
|
||||
if (vibratorIds.length != 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Both vibrators must have amplitude control
|
||||
for (int vid : vibratorIds) {
|
||||
if (!vm.getVibrator(vid).hasAmplitudeControl()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// This must only be called if hasDualAmplitudeControlledRumbleVibrators() is true!
|
||||
@TargetApi(31)
|
||||
private void rumbleDualVibrators(VibratorManager vm, short lowFreqMotor, short highFreqMotor) {
|
||||
// Normalize motor values to 0-255 amplitudes for VibrationManager
|
||||
highFreqMotor = (short)((highFreqMotor >> 8) & 0xFF);
|
||||
lowFreqMotor = (short)((lowFreqMotor >> 8) & 0xFF);
|
||||
|
||||
// If they're both zero, we can just call cancel().
|
||||
if (lowFreqMotor == 0 && highFreqMotor == 0) {
|
||||
vm.cancel();
|
||||
return;
|
||||
}
|
||||
|
||||
// There's no documentation that states that vibrators for FF_RUMBLE input devices will
|
||||
// always be enumerated in this order, but it seems consistent between Xbox Series X (USB),
|
||||
// PS3 (USB), and PS4 (USB+BT) controllers on Android 12 Beta 3.
|
||||
int[] vibratorIds = vm.getVibratorIds();
|
||||
int[] vibratorAmplitudes = new int[] { highFreqMotor, lowFreqMotor };
|
||||
|
||||
CombinedVibration.ParallelCombination combo = CombinedVibration.startParallel();
|
||||
|
||||
for (int i = 0; i < vibratorIds.length; i++) {
|
||||
// It's illegal to create a VibrationEffect with an amplitude of 0.
|
||||
// Simply excluding that vibrator from our ParallelCombination will turn it off.
|
||||
if (vibratorAmplitudes[i] != 0) {
|
||||
combo.addVibrator(vibratorIds[i], VibrationEffect.createOneShot(60000, vibratorAmplitudes[i]));
|
||||
}
|
||||
}
|
||||
|
||||
vm.vibrate(combo.combine());
|
||||
}
|
||||
|
||||
private void rumbleSingleVibrator(Vibrator vibrator, short lowFreqMotor, short highFreqMotor) {
|
||||
// Since we can only use a single amplitude value, compute the desired amplitude
|
||||
// by taking 80% of the big motor and 33% of the small motor, then capping to 255.
|
||||
// NB: This value is now 0-255 as required by VibrationEffect.
|
||||
@@ -1305,9 +1421,13 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
if (deviceContext.controllerNumber == controllerNumber) {
|
||||
foundMatchingDevice = true;
|
||||
|
||||
if (deviceContext.vibrator != null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && deviceContext.vibratorManager != null) {
|
||||
vibrated = true;
|
||||
rumbleVibrator(deviceContext.vibrator, lowFreqMotor, highFreqMotor);
|
||||
rumbleDualVibrators(deviceContext.vibratorManager, lowFreqMotor, highFreqMotor);
|
||||
}
|
||||
else if (deviceContext.vibrator != null) {
|
||||
vibrated = true;
|
||||
rumbleSingleVibrator(deviceContext.vibrator, lowFreqMotor, highFreqMotor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1327,12 +1447,12 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
// controls that triggered the rumble. Vibrate the device if
|
||||
// the user has requested that behavior.
|
||||
if (!foundMatchingDevice && prefConfig.onscreenController && !prefConfig.onlyL3R3 && prefConfig.vibrateOsc) {
|
||||
rumbleVibrator(deviceVibrator, lowFreqMotor, highFreqMotor);
|
||||
rumbleSingleVibrator(deviceVibrator, lowFreqMotor, highFreqMotor);
|
||||
}
|
||||
else if (foundMatchingDevice && !vibrated && prefConfig.vibrateFallbackToDevice) {
|
||||
// We found a device to vibrate but it didn't have rumble support. The user
|
||||
// has requested us to vibrate the device in this case.
|
||||
rumbleVibrator(deviceVibrator, lowFreqMotor, highFreqMotor);
|
||||
rumbleSingleVibrator(deviceVibrator, lowFreqMotor, highFreqMotor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1769,6 +1889,7 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
|
||||
class InputDeviceContext extends GenericControllerContext {
|
||||
public String name;
|
||||
public VibratorManager vibratorManager;
|
||||
public Vibrator vibrator;
|
||||
|
||||
public int leftStickXAxis = -1;
|
||||
@@ -1815,7 +1936,10 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
|
||||
public void destroy() {
|
||||
super.destroy();
|
||||
|
||||
if (vibrator != null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && vibratorManager != null) {
|
||||
vibratorManager.cancel();
|
||||
}
|
||||
else if (vibrator != null) {
|
||||
vibrator.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
+106
-7
@@ -2,7 +2,9 @@ package com.limelight.binding.input.capture;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.hardware.input.InputManager;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.view.InputDevice;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
@@ -12,11 +14,13 @@ import android.view.View;
|
||||
// pointer icon hiding behavior over our stream view just in case pointer capture
|
||||
// is unavailable on this system (ex: DeX, ChromeOS)
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
public class AndroidNativePointerCaptureProvider extends AndroidPointerIconCaptureProvider {
|
||||
public class AndroidNativePointerCaptureProvider extends AndroidPointerIconCaptureProvider implements InputManager.InputDeviceListener {
|
||||
private InputManager inputManager;
|
||||
private View targetView;
|
||||
|
||||
public AndroidNativePointerCaptureProvider(Activity activity, View targetView) {
|
||||
super(activity, targetView);
|
||||
this.inputManager = activity.getSystemService(InputManager.class);
|
||||
this.targetView = targetView;
|
||||
}
|
||||
|
||||
@@ -24,38 +28,133 @@ public class AndroidNativePointerCaptureProvider extends AndroidPointerIconCaptu
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
|
||||
}
|
||||
|
||||
// We only capture the pointer if we have a compatible InputDevice
|
||||
// present. This is a workaround for an Android 12 regression causing
|
||||
// incorrect mouse input when using the SPen.
|
||||
// https://github.com/moonlight-stream/moonlight-android/issues/1030
|
||||
private boolean hasCaptureCompatibleInputDevice() {
|
||||
for (int id : InputDevice.getDeviceIds()) {
|
||||
InputDevice device = InputDevice.getDevice(id);
|
||||
if (device == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip touchscreens when considering compatible capture devices.
|
||||
// Samsung devices on Android 12 will report a sec_touchpad device
|
||||
// with SOURCE_TOUCHSCREEN, SOURCE_KEYBOARD, and SOURCE_MOUSE.
|
||||
// Upon enabling pointer capture, that device will switch to
|
||||
// SOURCE_KEYBOARD and SOURCE_TOUCHPAD.
|
||||
if (device.supportsSource(InputDevice.SOURCE_TOUCHSCREEN)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (device.supportsSource(InputDevice.SOURCE_MOUSE) ||
|
||||
device.supportsSource(InputDevice.SOURCE_MOUSE_RELATIVE) ||
|
||||
device.supportsSource(InputDevice.SOURCE_TOUCHPAD)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableCapture() {
|
||||
super.enableCapture();
|
||||
targetView.requestPointerCapture();
|
||||
|
||||
// Listen for device events to enable/disable capture
|
||||
inputManager.registerInputDeviceListener(this, null);
|
||||
|
||||
// Capture now if we have a capture-capable device
|
||||
if (hasCaptureCompatibleInputDevice()) {
|
||||
targetView.requestPointerCapture();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disableCapture() {
|
||||
super.disableCapture();
|
||||
inputManager.unregisterInputDeviceListener(this);
|
||||
targetView.releasePointerCapture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean focusActive) {
|
||||
if (!focusActive || !isCapturing) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Recapture the pointer if focus was regained. On Android Q,
|
||||
// we have to delay a bit before requesting capture because otherwise
|
||||
// we'll hit the "requestPointerCapture called for a window that has no focus"
|
||||
// error and it will not actually capture the cursor.
|
||||
Handler h = new Handler();
|
||||
h.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (hasCaptureCompatibleInputDevice()) {
|
||||
targetView.requestPointerCapture();
|
||||
}
|
||||
}
|
||||
}, 500);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean eventHasRelativeMouseAxes(MotionEvent event) {
|
||||
return event.getSource() == InputDevice.SOURCE_MOUSE_RELATIVE;
|
||||
// SOURCE_MOUSE_RELATIVE is how SOURCE_MOUSE appears when our view has pointer capture.
|
||||
// SOURCE_TOUCHPAD will have relative axes populated iff our view has pointer capture.
|
||||
// See https://developer.android.com/reference/android/view/View#requestPointerCapture()
|
||||
int eventSource = event.getSource();
|
||||
return (eventSource == InputDevice.SOURCE_MOUSE_RELATIVE && event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE) ||
|
||||
(eventSource == InputDevice.SOURCE_TOUCHPAD && targetView.hasPointerCapture());
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getRelativeAxisX(MotionEvent event) {
|
||||
float x = event.getX();
|
||||
int axis = (event.getSource() == InputDevice.SOURCE_MOUSE_RELATIVE) ?
|
||||
MotionEvent.AXIS_X : MotionEvent.AXIS_RELATIVE_X;
|
||||
float x = event.getAxisValue(axis);
|
||||
for (int i = 0; i < event.getHistorySize(); i++) {
|
||||
x += event.getHistoricalX(i);
|
||||
x += event.getHistoricalAxisValue(axis, i);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getRelativeAxisY(MotionEvent event) {
|
||||
float y = event.getY();
|
||||
int axis = (event.getSource() == InputDevice.SOURCE_MOUSE_RELATIVE) ?
|
||||
MotionEvent.AXIS_Y : MotionEvent.AXIS_RELATIVE_Y;
|
||||
float y = event.getAxisValue(axis);
|
||||
for (int i = 0; i < event.getHistorySize(); i++) {
|
||||
y += event.getHistoricalY(i);
|
||||
y += event.getHistoricalAxisValue(axis, i);
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInputDeviceAdded(int deviceId) {
|
||||
// Check if we've added a capture-compatible device
|
||||
if (!targetView.hasPointerCapture() && hasCaptureCompatibleInputDevice()) {
|
||||
targetView.requestPointerCapture();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInputDeviceRemoved(int deviceId) {
|
||||
// Check if the capture-compatible device was removed
|
||||
if (targetView.hasPointerCapture() && !hasCaptureCompatibleInputDevice()) {
|
||||
targetView.releasePointerCapture();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInputDeviceChanged(int deviceId) {
|
||||
// Emulating a remove+add should be sufficient for our purposes.
|
||||
//
|
||||
// Note: This callback must be handled carefully because it can happen as a result of
|
||||
// calling requestPointerCapture(). This can cause trackpad devices to gain SOURCE_MOUSE_RELATIVE
|
||||
// and re-enter this callback.
|
||||
onInputDeviceRemoved(deviceId);
|
||||
onInputDeviceAdded(deviceId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,4 +33,6 @@ public abstract class InputCaptureProvider {
|
||||
public float getRelativeAxisY(MotionEvent event) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void onWindowFocusChanged(boolean focusActive) {}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,12 @@ public class UsbDriverService extends Service implements UsbDriverListener {
|
||||
// just returning a false result or returning 0 enumerated devices,
|
||||
// they throw an undocumented SecurityException from this call, crashing
|
||||
// the whole app. :(
|
||||
usbManager.requestPermission(device, PendingIntent.getBroadcast(UsbDriverService.this, 0, new Intent(ACTION_USB_PERMISSION), 0));
|
||||
int intentFlags = 0;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
// This PendingIntent must be mutable to allow the framework to populate EXTRA_DEVICE and EXTRA_PERMISSION_GRANTED.
|
||||
intentFlags |= PendingIntent.FLAG_MUTABLE;
|
||||
}
|
||||
usbManager.requestPermission(device, PendingIntent.getBroadcast(UsbDriverService.this, 0, new Intent(ACTION_USB_PERMISSION), intentFlags));
|
||||
} catch (SecurityException e) {
|
||||
Toast.makeText(this, this.getText(R.string.error_usb_prohibited), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ public class Xbox360Controller extends AbstractXboxController {
|
||||
0x0f0d, // Hori
|
||||
0x1038, // SteelSeries
|
||||
0x11c9, // Nacon
|
||||
0x1209, // Ardwiino
|
||||
0x12ab, // Unknown
|
||||
0x1430, // RedOctane
|
||||
0x146b, // BigBen
|
||||
@@ -33,8 +34,11 @@ public class Xbox360Controller extends AbstractXboxController {
|
||||
0x15e4, // Numark
|
||||
0x162e, // Joytech
|
||||
0x1689, // Razer Onza
|
||||
0x1949, // Lab126 (Amazon Luna)
|
||||
0x1bad, // Harmonix
|
||||
0x20d6, // PowerA
|
||||
0x24c6, // PowerA
|
||||
0x2f24, // GameSir
|
||||
};
|
||||
|
||||
public static boolean canClaimDevice(UsbDevice device) {
|
||||
|
||||
@@ -21,7 +21,9 @@ public class XboxOneController extends AbstractXboxController {
|
||||
0x0e6f, // Unknown
|
||||
0x0f0d, // Hori
|
||||
0x1532, // Razer Wildcat
|
||||
0x20d6, // PowerA
|
||||
0x24c6, // PowerA
|
||||
0x2e24, // Hyperkin
|
||||
};
|
||||
|
||||
private static final byte[] FW2015_INIT = {0x05, 0x20, 0x00, 0x01, 0x00};
|
||||
|
||||
@@ -23,13 +23,12 @@ public class AbsoluteTouchContext implements TouchContext {
|
||||
private boolean confirmedTap;
|
||||
private Timer longPressTimer;
|
||||
private Timer tapDownTimer;
|
||||
private float accumulatedScrollDelta;
|
||||
|
||||
private final NvConnection conn;
|
||||
private final int actionIndex;
|
||||
private final View targetView;
|
||||
|
||||
private static final int SCROLL_SPEED_DIVISOR = 20;
|
||||
private static final int SCROLL_SPEED_FACTOR = 3;
|
||||
|
||||
private static final int LONG_PRESS_TIME_THRESHOLD = 650;
|
||||
private static final int LONG_PRESS_DISTANCE_THRESHOLD = 30;
|
||||
@@ -65,7 +64,6 @@ public class AbsoluteTouchContext implements TouchContext {
|
||||
lastTouchLocationY = lastTouchDownY = eventY;
|
||||
lastTouchDownTime = SystemClock.uptimeMillis();
|
||||
cancelled = confirmedTap = confirmedLongPress = false;
|
||||
accumulatedScrollDelta = 0;
|
||||
|
||||
if (actionIndex == 0) {
|
||||
// Start the timers
|
||||
@@ -228,11 +226,7 @@ public class AbsoluteTouchContext implements TouchContext {
|
||||
}
|
||||
}
|
||||
else if (actionIndex == 1) {
|
||||
accumulatedScrollDelta += (eventY - lastTouchLocationY) / (float)SCROLL_SPEED_DIVISOR;
|
||||
if ((short)accumulatedScrollDelta != 0) {
|
||||
conn.sendMouseHighResScroll((short)accumulatedScrollDelta);
|
||||
accumulatedScrollDelta -= (short)accumulatedScrollDelta;
|
||||
}
|
||||
conn.sendMouseHighResScroll((short)((eventY - lastTouchLocationY) * SCROLL_SPEED_FACTOR));
|
||||
}
|
||||
|
||||
lastTouchLocationX = eventX;
|
||||
|
||||
@@ -36,7 +36,7 @@ public class RelativeTouchContext implements TouchContext {
|
||||
private static final int TAP_TIME_THRESHOLD = 250;
|
||||
private static final int DRAG_TIME_THRESHOLD = 650;
|
||||
|
||||
private static final int SCROLL_SPEED_DIVISOR = 20;
|
||||
private static final int SCROLL_SPEED_FACTOR = 5;
|
||||
|
||||
public RelativeTouchContext(NvConnection conn, int actionIndex,
|
||||
int referenceWidth, int referenceHeight, View view)
|
||||
@@ -147,6 +147,9 @@ public class RelativeTouchContext implements TouchContext {
|
||||
}
|
||||
|
||||
private synchronized void startDragTimer() {
|
||||
// Cancel any existing drag timers
|
||||
cancelDragTimer();
|
||||
|
||||
dragTimer = new Timer(true);
|
||||
dragTimer.schedule(new TimerTask() {
|
||||
@Override
|
||||
@@ -157,6 +160,11 @@ public class RelativeTouchContext implements TouchContext {
|
||||
return;
|
||||
}
|
||||
|
||||
// The drag should only be processed for the primary finger
|
||||
if (actionIndex != maxPointerCountInGesture - 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if someone cancelled us
|
||||
if (dragTimer == null) {
|
||||
return;
|
||||
@@ -240,9 +248,7 @@ public class RelativeTouchContext implements TouchContext {
|
||||
|
||||
if (pointerCount == 2) {
|
||||
if (confirmedScroll) {
|
||||
deltaY /= SCROLL_SPEED_DIVISOR;
|
||||
|
||||
conn.sendMouseHighResScroll((short) deltaY);
|
||||
conn.sendMouseHighResScroll((short)(deltaY * SCROLL_SPEED_FACTOR));
|
||||
}
|
||||
} else {
|
||||
conn.sendMouseMove((short) deltaX, (short) deltaY);
|
||||
|
||||
@@ -177,6 +177,15 @@ public class DigitalButton extends VirtualControllerElement {
|
||||
listener.onClick();
|
||||
}
|
||||
|
||||
if (timerLongClick != null) {
|
||||
timerLongClick.cancel();
|
||||
timerLongClick = null;
|
||||
}
|
||||
if (longClickTimerTask != null) {
|
||||
longClickTimerTask.cancel();
|
||||
longClickTimerTask = null;
|
||||
}
|
||||
|
||||
timerLongClick = new Timer();
|
||||
longClickTimerTask = new TimerLongClickTimerTask();
|
||||
timerLongClick.schedule(longClickTimerTask, timerLongClickTimeout);
|
||||
@@ -200,9 +209,11 @@ public class DigitalButton extends VirtualControllerElement {
|
||||
// We may be called for a release without a prior click
|
||||
if (timerLongClick != null) {
|
||||
timerLongClick.cancel();
|
||||
timerLongClick = null;
|
||||
}
|
||||
if (longClickTimerTask != null) {
|
||||
longClickTimerTask.cancel();
|
||||
longClickTimerTask = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+23
-21
@@ -9,12 +9,11 @@ import android.util.DisplayMetrics;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.limelight.LimeLog;
|
||||
import com.limelight.R;
|
||||
import com.limelight.binding.input.ControllerHandler;
|
||||
import com.limelight.nvstream.NvConnection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -40,11 +39,10 @@ public class VirtualController {
|
||||
|
||||
private static final boolean _PRINT_DEBUG_INFORMATION = false;
|
||||
|
||||
private ControllerHandler controllerHandler;
|
||||
private Context context = null;
|
||||
private final ControllerHandler controllerHandler;
|
||||
private final Context context;
|
||||
|
||||
private FrameLayout frame_layout = null;
|
||||
private RelativeLayout relative_layout = null;
|
||||
|
||||
private Timer retransmitTimer;
|
||||
|
||||
@@ -60,10 +58,6 @@ public class VirtualController {
|
||||
this.frame_layout = layout;
|
||||
this.context = context;
|
||||
|
||||
relative_layout = new RelativeLayout(context);
|
||||
|
||||
frame_layout.addView(relative_layout);
|
||||
|
||||
buttonConfigure = new Button(context);
|
||||
buttonConfigure.setAlpha(0.25f);
|
||||
buttonConfigure.setFocusable(false);
|
||||
@@ -87,7 +81,7 @@ public class VirtualController {
|
||||
|
||||
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
|
||||
|
||||
relative_layout.invalidate();
|
||||
buttonConfigure.invalidate();
|
||||
|
||||
for (VirtualControllerElement element : elements) {
|
||||
element.invalidate();
|
||||
@@ -99,11 +93,20 @@ public class VirtualController {
|
||||
|
||||
public void hide() {
|
||||
retransmitTimer.cancel();
|
||||
relative_layout.setVisibility(View.INVISIBLE);
|
||||
|
||||
for (VirtualControllerElement element : elements) {
|
||||
element.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
buttonConfigure.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
public void show() {
|
||||
relative_layout.setVisibility(View.VISIBLE);
|
||||
for (VirtualControllerElement element : elements) {
|
||||
element.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
buttonConfigure.setVisibility(View.VISIBLE);
|
||||
|
||||
// HACK: GFE sometimes discards gamepad packets when they are received
|
||||
// very shortly after another. This can be critical if an axis zeroing packet
|
||||
@@ -120,9 +123,11 @@ public class VirtualController {
|
||||
|
||||
public void removeElements() {
|
||||
for (VirtualControllerElement element : elements) {
|
||||
relative_layout.removeView(element);
|
||||
frame_layout.removeView(element);
|
||||
}
|
||||
elements.clear();
|
||||
|
||||
frame_layout.removeView(buttonConfigure);
|
||||
}
|
||||
|
||||
public void setOpacity(int opacity) {
|
||||
@@ -134,10 +139,10 @@ public class VirtualController {
|
||||
|
||||
public void addElement(VirtualControllerElement element, int x, int y, int width, int height) {
|
||||
elements.add(element);
|
||||
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(width, height);
|
||||
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(width, height);
|
||||
layoutParams.setMargins(x, y, 0, 0);
|
||||
|
||||
relative_layout.addView(element, layoutParams);
|
||||
frame_layout.addView(element, layoutParams);
|
||||
}
|
||||
|
||||
public List<VirtualControllerElement> getElements() {
|
||||
@@ -146,23 +151,20 @@ public class VirtualController {
|
||||
|
||||
private static final void _DBG(String text) {
|
||||
if (_PRINT_DEBUG_INFORMATION) {
|
||||
System.out.println("VirtualController: " + text);
|
||||
LimeLog.info("VirtualController: " + text);
|
||||
}
|
||||
}
|
||||
|
||||
public void refreshLayout() {
|
||||
relative_layout.removeAllViews();
|
||||
removeElements();
|
||||
|
||||
DisplayMetrics screen = context.getResources().getDisplayMetrics();
|
||||
|
||||
int buttonSize = (int)(screen.heightPixels*0.06f);
|
||||
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(buttonSize, buttonSize);
|
||||
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
|
||||
params.addRule(RelativeLayout.ALIGN_PARENT_TOP, RelativeLayout.TRUE);
|
||||
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(buttonSize, buttonSize);
|
||||
params.leftMargin = 15;
|
||||
params.topMargin = 15;
|
||||
relative_layout.addView(buttonConfigure, params);
|
||||
frame_layout.addView(buttonConfigure, params);
|
||||
|
||||
// Start with the default layout
|
||||
VirtualControllerConfigurationLoader.createDefaultLayout(this, context);
|
||||
|
||||
+5
-5
@@ -12,7 +12,7 @@ import android.graphics.Paint;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
@@ -72,7 +72,7 @@ public abstract class VirtualControllerElement extends View {
|
||||
int newPos_x = (int) getX() + x - pressed_x;
|
||||
int newPos_y = (int) getY() + y - pressed_y;
|
||||
|
||||
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
|
||||
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) getLayoutParams();
|
||||
|
||||
layoutParams.leftMargin = newPos_x > 0 ? newPos_x : 0;
|
||||
layoutParams.topMargin = newPos_y > 0 ? newPos_y : 0;
|
||||
@@ -83,7 +83,7 @@ public abstract class VirtualControllerElement extends View {
|
||||
}
|
||||
|
||||
protected void resizeElement(int pressed_x, int pressed_y, int width, int height) {
|
||||
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
|
||||
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) getLayoutParams();
|
||||
|
||||
int newHeight = height + (startSize_y - pressed_y);
|
||||
int newWidth = width + (startSize_x - pressed_x);
|
||||
@@ -316,7 +316,7 @@ public abstract class VirtualControllerElement extends View {
|
||||
public JSONObject getConfiguration() throws JSONException {
|
||||
JSONObject configuration = new JSONObject();
|
||||
|
||||
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
|
||||
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) getLayoutParams();
|
||||
|
||||
configuration.put("LEFT", layoutParams.leftMargin);
|
||||
configuration.put("TOP", layoutParams.topMargin);
|
||||
@@ -327,7 +327,7 @@ public abstract class VirtualControllerElement extends View {
|
||||
}
|
||||
|
||||
public void loadConfiguration(JSONObject configuration) throws JSONException {
|
||||
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) getLayoutParams();
|
||||
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) getLayoutParams();
|
||||
|
||||
layoutParams.leftMargin = configuration.getInt("LEFT");
|
||||
layoutParams.topMargin = configuration.getInt("TOP");
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.limelight.binding.video;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Locale;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
import org.jcodec.codecs.h264.H264Utils;
|
||||
import org.jcodec.codecs.h264.io.model.SeqParameterSet;
|
||||
@@ -20,11 +21,14 @@ import android.media.MediaFormat;
|
||||
import android.media.MediaCodec.BufferInfo;
|
||||
import android.media.MediaCodec.CodecException;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Range;
|
||||
import android.view.Choreographer;
|
||||
import android.view.SurfaceHolder;
|
||||
|
||||
public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
public class MediaCodecDecoderRenderer extends VideoDecoderRenderer implements Choreographer.FrameCallback {
|
||||
|
||||
private static final boolean USE_FRAME_RENDER_TIME = false;
|
||||
private static final boolean FRAME_RENDER_TIME_ONLY = USE_FRAME_RENDER_TIME && false;
|
||||
@@ -46,7 +50,6 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
private Thread rendererThread;
|
||||
private boolean needsSpsBitstreamFixup, isExynos4;
|
||||
private boolean adaptivePlayback, directSubmit;
|
||||
private boolean lowLatency;
|
||||
private boolean constrainedHighProfile;
|
||||
private boolean refFrameInvalidationAvc, refFrameInvalidationHevc;
|
||||
private boolean refFrameInvalidationActive;
|
||||
@@ -59,7 +62,6 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
private int consecutiveCrashCount;
|
||||
private String glRenderer;
|
||||
private boolean foreground = true;
|
||||
private boolean legacyFrameDropRendering = false;
|
||||
private PerfOverlayListener perfListener;
|
||||
|
||||
private MediaFormat inputFormat;
|
||||
@@ -82,9 +84,15 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
private int refreshRate;
|
||||
private PreferenceConfiguration prefs;
|
||||
|
||||
private LinkedBlockingQueue<Integer> outputBufferQueue = new LinkedBlockingQueue<>();
|
||||
private static final int OUTPUT_BUFFER_QUEUE_LIMIT = 2;
|
||||
private long lastRenderedFrameTimeNanos;
|
||||
|
||||
private int numSpsIn;
|
||||
private int numPpsIn;
|
||||
private int numVpsIn;
|
||||
private int numFramesIn;
|
||||
private int numFramesOut;
|
||||
|
||||
private MediaCodecInfo findAvcDecoder() {
|
||||
MediaCodecInfo decoder = MediaCodecHelper.findProbableSafeDecoder("video/avc", MediaCodecInfo.CodecProfileLevel.AVCProfileHigh);
|
||||
@@ -95,7 +103,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
}
|
||||
|
||||
private MediaCodecInfo findHevcDecoder(PreferenceConfiguration prefs, boolean meteredNetwork, boolean requestedHdr) {
|
||||
// Don't return anything if H.265 is forced off
|
||||
// Don't return anything if HEVC is forced off
|
||||
if (prefs.videoFormat == PreferenceConfiguration.FORCE_H265_OFF) {
|
||||
return null;
|
||||
}
|
||||
@@ -107,7 +115,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
// for even required levels of HEVC.
|
||||
MediaCodecInfo decoderInfo = MediaCodecHelper.findProbableSafeDecoder("video/hevc", -1);
|
||||
if (decoderInfo != null) {
|
||||
if (!MediaCodecHelper.decoderIsWhitelistedForHevc(decoderInfo.getName(), meteredNetwork)) {
|
||||
if (!MediaCodecHelper.decoderIsWhitelistedForHevc(decoderInfo.getName(), meteredNetwork, prefs)) {
|
||||
LimeLog.info("Found HEVC decoder, but it's not whitelisted - "+decoderInfo.getName());
|
||||
|
||||
// HDR implies HEVC forced on, since HEVCMain10HDR10 is required for HDR.
|
||||
@@ -197,15 +205,6 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
return avcDecoder != null;
|
||||
}
|
||||
|
||||
public boolean isBlacklistedForFrameRate(int frameRate) {
|
||||
return avcDecoder != null && MediaCodecHelper.decoderBlacklistedForFrameRate(avcDecoder.getName(), frameRate);
|
||||
}
|
||||
|
||||
public void enableLegacyFrameDropRendering() {
|
||||
LimeLog.info("Legacy frame drop rendering enabled");
|
||||
legacyFrameDropRendering = true;
|
||||
}
|
||||
|
||||
public boolean isHevcMain10Hdr10Supported() {
|
||||
if (hevcDecoder == null) {
|
||||
return false;
|
||||
@@ -241,11 +240,11 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
this.refreshRate = redrawRate;
|
||||
|
||||
String mimeType;
|
||||
String selectedDecoderName;
|
||||
MediaCodecInfo selectedDecoderInfo;
|
||||
|
||||
if ((videoFormat & MoonBridge.VIDEO_FORMAT_MASK_H264) != 0) {
|
||||
mimeType = "video/avc";
|
||||
selectedDecoderName = avcDecoder.getName();
|
||||
selectedDecoderInfo = avcDecoder;
|
||||
|
||||
if (avcDecoder == null) {
|
||||
LimeLog.severe("No available AVC decoder!");
|
||||
@@ -258,31 +257,28 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
}
|
||||
|
||||
// These fixups only apply to H264 decoders
|
||||
needsSpsBitstreamFixup = MediaCodecHelper.decoderNeedsSpsBitstreamRestrictions(selectedDecoderName);
|
||||
needsBaselineSpsHack = MediaCodecHelper.decoderNeedsBaselineSpsHack(selectedDecoderName);
|
||||
constrainedHighProfile = MediaCodecHelper.decoderNeedsConstrainedHighProfile(selectedDecoderName);
|
||||
needsSpsBitstreamFixup = MediaCodecHelper.decoderNeedsSpsBitstreamRestrictions(selectedDecoderInfo.getName());
|
||||
needsBaselineSpsHack = MediaCodecHelper.decoderNeedsBaselineSpsHack(selectedDecoderInfo.getName());
|
||||
constrainedHighProfile = MediaCodecHelper.decoderNeedsConstrainedHighProfile(selectedDecoderInfo.getName());
|
||||
isExynos4 = MediaCodecHelper.isExynos4Device();
|
||||
if (needsSpsBitstreamFixup) {
|
||||
LimeLog.info("Decoder "+selectedDecoderName+" needs SPS bitstream restrictions fixup");
|
||||
LimeLog.info("Decoder "+selectedDecoderInfo.getName()+" needs SPS bitstream restrictions fixup");
|
||||
}
|
||||
if (needsBaselineSpsHack) {
|
||||
LimeLog.info("Decoder "+selectedDecoderName+" needs baseline SPS hack");
|
||||
LimeLog.info("Decoder "+selectedDecoderInfo.getName()+" needs baseline SPS hack");
|
||||
}
|
||||
if (constrainedHighProfile) {
|
||||
LimeLog.info("Decoder "+selectedDecoderName+" needs constrained high profile");
|
||||
LimeLog.info("Decoder "+selectedDecoderInfo.getName()+" needs constrained high profile");
|
||||
}
|
||||
if (isExynos4) {
|
||||
LimeLog.info("Decoder "+selectedDecoderName+" is on Exynos 4");
|
||||
LimeLog.info("Decoder "+selectedDecoderInfo.getName()+" is on Exynos 4");
|
||||
}
|
||||
|
||||
refFrameInvalidationActive = refFrameInvalidationAvc;
|
||||
|
||||
lowLatency = MediaCodecHelper.decoderSupportsLowLatency(avcDecoder, mimeType);
|
||||
adaptivePlayback = MediaCodecHelper.decoderSupportsAdaptivePlayback(avcDecoder, mimeType);
|
||||
}
|
||||
else if ((videoFormat & MoonBridge.VIDEO_FORMAT_MASK_H265) != 0) {
|
||||
mimeType = "video/hevc";
|
||||
selectedDecoderName = hevcDecoder.getName();
|
||||
selectedDecoderInfo = hevcDecoder;
|
||||
|
||||
if (hevcDecoder == null) {
|
||||
LimeLog.severe("No available HEVC decoder!");
|
||||
@@ -290,9 +286,6 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
}
|
||||
|
||||
refFrameInvalidationActive = refFrameInvalidationHevc;
|
||||
|
||||
lowLatency = MediaCodecHelper.decoderSupportsLowLatency(hevcDecoder, mimeType);
|
||||
adaptivePlayback = MediaCodecHelper.decoderSupportsAdaptivePlayback(hevcDecoder, mimeType);
|
||||
}
|
||||
else {
|
||||
// Unknown format
|
||||
@@ -300,10 +293,12 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
return -3;
|
||||
}
|
||||
|
||||
adaptivePlayback = MediaCodecHelper.decoderSupportsAdaptivePlayback(selectedDecoderInfo, mimeType);
|
||||
|
||||
// Codecs have been known to throw all sorts of crazy runtime exceptions
|
||||
// due to implementation problems
|
||||
try {
|
||||
videoDecoder = MediaCodec.createByCodecName(selectedDecoderName);
|
||||
videoDecoder = MediaCodec.createByCodecName(selectedDecoderInfo.getName());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return -4;
|
||||
@@ -313,10 +308,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
|
||||
// Avoid setting KEY_FRAME_RATE on Lollipop and earlier to reduce compatibility risk
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
// We use prefs.fps instead of redrawRate here because the low latency hack in Game.java
|
||||
// may leave us with an odd redrawRate value like 59 or 49 which might cause the decoder
|
||||
// to puke. To be safe, we'll use the unmodified value.
|
||||
videoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, prefs.fps);
|
||||
videoFormat.setInteger(MediaFormat.KEY_FRAME_RATE, redrawRate);
|
||||
}
|
||||
|
||||
// Adaptive playback can also be enabled by the whitelist on pre-KitKat devices
|
||||
@@ -326,26 +318,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
videoFormat.setInteger(MediaFormat.KEY_MAX_HEIGHT, height);
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && lowLatency) {
|
||||
videoFormat.setInteger(MediaFormat.KEY_LOW_LATENCY, 1);
|
||||
}
|
||||
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
// Set the Qualcomm vendor low latency extension if the Android R option is unavailable
|
||||
if (MediaCodecHelper.decoderSupportsQcomVendorLowLatency(selectedDecoderName)) {
|
||||
// MediaCodec supports vendor-defined format keys using the "vendor.<extension name>.<parameter name>" syntax.
|
||||
// These allow access to functionality that is not exposed through documented MediaFormat.KEY_* values.
|
||||
// https://cs.android.com/android/platform/superproject/+/master:hardware/qcom/sdm845/media/mm-video-v4l2/vidc/common/inc/vidc_vendor_extensions.h;l=67
|
||||
//
|
||||
// Examples of Qualcomm's vendor extensions for Snapdragon 845:
|
||||
// https://cs.android.com/android/platform/superproject/+/master:hardware/qcom/sdm845/media/mm-video-v4l2/vidc/vdec/src/omx_vdec_extensions.hpp
|
||||
// https://cs.android.com/android/_/android/platform/hardware/qcom/sm8150/media/+/0621ceb1c1b19564999db8293574a0e12952ff6c
|
||||
videoFormat.setInteger("vendor.qti-ext-dec-low-latency.enable", 1);
|
||||
}
|
||||
|
||||
if (MediaCodecHelper.decoderSupportsMaxOperatingRate(selectedDecoderName)) {
|
||||
videoFormat.setInteger(MediaFormat.KEY_OPERATING_RATE, Short.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
MediaCodecHelper.setDecoderLowLatencyOptions(videoFormat, selectedDecoderInfo, mimeType);
|
||||
|
||||
configuredFormat = videoFormat;
|
||||
LimeLog.info("Configuring with format: "+configuredFormat);
|
||||
@@ -375,7 +348,7 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
}, null);
|
||||
}
|
||||
|
||||
LimeLog.info("Using codec "+selectedDecoderName+" for hardware decoding "+mimeType);
|
||||
LimeLog.info("Using codec "+selectedDecoderInfo.getName()+" for hardware decoding "+mimeType);
|
||||
|
||||
// Start the decoder
|
||||
videoDecoder.start();
|
||||
@@ -440,6 +413,41 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFrame(long frameTimeNanos) {
|
||||
// Do nothing if we're stopping
|
||||
if (stopping) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't render unless a new frame is due. This prevents microstutter when streaming
|
||||
// at a frame rate that doesn't match the display (such as 60 FPS on 120 Hz).
|
||||
long actualFrameTimeDeltaNs = frameTimeNanos - lastRenderedFrameTimeNanos;
|
||||
long expectedFrameTimeDeltaNs = 800000000 / refreshRate; // within 80% of the next frame
|
||||
if (actualFrameTimeDeltaNs >= expectedFrameTimeDeltaNs) {
|
||||
// Render up to one frame when in frame pacing mode.
|
||||
//
|
||||
// NB: Since the queue limit is 2, we won't starve the decoder of output buffers
|
||||
// by holding onto them for too long. This also ensures we will have that 1 extra
|
||||
// frame of buffer to smooth over network/rendering jitter.
|
||||
Integer nextOutputBuffer = outputBufferQueue.poll();
|
||||
if (nextOutputBuffer != null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
videoDecoder.releaseOutputBuffer(nextOutputBuffer, frameTimeNanos);
|
||||
}
|
||||
else {
|
||||
videoDecoder.releaseOutputBuffer(nextOutputBuffer, true);
|
||||
}
|
||||
|
||||
lastRenderedFrameTimeNanos = frameTimeNanos;
|
||||
activeWindowVideoStats.totalFramesRendered++;
|
||||
}
|
||||
}
|
||||
|
||||
// Request another callback for next frame
|
||||
Choreographer.getInstance().postFrameCallback(this);
|
||||
}
|
||||
|
||||
private void startRendererThread()
|
||||
{
|
||||
rendererThread = new Thread() {
|
||||
@@ -454,32 +462,60 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
long presentationTimeUs = info.presentationTimeUs;
|
||||
int lastIndex = outIndex;
|
||||
|
||||
// Get the last output buffer in the queue
|
||||
while ((outIndex = videoDecoder.dequeueOutputBuffer(info, 0)) >= 0) {
|
||||
videoDecoder.releaseOutputBuffer(lastIndex, false);
|
||||
numFramesOut++;
|
||||
|
||||
lastIndex = outIndex;
|
||||
presentationTimeUs = info.presentationTimeUs;
|
||||
}
|
||||
// Render the latest frame now if frame pacing isn't in balanced mode
|
||||
if (prefs.framePacing != PreferenceConfiguration.FRAME_PACING_BALANCED) {
|
||||
// Get the last output buffer in the queue
|
||||
while ((outIndex = videoDecoder.dequeueOutputBuffer(info, 0)) >= 0) {
|
||||
videoDecoder.releaseOutputBuffer(lastIndex, false);
|
||||
|
||||
// Render the last buffer
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
if (legacyFrameDropRendering) {
|
||||
// Use a PTS that will cause this frame to be dropped if another comes in within
|
||||
// the same V-sync period
|
||||
videoDecoder.releaseOutputBuffer(lastIndex, System.nanoTime());
|
||||
numFramesOut++;
|
||||
|
||||
lastIndex = outIndex;
|
||||
presentationTimeUs = info.presentationTimeUs;
|
||||
}
|
||||
|
||||
if (prefs.framePacing == PreferenceConfiguration.FRAME_PACING_MAX_SMOOTHNESS ||
|
||||
prefs.framePacing == PreferenceConfiguration.FRAME_PACING_CAP_FPS) {
|
||||
// In max smoothness or cap FPS mode, we want to never drop frames
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
// Use a PTS that will cause this frame to never be dropped
|
||||
videoDecoder.releaseOutputBuffer(lastIndex, 0);
|
||||
}
|
||||
else {
|
||||
videoDecoder.releaseOutputBuffer(lastIndex, true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Use a PTS that will cause this frame to never be dropped if frame dropping
|
||||
// is disabled
|
||||
videoDecoder.releaseOutputBuffer(lastIndex, 0);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
// Use a PTS that will cause this frame to be dropped if another comes in within
|
||||
// the same V-sync period
|
||||
videoDecoder.releaseOutputBuffer(lastIndex, System.nanoTime());
|
||||
}
|
||||
else {
|
||||
videoDecoder.releaseOutputBuffer(lastIndex, true);
|
||||
}
|
||||
}
|
||||
|
||||
activeWindowVideoStats.totalFramesRendered++;
|
||||
}
|
||||
else {
|
||||
videoDecoder.releaseOutputBuffer(lastIndex, true);
|
||||
}
|
||||
// For balanced frame pacing case, the Choreographer callback will handle rendering.
|
||||
// We just put all frames into the output buffer queue and let it handle things.
|
||||
|
||||
activeWindowVideoStats.totalFramesRendered++;
|
||||
// Discard the oldest buffer if we've exceeded our limit.
|
||||
//
|
||||
// NB: We have to do this on the producer side because the consumer may not
|
||||
// run for a while (if there is a huge mismatch between stream FPS and display
|
||||
// refresh rate).
|
||||
if (outputBufferQueue.size() == OUTPUT_BUFFER_QUEUE_LIMIT) {
|
||||
videoDecoder.releaseOutputBuffer(outputBufferQueue.take(), false);
|
||||
}
|
||||
|
||||
// Add this buffer
|
||||
outputBufferQueue.add(lastIndex);
|
||||
}
|
||||
|
||||
// Add delta time to the totals (excluding probable outliers)
|
||||
long delta = MediaCodecHelper.getMonotonicMillis() - (presentationTimeUs / 1000);
|
||||
@@ -554,6 +590,18 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
@Override
|
||||
public void start() {
|
||||
startRendererThread();
|
||||
|
||||
// Start Choreographer callbacks for rendering with frame pacing in balanced mode
|
||||
// NB: This must be done on a thread with a looper!
|
||||
if (prefs.framePacing == PreferenceConfiguration.FRAME_PACING_BALANCED) {
|
||||
Handler h = new Handler(Looper.getMainLooper());
|
||||
h.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Choreographer.getInstance().postFrameCallback(MediaCodecDecoderRenderer.this);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// !!! May be called even if setup()/start() fails !!!
|
||||
@@ -565,6 +613,17 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
if (rendererThread != null) {
|
||||
rendererThread.interrupt();
|
||||
}
|
||||
|
||||
// Halt further Choreographer callbacks
|
||||
if (prefs.framePacing == PreferenceConfiguration.FRAME_PACING_BALANCED) {
|
||||
Handler h = new Handler(Looper.getMainLooper());
|
||||
h.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Choreographer.getInstance().removeFrameCallback(MediaCodecDecoderRenderer.this);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -583,6 +642,11 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
videoDecoder.release();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHdrMode(boolean enabled) {
|
||||
// TODO: Set HDR metadata?
|
||||
}
|
||||
|
||||
private boolean queueInputBuffer(int inputBufferIndex, int offset, int length, long timestampUs, int codecFlags) {
|
||||
try {
|
||||
videoDecoder.queueInputBuffer(inputBufferIndex,
|
||||
@@ -674,17 +738,18 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
}
|
||||
|
||||
float decodeTimeMs = (float)lastTwo.decoderTimeMs / lastTwo.totalFramesReceived;
|
||||
String perfText = context.getString(
|
||||
R.string.perf_overlay_text,
|
||||
initialWidth + "x" + initialHeight,
|
||||
decoder,
|
||||
fps.totalFps,
|
||||
fps.receivedFps,
|
||||
fps.renderedFps,
|
||||
(float)lastTwo.framesLost / lastTwo.totalFrames * 100,
|
||||
((float)lastTwo.totalTimeMs / lastTwo.totalFramesReceived) - decodeTimeMs,
|
||||
decodeTimeMs);
|
||||
perfListener.onPerfUpdate(perfText);
|
||||
long rttInfo = MoonBridge.getEstimatedRttInfo();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(context.getString(R.string.perf_overlay_streamdetails, initialWidth + "x" + initialHeight, fps.totalFps)).append('\n');
|
||||
sb.append(context.getString(R.string.perf_overlay_decoder, decoder)).append('\n');
|
||||
sb.append(context.getString(R.string.perf_overlay_incomingfps, fps.receivedFps)).append('\n');
|
||||
sb.append(context.getString(R.string.perf_overlay_renderingfps, fps.renderedFps)).append('\n');
|
||||
sb.append(context.getString(R.string.perf_overlay_netdrops,
|
||||
(float)lastTwo.framesLost / lastTwo.totalFrames * 100)).append('\n');
|
||||
sb.append(context.getString(R.string.perf_overlay_netlatency,
|
||||
(int)(rttInfo >> 32), (int)rttInfo)).append('\n');
|
||||
sb.append(context.getString(R.string.perf_overlay_dectime, decodeTimeMs));
|
||||
perfListener.onPerfUpdate(sb.toString());
|
||||
}
|
||||
|
||||
globalVideoStats.add(activeWindowVideoStats);
|
||||
@@ -919,6 +984,8 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
|
||||
submitCsdNextCall = false;
|
||||
}
|
||||
|
||||
numFramesIn++;
|
||||
}
|
||||
|
||||
if (decodeUnitLength > buf.limit() - buf.position()) {
|
||||
@@ -1064,8 +1131,31 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
}
|
||||
|
||||
private String generateText(MediaCodecDecoderRenderer renderer, Exception originalException, ByteBuffer currentBuffer, int currentCodecFlags) {
|
||||
String str = "";
|
||||
String str;
|
||||
|
||||
if (renderer.numVpsIn == 0 && renderer.numSpsIn == 0 && renderer.numPpsIn == 0) {
|
||||
str = "PreSPSError";
|
||||
}
|
||||
else if (renderer.numSpsIn > 0 && renderer.numPpsIn == 0) {
|
||||
str = "PrePPSError";
|
||||
}
|
||||
else if (renderer.numPpsIn > 0 && renderer.numFramesIn == 0) {
|
||||
str = "PreIFrameError";
|
||||
}
|
||||
else if (renderer.numFramesIn > 0 && renderer.outputFormat == null) {
|
||||
str = "PreOutputConfigError";
|
||||
}
|
||||
else if (renderer.outputFormat != null && renderer.numFramesOut == 0) {
|
||||
str = "PreOutputError";
|
||||
}
|
||||
else if (renderer.numFramesOut <= renderer.refreshRate * 30) {
|
||||
str = "EarlyOutputError";
|
||||
}
|
||||
else {
|
||||
str = "ErrorWhileStreaming";
|
||||
}
|
||||
|
||||
str += ": 1\n";
|
||||
str += "Format: "+String.format("%x", renderer.videoFormat)+"\n";
|
||||
str += "AVC Decoder: "+((renderer.avcDecoder != null) ? renderer.avcDecoder.getName():"(none)")+"\n";
|
||||
str += "HEVC Decoder: "+((renderer.hevcDecoder != null) ? renderer.hevcDecoder.getName():"(none)")+"\n";
|
||||
@@ -1099,20 +1189,25 @@ public class MediaCodecDecoderRenderer extends VideoDecoderRenderer {
|
||||
str += "Adaptive playback: "+renderer.adaptivePlayback+"\n";
|
||||
str += "GL Renderer: "+renderer.glRenderer+"\n";
|
||||
str += "Build fingerprint: "+Build.FINGERPRINT+"\n";
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
str += "SOC: "+Build.SOC_MANUFACTURER+" - "+Build.SOC_MODEL+"\n";
|
||||
str += "Performance class: "+Build.VERSION.MEDIA_PERFORMANCE_CLASS+"\n";
|
||||
}
|
||||
str += "Foreground: "+renderer.foreground+"\n";
|
||||
str += "Consecutive crashes: "+renderer.consecutiveCrashCount+"\n";
|
||||
str += "RFI active: "+renderer.refFrameInvalidationActive+"\n";
|
||||
str += "Using modern SPS patching: "+(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)+"\n";
|
||||
str += "Low latency mode: "+renderer.lowLatency+"\n";
|
||||
str += "Video dimensions: "+renderer.initialWidth+"x"+renderer.initialHeight+"\n";
|
||||
str += "FPS target: "+renderer.refreshRate+"\n";
|
||||
str += "Bitrate: "+renderer.prefs.bitrate+" Kbps \n";
|
||||
str += "In stats: "+renderer.numVpsIn+", "+renderer.numSpsIn+", "+renderer.numPpsIn+"\n";
|
||||
str += "CSD stats: "+renderer.numVpsIn+", "+renderer.numSpsIn+", "+renderer.numPpsIn+"\n";
|
||||
str += "Frames in-out: "+renderer.numFramesIn+", "+renderer.numFramesOut+"\n";
|
||||
str += "Total frames received: "+renderer.globalVideoStats.totalFramesReceived+"\n";
|
||||
str += "Total frames rendered: "+renderer.globalVideoStats.totalFramesRendered+"\n";
|
||||
str += "Frame losses: "+renderer.globalVideoStats.framesLost+" in "+renderer.globalVideoStats.frameLossEvents+" loss events\n";
|
||||
str += "Average end-to-end client latency: "+renderer.getAverageEndToEndLatency()+"ms\n";
|
||||
str += "Average hardware decoder latency: "+renderer.getAverageDecoderLatency()+"ms\n";
|
||||
str += "Frame pacing mode: "+renderer.prefs.framePacing+"\n";
|
||||
|
||||
if (currentBuffer != null) {
|
||||
str += "Current buffer: ";
|
||||
|
||||
@@ -18,9 +18,11 @@ import android.media.MediaCodecInfo;
|
||||
import android.media.MediaCodecList;
|
||||
import android.media.MediaCodecInfo.CodecCapabilities;
|
||||
import android.media.MediaCodecInfo.CodecProfileLevel;
|
||||
import android.media.MediaFormat;
|
||||
import android.os.Build;
|
||||
|
||||
import com.limelight.LimeLog;
|
||||
import com.limelight.preferences.PreferenceConfiguration;
|
||||
|
||||
public class MediaCodecHelper {
|
||||
|
||||
@@ -36,9 +38,11 @@ public class MediaCodecHelper {
|
||||
private static final List<String> whitelistedHevcDecoders;
|
||||
private static final List<String> refFrameInvalidationAvcPrefixes;
|
||||
private static final List<String> refFrameInvalidationHevcPrefixes;
|
||||
private static final List<String> blacklisted49FpsDecoderPrefixes;
|
||||
private static final List<String> blacklisted59FpsDecoderPrefixes;
|
||||
private static final List<String> qualcommDecoderPrefixes;
|
||||
private static final List<String> kirinDecoderPrefixes;
|
||||
private static final List<String> exynosDecoderPrefixes;
|
||||
|
||||
public static final boolean IS_EMULATOR = Build.HARDWARE.equals("ranchu") || Build.HARDWARE.equals("cheets");
|
||||
|
||||
private static boolean isLowEndSnapdragon = false;
|
||||
private static boolean isAdreno620 = false;
|
||||
@@ -78,7 +82,7 @@ public class MediaCodecHelper {
|
||||
|
||||
// Blacklist software decoders that don't support H264 high profile,
|
||||
// but exclude the official AOSP and CrOS emulator from this restriction.
|
||||
if (!Build.HARDWARE.equals("ranchu") && !Build.HARDWARE.equals("cheets")) {
|
||||
if (!IS_EMULATOR) {
|
||||
blacklistedDecoderPrefixes.add("omx.google");
|
||||
blacklistedDecoderPrefixes.add("AVCDecoder");
|
||||
}
|
||||
@@ -113,7 +117,7 @@ public class MediaCodecHelper {
|
||||
// if adaptive playback was enabled so let's avoid it to be safe.
|
||||
blacklistedAdaptivePlaybackPrefixes.add("omx.intel");
|
||||
// The MediaTek decoder crashes at 1080p when adaptive playback is enabled
|
||||
// on some Android TV devices with H.265 only.
|
||||
// on some Android TV devices with HEVC only.
|
||||
blacklistedAdaptivePlaybackPrefixes.add("omx.mtk");
|
||||
|
||||
constrainedHighProfilePrefixes = new LinkedList<>();
|
||||
@@ -144,7 +148,10 @@ public class MediaCodecHelper {
|
||||
// I know the Fire TV 2 and 3 works, so I'll whitelist Amazon devices which seem to actually be tested.
|
||||
if (Build.MANUFACTURER.equalsIgnoreCase("Amazon")) {
|
||||
whitelistedHevcDecoders.add("omx.mtk");
|
||||
whitelistedHevcDecoders.add("omx.amlogic");
|
||||
|
||||
// This broke at some point on the Fire TV 3 and now the decoder
|
||||
// never produces any output frames.
|
||||
//whitelistedHevcDecoders.add("omx.amlogic");
|
||||
}
|
||||
|
||||
// Plot twist: On newer Sony devices (BRAVIA_ATV2, BRAVIA_ATV3_4K, BRAVIA_UR1_4K) the H.264 decoder crashes
|
||||
@@ -160,6 +167,12 @@ public class MediaCodecHelper {
|
||||
whitelistedHevcDecoders.add("omx.amlogic");
|
||||
}
|
||||
|
||||
// Realtek SoCs are used inside many Android TV devices and can only do 4K60 with HEVC.
|
||||
// We'll enable those HEVC decoders by default and see if anything breaks.
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
whitelistedHevcDecoders.add("omx.realtek");
|
||||
}
|
||||
|
||||
// These theoretically have good HEVC decoding capabilities (potentially better than
|
||||
// their AVC decoders), but haven't been tested enough
|
||||
//whitelistedHevcDecoders.add("omx.rk");
|
||||
@@ -179,24 +192,6 @@ public class MediaCodecHelper {
|
||||
// Qualcomm is currently the only decoders in this group.
|
||||
}
|
||||
|
||||
static {
|
||||
blacklisted49FpsDecoderPrefixes = new LinkedList<>();
|
||||
blacklisted59FpsDecoderPrefixes = new LinkedList<>();
|
||||
|
||||
// We see a bunch of crashes on MediaTek Android TVs running
|
||||
// at 49 FPS (PAL 50 Hz - 1). Blacklist this frame rate for
|
||||
// these devices and hope they fix it in Pie.
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) {
|
||||
blacklisted49FpsDecoderPrefixes.add("omx.mtk");
|
||||
|
||||
// 59 FPS also seems to crash on the Sony Bravia TV ATV3 model.
|
||||
// Blacklist that frame rate on these devices too.
|
||||
if (Build.DEVICE.startsWith("BRAVIA_ATV3")) {
|
||||
blacklisted59FpsDecoderPrefixes.add("omx.mtk");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
qualcommDecoderPrefixes = new LinkedList<>();
|
||||
|
||||
@@ -204,6 +199,18 @@ public class MediaCodecHelper {
|
||||
qualcommDecoderPrefixes.add("c2.qti");
|
||||
}
|
||||
|
||||
static {
|
||||
kirinDecoderPrefixes = new LinkedList<>();
|
||||
|
||||
kirinDecoderPrefixes.add("omx.hisi");
|
||||
}
|
||||
|
||||
static {
|
||||
exynosDecoderPrefixes = new LinkedList<>();
|
||||
|
||||
exynosDecoderPrefixes.add("omx.exynos");
|
||||
}
|
||||
|
||||
private static boolean isPowerVR(String glRenderer) {
|
||||
return glRenderer.toLowerCase().contains("powervr");
|
||||
}
|
||||
@@ -350,7 +357,7 @@ public class MediaCodecHelper {
|
||||
return System.nanoTime() / 1000000L;
|
||||
}
|
||||
|
||||
public static boolean decoderSupportsLowLatency(MediaCodecInfo decoderInfo, String mimeType) {
|
||||
private static boolean decoderSupportsAndroidRLowLatency(MediaCodecInfo decoderInfo, String mimeType) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
try {
|
||||
if (decoderInfo.getCapabilitiesForType(mimeType).isFeatureSupported(CodecCapabilities.FEATURE_LowLatency)) {
|
||||
@@ -366,7 +373,7 @@ public class MediaCodecHelper {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean decoderSupportsMaxOperatingRate(String decoderName) {
|
||||
private static boolean decoderSupportsMaxOperatingRate(String decoderName) {
|
||||
// Operate at maximum rate to lower latency as much as possible on
|
||||
// some Qualcomm platforms. We could also set KEY_PRIORITY to 0 (realtime)
|
||||
// but that will actually result in the decoder crashing if it can't satisfy
|
||||
@@ -381,6 +388,43 @@ public class MediaCodecHelper {
|
||||
!isAdreno620;
|
||||
}
|
||||
|
||||
public static void setDecoderLowLatencyOptions(MediaFormat videoFormat, MediaCodecInfo decoderInfo, String mimeType) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && decoderSupportsAndroidRLowLatency(decoderInfo, mimeType)) {
|
||||
videoFormat.setInteger(MediaFormat.KEY_LOW_LATENCY, 1);
|
||||
}
|
||||
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
// MediaCodec supports vendor-defined format keys using the "vendor.<extension name>.<parameter name>" syntax.
|
||||
// These allow access to functionality that is not exposed through documented MediaFormat.KEY_* values.
|
||||
// https://cs.android.com/android/platform/superproject/+/master:hardware/qcom/sdm845/media/mm-video-v4l2/vidc/common/inc/vidc_vendor_extensions.h;l=67
|
||||
//
|
||||
// MediaCodec vendor extension support was introduced in Android 8.0:
|
||||
// https://cs.android.com/android/_/android/platform/frameworks/av/+/01c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
// Try vendor-specific low latency options
|
||||
if (isDecoderInList(qualcommDecoderPrefixes, decoderInfo.getName())) {
|
||||
// Examples of Qualcomm's vendor extensions for Snapdragon 845:
|
||||
// https://cs.android.com/android/platform/superproject/+/master:hardware/qcom/sdm845/media/mm-video-v4l2/vidc/vdec/src/omx_vdec_extensions.hpp
|
||||
// https://cs.android.com/android/_/android/platform/hardware/qcom/sm8150/media/+/0621ceb1c1b19564999db8293574a0e12952ff6c
|
||||
videoFormat.setInteger("vendor.qti-ext-dec-low-latency.enable", 1);
|
||||
}
|
||||
else if (isDecoderInList(kirinDecoderPrefixes, decoderInfo.getName())) {
|
||||
// Kirin low latency options
|
||||
// https://developer.huawei.com/consumer/cn/forum/topic/0202325564295980115
|
||||
videoFormat.setInteger("vendor.hisi-ext-low-latency-video-dec.video-scene-for-low-latency-req", 1);
|
||||
videoFormat.setInteger("vendor.hisi-ext-low-latency-video-dec.video-scene-for-low-latency-rdy", -1);
|
||||
}
|
||||
else if (isDecoderInList(exynosDecoderPrefixes, decoderInfo.getName())) {
|
||||
// Exynos low latency option for H.264 decoder
|
||||
videoFormat.setInteger("vendor.rtc-ext-dec-low-latency.enable", 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (MediaCodecHelper.decoderSupportsMaxOperatingRate(decoderInfo.getName())) {
|
||||
videoFormat.setInteger(MediaFormat.KEY_OPERATING_RATE, Short.MAX_VALUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean decoderSupportsAdaptivePlayback(MediaCodecInfo decoderInfo, String mimeType) {
|
||||
// Possibly enable adaptive playback on KitKat and above
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||
@@ -406,13 +450,6 @@ public class MediaCodecHelper {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean decoderSupportsQcomVendorLowLatency(String decoderName) {
|
||||
// MediaCodec vendor extension support was introduced in Android 8.0:
|
||||
// https://cs.android.com/android/_/android/platform/frameworks/av/+/01c10f8cdcd58d1e7025f426a72e6e75ba5d7fc2
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
|
||||
isDecoderInList(qualcommDecoderPrefixes, decoderName);
|
||||
}
|
||||
|
||||
public static boolean decoderNeedsConstrainedHighProfile(String decoderName) {
|
||||
return isDecoderInList(constrainedHighProfilePrefixes, decoderName);
|
||||
}
|
||||
@@ -429,18 +466,6 @@ public class MediaCodecHelper {
|
||||
return isDecoderInList(baselineProfileHackPrefixes, decoderName);
|
||||
}
|
||||
|
||||
public static boolean decoderBlacklistedForFrameRate(String decoderName, int fps) {
|
||||
if (fps == 49) {
|
||||
return isDecoderInList(blacklisted49FpsDecoderPrefixes, decoderName);
|
||||
}
|
||||
else if (fps == 59) {
|
||||
return isDecoderInList(blacklisted59FpsDecoderPrefixes, decoderName);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean decoderSupportsRefFrameInvalidationAvc(String decoderName, int videoHeight) {
|
||||
// Reference frame invalidation is broken on low-end Snapdragon SoCs at 1080p.
|
||||
if (videoHeight > 720 && isLowEndSnapdragon) {
|
||||
@@ -460,7 +485,7 @@ public class MediaCodecHelper {
|
||||
return isDecoderInList(refFrameInvalidationHevcPrefixes, decoderName);
|
||||
}
|
||||
|
||||
public static boolean decoderIsWhitelistedForHevc(String decoderName, boolean meteredData) {
|
||||
public static boolean decoderIsWhitelistedForHevc(String decoderName, boolean meteredData, PreferenceConfiguration prefs) {
|
||||
// TODO: Shield Tablet K1/LTE?
|
||||
//
|
||||
// NVIDIA does partial HEVC acceleration on the Shield Tablet. I don't know
|
||||
@@ -495,9 +520,10 @@ public class MediaCodecHelper {
|
||||
// Some devices have HEVC decoders that we prefer not to use
|
||||
// typically because it can't support reference frame invalidation.
|
||||
// However, we will use it for HDR and for streaming over mobile networks
|
||||
// since it works fine otherwise.
|
||||
// since it works fine otherwise. We will also use it for 4K because RFI
|
||||
// is currently disabled due to issues with video corruption.
|
||||
if (isDecoderInList(deprioritizedHevcDecoders, decoderName)) {
|
||||
if (meteredData) {
|
||||
if (meteredData || (prefs.width == 3840 && prefs.height == 2160)) {
|
||||
LimeLog.info("Selected deprioritized decoder");
|
||||
return true;
|
||||
}
|
||||
@@ -564,13 +590,6 @@ public class MediaCodecHelper {
|
||||
if (codecInfo.isEncoder()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip compatibility aliases on Q+
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
if (codecInfo.isAlias()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for preferred decoders
|
||||
if (preferredDecoder.equalsIgnoreCase(codecInfo.getName())) {
|
||||
@@ -586,7 +605,7 @@ public class MediaCodecHelper {
|
||||
private static boolean isCodecBlacklisted(MediaCodecInfo codecInfo) {
|
||||
// Use the new isSoftwareOnly() function on Android Q
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
if (codecInfo.isSoftwareOnly()) {
|
||||
if (!IS_EMULATOR && codecInfo.isSoftwareOnly()) {
|
||||
LimeLog.info("Skipping software-only decoder: "+codecInfo.getName());
|
||||
return true;
|
||||
}
|
||||
@@ -656,43 +675,57 @@ public class MediaCodecHelper {
|
||||
// and we want to be sure all callers are handling this possibility
|
||||
@SuppressWarnings("RedundantThrows")
|
||||
private static MediaCodecInfo findKnownSafeDecoder(String mimeType, int requiredProfile) throws Exception {
|
||||
for (MediaCodecInfo codecInfo : getMediaCodecList()) {
|
||||
// Skip encoders
|
||||
if (codecInfo.isEncoder()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip compatibility aliases on Q+
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
if (codecInfo.isAlias()) {
|
||||
// Some devices (Exynos devces, at least) have two sets of decoders.
|
||||
// The first set of decoders are C2 which do not support FEATURE_LowLatency,
|
||||
// but the second set of OMX decoders do support FEATURE_LowLatency. We want
|
||||
// to pick the OMX decoders despite the fact that C2 is listed first.
|
||||
// On some Qualcomm devices (like Pixel 4), there are separate low latency decoders
|
||||
// (like c2.qti.hevc.decoder.low_latency) that advertise FEATURE_LowLatency while
|
||||
// the standard ones (like c2.qti.hevc.decoder) do not. Like Exynos, the decoders
|
||||
// with FEATURE_LowLatency support are listed after the standard ones.
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (MediaCodecInfo codecInfo : getMediaCodecList()) {
|
||||
// Skip encoders
|
||||
if (codecInfo.isEncoder()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Find a decoder that supports the requested video format
|
||||
for (String mime : codecInfo.getSupportedTypes()) {
|
||||
if (mime.equalsIgnoreCase(mimeType)) {
|
||||
LimeLog.info("Examining decoder capabilities of "+codecInfo.getName());
|
||||
|
||||
// Skip blacklisted codecs
|
||||
if (isCodecBlacklisted(codecInfo)) {
|
||||
// Skip compatibility aliases on Q+
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
if (codecInfo.isAlias()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
CodecCapabilities caps = codecInfo.getCapabilitiesForType(mime);
|
||||
// Find a decoder that supports the requested video format
|
||||
for (String mime : codecInfo.getSupportedTypes()) {
|
||||
if (mime.equalsIgnoreCase(mimeType)) {
|
||||
LimeLog.info("Examining decoder capabilities of " + codecInfo.getName() + " (round " + (i + 1) + ")");
|
||||
|
||||
if (requiredProfile != -1) {
|
||||
for (CodecProfileLevel profile : caps.profileLevels) {
|
||||
if (profile.profile == requiredProfile) {
|
||||
LimeLog.info("Decoder " + codecInfo.getName() + " supports required profile");
|
||||
return codecInfo;
|
||||
}
|
||||
// Skip blacklisted codecs
|
||||
if (isCodecBlacklisted(codecInfo)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LimeLog.info("Decoder " + codecInfo.getName() + " does NOT support required profile");
|
||||
}
|
||||
else {
|
||||
return codecInfo;
|
||||
CodecCapabilities caps = codecInfo.getCapabilitiesForType(mime);
|
||||
|
||||
if (i == 0 && !decoderSupportsAndroidRLowLatency(codecInfo, mime)) {
|
||||
LimeLog.info("Skipping decoder that lacks FEATURE_LowLatency for round 1");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (requiredProfile != -1) {
|
||||
for (CodecProfileLevel profile : caps.profileLevels) {
|
||||
if (profile.profile == requiredProfile) {
|
||||
LimeLog.info("Decoder " + codecInfo.getName() + " supports required profile");
|
||||
return codecInfo;
|
||||
}
|
||||
}
|
||||
|
||||
LimeLog.info("Decoder " + codecInfo.getName() + " does NOT support required profile");
|
||||
} else {
|
||||
return codecInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ import java.io.OutputStream;
|
||||
import java.io.StringReader;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
@@ -49,8 +47,7 @@ public class ComputerManagerService extends Service {
|
||||
private static final int APPLIST_POLLING_PERIOD_MS = 30000;
|
||||
private static final int APPLIST_FAILED_POLLING_RETRY_MS = 2000;
|
||||
private static final int MDNS_QUERY_PERIOD_MS = 1000;
|
||||
private static final int FAST_POLL_TIMEOUT = 1000;
|
||||
private static final int OFFLINE_POLL_TRIES = 5;
|
||||
private static final int OFFLINE_POLL_TRIES = 3;
|
||||
private static final int INITIAL_POLL_TRIES = 2;
|
||||
private static final int EMPTY_LIST_THRESHOLD = 3;
|
||||
private static final int POLL_DATA_TTL_MS = 30000;
|
||||
@@ -528,11 +525,6 @@ public class ComputerManagerService extends Service {
|
||||
}
|
||||
|
||||
private ComputerDetails tryPollIp(ComputerDetails details, String address) {
|
||||
// Fast poll this address first to determine if we can connect at the TCP layer
|
||||
if (!fastPollIp(address)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
NvHTTP http = new NvHTTP(address, idManager.getUniqueId(), details.serverCert,
|
||||
PlatformBinding.getCryptoProvider(ComputerManagerService.this));
|
||||
@@ -551,104 +543,113 @@ public class ComputerManagerService extends Service {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Set the new active address
|
||||
newDetails.activeAddress = address;
|
||||
|
||||
return newDetails;
|
||||
} catch (XmlPullParserException | IOException e) {
|
||||
} catch (XmlPullParserException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} catch (IOException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Just try to establish a TCP connection to speculatively detect a running
|
||||
// GFE server
|
||||
private boolean fastPollIp(String address) {
|
||||
if (address == null) {
|
||||
// Don't bother if our address is null
|
||||
return false;
|
||||
}
|
||||
private static class ParallelPollTuple {
|
||||
public String address;
|
||||
public ComputerDetails existingDetails;
|
||||
|
||||
Socket s = new Socket();
|
||||
try {
|
||||
s.connect(new InetSocketAddress(address, NvHTTP.HTTPS_PORT), FAST_POLL_TIMEOUT);
|
||||
s.close();
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
public boolean complete;
|
||||
public ComputerDetails returnedDetails;
|
||||
|
||||
public ParallelPollTuple(String address, ComputerDetails existingDetails) {
|
||||
this.address = address;
|
||||
this.existingDetails = existingDetails;
|
||||
}
|
||||
}
|
||||
|
||||
private void startFastPollThread(final String address, final boolean[] info) {
|
||||
private void startParallelPollThread(ParallelPollTuple tuple, HashSet<String> uniqueAddresses) {
|
||||
// Don't bother starting a polling thread for an address that doesn't exist
|
||||
// or if the address has already been polled with an earlier tuple
|
||||
if (tuple.address == null || !uniqueAddresses.add(tuple.address)) {
|
||||
tuple.complete = true;
|
||||
tuple.returnedDetails = null;
|
||||
return;
|
||||
}
|
||||
|
||||
Thread t = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
boolean pollRes = fastPollIp(address);
|
||||
ComputerDetails details = tryPollIp(tuple.existingDetails, tuple.address);
|
||||
|
||||
synchronized (info) {
|
||||
info[0] = true; // Done
|
||||
info[1] = pollRes; // Polling result
|
||||
synchronized (tuple) {
|
||||
tuple.complete = true; // Done
|
||||
tuple.returnedDetails = details; // Polling result
|
||||
|
||||
info.notify();
|
||||
tuple.notify();
|
||||
}
|
||||
}
|
||||
};
|
||||
t.setName("Fast Poll - "+address);
|
||||
t.setName("Parallel Poll - "+tuple.address+" - "+tuple.existingDetails.name);
|
||||
t.start();
|
||||
}
|
||||
|
||||
private String fastPollPc(final String localAddress, final String remoteAddress, final String manualAddress, final String ipv6Address) throws InterruptedException {
|
||||
final boolean[] remoteInfo = new boolean[2];
|
||||
final boolean[] localInfo = new boolean[2];
|
||||
final boolean[] manualInfo = new boolean[2];
|
||||
final boolean[] ipv6Info = new boolean[2];
|
||||
private ComputerDetails parallelPollPc(ComputerDetails details) throws InterruptedException {
|
||||
ParallelPollTuple localInfo = new ParallelPollTuple(details.localAddress, details);
|
||||
ParallelPollTuple manualInfo = new ParallelPollTuple(details.manualAddress, details);
|
||||
ParallelPollTuple remoteInfo = new ParallelPollTuple(details.remoteAddress, details);
|
||||
ParallelPollTuple ipv6Info = new ParallelPollTuple(details.ipv6Address, details);
|
||||
|
||||
startFastPollThread(localAddress, localInfo);
|
||||
startFastPollThread(remoteAddress, remoteInfo);
|
||||
startFastPollThread(manualAddress, manualInfo);
|
||||
startFastPollThread(ipv6Address, ipv6Info);
|
||||
// These must be started in order of precedence for the deduplication algorithm
|
||||
// to result in the correct behavior.
|
||||
HashSet<String> uniqueAddresses = new HashSet<>();
|
||||
startParallelPollThread(localInfo, uniqueAddresses);
|
||||
startParallelPollThread(manualInfo, uniqueAddresses);
|
||||
startParallelPollThread(remoteInfo, uniqueAddresses);
|
||||
startParallelPollThread(ipv6Info, uniqueAddresses);
|
||||
|
||||
// Check local first
|
||||
synchronized (localInfo) {
|
||||
while (!localInfo[0]) {
|
||||
while (!localInfo.complete) {
|
||||
localInfo.wait(500);
|
||||
}
|
||||
|
||||
if (localInfo[1]) {
|
||||
return localAddress;
|
||||
if (localInfo.returnedDetails != null) {
|
||||
localInfo.returnedDetails.activeAddress = localInfo.address;
|
||||
return localInfo.returnedDetails;
|
||||
}
|
||||
}
|
||||
|
||||
// Now manual
|
||||
synchronized (manualInfo) {
|
||||
while (!manualInfo[0]) {
|
||||
while (!manualInfo.complete) {
|
||||
manualInfo.wait(500);
|
||||
}
|
||||
|
||||
if (manualInfo[1]) {
|
||||
return manualAddress;
|
||||
if (manualInfo.returnedDetails != null) {
|
||||
manualInfo.returnedDetails.activeAddress = manualInfo.address;
|
||||
return manualInfo.returnedDetails;
|
||||
}
|
||||
}
|
||||
|
||||
// Now remote IPv4
|
||||
synchronized (remoteInfo) {
|
||||
while (!remoteInfo[0]) {
|
||||
while (!remoteInfo.complete) {
|
||||
remoteInfo.wait(500);
|
||||
}
|
||||
|
||||
if (remoteInfo[1]) {
|
||||
return remoteAddress;
|
||||
if (remoteInfo.returnedDetails != null) {
|
||||
remoteInfo.returnedDetails.activeAddress = remoteInfo.address;
|
||||
return remoteInfo.returnedDetails;
|
||||
}
|
||||
}
|
||||
|
||||
// Now global IPv6
|
||||
synchronized (ipv6Info) {
|
||||
while (!ipv6Info[0]) {
|
||||
while (!ipv6Info.complete) {
|
||||
ipv6Info.wait(500);
|
||||
}
|
||||
|
||||
if (ipv6Info[1]) {
|
||||
return ipv6Address;
|
||||
if (ipv6Info.returnedDetails != null) {
|
||||
ipv6Info.returnedDetails.activeAddress = ipv6Info.address;
|
||||
return ipv6Info.returnedDetails;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -656,41 +657,10 @@ public class ComputerManagerService extends Service {
|
||||
}
|
||||
|
||||
private boolean pollComputer(ComputerDetails details) throws InterruptedException {
|
||||
ComputerDetails polledDetails;
|
||||
|
||||
// Do a TCP-level connection to the HTTP server to see if it's listening.
|
||||
// Do not write this address to details.activeAddress because:
|
||||
// a) it's only a candidate and may be wrong (multiple PCs behind a single router)
|
||||
// b) if it's null, it will be unexpectedly nulling the activeAddress of a possibly online PC
|
||||
LimeLog.info("Starting fast poll for "+details.name+" ("+details.localAddress +", "+details.remoteAddress +", "+details.manualAddress+", "+details.ipv6Address+")");
|
||||
String candidateAddress = fastPollPc(details.localAddress, details.remoteAddress, details.manualAddress, details.ipv6Address);
|
||||
LimeLog.info("Fast poll for "+details.name+" returned candidate address: "+candidateAddress);
|
||||
|
||||
// If no connection could be established to either IP address, there's nothing we can do
|
||||
if (candidateAddress == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try using the active address from fast-poll
|
||||
polledDetails = tryPollIp(details, candidateAddress);
|
||||
if (polledDetails == null) {
|
||||
// If that failed, try all unique addresses except what we've
|
||||
// already tried
|
||||
HashSet<String> uniqueAddresses = new HashSet<>();
|
||||
uniqueAddresses.add(details.localAddress);
|
||||
uniqueAddresses.add(details.manualAddress);
|
||||
uniqueAddresses.add(details.remoteAddress);
|
||||
uniqueAddresses.add(details.ipv6Address);
|
||||
for (String addr : uniqueAddresses) {
|
||||
if (addr == null || addr.equals(candidateAddress)) {
|
||||
continue;
|
||||
}
|
||||
polledDetails = tryPollIp(details, addr);
|
||||
if (polledDetails != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Poll all addresses in parallel to speed up the process
|
||||
LimeLog.info("Starting parallel poll for "+details.name+" ("+details.localAddress +", "+details.remoteAddress +", "+details.manualAddress+", "+details.ipv6Address+")");
|
||||
ComputerDetails polledDetails = parallelPollPc(details);
|
||||
LimeLog.info("Parallel poll for "+details.name+" returned address: "+details.activeAddress);
|
||||
|
||||
if (polledDetails != null) {
|
||||
details.update(polledDetails);
|
||||
|
||||
@@ -15,6 +15,9 @@ public class ConnectionContext {
|
||||
// This is the version quad from the appversion tag of /serverinfo
|
||||
public String serverAppVersion;
|
||||
public String serverGfeVersion;
|
||||
|
||||
// This is the sessionUrl0 tag from /resume and /launch
|
||||
public String rtspSessionUrl;
|
||||
|
||||
public int negotiatedWidth, negotiatedHeight;
|
||||
public boolean negotiatedHdr;
|
||||
|
||||
@@ -122,7 +122,7 @@ public class NvConnection {
|
||||
}
|
||||
else if ((context.streamConfig.getWidth() > 4096 || context.streamConfig.getHeight() > 4096) &&
|
||||
!context.streamConfig.getHevcSupported()) {
|
||||
context.connListener.displayMessage("Your streaming device must support H.265 to stream at resolutions above 4K.");
|
||||
context.connListener.displayMessage("Your streaming device must support HEVC to stream at resolutions above 4K.");
|
||||
return false;
|
||||
}
|
||||
else if (context.streamConfig.getHeight() >= 2160 && !h.supports4K(serverInfo)) {
|
||||
@@ -275,7 +275,7 @@ public class NvConnection {
|
||||
synchronized (MoonBridge.class) {
|
||||
MoonBridge.setupBridge(videoDecoderRenderer, audioRenderer, connectionListener);
|
||||
int ret = MoonBridge.startConnection(context.serverAddress,
|
||||
context.serverAppVersion, context.serverGfeVersion,
|
||||
context.serverAppVersion, context.serverGfeVersion, context.rtspSessionUrl,
|
||||
context.negotiatedWidth, context.negotiatedHeight,
|
||||
context.streamConfig.getRefreshRate(), context.streamConfig.getBitrate(),
|
||||
context.streamConfig.getMaxPacketSize(),
|
||||
@@ -284,6 +284,7 @@ public class NvConnection {
|
||||
context.negotiatedHdr,
|
||||
context.streamConfig.getHevcBitratePercentageMultiplier(),
|
||||
context.streamConfig.getClientRefreshRateX100(),
|
||||
context.streamConfig.getEncryptionFlags(),
|
||||
context.riKey.getEncoded(), ib.array(),
|
||||
context.videoCapabilities);
|
||||
if (ret != 0) {
|
||||
@@ -366,6 +367,12 @@ public class NvConnection {
|
||||
}
|
||||
}
|
||||
|
||||
public void sendUtf8Text(final String text) {
|
||||
if (!isMonkey) {
|
||||
MoonBridge.sendUtf8Text(text);
|
||||
}
|
||||
}
|
||||
|
||||
public static String findExternalAddressForMdns(String stunHostname, int stunPort) {
|
||||
return MoonBridge.findExternalAddressIP4(stunHostname, stunPort);
|
||||
}
|
||||
|
||||
@@ -13,4 +13,6 @@ public interface NvConnectionListener {
|
||||
void displayTransientMessage(String message);
|
||||
|
||||
void rumble(short controllerNumber, short lowFreqMotor, short highFreqMotor);
|
||||
|
||||
void setHdrMode(boolean enabled);
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ public class StreamConfiguration {
|
||||
private int hevcBitratePercentageMultiplier;
|
||||
private boolean enableHdr;
|
||||
private int attachedGamepadMask;
|
||||
private int encryptionFlags;
|
||||
|
||||
public static class Builder {
|
||||
private StreamConfiguration config = new StreamConfiguration();
|
||||
@@ -110,7 +111,17 @@ public class StreamConfiguration {
|
||||
config.clientRefreshRateX100 = refreshRateX100;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public StreamConfiguration.Builder setAudioEncryption(boolean enable) {
|
||||
if (enable) {
|
||||
config.encryptionFlags |= MoonBridge.ENCFLG_AUDIO;
|
||||
}
|
||||
else {
|
||||
config.encryptionFlags &= ~MoonBridge.ENCFLG_AUDIO;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public StreamConfiguration.Builder setAudioConfiguration(MoonBridge.AudioConfiguration audioConfig) {
|
||||
config.audioConfiguration = audioConfig;
|
||||
return this;
|
||||
@@ -211,4 +222,8 @@ public class StreamConfiguration {
|
||||
public int getClientRefreshRateX100() {
|
||||
return clientRefreshRateX100;
|
||||
}
|
||||
|
||||
public int getEncryptionFlags() {
|
||||
return encryptionFlags;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,4 +15,6 @@ public abstract class VideoDecoderRenderer {
|
||||
public abstract void cleanup();
|
||||
|
||||
public abstract int getCapabilities();
|
||||
|
||||
public abstract void setHdrMode(boolean enabled);
|
||||
}
|
||||
|
||||
@@ -680,7 +680,13 @@ public class NvHTTP {
|
||||
(context.streamConfig.getAttachedGamepadMask() != 0 ? "&gcmap=" + context.streamConfig.getAttachedGamepadMask() : ""),
|
||||
false);
|
||||
String gameSession = getXmlString(xmlStr, "gamesession");
|
||||
return gameSession != null && !gameSession.equals("0");
|
||||
if (gameSession != null && !gameSession.equals("0")) {
|
||||
context.rtspSessionUrl = getXmlString(xmlStr, "sessionUrl0");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean resumeApp(ConnectionContext context) throws IOException, XmlPullParserException {
|
||||
@@ -690,7 +696,13 @@ public class NvHTTP {
|
||||
"&surroundAudioInfo=" + context.streamConfig.getAudioConfiguration().getSurroundAudioInfo(),
|
||||
false);
|
||||
String resume = getXmlString(xmlStr, "resume");
|
||||
return Integer.parseInt(resume) != 0;
|
||||
if (Integer.parseInt(resume) != 0) {
|
||||
context.rtspSessionUrl = getXmlString(xmlStr, "sessionUrl0");
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean quitApp() throws IOException, XmlPullParserException {
|
||||
|
||||
@@ -18,6 +18,10 @@ public class MoonBridge {
|
||||
public static final int VIDEO_FORMAT_MASK_H264 = 0x00FF;
|
||||
public static final int VIDEO_FORMAT_MASK_H265 = 0xFF00;
|
||||
|
||||
public static final int ENCFLG_NONE = 0;
|
||||
public static final int ENCFLG_AUDIO = 1;
|
||||
public static final int ENCFLG_ALL = 0xFFFFFFFF;
|
||||
|
||||
public static final int BUFFER_TYPE_PICDATA = 0;
|
||||
public static final int BUFFER_TYPE_SPS = 1;
|
||||
public static final int BUFFER_TYPE_PPS = 2;
|
||||
@@ -37,6 +41,7 @@ public class MoonBridge {
|
||||
public static final int ML_ERROR_NO_VIDEO_TRAFFIC = -100;
|
||||
public static final int ML_ERROR_NO_VIDEO_FRAME = -101;
|
||||
public static final int ML_ERROR_UNEXPECTED_EARLY_TERMINATION = -102;
|
||||
public static final int ML_ERROR_PROTECTED_CONTENT = -103;
|
||||
|
||||
public static final int ML_PORT_INDEX_TCP_47984 = 0;
|
||||
public static final int ML_PORT_INDEX_TCP_47989 = 1;
|
||||
@@ -235,6 +240,12 @@ public class MoonBridge {
|
||||
}
|
||||
}
|
||||
|
||||
public static void bridgeClSetHdrMode(boolean enabled) {
|
||||
if (connectionListener != null) {
|
||||
connectionListener.setHdrMode(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setupBridge(VideoDecoderRenderer videoRenderer, AudioRenderer audioRenderer, NvConnectionListener connectionListener) {
|
||||
MoonBridge.videoRenderer = videoRenderer;
|
||||
MoonBridge.audioRenderer = audioRenderer;
|
||||
@@ -248,12 +259,14 @@ public class MoonBridge {
|
||||
}
|
||||
|
||||
public static native int startConnection(String address, String appVersion, String gfeVersion,
|
||||
String rtspSessionUrl,
|
||||
int width, int height, int fps,
|
||||
int bitrate, int packetSize, int streamingRemotely,
|
||||
int audioConfiguration, boolean supportsHevc,
|
||||
boolean enableHdr,
|
||||
int hevcBitratePercentageMultiplier,
|
||||
int clientRefreshRateX100,
|
||||
int encryptionFlags,
|
||||
byte[] riAesKey, byte[] riAesIv,
|
||||
int videoCapabilities);
|
||||
|
||||
@@ -284,6 +297,8 @@ public class MoonBridge {
|
||||
|
||||
public static native void sendMouseHighResScroll(short scrollAmount);
|
||||
|
||||
public static native void sendUtf8Text(String text);
|
||||
|
||||
public static native String getStageName(int stage);
|
||||
|
||||
public static native String findExternalAddressIP4(String stunHostName, int stunPort);
|
||||
@@ -300,5 +315,8 @@ public class MoonBridge {
|
||||
|
||||
public static native String stringifyPortFlags(int portFlags, String separator);
|
||||
|
||||
// The RTT is in the top 32 bits, and the RTT variance is in the bottom 32 bits
|
||||
public static native long getEstimatedRttInfo();
|
||||
|
||||
public static native void init();
|
||||
}
|
||||
|
||||
@@ -88,11 +88,11 @@ public class AddComputerManually extends Activity {
|
||||
|
||||
// Couldn't find a matching interface
|
||||
return true;
|
||||
} catch (SocketException e) {
|
||||
} catch (Exception e) {
|
||||
// Catch all exceptions because some broken Android devices
|
||||
// will throw an NPE from inside getNetworkInterfaces().
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
} catch (UnknownHostException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ public class PreferenceConfiguration {
|
||||
private static final String VIDEO_FORMAT_PREF_STRING = "video_format";
|
||||
private static final String ONSCREEN_CONTROLLER_PREF_STRING = "checkbox_show_onscreen_controls";
|
||||
private static final String ONLY_L3_R3_PREF_STRING = "checkbox_only_show_L3R3";
|
||||
private static final String DISABLE_FRAME_DROP_PREF_STRING = "checkbox_disable_frame_drop";
|
||||
private static final String LEGACY_DISABLE_FRAME_DROP_PREF_STRING = "checkbox_disable_frame_drop";
|
||||
private static final String ENABLE_HDR_PREF_STRING = "checkbox_enable_hdr";
|
||||
private static final String ENABLE_PIP_PREF_STRING = "checkbox_enable_pip";
|
||||
private static final String ENABLE_PERF_OVERLAY_STRING = "checkbox_enable_perf_overlay";
|
||||
@@ -43,6 +43,7 @@ public class PreferenceConfiguration {
|
||||
private static final String FLIP_FACE_BUTTONS_PREF_STRING = "checkbox_flip_face_buttons";
|
||||
private static final String TOUCHSCREEN_TRACKPAD_PREF_STRING = "checkbox_touchscreen_trackpad";
|
||||
private static final String LATENCY_TOAST_PREF_STRING = "checkbox_enable_post_stream_toast";
|
||||
private static final String FRAME_PACING_PREF_STRING = "frame_pacing";
|
||||
|
||||
static final String DEFAULT_RESOLUTION = "1280x720";
|
||||
static final String DEFAULT_FPS = "60";
|
||||
@@ -58,7 +59,6 @@ public class PreferenceConfiguration {
|
||||
private static final String DEFAULT_VIDEO_FORMAT = "auto";
|
||||
private static final boolean ONSCREEN_CONTROLLER_DEFAULT = false;
|
||||
private static final boolean ONLY_L3_R3_DEFAULT = false;
|
||||
private static final boolean DEFAULT_DISABLE_FRAME_DROP = false;
|
||||
private static final boolean DEFAULT_ENABLE_HDR = false;
|
||||
private static final boolean DEFAULT_ENABLE_PIP = false;
|
||||
private static final boolean DEFAULT_ENABLE_PERF_OVERLAY = false;
|
||||
@@ -72,11 +72,17 @@ public class PreferenceConfiguration {
|
||||
private static final boolean DEFAULT_TOUCHSCREEN_TRACKPAD = true;
|
||||
private static final String DEFAULT_AUDIO_CONFIG = "2"; // Stereo
|
||||
private static final boolean DEFAULT_LATENCY_TOAST = false;
|
||||
private static final String DEFAULT_FRAME_PACING = "latency";
|
||||
|
||||
public static final int FORCE_H265_ON = -1;
|
||||
public static final int AUTOSELECT_H265 = 0;
|
||||
public static final int FORCE_H265_OFF = 1;
|
||||
|
||||
public static final int FRAME_PACING_MIN_LATENCY = 0;
|
||||
public static final int FRAME_PACING_BALANCED = 1;
|
||||
public static final int FRAME_PACING_CAP_FPS = 2;
|
||||
public static final int FRAME_PACING_MAX_SMOOTHNESS = 3;
|
||||
|
||||
public static final String RES_360P = "640x360";
|
||||
public static final String RES_480P = "854x480";
|
||||
public static final String RES_720P = "1280x720";
|
||||
@@ -95,7 +101,6 @@ public class PreferenceConfiguration {
|
||||
public boolean smallIconMode, multiController, usbDriver, flipFaceButtons;
|
||||
public boolean onscreenController;
|
||||
public boolean onlyL3R3;
|
||||
public boolean disableFrameDrop;
|
||||
public boolean enableHdr;
|
||||
public boolean enablePip;
|
||||
public boolean enablePerfOverlay;
|
||||
@@ -108,6 +113,7 @@ public class PreferenceConfiguration {
|
||||
public boolean vibrateFallbackToDevice;
|
||||
public boolean touchscreenTrackpad;
|
||||
public MoonBridge.AudioConfiguration audioConfiguration;
|
||||
public int framePacing;
|
||||
|
||||
public static boolean isNativeResolution(int width, int height) {
|
||||
// It's not a native resolution if it matches an existing resolution option
|
||||
@@ -264,6 +270,37 @@ public class PreferenceConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
private static int getFramePacingValue(Context context) {
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
|
||||
// Migrate legacy never drop frames option to the new location
|
||||
if (prefs.contains(LEGACY_DISABLE_FRAME_DROP_PREF_STRING)) {
|
||||
boolean legacyNeverDropFrames = prefs.getBoolean(LEGACY_DISABLE_FRAME_DROP_PREF_STRING, false);
|
||||
prefs.edit()
|
||||
.remove(LEGACY_DISABLE_FRAME_DROP_PREF_STRING)
|
||||
.putString(FRAME_PACING_PREF_STRING, legacyNeverDropFrames ? "balanced" : "latency")
|
||||
.apply();
|
||||
}
|
||||
|
||||
String str = prefs.getString(FRAME_PACING_PREF_STRING, DEFAULT_FRAME_PACING);
|
||||
if (str.equals("latency")) {
|
||||
return FRAME_PACING_MIN_LATENCY;
|
||||
}
|
||||
else if (str.equals("balanced")) {
|
||||
return FRAME_PACING_BALANCED;
|
||||
}
|
||||
else if (str.equals("cap-fps")) {
|
||||
return FRAME_PACING_CAP_FPS;
|
||||
}
|
||||
else if (str.equals("smoothness")) {
|
||||
return FRAME_PACING_MAX_SMOOTHNESS;
|
||||
}
|
||||
else {
|
||||
// Should never get here
|
||||
return FRAME_PACING_MIN_LATENCY;
|
||||
}
|
||||
}
|
||||
|
||||
public static void resetStreamingSettings(Context context) {
|
||||
// We consider resolution, FPS, bitrate, HDR, and video format as "streaming settings" here
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
@@ -387,6 +424,7 @@ public class PreferenceConfiguration {
|
||||
}
|
||||
|
||||
config.videoFormat = getVideoFormatValue(context);
|
||||
config.framePacing = getFramePacingValue(context);
|
||||
|
||||
config.deadzonePercentage = prefs.getInt(DEADZONE_PREF_STRING, DEFAULT_DEADZONE);
|
||||
|
||||
@@ -404,7 +442,6 @@ public class PreferenceConfiguration {
|
||||
config.usbDriver = prefs.getBoolean(USB_DRIVER_PREF_SRING, DEFAULT_USB_DRIVER);
|
||||
config.onscreenController = prefs.getBoolean(ONSCREEN_CONTROLLER_PREF_STRING, ONSCREEN_CONTROLLER_DEFAULT);
|
||||
config.onlyL3R3 = prefs.getBoolean(ONLY_L3_R3_PREF_STRING, ONLY_L3_R3_DEFAULT);
|
||||
config.disableFrameDrop = prefs.getBoolean(DISABLE_FRAME_DROP_PREF_STRING, DEFAULT_DISABLE_FRAME_DROP);
|
||||
config.enableHdr = prefs.getBoolean(ENABLE_HDR_PREF_STRING, DEFAULT_ENABLE_HDR);
|
||||
config.enablePip = prefs.getBoolean(ENABLE_PIP_PREF_STRING, DEFAULT_ENABLE_PIP);
|
||||
config.enablePerfOverlay = prefs.getBoolean(ENABLE_PERF_OVERLAY_STRING, DEFAULT_ENABLE_PERF_OVERLAY);
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.limelight.preferences;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.media.MediaCodecInfo;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
@@ -15,11 +16,14 @@ import android.preference.PreferenceCategory;
|
||||
import android.preference.PreferenceFragment;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Range;
|
||||
import android.view.Display;
|
||||
import android.view.DisplayCutout;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowInsets;
|
||||
|
||||
import com.limelight.LimeLog;
|
||||
import com.limelight.PcView;
|
||||
@@ -28,15 +32,19 @@ import com.limelight.binding.video.MediaCodecHelper;
|
||||
import com.limelight.utils.Dialog;
|
||||
import com.limelight.utils.UiHelper;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class StreamSettings extends Activity {
|
||||
private PreferenceConfiguration previousPrefs;
|
||||
|
||||
// HACK for Android 9
|
||||
static DisplayCutout displayCutoutP;
|
||||
|
||||
void reloadSettings() {
|
||||
getFragmentManager().beginTransaction().replace(
|
||||
R.id.stream_settings, new SettingsFragment()
|
||||
).commit();
|
||||
).commitAllowingStateLoss();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -48,11 +56,28 @@ public class StreamSettings extends Activity {
|
||||
UiHelper.setLocale(this);
|
||||
|
||||
setContentView(R.layout.activity_stream_settings);
|
||||
reloadSettings();
|
||||
|
||||
UiHelper.notifyNewRootView(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
|
||||
// We have to use this hack on Android 9 because we don't have Display.getCutout()
|
||||
// which was added in Android 10.
|
||||
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.P) {
|
||||
// Insets can be null when the activity is recreated on screen rotation
|
||||
// https://stackoverflow.com/questions/61241255/windowinsets-getdisplaycutout-is-null-everywhere-except-within-onattachedtowindo
|
||||
WindowInsets insets = getWindow().getDecorView().getRootWindowInsets();
|
||||
if (insets != null) {
|
||||
displayCutoutP = insets.getDisplayCutout();
|
||||
}
|
||||
}
|
||||
|
||||
reloadSettings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
finish();
|
||||
@@ -76,10 +101,20 @@ public class StreamSettings extends Activity {
|
||||
pref.setValue(value);
|
||||
}
|
||||
|
||||
private void addNativeResolutionEntry(int nativeWidth, int nativeHeight) {
|
||||
private void addNativeResolutionEntry(int nativeWidth, int nativeHeight, boolean insetsRemoved) {
|
||||
ListPreference pref = (ListPreference) findPreference(PreferenceConfiguration.RESOLUTION_PREF_STRING);
|
||||
|
||||
String newName = getResources().getString(R.string.resolution_prefix_native) + " ("+nativeWidth+"x"+nativeHeight+")";
|
||||
String newName;
|
||||
|
||||
if (insetsRemoved) {
|
||||
newName = getResources().getString(R.string.resolution_prefix_native_fullscreen);
|
||||
}
|
||||
else {
|
||||
newName = getResources().getString(R.string.resolution_prefix_native);
|
||||
}
|
||||
|
||||
newName += " ("+nativeWidth+"x"+nativeHeight+")";
|
||||
|
||||
String newValue = nativeWidth+"x"+nativeHeight;
|
||||
|
||||
CharSequence[] values = pref.getEntryValues();
|
||||
@@ -173,7 +208,7 @@ public class StreamSettings extends Activity {
|
||||
|
||||
// hide on-screen controls category on non touch screen devices
|
||||
if (!getActivity().getPackageManager().
|
||||
hasSystemFeature("android.hardware.touchscreen")) {
|
||||
hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)) {
|
||||
{
|
||||
PreferenceCategory category =
|
||||
(PreferenceCategory) findPreference("category_onscreen_controls");
|
||||
@@ -197,6 +232,13 @@ public class StreamSettings extends Activity {
|
||||
category.removePreference(findPreference("checkbox_enable_pip"));
|
||||
}
|
||||
|
||||
// Fire TV apps are not allowed to use WebViews or browsers, so hide the Help category
|
||||
/*if (getActivity().getPackageManager().hasSystemFeature("amazon.hardware.fire_tv")) {
|
||||
PreferenceCategory category =
|
||||
(PreferenceCategory) findPreference("category_help");
|
||||
screen.removePreference(category);
|
||||
}*/
|
||||
|
||||
// Remove the vibration options if the device can't vibrate
|
||||
if (!((Vibrator)getActivity().getSystemService(Context.VIBRATOR_SERVICE)).hasVibrator()) {
|
||||
PreferenceCategory category =
|
||||
@@ -218,6 +260,38 @@ public class StreamSettings extends Activity {
|
||||
|
||||
int maxSupportedResW = 0;
|
||||
|
||||
// Add a native resolution with any insets included for users that don't want content
|
||||
// behind the notch of their display
|
||||
boolean hasInsets = false;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
DisplayCutout cutout;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
// Use the much nicer Display.getCutout() API on Android 10+
|
||||
cutout = display.getCutout();
|
||||
}
|
||||
else {
|
||||
// Android 9 only
|
||||
cutout = displayCutoutP;
|
||||
}
|
||||
|
||||
if (cutout != null) {
|
||||
int widthInsets = cutout.getSafeInsetLeft() + cutout.getSafeInsetRight();
|
||||
int heightInsets = cutout.getSafeInsetBottom() + cutout.getSafeInsetTop();
|
||||
|
||||
if (widthInsets != 0 || heightInsets != 0) {
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
display.getRealMetrics(metrics);
|
||||
|
||||
int width = Math.max(metrics.widthPixels - widthInsets, metrics.heightPixels - heightInsets);
|
||||
int height = Math.min(metrics.widthPixels - widthInsets, metrics.heightPixels - heightInsets);
|
||||
|
||||
addNativeResolutionEntry(width, height, false);
|
||||
hasInsets = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Always allow resolutions that are smaller or equal to the active
|
||||
// display resolution because decoders can report total non-sense to us.
|
||||
// For example, a p201 device reports:
|
||||
@@ -233,7 +307,12 @@ public class StreamSettings extends Activity {
|
||||
int width = Math.max(candidate.getPhysicalWidth(), candidate.getPhysicalHeight());
|
||||
int height = Math.min(candidate.getPhysicalWidth(), candidate.getPhysicalHeight());
|
||||
|
||||
addNativeResolutionEntry(width, height);
|
||||
// Some TVs report strange values here, so let's avoid native resolutions on a TV
|
||||
// unless they report greater than 4K resolutions.
|
||||
if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEVISION) ||
|
||||
(width > 3840 || height > 2160)) {
|
||||
addNativeResolutionEntry(width, height, hasInsets);
|
||||
}
|
||||
|
||||
if ((width >= 3840 || height >= 2160) && maxSupportedResW < 3840) {
|
||||
maxSupportedResW = 3840;
|
||||
@@ -334,11 +413,29 @@ public class StreamSettings extends Activity {
|
||||
// Never remove 720p
|
||||
}
|
||||
}
|
||||
else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||
// On Android 4.2 and later, we can get the true metrics via the
|
||||
// getRealMetrics() function (unlike the lies that getWidth() and getHeight()
|
||||
// tell to us).
|
||||
DisplayMetrics metrics = new DisplayMetrics();
|
||||
getActivity().getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
|
||||
int width = Math.max(metrics.widthPixels, metrics.heightPixels);
|
||||
int height = Math.min(metrics.widthPixels, metrics.heightPixels);
|
||||
addNativeResolutionEntry(width, height, false);
|
||||
}
|
||||
else {
|
||||
// On Android 4.1, we have to resort to reflection to invoke hidden APIs
|
||||
// to get the real screen dimensions.
|
||||
Display display = getActivity().getWindowManager().getDefaultDisplay();
|
||||
int width = Math.max(display.getWidth(), display.getHeight());
|
||||
int height = Math.min(display.getWidth(), display.getHeight());
|
||||
addNativeResolutionEntry(width, height);
|
||||
try {
|
||||
Method getRawHeightFunc = Display.class.getMethod("getRawHeight");
|
||||
Method getRawWidthFunc = Display.class.getMethod("getRawWidth");
|
||||
int width = (Integer) getRawWidthFunc.invoke(display);
|
||||
int height = (Integer) getRawHeightFunc.invoke(display);
|
||||
addNativeResolutionEntry(Math.max(width, height), Math.min(width, height), false);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (!PreferenceConfiguration.readPreferences(this.getActivity()).unlockFps) {
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.limelight.preferences;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.preference.Preference;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.limelight.utils.HelpLauncher;
|
||||
|
||||
public class WebLauncherPreference extends Preference {
|
||||
private String url;
|
||||
|
||||
public WebLauncherPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
initialize(attrs);
|
||||
}
|
||||
|
||||
public WebLauncherPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initialize(attrs);
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public WebLauncherPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
initialize(attrs);
|
||||
}
|
||||
|
||||
private void initialize(AttributeSet attrs) {
|
||||
if (attrs == null) {
|
||||
throw new IllegalStateException("WebLauncherPreference must have attributes!");
|
||||
}
|
||||
|
||||
url = attrs.getAttributeValue(null, "url");
|
||||
if (url == null) {
|
||||
throw new IllegalStateException("WebLauncherPreference must have 'url' attribute!");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick() {
|
||||
HelpLauncher.launchUrl(getContext(), url);
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ import android.net.Uri;
|
||||
import com.limelight.HelpActivity;
|
||||
|
||||
public class HelpLauncher {
|
||||
private static void launchUrl(Context context, String url) {
|
||||
public static void launchUrl(Context context, String url) {
|
||||
// Try to launch the default browser
|
||||
try {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||
|
||||
@@ -39,7 +39,7 @@ public class ShortcutHelper {
|
||||
@TargetApi(Build.VERSION_CODES.N_MR1)
|
||||
private void reapShortcutsForDynamicAdd() {
|
||||
List<ShortcutInfo> dynamicShortcuts = sm.getDynamicShortcuts();
|
||||
while (dynamicShortcuts.size() >= sm.getMaxShortcutCountPerActivity()) {
|
||||
while (!dynamicShortcuts.isEmpty() && dynamicShortcuts.size() >= sm.getMaxShortcutCountPerActivity()) {
|
||||
ShortcutInfo maxRankShortcut = dynamicShortcuts.get(0);
|
||||
for (ShortcutInfo scut : dynamicShortcuts) {
|
||||
if (maxRankShortcut.getRank() < scut.getRank()) {
|
||||
@@ -118,8 +118,16 @@ public class ShortcutHelper {
|
||||
// To avoid a random carousel of shortcuts popping in and out based on polling status,
|
||||
// we only add shortcuts if it's not at the limit or the user made a conscious action
|
||||
// to interact with this PC.
|
||||
if (forceAdd || sm.getDynamicShortcuts().size() < sm.getMaxShortcutCountPerActivity()) {
|
||||
|
||||
if (forceAdd) {
|
||||
// This should free an entry for us to add one below
|
||||
reapShortcutsForDynamicAdd();
|
||||
}
|
||||
|
||||
// We still need to check the maximum shortcut count even after reaping,
|
||||
// because there's a possibility that it could be zero.
|
||||
if (sm.getDynamicShortcuts().size() < sm.getMaxShortcutCountPerActivity()) {
|
||||
// Add a shortcut if there is room
|
||||
sm.addDynamicShortcuts(Collections.singletonList(sinfo));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,9 +18,10 @@ LOCAL_SRC_FILES := moonlight-common-c/src/AudioStream.c \
|
||||
moonlight-common-c/src/LinkedBlockingQueue.c \
|
||||
moonlight-common-c/src/Misc.c \
|
||||
moonlight-common-c/src/Platform.c \
|
||||
moonlight-common-c/src/PlatformCrypto.c \
|
||||
moonlight-common-c/src/PlatformSockets.c \
|
||||
moonlight-common-c/src/RtpFecQueue.c \
|
||||
moonlight-common-c/src/RtpReorderQueue.c \
|
||||
moonlight-common-c/src/RtpAudioQueue.c \
|
||||
moonlight-common-c/src/RtpVideoQueue.c \
|
||||
moonlight-common-c/src/RtspConnection.c \
|
||||
moonlight-common-c/src/RtspParser.c \
|
||||
moonlight-common-c/src/SdpGenerator.c \
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH
|
||||
OUTPUT_DIR=~/openssl
|
||||
|
||||
BASE_ARGS="no-shared no-ssl3 no-stdio no-engine no-hw"
|
||||
|
||||
set -e
|
||||
|
||||
./Configure android-arm $BASE_ARGS -D__ANDROID_API__=16
|
||||
make clean
|
||||
make build_libs -j`nproc`
|
||||
cp lib*.a $OUTPUT_DIR/armeabi-v7a/
|
||||
|
||||
./Configure android-arm64 $BASE_ARGS -D__ANDROID_API__=21
|
||||
make clean
|
||||
make build_libs -j`nproc`
|
||||
cp lib*.a $OUTPUT_DIR/arm64-v8a/
|
||||
|
||||
./Configure android-x86 $BASE_ARGS -D__ANDROID_API__=16
|
||||
make clean
|
||||
make build_libs -j`nproc`
|
||||
cp lib*.a $OUTPUT_DIR/x86/
|
||||
|
||||
./Configure android-x86_64 $BASE_ARGS -D__ANDROID_API__=21
|
||||
make clean
|
||||
make build_libs -j`nproc`
|
||||
cp lib*.a $OUTPUT_DIR/x86_64/
|
||||
cp -R include/ $OUTPUT_DIR/include
|
||||
@@ -32,6 +32,7 @@ static jmethodID BridgeClConnectionStartedMethod;
|
||||
static jmethodID BridgeClConnectionTerminatedMethod;
|
||||
static jmethodID BridgeClRumbleMethod;
|
||||
static jmethodID BridgeClConnectionStatusUpdateMethod;
|
||||
static jmethodID BridgeClSetHdrModeMethod;
|
||||
static jbyteArray DecodedFrameBuffer;
|
||||
static jshortArray DecodedAudioBuffer;
|
||||
|
||||
@@ -92,6 +93,7 @@ Java_com_limelight_nvstream_jni_MoonBridge_init(JNIEnv *env, jclass clazz) {
|
||||
BridgeClConnectionTerminatedMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeClConnectionTerminated", "(I)V");
|
||||
BridgeClRumbleMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeClRumble", "(SSS)V");
|
||||
BridgeClConnectionStatusUpdateMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeClConnectionStatusUpdate", "(I)V");
|
||||
BridgeClSetHdrModeMethod = (*env)->GetStaticMethodID(env, clazz, "bridgeClSetHdrMode", "(Z)V");
|
||||
}
|
||||
|
||||
int BridgeDrSetup(int videoFormat, int width, int height, int redrawRate, void* context, int drFlags) {
|
||||
@@ -326,6 +328,16 @@ void BridgeClConnectionStatusUpdate(int connectionStatus) {
|
||||
}
|
||||
}
|
||||
|
||||
void BridgeClSetHdrMode(bool enabled) {
|
||||
JNIEnv* env = GetThreadEnv();
|
||||
|
||||
(*env)->CallStaticVoidMethod(env, GlobalBridgeClass, BridgeClSetHdrModeMethod, enabled);
|
||||
if ((*env)->ExceptionCheck(env)) {
|
||||
// We will crash here
|
||||
(*JVM)->DetachCurrentThread(JVM);
|
||||
}
|
||||
}
|
||||
|
||||
void BridgeClLogMessage(const char* format, ...) {
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
@@ -359,23 +371,27 @@ static CONNECTION_LISTENER_CALLBACKS BridgeConnListenerCallbacks = {
|
||||
.logMessage = BridgeClLogMessage,
|
||||
.rumble = BridgeClRumble,
|
||||
.connectionStatusUpdate = BridgeClConnectionStatusUpdate,
|
||||
.setHdrMode = BridgeClSetHdrMode,
|
||||
};
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_limelight_nvstream_jni_MoonBridge_startConnection(JNIEnv *env, jclass clazz,
|
||||
jstring address, jstring appVersion, jstring gfeVersion,
|
||||
jstring rtspSessionUrl,
|
||||
jint width, jint height, jint fps,
|
||||
jint bitrate, jint packetSize, jint streamingRemotely,
|
||||
jint audioConfiguration, jboolean supportsHevc,
|
||||
jboolean enableHdr,
|
||||
jint hevcBitratePercentageMultiplier,
|
||||
jint clientRefreshRateX100,
|
||||
jint encryptionFlags,
|
||||
jbyteArray riAesKey, jbyteArray riAesIv,
|
||||
jint videoCapabilities) {
|
||||
SERVER_INFORMATION serverInfo = {
|
||||
.address = (*env)->GetStringUTFChars(env, address, 0),
|
||||
.serverInfoAppVersion = (*env)->GetStringUTFChars(env, appVersion, 0),
|
||||
.serverInfoGfeVersion = gfeVersion ? (*env)->GetStringUTFChars(env, gfeVersion, 0) : NULL,
|
||||
.rtspSessionUrl = rtspSessionUrl ? (*env)->GetStringUTFChars(env, rtspSessionUrl, 0) : NULL,
|
||||
};
|
||||
STREAM_CONFIGURATION streamConfig = {
|
||||
.width = width,
|
||||
@@ -388,7 +404,8 @@ Java_com_limelight_nvstream_jni_MoonBridge_startConnection(JNIEnv *env, jclass c
|
||||
.supportsHevc = supportsHevc,
|
||||
.enableHdr = enableHdr,
|
||||
.hevcBitratePercentageMultiplier = hevcBitratePercentageMultiplier,
|
||||
.clientRefreshRateX100 = clientRefreshRateX100
|
||||
.clientRefreshRateX100 = clientRefreshRateX100,
|
||||
.encryptionFlags = encryptionFlags,
|
||||
};
|
||||
|
||||
jbyte* riAesKeyBuf = (*env)->GetByteArrayElements(env, riAesKey, NULL);
|
||||
@@ -414,6 +431,9 @@ Java_com_limelight_nvstream_jni_MoonBridge_startConnection(JNIEnv *env, jclass c
|
||||
if (gfeVersion != NULL) {
|
||||
(*env)->ReleaseStringUTFChars(env, gfeVersion, serverInfo.serverInfoGfeVersion);
|
||||
}
|
||||
if (rtspSessionUrl != NULL) {
|
||||
(*env)->ReleaseStringUTFChars(env, rtspSessionUrl, serverInfo.rtspSessionUrl);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
Submodule app/src/main/jni/moonlight-core/moonlight-common-c updated: 021fe902d9...e62dc56047
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -8,9 +8,15 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is only used by HP C on VMS, and is included automatically
|
||||
* This file is only used by HP C/C++ on VMS, and is included automatically
|
||||
* after each header file from this directory
|
||||
*/
|
||||
|
||||
/*
|
||||
* The C++ compiler doesn't understand these pragmas, even though it
|
||||
* understands the corresponding command line qualifier.
|
||||
*/
|
||||
#ifndef __cplusplus
|
||||
/* restore state. Must correspond to the save in __decc_include_prologue.h */
|
||||
#pragma names restore
|
||||
# pragma names restore
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -8,13 +8,19 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is only used by HP C on VMS, and is included automatically
|
||||
* This file is only used by HP C/C++ on VMS, and is included automatically
|
||||
* after each header file from this directory
|
||||
*/
|
||||
|
||||
/*
|
||||
* The C++ compiler doesn't understand these pragmas, even though it
|
||||
* understands the corresponding command line qualifier.
|
||||
*/
|
||||
#ifndef __cplusplus
|
||||
/* save state */
|
||||
#pragma names save
|
||||
# pragma names save
|
||||
/* have the compiler shorten symbols larger than 31 chars to 23 chars
|
||||
* followed by a 8 hex char CRC
|
||||
*/
|
||||
#pragma names as_is,shortened
|
||||
# pragma names as_is,shortened
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,8 @@
|
||||
#ifndef HEADER_ASN1ERR_H
|
||||
# define HEADER_ASN1ERR_H
|
||||
|
||||
# include <openssl/symhacks.h>
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
@@ -49,6 +51,7 @@ int ERR_load_ASN1_strings(void);
|
||||
# define ASN1_F_ASN1_ITEM_DUP 191
|
||||
# define ASN1_F_ASN1_ITEM_EMBED_D2I 120
|
||||
# define ASN1_F_ASN1_ITEM_EMBED_NEW 121
|
||||
# define ASN1_F_ASN1_ITEM_EX_I2D 144
|
||||
# define ASN1_F_ASN1_ITEM_FLAGS_I2D 118
|
||||
# define ASN1_F_ASN1_ITEM_I2D_BIO 192
|
||||
# define ASN1_F_ASN1_ITEM_I2D_FP 193
|
||||
@@ -141,6 +144,7 @@ int ERR_load_ASN1_strings(void);
|
||||
# define ASN1_R_ASN1_SIG_PARSE_ERROR 204
|
||||
# define ASN1_R_AUX_ERROR 100
|
||||
# define ASN1_R_BAD_OBJECT_HEADER 102
|
||||
# define ASN1_R_BAD_TEMPLATE 230
|
||||
# define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214
|
||||
# define ASN1_R_BN_LIB 105
|
||||
# define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_ASYNCERR_H
|
||||
# define HEADER_ASYNCERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -20,10 +20,6 @@
|
||||
# include <openssl/crypto.h>
|
||||
# include <openssl/bioerr.h>
|
||||
|
||||
# ifndef OPENSSL_NO_SCTP
|
||||
# include <openssl/e_os2.h>
|
||||
# endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -173,6 +169,7 @@ extern "C" {
|
||||
*/
|
||||
# define BIO_FLAGS_MEM_RDONLY 0x200
|
||||
# define BIO_FLAGS_NONCLEAR_RST 0x400
|
||||
# define BIO_FLAGS_IN_EOF 0x800
|
||||
|
||||
typedef union bio_addr_st BIO_ADDR;
|
||||
typedef struct bio_addrinfo_st BIO_ADDRINFO;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_BIOERR_H
|
||||
# define HEADER_BIOERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
@@ -56,7 +56,7 @@ extern "C" {
|
||||
* avoid leaking exponent information through timing,
|
||||
* BN_mod_exp_mont() will call BN_mod_exp_mont_consttime,
|
||||
* BN_div() will call BN_div_no_branch,
|
||||
* BN_mod_inverse() will call BN_mod_inverse_no_branch.
|
||||
* BN_mod_inverse() will call bn_mod_inverse_no_branch.
|
||||
*/
|
||||
# define BN_FLG_CONSTTIME 0x04
|
||||
# define BN_FLG_SECURE 0x08
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_BNERR_H
|
||||
# define HEADER_BNERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_BUFERR_H
|
||||
# define HEADER_BUFERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2008-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -284,8 +284,6 @@ int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si,
|
||||
void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid,
|
||||
int lastpos, int type);
|
||||
|
||||
# ifdef HEADER_X509V3_H
|
||||
|
||||
int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr);
|
||||
CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
|
||||
int allorfirst,
|
||||
@@ -298,7 +296,6 @@ void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr,
|
||||
int *pallorfirst,
|
||||
STACK_OF(GENERAL_NAMES) **plist,
|
||||
STACK_OF(GENERAL_NAMES) **prto);
|
||||
# endif
|
||||
int CMS_RecipientInfo_kari_get0_alg(CMS_RecipientInfo *ri,
|
||||
X509_ALGOR **palg,
|
||||
ASN1_OCTET_STRING **pukm);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_CMSERR_H
|
||||
# define HEADER_CMSERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# include <openssl/opensslconf.h>
|
||||
|
||||
# ifndef OPENSSL_NO_CMS
|
||||
@@ -101,6 +105,7 @@ int ERR_load_CMS_strings(void);
|
||||
# define CMS_F_CMS_SIGNERINFO_VERIFY_CERT 153
|
||||
# define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT 154
|
||||
# define CMS_F_CMS_SIGN_RECEIPT 163
|
||||
# define CMS_F_CMS_SI_CHECK_ATTRIBUTES 183
|
||||
# define CMS_F_CMS_STREAM 155
|
||||
# define CMS_F_CMS_UNCOMPRESS 156
|
||||
# define CMS_F_CMS_VERIFY 157
|
||||
@@ -110,6 +115,7 @@ int ERR_load_CMS_strings(void);
|
||||
* CMS reason codes.
|
||||
*/
|
||||
# define CMS_R_ADD_SIGNER_ERROR 99
|
||||
# define CMS_R_ATTRIBUTE_ERROR 161
|
||||
# define CMS_R_CERTIFICATE_ALREADY_PRESENT 175
|
||||
# define CMS_R_CERTIFICATE_HAS_NO_KEYID 160
|
||||
# define CMS_R_CERTIFICATE_VERIFY_ERROR 100
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_COMPERR_H
|
||||
# define HEADER_COMPERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# include <openssl/opensslconf.h>
|
||||
|
||||
# ifndef OPENSSL_NO_COMP
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_CONFERR_H
|
||||
# define HEADER_CONFERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,12 +11,13 @@
|
||||
#ifndef HEADER_CRYPTOERR_H
|
||||
# define HEADER_CRYPTOERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
|
||||
# include <openssl/symhacks.h>
|
||||
|
||||
int ERR_load_CRYPTO_strings(void);
|
||||
|
||||
/*
|
||||
|
||||
@@ -463,8 +463,6 @@ __owur int CTLOG_STORE_load_file(CTLOG_STORE *store, const char *file);
|
||||
|
||||
/*
|
||||
* Loads the default CT log list into a |store|.
|
||||
* See internal/cryptlib.h for the environment variable and file path that are
|
||||
* consulted to find the default file.
|
||||
* Returns 1 if loading is successful, or 0 otherwise.
|
||||
*/
|
||||
__owur int CTLOG_STORE_load_default_file(CTLOG_STORE *store);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_CTERR_H
|
||||
# define HEADER_CTERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# include <openssl/opensslconf.h>
|
||||
|
||||
# ifndef OPENSSL_NO_CT
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_DHERR_H
|
||||
# define HEADER_DHERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# include <openssl/opensslconf.h>
|
||||
|
||||
# ifndef OPENSSL_NO_DH
|
||||
|
||||
@@ -162,6 +162,12 @@ DH *DSA_dup_DH(const DSA *r);
|
||||
# define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \
|
||||
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \
|
||||
EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL)
|
||||
# define EVP_PKEY_CTX_set_dsa_paramgen_q_bits(ctx, qbits) \
|
||||
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \
|
||||
EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, qbits, NULL)
|
||||
# define EVP_PKEY_CTX_set_dsa_paramgen_md(ctx, md) \
|
||||
EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \
|
||||
EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, (void *)(md))
|
||||
|
||||
# define EVP_PKEY_CTRL_DSA_PARAMGEN_BITS (EVP_PKEY_ALG_CTRL + 1)
|
||||
# define EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS (EVP_PKEY_ALG_CTRL + 2)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_DSAERR_H
|
||||
# define HEADER_DSAERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# include <openssl/opensslconf.h>
|
||||
|
||||
# ifndef OPENSSL_NO_DSA
|
||||
@@ -57,6 +61,7 @@ int ERR_load_DSA_strings(void);
|
||||
# define DSA_R_INVALID_DIGEST_TYPE 106
|
||||
# define DSA_R_INVALID_PARAMETERS 112
|
||||
# define DSA_R_MISSING_PARAMETERS 101
|
||||
# define DSA_R_MISSING_PRIVATE_KEY 111
|
||||
# define DSA_R_MODULUS_TOO_LARGE 103
|
||||
# define DSA_R_NO_PARAMETERS_SET 107
|
||||
# define DSA_R_PARAMETER_ENCODING_ERROR 105
|
||||
|
||||
@@ -43,7 +43,7 @@ extern "C" {
|
||||
|
||||
# define DTLS1_AL_HEADER_LENGTH 2
|
||||
|
||||
/* Timeout multipliers (timeout slice is defined in apps/timeouts.h */
|
||||
/* Timeout multipliers */
|
||||
# define DTLS1_TMO_READ_COUNT 2
|
||||
# define DTLS1_TMO_WRITE_COUNT 2
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -241,7 +241,7 @@ typedef UINT64 uint64_t;
|
||||
defined(__osf__) || defined(__sgi) || defined(__hpux) || \
|
||||
defined(OPENSSL_SYS_VMS) || defined (__OpenBSD__)
|
||||
# include <inttypes.h>
|
||||
# elif defined(_MSC_VER) && _MSC_VER<=1500
|
||||
# elif defined(_MSC_VER) && _MSC_VER<1600
|
||||
/*
|
||||
* minimally required typdefs for systems not supporting inttypes.h or
|
||||
* stdint.h: currently just older VC++
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
@@ -142,7 +142,7 @@ const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group);
|
||||
*/
|
||||
int EC_METHOD_get_field_type(const EC_METHOD *meth);
|
||||
|
||||
/** Sets the generator and it's order/cofactor of a EC_GROUP object.
|
||||
/** Sets the generator and its order/cofactor of a EC_GROUP object.
|
||||
* \param group EC_GROUP object
|
||||
* \param generator EC_POINT object with the generator.
|
||||
* \param order the order of the group generated by the generator.
|
||||
@@ -829,6 +829,8 @@ void EC_KEY_set_flags(EC_KEY *key, int flags);
|
||||
|
||||
void EC_KEY_clear_flags(EC_KEY *key, int flags);
|
||||
|
||||
int EC_KEY_decoded_from_explicit_params(const EC_KEY *key);
|
||||
|
||||
/** Creates a new EC_KEY object using a named curve as underlying
|
||||
* EC_GROUP object.
|
||||
* \param nid NID of the named curve.
|
||||
@@ -1138,7 +1140,8 @@ void ECDSA_SIG_free(ECDSA_SIG *sig);
|
||||
* (*pp += length of the DER encoded signature)).
|
||||
* \param sig pointer to the ECDSA_SIG object
|
||||
* \param pp pointer to a unsigned char pointer for the output or NULL
|
||||
* \return the length of the DER encoded ECDSA_SIG object or 0
|
||||
* \return the length of the DER encoded ECDSA_SIG object or a negative value
|
||||
* on error
|
||||
*/
|
||||
int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_ECERR_H
|
||||
# define HEADER_ECERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# include <openssl/opensslconf.h>
|
||||
|
||||
# ifndef OPENSSL_NO_EC
|
||||
@@ -239,6 +243,7 @@ int ERR_load_EC_strings(void);
|
||||
# define EC_R_LADDER_POST_FAILURE 136
|
||||
# define EC_R_LADDER_PRE_FAILURE 153
|
||||
# define EC_R_LADDER_STEP_FAILURE 162
|
||||
# define EC_R_MISSING_OID 167
|
||||
# define EC_R_MISSING_PARAMETERS 124
|
||||
# define EC_R_MISSING_PRIVATE_KEY 125
|
||||
# define EC_R_NEED_NEW_SETUP_VALUES 157
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_ENGINEERR_H
|
||||
# define HEADER_ENGINEERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# include <openssl/opensslconf.h>
|
||||
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -37,6 +37,7 @@ extern "C" {
|
||||
# define ERR_TXT_STRING 0x02
|
||||
|
||||
# define ERR_FLAG_MARK 0x01
|
||||
# define ERR_FLAG_CLEAR 0x02
|
||||
|
||||
# define ERR_NUM_ERRORS 16
|
||||
typedef struct err_state_st {
|
||||
|
||||
@@ -180,7 +180,7 @@ int (*EVP_MD_meth_get_ctrl(const EVP_MD *md))(EVP_MD_CTX *ctx, int cmd,
|
||||
* if the following flag is set.
|
||||
*/
|
||||
# define EVP_MD_CTX_FLAG_FINALISE 0x0200
|
||||
/* NOTE: 0x0400 is reserved for internal usage in evp_int.h */
|
||||
/* NOTE: 0x0400 is reserved for internal usage */
|
||||
|
||||
EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len);
|
||||
EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher);
|
||||
@@ -260,6 +260,8 @@ int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
|
||||
# define EVP_CIPH_RAND_KEY 0x200
|
||||
/* cipher has its own additional copying logic */
|
||||
# define EVP_CIPH_CUSTOM_COPY 0x400
|
||||
/* Don't use standard iv length function */
|
||||
# define EVP_CIPH_CUSTOM_IV_LENGTH 0x800
|
||||
/* Allow use default ASN1 get/set iv */
|
||||
# define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000
|
||||
/* Buffer length in bits not bytes: CFB1 mode only */
|
||||
@@ -349,6 +351,8 @@ int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *,
|
||||
/* Set the input buffer lengths to use for a pipelined operation */
|
||||
# define EVP_CTRL_SET_PIPELINE_INPUT_LENS 0x24
|
||||
|
||||
# define EVP_CTRL_GET_IVLEN 0x25
|
||||
|
||||
/* Padding modes */
|
||||
#define EVP_PADDING_PKCS7 1
|
||||
#define EVP_PADDING_ISO7816_4 2
|
||||
@@ -995,6 +999,7 @@ int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len);
|
||||
int EVP_PKEY_set_alias_type(EVP_PKEY *pkey, int type);
|
||||
# ifndef OPENSSL_NO_ENGINE
|
||||
int EVP_PKEY_set1_engine(EVP_PKEY *pkey, ENGINE *e);
|
||||
ENGINE *EVP_PKEY_get0_engine(const EVP_PKEY *pkey);
|
||||
# endif
|
||||
int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key);
|
||||
void *EVP_PKEY_get0(const EVP_PKEY *pkey);
|
||||
@@ -1507,6 +1512,20 @@ void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
|
||||
const char *type,
|
||||
const char *value));
|
||||
|
||||
void EVP_PKEY_meth_set_digestsign(EVP_PKEY_METHOD *pmeth,
|
||||
int (*digestsign) (EVP_MD_CTX *ctx,
|
||||
unsigned char *sig,
|
||||
size_t *siglen,
|
||||
const unsigned char *tbs,
|
||||
size_t tbslen));
|
||||
|
||||
void EVP_PKEY_meth_set_digestverify(EVP_PKEY_METHOD *pmeth,
|
||||
int (*digestverify) (EVP_MD_CTX *ctx,
|
||||
const unsigned char *sig,
|
||||
size_t siglen,
|
||||
const unsigned char *tbs,
|
||||
size_t tbslen));
|
||||
|
||||
void EVP_PKEY_meth_set_check(EVP_PKEY_METHOD *pmeth,
|
||||
int (*check) (EVP_PKEY *pkey));
|
||||
|
||||
@@ -1612,6 +1631,20 @@ void EVP_PKEY_meth_get_ctrl(const EVP_PKEY_METHOD *pmeth,
|
||||
const char *type,
|
||||
const char *value));
|
||||
|
||||
void EVP_PKEY_meth_get_digestsign(EVP_PKEY_METHOD *pmeth,
|
||||
int (**digestsign) (EVP_MD_CTX *ctx,
|
||||
unsigned char *sig,
|
||||
size_t *siglen,
|
||||
const unsigned char *tbs,
|
||||
size_t tbslen));
|
||||
|
||||
void EVP_PKEY_meth_get_digestverify(EVP_PKEY_METHOD *pmeth,
|
||||
int (**digestverify) (EVP_MD_CTX *ctx,
|
||||
const unsigned char *sig,
|
||||
size_t siglen,
|
||||
const unsigned char *tbs,
|
||||
size_t tbslen));
|
||||
|
||||
void EVP_PKEY_meth_get_check(const EVP_PKEY_METHOD *pmeth,
|
||||
int (**pcheck) (EVP_PKEY *pkey));
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,8 @@
|
||||
#ifndef HEADER_EVPERR_H
|
||||
# define HEADER_EVPERR_H
|
||||
|
||||
# include <openssl/symhacks.h>
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
@@ -20,11 +22,14 @@ int ERR_load_EVP_strings(void);
|
||||
* EVP function codes.
|
||||
*/
|
||||
# define EVP_F_AESNI_INIT_KEY 165
|
||||
# define EVP_F_AESNI_XTS_INIT_KEY 207
|
||||
# define EVP_F_AES_GCM_CTRL 196
|
||||
# define EVP_F_AES_INIT_KEY 133
|
||||
# define EVP_F_AES_OCB_CIPHER 169
|
||||
# define EVP_F_AES_T4_INIT_KEY 178
|
||||
# define EVP_F_AES_T4_XTS_INIT_KEY 208
|
||||
# define EVP_F_AES_WRAP_CIPHER 170
|
||||
# define EVP_F_AES_XTS_INIT_KEY 209
|
||||
# define EVP_F_ALG_MODULE_INIT 177
|
||||
# define EVP_F_ARIA_CCM_INIT_KEY 175
|
||||
# define EVP_F_ARIA_GCM_CTRL 197
|
||||
@@ -115,6 +120,7 @@ int ERR_load_EVP_strings(void);
|
||||
# define EVP_F_PKEY_SET_TYPE 158
|
||||
# define EVP_F_RC2_MAGIC_TO_METH 109
|
||||
# define EVP_F_RC5_CTRL 125
|
||||
# define EVP_F_R_32_12_16_INIT_KEY 242
|
||||
# define EVP_F_S390X_AES_GCM_CTRL 201
|
||||
# define EVP_F_UPDATE 173
|
||||
|
||||
@@ -124,6 +130,7 @@ int ERR_load_EVP_strings(void);
|
||||
# define EVP_R_AES_KEY_SETUP_FAILED 143
|
||||
# define EVP_R_ARIA_KEY_SETUP_FAILED 176
|
||||
# define EVP_R_BAD_DECRYPT 100
|
||||
# define EVP_R_BAD_KEY_LENGTH 195
|
||||
# define EVP_R_BUFFER_TOO_SMALL 155
|
||||
# define EVP_R_CAMELLIA_KEY_SETUP_FAILED 157
|
||||
# define EVP_R_CIPHER_PARAMETER_ERROR 122
|
||||
@@ -151,6 +158,7 @@ int ERR_load_EVP_strings(void);
|
||||
# define EVP_R_INPUT_NOT_INITIALIZED 111
|
||||
# define EVP_R_INVALID_DIGEST 152
|
||||
# define EVP_R_INVALID_FIPS_MODE 168
|
||||
# define EVP_R_INVALID_IV_LENGTH 194
|
||||
# define EVP_R_INVALID_KEY 163
|
||||
# define EVP_R_INVALID_KEY_LENGTH 130
|
||||
# define EVP_R_INVALID_OPERATION 148
|
||||
@@ -169,6 +177,7 @@ int ERR_load_EVP_strings(void);
|
||||
# define EVP_R_ONLY_ONESHOT_SUPPORTED 177
|
||||
# define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150
|
||||
# define EVP_R_OPERATON_NOT_INITIALIZED 151
|
||||
# define EVP_R_OUTPUT_WOULD_OVERFLOW 184
|
||||
# define EVP_R_PARTIALLY_OVERLAPPING 162
|
||||
# define EVP_R_PBKDF2_ERROR 181
|
||||
# define EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED 179
|
||||
@@ -190,5 +199,6 @@ int ERR_load_EVP_strings(void);
|
||||
# define EVP_R_UNSUPPORTED_SALT_TYPE 126
|
||||
# define EVP_R_WRAP_MODE_NOT_ALLOWED 170
|
||||
# define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109
|
||||
# define EVP_R_XTS_DUPLICATED_KEYS 183
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_KDFERR_H
|
||||
# define HEADER_KDFERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -120,9 +120,8 @@ void OPENSSL_LH_node_usage_stats_bio(const OPENSSL_LHASH *lh, BIO *out);
|
||||
|
||||
# define DEFINE_LHASH_OF(type) \
|
||||
LHASH_OF(type) { union lh_##type##_dummy { void* d1; unsigned long d2; int d3; } dummy; }; \
|
||||
static ossl_inline LHASH_OF(type) * \
|
||||
lh_##type##_new(unsigned long (*hfn)(const type *), \
|
||||
int (*cfn)(const type *, const type *)) \
|
||||
static ossl_unused ossl_inline LHASH_OF(type) *lh_##type##_new(unsigned long (*hfn)(const type *), \
|
||||
int (*cfn)(const type *, const type *)) \
|
||||
{ \
|
||||
return (LHASH_OF(type) *) \
|
||||
OPENSSL_LH_new((OPENSSL_LH_HASHFUNC)hfn, (OPENSSL_LH_COMPFUNC)cfn); \
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* WARNING: do not edit!
|
||||
* Generated by crypto/objects/objects.pl
|
||||
*
|
||||
* Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
@@ -1290,12 +1290,12 @@
|
||||
#define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L
|
||||
|
||||
#define SN_ms_smartcard_login "msSmartcardLogin"
|
||||
#define LN_ms_smartcard_login "Microsoft Smartcardlogin"
|
||||
#define LN_ms_smartcard_login "Microsoft Smartcard Login"
|
||||
#define NID_ms_smartcard_login 648
|
||||
#define OBJ_ms_smartcard_login 1L,3L,6L,1L,4L,1L,311L,20L,2L,2L
|
||||
|
||||
#define SN_ms_upn "msUPN"
|
||||
#define LN_ms_upn "Microsoft Universal Principal Name"
|
||||
#define LN_ms_upn "Microsoft User Principal Name"
|
||||
#define NID_ms_upn 649
|
||||
#define OBJ_ms_upn 1L,3L,6L,1L,4L,1L,311L,20L,2L,3L
|
||||
|
||||
@@ -4280,7 +4280,7 @@
|
||||
|
||||
#define SN_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 "id-tc26-wrap-gostr3412-2015-kuznyechik-kexp15"
|
||||
#define NID_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 1183
|
||||
#define OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 OBJ_id_tc26_wrap_gostr3412_2015_magma,1L
|
||||
#define OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik,1L
|
||||
|
||||
#define SN_id_tc26_constants "id-tc26-constants"
|
||||
#define NID_id_tc26_constants 994
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_OBJERR_H
|
||||
# define HEADER_OBJERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -123,7 +123,7 @@ typedef struct ocsp_service_locator_st OCSP_SERVICELOC;
|
||||
(char *(*)())d2i_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST, \
|
||||
bp,(char **)(x),cb,NULL)
|
||||
|
||||
# define PEM_read_bio_OCSP_RESPONSE(bp,x,cb)(OCSP_RESPONSE *)PEM_ASN1_read_bio(\
|
||||
# define PEM_read_bio_OCSP_RESPONSE(bp,x,cb) (OCSP_RESPONSE *)PEM_ASN1_read_bio(\
|
||||
(char *(*)())d2i_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE, \
|
||||
bp,(char **)(x),cb,NULL)
|
||||
|
||||
@@ -229,8 +229,8 @@ int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs,
|
||||
int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath,
|
||||
int *pssl);
|
||||
|
||||
int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b);
|
||||
int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b);
|
||||
int OCSP_id_issuer_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b);
|
||||
int OCSP_id_cmp(const OCSP_CERTID *a, const OCSP_CERTID *b);
|
||||
|
||||
int OCSP_request_onereq_count(OCSP_REQUEST *req);
|
||||
OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_OCSPERR_H
|
||||
# define HEADER_OCSPERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# include <openssl/opensslconf.h>
|
||||
|
||||
# ifndef OPENSSL_NO_OCSP
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* WARNING: do not edit!
|
||||
* Generated by Makefile from include/openssl/opensslconf.h.in
|
||||
*
|
||||
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -24,9 +24,6 @@ extern "C" {
|
||||
* OpenSSL was configured with the following options:
|
||||
*/
|
||||
|
||||
#ifndef OPENSSL_NO_COMP
|
||||
# define OPENSSL_NO_COMP
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_MD2
|
||||
# define OPENSSL_NO_MD2
|
||||
#endif
|
||||
@@ -48,9 +45,6 @@ extern "C" {
|
||||
#ifndef OPENSSL_NO_ASAN
|
||||
# define OPENSSL_NO_ASAN
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_ASM
|
||||
# define OPENSSL_NO_ASM
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_CAPIENG
|
||||
# define OPENSSL_NO_CAPIENG
|
||||
#endif
|
||||
@@ -120,9 +114,6 @@ extern "C" {
|
||||
#ifndef OPENSSL_NO_DYNAMIC_ENGINE
|
||||
# define OPENSSL_NO_DYNAMIC_ENGINE
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_AFALGENG
|
||||
# define OPENSSL_NO_AFALGENG
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
@@ -144,6 +135,11 @@ extern "C" {
|
||||
# undef DECLARE_DEPRECATED
|
||||
# define DECLARE_DEPRECATED(f) f __attribute__ ((deprecated));
|
||||
# endif
|
||||
# elif defined(__SUNPRO_C)
|
||||
# if (__SUNPRO_C >= 0x5130)
|
||||
# undef DECLARE_DEPRECATED
|
||||
# define DECLARE_DEPRECATED(f) f __attribute__ ((deprecated));
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* {- join("\n * ", @autowarntext) -}
|
||||
*
|
||||
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -77,6 +77,11 @@ extern "C" {
|
||||
# undef DECLARE_DEPRECATED
|
||||
# define DECLARE_DEPRECATED(f) f __attribute__ ((deprecated));
|
||||
# endif
|
||||
# elif defined(__SUNPRO_C)
|
||||
# if (__SUNPRO_C >= 0x5130)
|
||||
# undef DECLARE_DEPRECATED
|
||||
# define DECLARE_DEPRECATED(f) f __attribute__ ((deprecated));
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -39,8 +39,8 @@ extern "C" {
|
||||
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
|
||||
* major minor fix final patch/beta)
|
||||
*/
|
||||
# define OPENSSL_VERSION_NUMBER 0x1010102fL
|
||||
# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1b 26 Feb 2019"
|
||||
# define OPENSSL_VERSION_NUMBER 0x101010bfL
|
||||
# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1k 25 Mar 2021"
|
||||
|
||||
/*-
|
||||
* The macros below are to be used for shared library (.so, .dll, ...)
|
||||
|
||||
@@ -109,6 +109,7 @@ typedef struct dsa_method DSA_METHOD;
|
||||
|
||||
typedef struct rsa_st RSA;
|
||||
typedef struct rsa_meth_st RSA_METHOD;
|
||||
typedef struct rsa_pss_params_st RSA_PSS_PARAMS;
|
||||
|
||||
typedef struct ec_key_st EC_KEY;
|
||||
typedef struct ec_key_method_st EC_KEY_METHOD;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_PEMERR_H
|
||||
# define HEADER_PEMERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
@@ -57,6 +61,7 @@ int ERR_load_PEM_strings(void);
|
||||
# define PEM_F_PEM_SIGNFINAL 112
|
||||
# define PEM_F_PEM_WRITE 113
|
||||
# define PEM_F_PEM_WRITE_BIO 114
|
||||
# define PEM_F_PEM_WRITE_BIO_PRIVATEKEY_TRADITIONAL 147
|
||||
# define PEM_F_PEM_WRITE_PRIVATEKEY 139
|
||||
# define PEM_F_PEM_X509_INFO_READ 115
|
||||
# define PEM_F_PEM_X509_INFO_READ_BIO 116
|
||||
@@ -95,5 +100,6 @@ int ERR_load_PEM_strings(void);
|
||||
# define PEM_R_UNSUPPORTED_CIPHER 113
|
||||
# define PEM_R_UNSUPPORTED_ENCRYPTION 114
|
||||
# define PEM_R_UNSUPPORTED_KEY_COMPONENTS 126
|
||||
# define PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE 110
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_PKCS12ERR_H
|
||||
# define HEADER_PKCS12ERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_PKCS7ERR_H
|
||||
# define HEADER_PKCS7ERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,8 @@
|
||||
#ifndef HEADER_RANDERR_H
|
||||
# define HEADER_RANDERR_H
|
||||
|
||||
# include <openssl/symhacks.h>
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
@@ -19,6 +21,7 @@ int ERR_load_RAND_strings(void);
|
||||
/*
|
||||
* RAND function codes.
|
||||
*/
|
||||
# define RAND_F_DATA_COLLECT_METHOD 127
|
||||
# define RAND_F_DRBG_BYTES 101
|
||||
# define RAND_F_DRBG_GET_ENTROPY 105
|
||||
# define RAND_F_DRBG_SETUP 117
|
||||
@@ -42,7 +45,9 @@ int ERR_load_RAND_strings(void);
|
||||
# define RAND_F_RAND_POOL_ADD_END 114
|
||||
# define RAND_F_RAND_POOL_ATTACH 124
|
||||
# define RAND_F_RAND_POOL_BYTES_NEEDED 115
|
||||
# define RAND_F_RAND_POOL_GROW 125
|
||||
# define RAND_F_RAND_POOL_NEW 116
|
||||
# define RAND_F_RAND_PSEUDO_BYTES 126
|
||||
# define RAND_F_RAND_WRITE_FILE 112
|
||||
|
||||
/*
|
||||
|
||||
@@ -224,6 +224,7 @@ const BIGNUM *RSA_get0_q(const RSA *d);
|
||||
const BIGNUM *RSA_get0_dmp1(const RSA *r);
|
||||
const BIGNUM *RSA_get0_dmq1(const RSA *r);
|
||||
const BIGNUM *RSA_get0_iqmp(const RSA *r);
|
||||
const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *r);
|
||||
void RSA_clear_flags(RSA *r, int flags);
|
||||
int RSA_test_flags(const RSA *r, int flags);
|
||||
void RSA_set_flags(RSA *r, int flags);
|
||||
@@ -279,14 +280,14 @@ int RSA_pkey_ctx_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, void *p2);
|
||||
DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPublicKey)
|
||||
DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPrivateKey)
|
||||
|
||||
typedef struct rsa_pss_params_st {
|
||||
struct rsa_pss_params_st {
|
||||
X509_ALGOR *hashAlgorithm;
|
||||
X509_ALGOR *maskGenAlgorithm;
|
||||
ASN1_INTEGER *saltLength;
|
||||
ASN1_INTEGER *trailerField;
|
||||
/* Decoded hash algorithm from maskGenAlgorithm */
|
||||
X509_ALGOR *maskHash;
|
||||
} RSA_PSS_PARAMS;
|
||||
};
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_RSAERR_H
|
||||
# define HEADER_RSAERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
@@ -126,6 +130,7 @@ int ERR_load_RSA_strings(void);
|
||||
# define RSA_R_KEY_PRIME_NUM_INVALID 165
|
||||
# define RSA_R_KEY_SIZE_TOO_SMALL 120
|
||||
# define RSA_R_LAST_OCTET_INVALID 134
|
||||
# define RSA_R_MISSING_PRIVATE_KEY 179
|
||||
# define RSA_R_MGF1_DIGEST_NOT_ALLOWED 152
|
||||
# define RSA_R_MODULUS_TOO_LARGE 105
|
||||
# define RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R 168
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
* Copyright 2005 Nokia. All rights reserved.
|
||||
*
|
||||
@@ -1364,24 +1364,24 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)(st))
|
||||
# define SSL_CTX_set1_chain_cert_store(ctx,st) \
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)(st))
|
||||
# define SSL_set0_chain(ctx,sk) \
|
||||
SSL_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)(sk))
|
||||
# define SSL_set1_chain(ctx,sk) \
|
||||
SSL_ctrl(ctx,SSL_CTRL_CHAIN,1,(char *)(sk))
|
||||
# define SSL_add0_chain_cert(ctx,x509) \
|
||||
SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)(x509))
|
||||
# define SSL_add1_chain_cert(ctx,x509) \
|
||||
SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)(x509))
|
||||
# define SSL_get0_chain_certs(ctx,px509) \
|
||||
SSL_ctrl(ctx,SSL_CTRL_GET_CHAIN_CERTS,0,px509)
|
||||
# define SSL_clear_chain_certs(ctx) \
|
||||
SSL_set0_chain(ctx,NULL)
|
||||
# define SSL_set0_chain(s,sk) \
|
||||
SSL_ctrl(s,SSL_CTRL_CHAIN,0,(char *)(sk))
|
||||
# define SSL_set1_chain(s,sk) \
|
||||
SSL_ctrl(s,SSL_CTRL_CHAIN,1,(char *)(sk))
|
||||
# define SSL_add0_chain_cert(s,x509) \
|
||||
SSL_ctrl(s,SSL_CTRL_CHAIN_CERT,0,(char *)(x509))
|
||||
# define SSL_add1_chain_cert(s,x509) \
|
||||
SSL_ctrl(s,SSL_CTRL_CHAIN_CERT,1,(char *)(x509))
|
||||
# define SSL_get0_chain_certs(s,px509) \
|
||||
SSL_ctrl(s,SSL_CTRL_GET_CHAIN_CERTS,0,px509)
|
||||
# define SSL_clear_chain_certs(s) \
|
||||
SSL_set0_chain(s,NULL)
|
||||
# define SSL_build_cert_chain(s, flags) \
|
||||
SSL_ctrl(s,SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL)
|
||||
# define SSL_select_current_cert(ctx,x509) \
|
||||
SSL_ctrl(ctx,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)(x509))
|
||||
# define SSL_set_current_cert(ctx,op) \
|
||||
SSL_ctrl(ctx,SSL_CTRL_SET_CURRENT_CERT, op, NULL)
|
||||
# define SSL_select_current_cert(s,x509) \
|
||||
SSL_ctrl(s,SSL_CTRL_SELECT_CURRENT_CERT,0,(char *)(x509))
|
||||
# define SSL_set_current_cert(s,op) \
|
||||
SSL_ctrl(s,SSL_CTRL_SET_CURRENT_CERT, op, NULL)
|
||||
# define SSL_set0_verify_cert_store(s,st) \
|
||||
SSL_ctrl(s,SSL_CTRL_SET_VERIFY_CERT_STORE,0,(char *)(st))
|
||||
# define SSL_set1_verify_cert_store(s,st) \
|
||||
@@ -1390,34 +1390,34 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
|
||||
SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,0,(char *)(st))
|
||||
# define SSL_set1_chain_cert_store(s,st) \
|
||||
SSL_ctrl(s,SSL_CTRL_SET_CHAIN_CERT_STORE,1,(char *)(st))
|
||||
# define SSL_get1_groups(ctx, s) \
|
||||
SSL_ctrl(ctx,SSL_CTRL_GET_GROUPS,0,(char *)(s))
|
||||
# define SSL_get1_groups(s, glist) \
|
||||
SSL_ctrl(s,SSL_CTRL_GET_GROUPS,0,(int*)(glist))
|
||||
# define SSL_CTX_set1_groups(ctx, glist, glistlen) \
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_GROUPS,glistlen,(char *)(glist))
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_GROUPS,glistlen,(int *)(glist))
|
||||
# define SSL_CTX_set1_groups_list(ctx, s) \
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_GROUPS_LIST,0,(char *)(s))
|
||||
# define SSL_set1_groups(ctx, glist, glistlen) \
|
||||
SSL_ctrl(ctx,SSL_CTRL_SET_GROUPS,glistlen,(char *)(glist))
|
||||
# define SSL_set1_groups_list(ctx, s) \
|
||||
SSL_ctrl(ctx,SSL_CTRL_SET_GROUPS_LIST,0,(char *)(s))
|
||||
# define SSL_set1_groups(s, glist, glistlen) \
|
||||
SSL_ctrl(s,SSL_CTRL_SET_GROUPS,glistlen,(char *)(glist))
|
||||
# define SSL_set1_groups_list(s, str) \
|
||||
SSL_ctrl(s,SSL_CTRL_SET_GROUPS_LIST,0,(char *)(str))
|
||||
# define SSL_get_shared_group(s, n) \
|
||||
SSL_ctrl(s,SSL_CTRL_GET_SHARED_GROUP,n,NULL)
|
||||
# define SSL_CTX_set1_sigalgs(ctx, slist, slistlen) \
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS,slistlen,(int *)(slist))
|
||||
# define SSL_CTX_set1_sigalgs_list(ctx, s) \
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)(s))
|
||||
# define SSL_set1_sigalgs(ctx, slist, slistlen) \
|
||||
SSL_ctrl(ctx,SSL_CTRL_SET_SIGALGS,slistlen,(int *)(slist))
|
||||
# define SSL_set1_sigalgs_list(ctx, s) \
|
||||
SSL_ctrl(ctx,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)(s))
|
||||
# define SSL_set1_sigalgs(s, slist, slistlen) \
|
||||
SSL_ctrl(s,SSL_CTRL_SET_SIGALGS,slistlen,(int *)(slist))
|
||||
# define SSL_set1_sigalgs_list(s, str) \
|
||||
SSL_ctrl(s,SSL_CTRL_SET_SIGALGS_LIST,0,(char *)(str))
|
||||
# define SSL_CTX_set1_client_sigalgs(ctx, slist, slistlen) \
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,slistlen,(int *)(slist))
|
||||
# define SSL_CTX_set1_client_sigalgs_list(ctx, s) \
|
||||
SSL_CTX_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)(s))
|
||||
# define SSL_set1_client_sigalgs(ctx, slist, slistlen) \
|
||||
SSL_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS,clistlen,(int *)(slist))
|
||||
# define SSL_set1_client_sigalgs_list(ctx, s) \
|
||||
SSL_ctrl(ctx,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)(s))
|
||||
# define SSL_set1_client_sigalgs(s, slist, slistlen) \
|
||||
SSL_ctrl(s,SSL_CTRL_SET_CLIENT_SIGALGS,slistlen,(int *)(slist))
|
||||
# define SSL_set1_client_sigalgs_list(s, str) \
|
||||
SSL_ctrl(s,SSL_CTRL_SET_CLIENT_SIGALGS_LIST,0,(char *)(str))
|
||||
# define SSL_get0_certificate_types(s, clist) \
|
||||
SSL_ctrl(s, SSL_CTRL_GET_CLIENT_CERT_TYPES, 0, (char *)(clist))
|
||||
# define SSL_CTX_set1_client_certificate_types(ctx, clist, clistlen) \
|
||||
@@ -2139,7 +2139,7 @@ size_t SSL_CTX_get_num_tickets(const SSL_CTX *ctx);
|
||||
# define SSL_cache_hit(s) SSL_session_reused(s)
|
||||
# endif
|
||||
|
||||
__owur int SSL_session_reused(SSL *s);
|
||||
__owur int SSL_session_reused(const SSL *s);
|
||||
__owur int SSL_is_server(const SSL *s);
|
||||
|
||||
__owur __owur SSL_CONF_CTX *SSL_CONF_CTX_new(void);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
@@ -292,6 +292,9 @@ extern "C" {
|
||||
|
||||
# define TLS1_FLAGS_STATELESS 0x0800
|
||||
|
||||
/* Set if extended master secret extension required on renegotiation */
|
||||
# define TLS1_FLAGS_REQUIRED_EXTMS 0x1000
|
||||
|
||||
# define SSL3_MT_HELLO_REQUEST 0
|
||||
# define SSL3_MT_CLIENT_HELLO 1
|
||||
# define SSL3_MT_SERVER_HELLO 2
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_SSLERR_H
|
||||
# define HEADER_SSLERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
@@ -84,6 +88,7 @@ int ERR_load_SSL_strings(void);
|
||||
# define SSL_F_OSSL_STATEM_SERVER_CONSTRUCT_MESSAGE 431
|
||||
# define SSL_F_OSSL_STATEM_SERVER_POST_PROCESS_MESSAGE 601
|
||||
# define SSL_F_OSSL_STATEM_SERVER_POST_WORK 602
|
||||
# define SSL_F_OSSL_STATEM_SERVER_PRE_WORK 640
|
||||
# define SSL_F_OSSL_STATEM_SERVER_PROCESS_MESSAGE 603
|
||||
# define SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION 418
|
||||
# define SSL_F_OSSL_STATEM_SERVER_WRITE_TRANSITION 604
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -85,7 +85,7 @@ OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx);
|
||||
int OSSL_STORE_eof(OSSL_STORE_CTX *ctx);
|
||||
|
||||
/*
|
||||
* Check if an error occured
|
||||
* Check if an error occurred
|
||||
* Returns 1 if it did, 0 otherwise.
|
||||
*/
|
||||
int OSSL_STORE_error(OSSL_STORE_CTX *ctx);
|
||||
@@ -117,7 +117,7 @@ int OSSL_STORE_close(OSSL_STORE_CTX *ctx);
|
||||
* Functions to generate OSSL_STORE_INFOs, one function for each type we
|
||||
* support having in them, as well as a generic constructor.
|
||||
*
|
||||
* In all cases, ownership of the object is transfered to the OSSL_STORE_INFO
|
||||
* In all cases, ownership of the object is transferred to the OSSL_STORE_INFO
|
||||
* and will therefore be freed when the OSSL_STORE_INFO is freed.
|
||||
*/
|
||||
OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_OSSL_STOREERR_H
|
||||
# define HEADER_OSSL_STOREERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
* Copyright 2005 Nokia. All rights reserved.
|
||||
*
|
||||
@@ -1222,7 +1222,7 @@ __owur int SSL_check_chain(SSL *s, X509 *x, EVP_PKEY *pk, STACK_OF(X509) *chain)
|
||||
/*
|
||||
* extended master secret
|
||||
*/
|
||||
# define TLS_MD_EXTENDED_MASTER_SECRET_CONST "\x65\x78\x74\x65\x63\x64\x65\x64\x20\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74"
|
||||
# define TLS_MD_EXTENDED_MASTER_SECRET_CONST "\x65\x78\x74\x65\x6e\x64\x65\x64\x20\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74"
|
||||
# endif
|
||||
|
||||
/* TLS Session Ticket extension struct */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_TSERR_H
|
||||
# define HEADER_TSERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# include <openssl/opensslconf.h>
|
||||
|
||||
# ifndef OPENSSL_NO_TS
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,10 @@
|
||||
#ifndef HEADER_UIERR_H
|
||||
# define HEADER_UIERR_H
|
||||
|
||||
# ifndef HEADER_SYMHACKS_H
|
||||
# include <openssl/symhacks.h>
|
||||
# endif
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
@@ -478,6 +478,7 @@ void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype,
|
||||
const void **ppval, const X509_ALGOR *algor);
|
||||
void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md);
|
||||
int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b);
|
||||
int X509_ALGOR_copy(X509_ALGOR *dest, const X509_ALGOR *src);
|
||||
|
||||
X509_NAME *X509_NAME_dup(X509_NAME *xn);
|
||||
X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne);
|
||||
@@ -679,6 +680,8 @@ X509_NAME *X509_REQ_get_subject_name(const X509_REQ *req);
|
||||
int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name);
|
||||
void X509_REQ_get0_signature(const X509_REQ *req, const ASN1_BIT_STRING **psig,
|
||||
const X509_ALGOR **palg);
|
||||
void X509_REQ_set0_signature(X509_REQ *req, ASN1_BIT_STRING *psig);
|
||||
int X509_REQ_set1_signature_algo(X509_REQ *req, X509_ALGOR *palg);
|
||||
int X509_REQ_get_signature_nid(const X509_REQ *req);
|
||||
int i2d_re_X509_REQ_tbs(X509_REQ *req, unsigned char **pp);
|
||||
int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey);
|
||||
@@ -930,7 +933,7 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE)
|
||||
int type,
|
||||
const unsigned char *bytes,
|
||||
int len);
|
||||
void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x,
|
||||
void *X509at_get0_data_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *x,
|
||||
const ASN1_OBJECT *obj, int lastpos, int type);
|
||||
X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
|
||||
int atrtype, const void *data,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -184,6 +184,10 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
|
||||
# define X509_V_ERR_OCSP_VERIFY_NEEDED 73 /* Need OCSP verification */
|
||||
# define X509_V_ERR_OCSP_VERIFY_FAILED 74 /* Couldn't verify cert through OCSP */
|
||||
# define X509_V_ERR_OCSP_CERT_UNKNOWN 75 /* Certificate wasn't recognized by the OCSP responder */
|
||||
# define X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH 76
|
||||
# define X509_V_ERR_NO_ISSUER_PUBLIC_KEY 77
|
||||
# define X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM 78
|
||||
# define X509_V_ERR_EC_KEY_EXPLICIT_PARAMS 79
|
||||
|
||||
/* Certificate verify flags */
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -11,6 +11,8 @@
|
||||
#ifndef HEADER_X509ERR_H
|
||||
# define HEADER_X509ERR_H
|
||||
|
||||
# include <openssl/symhacks.h>
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C"
|
||||
# endif
|
||||
@@ -61,6 +63,7 @@ int ERR_load_X509_strings(void);
|
||||
# define X509_F_X509_OBJECT_NEW 150
|
||||
# define X509_F_X509_PRINT_EX_FP 118
|
||||
# define X509_F_X509_PUBKEY_DECODE 148
|
||||
# define X509_F_X509_PUBKEY_GET 161
|
||||
# define X509_F_X509_PUBKEY_GET0 119
|
||||
# define X509_F_X509_PUBKEY_SET 120
|
||||
# define X509_F_X509_REQ_CHECK_PRIVATE_KEY 144
|
||||
@@ -93,6 +96,7 @@ int ERR_load_X509_strings(void);
|
||||
# define X509_R_CRL_ALREADY_DELTA 127
|
||||
# define X509_R_CRL_VERIFY_FAILURE 131
|
||||
# define X509_R_IDP_MISMATCH 128
|
||||
# define X509_R_INVALID_ATTRIBUTES 138
|
||||
# define X509_R_INVALID_DIRECTORY 113
|
||||
# define X509_R_INVALID_FIELD_NAME 119
|
||||
# define X509_R_INVALID_TRUST 123
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1999-2018 The OpenSSL Project Authors. All Rights Reserved.
|
||||
* Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
@@ -364,8 +364,9 @@ struct ISSUING_DIST_POINT_st {
|
||||
|
||||
# define EXFLAG_INVALID_POLICY 0x800
|
||||
# define EXFLAG_FRESHEST 0x1000
|
||||
/* Self signed */
|
||||
# define EXFLAG_SS 0x2000
|
||||
# define EXFLAG_SS 0x2000 /* cert is apparently self-signed */
|
||||
|
||||
# define EXFLAG_NO_FINGERPRINT 0x100000
|
||||
|
||||
# define KU_DIGITAL_SIGNATURE 0x0080
|
||||
# define KU_NON_REPUDIATION 0x0040
|
||||
@@ -497,10 +498,10 @@ DECLARE_ASN1_FUNCTIONS(OTHERNAME)
|
||||
DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME)
|
||||
int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b);
|
||||
void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value);
|
||||
void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype);
|
||||
void *GENERAL_NAME_get0_value(const GENERAL_NAME *a, int *ptype);
|
||||
int GENERAL_NAME_set0_othername(GENERAL_NAME *gen,
|
||||
ASN1_OBJECT *oid, ASN1_TYPE *value);
|
||||
int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen,
|
||||
int GENERAL_NAME_get0_otherName(const GENERAL_NAME *gen,
|
||||
ASN1_OBJECT **poid, ASN1_TYPE **pvalue);
|
||||
|
||||
char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
|
||||
@@ -661,6 +662,8 @@ uint32_t X509_get_key_usage(X509 *x);
|
||||
uint32_t X509_get_extended_key_usage(X509 *x);
|
||||
const ASN1_OCTET_STRING *X509_get0_subject_key_id(X509 *x);
|
||||
const ASN1_OCTET_STRING *X509_get0_authority_key_id(X509 *x);
|
||||
const GENERAL_NAMES *X509_get0_authority_issuer(X509 *x);
|
||||
const ASN1_INTEGER *X509_get0_authority_serial(X509 *x);
|
||||
|
||||
int X509_PURPOSE_get_count(void);
|
||||
X509_PURPOSE *X509_PURPOSE_get0(int idx);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user