mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2025-07-19 19:13:03 +00:00
PreferenceConfiguration.java: add language preference
This commit is contained in:
commit
9340dff45d
@ -102,17 +102,17 @@
|
|||||||
<orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
|
<orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
<orderEntry type="library" exported="" name="bcprov-jdk15on-1.51" level="project" />
|
<orderEntry type="library" exported="" name="bcprov-jdk15on-1.51" level="project" />
|
||||||
<orderEntry type="library" exported="" name="ion-2.0.1" level="project" />
|
<orderEntry type="library" exported="" name="gson-2.3.1" level="project" />
|
||||||
<orderEntry type="library" exported="" name="support-v4-r7" level="project" />
|
<orderEntry type="library" exported="" name="support-v4-r7" level="project" />
|
||||||
<orderEntry type="library" exported="" name="jmdns-fixed" level="project" />
|
<orderEntry type="library" exported="" name="jmdns-fixed" level="project" />
|
||||||
<orderEntry type="library" exported="" name="bcpkix-jdk15on-1.51" level="project" />
|
<orderEntry type="library" exported="" name="bcpkix-jdk15on-1.51" level="project" />
|
||||||
<orderEntry type="library" exported="" name="tinyrtsp" level="project" />
|
<orderEntry type="library" exported="" name="tinyrtsp" level="project" />
|
||||||
<orderEntry type="library" exported="" name="okhttp-2.1.0" level="project" />
|
<orderEntry type="library" exported="" name="okhttp-2.1.0" level="project" />
|
||||||
<orderEntry type="library" exported="" name="limelight-common" level="project" />
|
<orderEntry type="library" exported="" name="limelight-common" level="project" />
|
||||||
<orderEntry type="library" exported="" name="gson-2.3" level="project" />
|
|
||||||
<orderEntry type="library" exported="" name="okio-1.0.1" level="project" />
|
<orderEntry type="library" exported="" name="okio-1.0.1" level="project" />
|
||||||
|
<orderEntry type="library" exported="" name="androidasync-e1dfb4" level="project" />
|
||||||
<orderEntry type="library" exported="" name="jcodec-0.1.9" level="project" />
|
<orderEntry type="library" exported="" name="jcodec-0.1.9" level="project" />
|
||||||
<orderEntry type="library" exported="" name="androidasync-2.0.1" level="project" />
|
<orderEntry type="library" exported="" name="ion-2f46fa" level="project" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
|
|
||||||
|
@ -11,8 +11,8 @@ android {
|
|||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 21
|
targetSdkVersion 21
|
||||||
|
|
||||||
versionName "3.0"
|
versionName "3.0.1"
|
||||||
versionCode = 46
|
versionCode = 47
|
||||||
}
|
}
|
||||||
|
|
||||||
productFlavors {
|
productFlavors {
|
||||||
@ -62,13 +62,19 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile group: 'org.jcodec', name: 'jcodec', version: '0.1.9'
|
compile group: 'org.jcodec', name: 'jcodec', version: '+'
|
||||||
compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '1.51'
|
compile group: 'org.bouncycastle', name: 'bcprov-jdk15on', version: '+'
|
||||||
compile group: 'org.bouncycastle', name: 'bcpkix-jdk15on', version: '1.51'
|
compile group: 'org.bouncycastle', name: 'bcpkix-jdk15on', version: '+'
|
||||||
compile group: 'com.google.android', name: 'support-v4', version:'r7'
|
compile group: 'com.google.android', name: 'support-v4', version:'+'
|
||||||
compile group: 'com.koushikdutta.ion', name: 'ion', version:'2.0.1'
|
|
||||||
compile group: 'com.squareup.okhttp', name: 'okhttp', version:'2.1.0'
|
// FIXME: Pending resolution of issue #346 using custom build
|
||||||
compile group: 'com.squareup.okio', name:'okio', version:'1.0.1'
|
//compile group: 'com.koushikdutta.ion', name: 'ion', version:'+'
|
||||||
|
compile group: 'com.google.code.gson', name: 'gson', version:'+'
|
||||||
|
compile files('libs/androidasync-e1dfb4.jar')
|
||||||
|
compile files('libs/ion-2f46fa.jar')
|
||||||
|
|
||||||
|
compile group: 'com.squareup.okhttp', name: 'okhttp', version:'+'
|
||||||
|
compile group: 'com.squareup.okio', name:'okio', version:'+'
|
||||||
compile files('libs/jmdns-fixed.jar')
|
compile files('libs/jmdns-fixed.jar')
|
||||||
compile files('libs/limelight-common.jar')
|
compile files('libs/limelight-common.jar')
|
||||||
compile files('libs/tinyrtsp.jar')
|
compile files('libs/tinyrtsp.jar')
|
||||||
|
BIN
app/libs/androidasync-e1dfb4.jar
Normal file
BIN
app/libs/androidasync-e1dfb4.jar
Normal file
Binary file not shown.
BIN
app/libs/ion-2f46fa.jar
Normal file
BIN
app/libs/ion-2f46fa.jar
Normal file
Binary file not shown.
@ -178,7 +178,7 @@ public class Game extends Activity implements SurfaceHolder.Callback,
|
|||||||
.enableAdaptiveResolution((decoderRenderer.getCapabilities() &
|
.enableAdaptiveResolution((decoderRenderer.getCapabilities() &
|
||||||
VideoDecoderRenderer.CAPABILITY_ADAPTIVE_RESOLUTION) != 0)
|
VideoDecoderRenderer.CAPABILITY_ADAPTIVE_RESOLUTION) != 0)
|
||||||
.enableLocalAudioPlayback(prefConfig.playHostAudio)
|
.enableLocalAudioPlayback(prefConfig.playHostAudio)
|
||||||
.setMaxPacketSize(remote ? 1024 : 1392)
|
.setMaxPacketSize(remote ? 1024 : 1292)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// Initialize the connection
|
// Initialize the connection
|
||||||
|
@ -47,6 +47,7 @@ public class ControllerHandler {
|
|||||||
private NvConnection conn;
|
private NvConnection conn;
|
||||||
private double stickDeadzone;
|
private double stickDeadzone;
|
||||||
private final ControllerMapping defaultMapping = new ControllerMapping();
|
private final ControllerMapping defaultMapping = new ControllerMapping();
|
||||||
|
private boolean hasGameController;
|
||||||
|
|
||||||
public ControllerHandler(NvConnection conn, int deadzonePercentage) {
|
public ControllerHandler(NvConnection conn, int deadzonePercentage) {
|
||||||
this.conn = conn;
|
this.conn = conn;
|
||||||
@ -55,6 +56,20 @@ public class ControllerHandler {
|
|||||||
// is required for controller batching support to work.
|
// is required for controller batching support to work.
|
||||||
deadzonePercentage = 10;
|
deadzonePercentage = 10;
|
||||||
|
|
||||||
|
int[] ids = InputDevice.getDeviceIds();
|
||||||
|
for (int i = 0; i < ids.length; i++) {
|
||||||
|
InputDevice dev = InputDevice.getDevice(ids[i]);
|
||||||
|
if ((dev.getSources() & InputDevice.SOURCE_JOYSTICK) != 0 ||
|
||||||
|
(dev.getSources() & InputDevice.SOURCE_GAMEPAD) != 0) {
|
||||||
|
// This looks like a gamepad, but we'll check X and Y to be sure
|
||||||
|
if (getMotionRangeForJoystickAxis(dev, MotionEvent.AXIS_X) != null &&
|
||||||
|
getMotionRangeForJoystickAxis(dev, MotionEvent.AXIS_Y) != null) {
|
||||||
|
// This is a gamepad
|
||||||
|
hasGameController = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 1% is the lowest possible deadzone we support
|
// 1% is the lowest possible deadzone we support
|
||||||
if (deadzonePercentage <= 0) {
|
if (deadzonePercentage <= 0) {
|
||||||
deadzonePercentage = 1;
|
deadzonePercentage = 1;
|
||||||
@ -94,6 +109,12 @@ public class ControllerHandler {
|
|||||||
|
|
||||||
mapping.leftStickXAxis = MotionEvent.AXIS_X;
|
mapping.leftStickXAxis = MotionEvent.AXIS_X;
|
||||||
mapping.leftStickYAxis = MotionEvent.AXIS_Y;
|
mapping.leftStickYAxis = MotionEvent.AXIS_Y;
|
||||||
|
if (getMotionRangeForJoystickAxis(dev, mapping.leftStickXAxis) != null &&
|
||||||
|
getMotionRangeForJoystickAxis(dev, mapping.leftStickYAxis) != null) {
|
||||||
|
// This is a gamepad
|
||||||
|
hasGameController = true;
|
||||||
|
mapping.hasJoystickAxes = true;
|
||||||
|
}
|
||||||
|
|
||||||
InputDevice.MotionRange leftTriggerRange = getMotionRangeForJoystickAxis(dev, MotionEvent.AXIS_LTRIGGER);
|
InputDevice.MotionRange leftTriggerRange = getMotionRangeForJoystickAxis(dev, MotionEvent.AXIS_LTRIGGER);
|
||||||
InputDevice.MotionRange rightTriggerRange = getMotionRangeForJoystickAxis(dev, MotionEvent.AXIS_RTRIGGER);
|
InputDevice.MotionRange rightTriggerRange = getMotionRangeForJoystickAxis(dev, MotionEvent.AXIS_RTRIGGER);
|
||||||
@ -182,18 +203,19 @@ public class ControllerHandler {
|
|||||||
// It's important to have a valid deadzone so controller packet batching works properly
|
// It's important to have a valid deadzone so controller packet batching works properly
|
||||||
mapping.triggerDeadzone = Math.max(Math.abs(ltRange.getFlat()), Math.abs(rtRange.getFlat()));
|
mapping.triggerDeadzone = Math.max(Math.abs(ltRange.getFlat()), Math.abs(rtRange.getFlat()));
|
||||||
|
|
||||||
// For triggers without (valid) deadzones, we'll use 10%
|
// For triggers without (valid) deadzones, we'll use 13% (around XInput's default)
|
||||||
if (mapping.triggerDeadzone <= 0.02 ||
|
if (mapping.triggerDeadzone < 0.13f ||
|
||||||
mapping.triggerDeadzone > 0.30)
|
mapping.triggerDeadzone > 0.30f)
|
||||||
{
|
{
|
||||||
mapping.triggerDeadzone = 0.1f;
|
mapping.triggerDeadzone = 0.13f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (devName != null) {
|
||||||
// For the Nexus Player (and probably other ATV devices), we should
|
// For the Nexus Player (and probably other ATV devices), we should
|
||||||
// use the back button as start since it doesn't have a start/menu button
|
// use the back button as start since it doesn't have a start/menu button
|
||||||
// on the controller
|
// on the controller
|
||||||
if (devName != null && devName.contains("ASUS Gamepad")) {
|
if (devName.contains("ASUS Gamepad")) {
|
||||||
// We can only do this check on KitKat or higher, but it doesn't matter since ATV
|
// We can only do this check on KitKat or higher, but it doesn't matter since ATV
|
||||||
// is Android 5.0 anyway
|
// is Android 5.0 anyway
|
||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
|
||||||
@ -202,7 +224,22 @@ public class ControllerHandler {
|
|||||||
mapping.backIsStart = true;
|
mapping.backIsStart = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The ASUS Gamepad has triggers that sit far forward and are prone to false presses
|
||||||
|
// so we increase the deadzone on them to minimize this
|
||||||
|
mapping.triggerDeadzone = 0.30f;
|
||||||
}
|
}
|
||||||
|
// Classify this device as a remote by name
|
||||||
|
else if (devName.contains("Fire TV Remote") || devName.contains("Nexus Remote")) {
|
||||||
|
// It's only a remote if it doesn't any sticks
|
||||||
|
if (!mapping.hasJoystickAxes) {
|
||||||
|
mapping.isRemote = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LimeLog.info("Analog stick deadzone: "+mapping.leftStickDeadzoneRadius+" "+mapping.rightStickDeadzoneRadius);
|
||||||
|
LimeLog.info("Trigger deadzone: "+mapping.triggerDeadzone);
|
||||||
|
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
@ -233,7 +270,16 @@ public class ControllerHandler {
|
|||||||
leftStickX, leftStickY, rightStickX, rightStickY);
|
leftStickX, leftStickY, rightStickX, rightStickY);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int handleRemapping(ControllerMapping mapping, KeyEvent event) {
|
// Return a valid keycode, 0 to consume, or -1 to not consume the event
|
||||||
|
// Device MAY BE NULL
|
||||||
|
private int handleRemapping(ControllerMapping mapping, KeyEvent event) {
|
||||||
|
// For remotes, don't capture the back button
|
||||||
|
if (mapping.isRemote) {
|
||||||
|
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mapping.isDualShock4) {
|
if (mapping.isDualShock4) {
|
||||||
switch (event.getKeyCode()) {
|
switch (event.getKeyCode()) {
|
||||||
case KeyEvent.KEYCODE_BUTTON_Y:
|
case KeyEvent.KEYCODE_BUTTON_Y:
|
||||||
@ -718,5 +764,7 @@ public class ControllerHandler {
|
|||||||
public boolean isDualShock4;
|
public boolean isDualShock4;
|
||||||
public boolean isXboxController;
|
public boolean isXboxController;
|
||||||
public boolean backIsStart;
|
public boolean backIsStart;
|
||||||
|
public boolean isRemote;
|
||||||
|
public boolean hasJoystickAxes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,9 @@ public class AndroidCpuDecoderRenderer extends EnhancedDecoderRenderer {
|
|||||||
throw new IllegalStateException("AVC decoder initialization failure: "+err);
|
throw new IllegalStateException("AVC decoder initialization failure: "+err);
|
||||||
}
|
}
|
||||||
|
|
||||||
AvcDecoder.setRenderTarget(sh.getSurface());
|
if (!AvcDecoder.setRenderTarget(sh.getSurface())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
decoderBuffer = ByteBuffer.allocate(DECODER_BUFFER_SIZE + AvcDecoder.getInputPaddingSize());
|
decoderBuffer = ByteBuffer.allocate(DECODER_BUFFER_SIZE + AvcDecoder.getInputPaddingSize());
|
||||||
|
|
||||||
@ -252,7 +254,7 @@ public class AndroidCpuDecoderRenderer extends EnhancedDecoderRenderer {
|
|||||||
|
|
||||||
// Add delta time to the totals (excluding probable outliers)
|
// Add delta time to the totals (excluding probable outliers)
|
||||||
long delta = timeAfterDecode - decodeUnit.getReceiveTimestamp();
|
long delta = timeAfterDecode - decodeUnit.getReceiveTimestamp();
|
||||||
if (delta >= 0 && delta < 300) {
|
if (delta >= 0 && delta < 1000) {
|
||||||
totalTimeMs += delta;
|
totalTimeMs += delta;
|
||||||
totalFrames++;
|
totalFrames++;
|
||||||
}
|
}
|
||||||
|
@ -273,7 +273,7 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
|
|||||||
|
|
||||||
// Add delta time to the totals (excluding probable outliers)
|
// Add delta time to the totals (excluding probable outliers)
|
||||||
long delta = System.currentTimeMillis()-(presentationTimeUs/1000);
|
long delta = System.currentTimeMillis()-(presentationTimeUs/1000);
|
||||||
if (delta >= 0 && delta < 300) {
|
if (delta >= 0 && delta < 1000) {
|
||||||
decoderTimeMs += delta;
|
decoderTimeMs += delta;
|
||||||
totalTimeMs += delta;
|
totalTimeMs += delta;
|
||||||
}
|
}
|
||||||
@ -371,7 +371,7 @@ public class MediaCodecDecoderRenderer extends EnhancedDecoderRenderer {
|
|||||||
private void submitDecodeUnit(DecodeUnit decodeUnit, ByteBuffer buf, int inputBufferIndex) {
|
private void submitDecodeUnit(DecodeUnit decodeUnit, ByteBuffer buf, int inputBufferIndex) {
|
||||||
long currentTime = System.currentTimeMillis();
|
long currentTime = System.currentTimeMillis();
|
||||||
long delta = currentTime-decodeUnit.getReceiveTimestamp();
|
long delta = currentTime-decodeUnit.getReceiveTimestamp();
|
||||||
if (delta >= 0 && delta < 300) {
|
if (delta >= 0 && delta < 1000) {
|
||||||
totalTimeMs += currentTime-decodeUnit.getReceiveTimestamp();
|
totalTimeMs += currentTime-decodeUnit.getReceiveTimestamp();
|
||||||
totalFrames++;
|
totalFrames++;
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ public class MediaCodecHelper {
|
|||||||
spsFixupBitstreamFixupDecoderPrefixes.add("omx.nvidia");
|
spsFixupBitstreamFixupDecoderPrefixes.add("omx.nvidia");
|
||||||
spsFixupBitstreamFixupDecoderPrefixes.add("omx.qcom");
|
spsFixupBitstreamFixupDecoderPrefixes.add("omx.qcom");
|
||||||
spsFixupBitstreamFixupDecoderPrefixes.add("omx.mtk");
|
spsFixupBitstreamFixupDecoderPrefixes.add("omx.mtk");
|
||||||
|
spsFixupBitstreamFixupDecoderPrefixes.add("omx.brcm");
|
||||||
|
|
||||||
baselineProfileHackPrefixes = new LinkedList<String>();
|
baselineProfileHackPrefixes = new LinkedList<String>();
|
||||||
baselineProfileHackPrefixes.add("omx.intel");
|
baselineProfileHackPrefixes.add("omx.intel");
|
||||||
|
@ -244,9 +244,12 @@ public class ComputerManagerService extends Service {
|
|||||||
for (PollingTuple tuple : pollingTuples) {
|
for (PollingTuple tuple : pollingTuples) {
|
||||||
// Check if this is the same computer
|
// Check if this is the same computer
|
||||||
if (tuple.computer == details ||
|
if (tuple.computer == details ||
|
||||||
tuple.computer.localIp.equals(details.localIp) ||
|
// If there's no name on one of these computers, compare with the local IP
|
||||||
tuple.computer.remoteIp.equals(details.remoteIp) ||
|
((details.name.isEmpty() || tuple.computer.name.isEmpty()) &&
|
||||||
tuple.computer.name.equals(details.name)) {
|
tuple.computer.localIp.equals(details.localIp)) ||
|
||||||
|
// If there is a name on both computers, compare with name
|
||||||
|
((!details.name.isEmpty() && !tuple.computer.name.isEmpty()) &&
|
||||||
|
tuple.computer.name.equals(details.name))) {
|
||||||
|
|
||||||
// Start a polling thread if polling is active
|
// Start a polling thread if polling is active
|
||||||
if (pollingActive && tuple.thread == null) {
|
if (pollingActive && tuple.thread == null) {
|
||||||
@ -329,12 +332,22 @@ public class ComputerManagerService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ComputerDetails tryPollIp(InetAddress ipAddr) {
|
private ComputerDetails tryPollIp(ComputerDetails details, InetAddress ipAddr) {
|
||||||
try {
|
try {
|
||||||
NvHTTP http = new NvHTTP(ipAddr, idManager.getUniqueId(),
|
NvHTTP http = new NvHTTP(ipAddr, idManager.getUniqueId(),
|
||||||
null, PlatformBinding.getCryptoProvider(ComputerManagerService.this));
|
null, PlatformBinding.getCryptoProvider(ComputerManagerService.this));
|
||||||
|
|
||||||
return http.getComputerDetails();
|
ComputerDetails newDetails = http.getComputerDetails();
|
||||||
|
|
||||||
|
// Check if this is the PC we expected
|
||||||
|
if (details.uuid != null && newDetails.uuid != null &&
|
||||||
|
!details.uuid.equals(newDetails.uuid)) {
|
||||||
|
// We got the wrong PC!
|
||||||
|
LimeLog.info("Polling returned the wrong PC!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newDetails;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -343,20 +356,26 @@ public class ComputerManagerService extends Service {
|
|||||||
private boolean pollComputer(ComputerDetails details, boolean localFirst) {
|
private boolean pollComputer(ComputerDetails details, boolean localFirst) {
|
||||||
ComputerDetails polledDetails;
|
ComputerDetails polledDetails;
|
||||||
|
|
||||||
|
// If the local address is routable across the Internet,
|
||||||
|
// always consider this PC remote to be conservative
|
||||||
|
if (details.localIp.equals(details.remoteIp)) {
|
||||||
|
localFirst = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (localFirst) {
|
if (localFirst) {
|
||||||
polledDetails = tryPollIp(details.localIp);
|
polledDetails = tryPollIp(details, details.localIp);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
polledDetails = tryPollIp(details.remoteIp);
|
polledDetails = tryPollIp(details, details.remoteIp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (polledDetails == null && !details.localIp.equals(details.remoteIp)) {
|
if (polledDetails == null && !details.localIp.equals(details.remoteIp)) {
|
||||||
// Failed, so let's try the fallback
|
// Failed, so let's try the fallback
|
||||||
if (!localFirst) {
|
if (!localFirst) {
|
||||||
polledDetails = tryPollIp(details.localIp);
|
polledDetails = tryPollIp(details, details.localIp);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
polledDetails = tryPollIp(details.remoteIp);
|
polledDetails = tryPollIp(details, details.remoteIp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The fallback poll worked
|
// The fallback poll worked
|
||||||
@ -414,8 +433,8 @@ public class ComputerManagerService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (ComputerDetails computer : dbManager.getAllComputers()) {
|
for (ComputerDetails computer : dbManager.getAllComputers()) {
|
||||||
// Add this computer without a thread
|
// Add tuples for each computer
|
||||||
pollingTuples.add(new PollingTuple(computer, null));
|
addTuple(computer);
|
||||||
}
|
}
|
||||||
|
|
||||||
releaseLocalDatabaseReference();
|
releaseLocalDatabaseReference();
|
||||||
|
@ -13,6 +13,7 @@ public class PreferenceConfiguration {
|
|||||||
private static final String DISABLE_TOASTS_PREF_STRING = "checkbox_disable_warnings";
|
private static final String DISABLE_TOASTS_PREF_STRING = "checkbox_disable_warnings";
|
||||||
private static final String HOST_AUDIO_PREF_STRING = "checkbox_host_audio";
|
private static final String HOST_AUDIO_PREF_STRING = "checkbox_host_audio";
|
||||||
private static final String DEADZONE_PREF_STRING = "seekbar_deadzone";
|
private static final String DEADZONE_PREF_STRING = "seekbar_deadzone";
|
||||||
|
private static final String LANGUAGE_PREF_STRING = "list_languages";
|
||||||
|
|
||||||
private static final int BITRATE_DEFAULT_720_30 = 5;
|
private static final int BITRATE_DEFAULT_720_30 = 5;
|
||||||
private static final int BITRATE_DEFAULT_720_60 = 10;
|
private static final int BITRATE_DEFAULT_720_60 = 10;
|
||||||
@ -27,6 +28,7 @@ public class PreferenceConfiguration {
|
|||||||
private static final boolean DEFAULT_DISABLE_TOASTS = false;
|
private static final boolean DEFAULT_DISABLE_TOASTS = false;
|
||||||
private static final boolean DEFAULT_HOST_AUDIO = false;
|
private static final boolean DEFAULT_HOST_AUDIO = false;
|
||||||
private static final int DEFAULT_DEADZONE = 15;
|
private static final int DEFAULT_DEADZONE = 15;
|
||||||
|
private static final String DEFAULT_LANGUAGE = "default";
|
||||||
|
|
||||||
public static final int FORCE_HARDWARE_DECODER = -1;
|
public static final int FORCE_HARDWARE_DECODER = -1;
|
||||||
public static final int AUTOSELECT_DECODER = 0;
|
public static final int AUTOSELECT_DECODER = 0;
|
||||||
@ -37,6 +39,7 @@ public class PreferenceConfiguration {
|
|||||||
public int decoder;
|
public int decoder;
|
||||||
public int deadzonePercentage;
|
public int deadzonePercentage;
|
||||||
public boolean stretchVideo, enableSops, playHostAudio, disableWarnings;
|
public boolean stretchVideo, enableSops, playHostAudio, disableWarnings;
|
||||||
|
public String language;
|
||||||
|
|
||||||
public static int getDefaultBitrate(String resFpsString) {
|
public static int getDefaultBitrate(String resFpsString) {
|
||||||
if (resFpsString.equals("720p30")) {
|
if (resFpsString.equals("720p30")) {
|
||||||
@ -135,6 +138,8 @@ public class PreferenceConfiguration {
|
|||||||
|
|
||||||
config.deadzonePercentage = prefs.getInt(DEADZONE_PREF_STRING, DEFAULT_DEADZONE);
|
config.deadzonePercentage = prefs.getInt(DEADZONE_PREF_STRING, DEFAULT_DEADZONE);
|
||||||
|
|
||||||
|
config.language = prefs.getString(LANGUAGE_PREF_STRING, DEFAULT_LANGUAGE);
|
||||||
|
|
||||||
// Checkbox preferences
|
// Checkbox preferences
|
||||||
config.disableWarnings = prefs.getBoolean(DISABLE_TOASTS_PREF_STRING, DEFAULT_DISABLE_TOASTS);
|
config.disableWarnings = prefs.getBoolean(DISABLE_TOASTS_PREF_STRING, DEFAULT_DISABLE_TOASTS);
|
||||||
config.enableSops = prefs.getBoolean(SOPS_PREF_STRING, DEFAULT_SOPS);
|
config.enableSops = prefs.getBoolean(SOPS_PREF_STRING, DEFAULT_SOPS);
|
||||||
|
@ -69,9 +69,6 @@ int nv_avc_init(int width, int height, int perf_lvl, int thread_count) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show frames even before a reference frame
|
|
||||||
decoder_ctx->flags2 |= CODEC_FLAG2_SHOW_ALL;
|
|
||||||
|
|
||||||
if (perf_lvl & DISABLE_LOOP_FILTER) {
|
if (perf_lvl & DISABLE_LOOP_FILTER) {
|
||||||
// Skip the loop filter for performance reasons
|
// Skip the loop filter for performance reasons
|
||||||
decoder_ctx->skip_loop_filter = AVDISCARD_ALL;
|
decoder_ctx->skip_loop_filter = AVDISCARD_ALL;
|
||||||
@ -370,17 +367,20 @@ int nv_avc_decode(unsigned char* indata, int inlen) {
|
|||||||
|
|
||||||
// Only copy the picture at the end of decoding the packet
|
// Only copy the picture at the end of decoding the packet
|
||||||
if (got_pic) {
|
if (got_pic) {
|
||||||
|
// Clone the current decode frame outside of the mutex
|
||||||
|
AVFrame* new_frame = av_frame_clone(dec_frame);
|
||||||
|
AVFrame* old_frame;
|
||||||
|
|
||||||
|
// Swap it in under lock
|
||||||
pthread_mutex_lock(&mutex);
|
pthread_mutex_lock(&mutex);
|
||||||
|
old_frame = yuv_frame;
|
||||||
// Only clone this frame if the last frame was taken.
|
yuv_frame = new_frame;
|
||||||
// This saves on extra copies for frames that don't get
|
|
||||||
// rendered.
|
|
||||||
if (yuv_frame == NULL) {
|
|
||||||
// Clone a new frame
|
|
||||||
yuv_frame = av_frame_clone(dec_frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&mutex);
|
pthread_mutex_unlock(&mutex);
|
||||||
|
|
||||||
|
// Free the old frame outside of the mutex
|
||||||
|
if (old_frame != NULL) {
|
||||||
|
av_frame_free(&old_frame);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return err < 0 ? err : 0;
|
return err < 0 ? err : 0;
|
||||||
|
@ -87,7 +87,7 @@
|
|||||||
<string name="summary_seekbar_bitrate">Abbassa il bitrate per ridurre lo stuttering; alza il bitrate per aumenteare la qualità dell\'immagine</string>
|
<string name="summary_seekbar_bitrate">Abbassa il bitrate per ridurre lo stuttering; alza il bitrate per aumenteare la qualità dell\'immagine</string>
|
||||||
<string name="suffix_seekbar_bitrate">Mbps</string>
|
<string name="suffix_seekbar_bitrate">Mbps</string>
|
||||||
<string name="title_checkbox_stretch_video">Forza video in full-screen</string>
|
<string name="title_checkbox_stretch_video">Forza video in full-screen</string>
|
||||||
<string name="title_checkbox_disable_warnings">Disabilita i messaggi di warning</string>
|
<string name="title_checkbox_disable_warnings">Disabilita messaggi di warning</string>
|
||||||
<string name="summary_checkbox_disable_warnings">Disabilita i messaggi di warning sullo schermo durante lo streaming</string>
|
<string name="summary_checkbox_disable_warnings">Disabilita i messaggi di warning sullo schermo durante lo streaming</string>
|
||||||
<string name="title_language_list">Lingua</string>
|
<string name="title_language_list">Lingua</string>
|
||||||
<string name="summary_language_list">Lingua da usare in Limelight</string>
|
<string name="summary_language_list">Lingua da usare in Limelight</string>
|
||||||
@ -104,5 +104,5 @@
|
|||||||
|
|
||||||
<string name="category_advanced_settings">Impostazioni Avanzate</string>
|
<string name="category_advanced_settings">Impostazioni Avanzate</string>
|
||||||
<string name="title_decoder_list">Cambia decoder</string>
|
<string name="title_decoder_list">Cambia decoder</string>
|
||||||
<string name="summary_decoder_list">Il decoder software può aumentare la latenza video quando si usano impostazioni streaming basse</string>
|
<string name="summary_decoder_list">Il decoder software può ridurre la latenza video quando si usano impostazioni streaming basse</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -4,12 +4,12 @@ This file serves to document some of the decoder errata when using MediaCodec ha
|
|||||||
- Affected decoders: TI OMAP4, Allwinner A20
|
- Affected decoders: TI OMAP4, Allwinner A20
|
||||||
|
|
||||||
2. Some decoders have a huge per-frame latency with the unmodified SPS sent from NVENC. Setting max_dec_frame_buffering fixes this latency issue.
|
2. Some decoders have a huge per-frame latency with the unmodified SPS sent from NVENC. Setting max_dec_frame_buffering fixes this latency issue.
|
||||||
- Affected decoders: NVIDIA Tegra 3 and 4
|
- Affected decoders: NVIDIA Tegra 3 and 4, Broadcom VideoCore IV
|
||||||
|
|
||||||
3. Some decoders strictly require that you pass BUFFER_FLAG_CODEC_CONFIG and crash upon the IDR frame if you don't
|
3. Some decoders strictly require that you pass BUFFER_FLAG_CODEC_CONFIG and crash upon the IDR frame if you don't
|
||||||
- Affected decoders: TI OMAP4
|
- Affected decoders: TI OMAP4
|
||||||
|
|
||||||
4. Some decoders require num_ref_frames=1 and max_dec_frame_buffering=1 to avoid crashing on SPS or first I-frame
|
4. Some decoders require num_ref_frames=1 and max_dec_frame_buffering=1 to avoid crashing on SPS on first I-frame
|
||||||
- Affected decoders: Qualcomm in GS3 on 4.3+, Exynos 4 at 1080p only
|
- Affected decoders: Qualcomm in GS3 on 4.3+, Exynos 4 at 1080p only
|
||||||
|
|
||||||
5. Some decoders will hang if max_dec_frame_buffering is not present
|
5. Some decoders will hang if max_dec_frame_buffering is not present
|
||||||
|
Loading…
x
Reference in New Issue
Block a user