mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2026-10-20 23:36:53 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79f888fe47 | ||
|
|
9393bf7f79 | ||
|
|
1b1d4399a9 | ||
|
|
b2ad259a7c | ||
|
|
ac5c264090 | ||
|
|
fcfdd4e323 | ||
|
|
ea65bb2c0a | ||
|
|
b340055588 | ||
|
|
2918039b6f | ||
|
|
e8fd1f262a | ||
|
|
8887401644 | ||
|
|
f892db6ee8 | ||
|
|
829532c572 | ||
|
|
875eb1e773 | ||
|
|
f295289774 | ||
|
|
1f69b4f271 | ||
|
|
20a5a844db | ||
|
|
1a7a2f848e | ||
|
|
887dd9aa21 | ||
|
|
e1e4ccf318 | ||
|
|
ee6edd2404 |
No files matched your search
+3
-3
@@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.limelight"
|
package="com.limelight"
|
||||||
android:versionCode="26"
|
android:versionCode="30"
|
||||||
android:versionName="2.5.1" >
|
android:versionName="2.5.3" >
|
||||||
|
|
||||||
<uses-sdk
|
<uses-sdk
|
||||||
android:minSdkVersion="16"
|
android:minSdkVersion="16"
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
android:label="Add Computer Manually" >
|
android:label="Add Computer Manually" >
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
android:value="com.limelight.StreamSettings" />
|
android:value="com.limelight.PcView" />
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name="com.limelight.Game"
|
android:name="com.limelight.Game"
|
||||||
|
|||||||
+11
-10
@@ -39,26 +39,27 @@ or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>na
|
|||||||
}
|
}
|
||||||
public static final class id {
|
public static final class id {
|
||||||
public static final int addPc=0x7f080001;
|
public static final int addPc=0x7f080001;
|
||||||
public static final int advancedSettingsButton=0x7f080012;
|
public static final int advancedSettingsButton=0x7f080013;
|
||||||
public static final int appListText=0x7f080009;
|
public static final int appListText=0x7f080009;
|
||||||
public static final int autoDec=0x7f080004;
|
public static final int autoDec=0x7f080004;
|
||||||
public static final int bitrateLabel=0x7f080006;
|
public static final int bitrateLabel=0x7f080006;
|
||||||
public static final int bitrateSeekBar=0x7f080007;
|
public static final int bitrateSeekBar=0x7f080007;
|
||||||
public static final int config1080p30Selected=0x7f080010;
|
public static final int config1080p30Selected=0x7f080011;
|
||||||
public static final int config1080p60Selected=0x7f080011;
|
public static final int config1080p60Selected=0x7f080012;
|
||||||
public static final int config720p30Selected=0x7f08000e;
|
public static final int config720p30Selected=0x7f08000f;
|
||||||
public static final int config720p60Selected=0x7f08000f;
|
public static final int config720p60Selected=0x7f080010;
|
||||||
public static final int decoderConfigGroup=0x7f080002;
|
public static final int decoderConfigGroup=0x7f080002;
|
||||||
public static final int discoveryText=0x7f08000b;
|
public static final int discoveryText=0x7f08000b;
|
||||||
|
public static final int enableSops=0x7f080014;
|
||||||
public static final int hardwareDec=0x7f080005;
|
public static final int hardwareDec=0x7f080005;
|
||||||
public static final int hostTextView=0x7f080000;
|
public static final int hostTextView=0x7f080000;
|
||||||
public static final int manuallyAddPc=0x7f080014;
|
public static final int manuallyAddPc=0x7f08000c;
|
||||||
public static final int pcListView=0x7f080008;
|
public static final int pcListView=0x7f080008;
|
||||||
public static final int rowTextView=0x7f080015;
|
public static final int rowTextView=0x7f080016;
|
||||||
public static final int settingsButton=0x7f08000c;
|
public static final int settingsButton=0x7f08000d;
|
||||||
public static final int softwareDec=0x7f080003;
|
public static final int softwareDec=0x7f080003;
|
||||||
public static final int streamConfigGroup=0x7f08000d;
|
public static final int streamConfigGroup=0x7f08000e;
|
||||||
public static final int stretchToFill=0x7f080013;
|
public static final int stretchToFill=0x7f080015;
|
||||||
public static final int surfaceView=0x7f08000a;
|
public static final int surfaceView=0x7f08000a;
|
||||||
}
|
}
|
||||||
public static final class layout {
|
public static final class layout {
|
||||||
|
|||||||
Binary file not shown.
@@ -29,7 +29,7 @@
|
|||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:paddingTop="10dp"
|
android:paddingTop="0dp"
|
||||||
android:paddingBottom="10dp"
|
android:paddingBottom="10dp"
|
||||||
android:text="Applications" />
|
android:text="Applications" />
|
||||||
|
|
||||||
|
|||||||
@@ -29,8 +29,8 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||||
android:layout_below="@+id/settingsButton"
|
android:layout_below="@+id/manuallyAddPc"
|
||||||
android:paddingTop="20dp"
|
android:paddingTop="10dp"
|
||||||
android:paddingBottom="10dp"
|
android:paddingBottom="10dp"
|
||||||
android:text="Discovered PC List" />
|
android:text="Discovered PC List" />
|
||||||
|
|
||||||
@@ -41,5 +41,13 @@
|
|||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
android:text="Streaming Settings" />
|
android:text="Streaming Settings" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/manuallyAddPc"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@+id/settingsButton"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:text="Add PC Manually" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
@@ -54,18 +54,10 @@
|
|||||||
android:id="@+id/advancedSettingsButton"
|
android:id="@+id/advancedSettingsButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@+id/stretchToFill"
|
android:layout_below="@+id/enableSops"
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:layout_marginTop="15dp"
|
android:layout_marginTop="15dp"
|
||||||
android:text="Advanced Settings" />
|
android:text="Advanced Settings" />
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/manuallyAddPc"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_below="@+id/advancedSettingsButton"
|
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:text="Add PC Manually" />
|
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
android:id="@+id/stretchToFill"
|
android:id="@+id/stretchToFill"
|
||||||
@@ -74,6 +66,14 @@
|
|||||||
android:layout_below="@+id/streamConfigGroup"
|
android:layout_below="@+id/streamConfigGroup"
|
||||||
android:layout_marginTop="15dp"
|
android:layout_marginTop="15dp"
|
||||||
android:text="Stretch video to fill screen" />
|
android:text="Stretch video to fill screen" />
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/enableSops"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@+id/stretchToFill"
|
||||||
|
android:layout_marginTop="15dp"
|
||||||
|
android:text="Allow GFE to modify game settings for optimal streaming" />
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ public class AppView extends Activity {
|
|||||||
|
|
||||||
private final static int RESUME_ID = 1;
|
private final static int RESUME_ID = 1;
|
||||||
private final static int QUIT_ID = 2;
|
private final static int QUIT_ID = 2;
|
||||||
|
private final static int CANCEL_ID = 3;
|
||||||
|
|
||||||
public final static String ADDRESS_EXTRA = "Address";
|
public final static String ADDRESS_EXTRA = "Address";
|
||||||
public final static String UNIQUEID_EXTRA = "UniqueId";
|
public final static String UNIQUEID_EXTRA = "UniqueId";
|
||||||
@@ -80,8 +81,8 @@ public class AppView extends Activity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only open the context menu if it's running, otherwise start it
|
// Only open the context menu if something is running, otherwise start it
|
||||||
if (app.app.getIsRunning()) {
|
if (getRunningAppId() != -1) {
|
||||||
openContextMenu(arg1);
|
openContextMenu(arg1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -90,15 +91,14 @@ public class AppView extends Activity {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
registerForContextMenu(appList);
|
registerForContextMenu(appList);
|
||||||
updateAppList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
|
|
||||||
|
SpinnerDialog.closeDialogs(this);
|
||||||
Dialog.closeDialogs();
|
Dialog.closeDialogs();
|
||||||
SpinnerDialog.closeDialogs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -108,12 +108,43 @@ public class AppView extends Activity {
|
|||||||
updateAppList();
|
updateAppList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getRunningAppId() {
|
||||||
|
int runningAppId = -1;
|
||||||
|
for (int i = 0; i < appListAdapter.getCount(); i++) {
|
||||||
|
AppObject app = appListAdapter.getItem(i);
|
||||||
|
if (app.app == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (app.app.getIsRunning()) {
|
||||||
|
runningAppId = app.app.getAppId();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return runningAppId;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
|
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
|
||||||
super.onCreateContextMenu(menu, v, menuInfo);
|
super.onCreateContextMenu(menu, v, menuInfo);
|
||||||
|
|
||||||
menu.add(Menu.NONE, RESUME_ID, 1, "Resume Session");
|
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
|
||||||
menu.add(Menu.NONE, QUIT_ID, 2, "Quit Session");
|
AppObject selectedApp = (AppObject) appListAdapter.getItem(info.position);
|
||||||
|
if (selectedApp == null || selectedApp.app == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int runningAppId = getRunningAppId();
|
||||||
|
if (runningAppId != -1) {
|
||||||
|
if (runningAppId == selectedApp.app.getAppId()) {
|
||||||
|
menu.add(Menu.NONE, RESUME_ID, 1, "Resume Session");
|
||||||
|
menu.add(Menu.NONE, QUIT_ID, 2, "Quit Session");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
menu.add(Menu.NONE, RESUME_ID, 1, "Quit Current Game and Start");
|
||||||
|
menu.add(Menu.NONE, CANCEL_ID, 2, "Cancel");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -135,6 +166,9 @@ public class AppView extends Activity {
|
|||||||
doQuit(app.app);
|
doQuit(app.app);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
case CANCEL_ID:
|
||||||
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return super.onContextItemSelected(item);
|
return super.onContextItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|||||||
+29
-32
@@ -79,7 +79,8 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
public static final String REFRESH_RATE_PREF_STRING = "FPS";
|
public static final String REFRESH_RATE_PREF_STRING = "FPS";
|
||||||
public static final String DECODER_PREF_STRING = "Decoder";
|
public static final String DECODER_PREF_STRING = "Decoder";
|
||||||
public static final String BITRATE_PREF_STRING = "Bitrate";
|
public static final String BITRATE_PREF_STRING = "Bitrate";
|
||||||
public static final String STRETCH_PREF_STRING = "Stretch";
|
public static final String STRETCH_PREF_STRING = "Stretch";
|
||||||
|
public static final String SOPS_PREF_STRING = "Sops";
|
||||||
|
|
||||||
public static final int BITRATE_DEFAULT_720_30 = 5;
|
public static final int BITRATE_DEFAULT_720_30 = 5;
|
||||||
public static final int BITRATE_DEFAULT_720_60 = 10;
|
public static final int BITRATE_DEFAULT_720_60 = 10;
|
||||||
@@ -92,6 +93,7 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
public static final int DEFAULT_DECODER = 0;
|
public static final int DEFAULT_DECODER = 0;
|
||||||
public static final int DEFAULT_BITRATE = BITRATE_DEFAULT_720_60;
|
public static final int DEFAULT_BITRATE = BITRATE_DEFAULT_720_60;
|
||||||
public static final boolean DEFAULT_STRETCH = false;
|
public static final boolean DEFAULT_STRETCH = false;
|
||||||
|
public static final boolean DEFAULT_SOPS = true;
|
||||||
|
|
||||||
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;
|
||||||
@@ -148,10 +150,12 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
}
|
}
|
||||||
|
|
||||||
int refreshRate, bitrate;
|
int refreshRate, bitrate;
|
||||||
|
boolean sops;
|
||||||
width = prefs.getInt(WIDTH_PREF_STRING, DEFAULT_WIDTH);
|
width = prefs.getInt(WIDTH_PREF_STRING, DEFAULT_WIDTH);
|
||||||
height = prefs.getInt(HEIGHT_PREF_STRING, DEFAULT_HEIGHT);
|
height = prefs.getInt(HEIGHT_PREF_STRING, DEFAULT_HEIGHT);
|
||||||
refreshRate = prefs.getInt(REFRESH_RATE_PREF_STRING, DEFAULT_REFRESH_RATE);
|
refreshRate = prefs.getInt(REFRESH_RATE_PREF_STRING, DEFAULT_REFRESH_RATE);
|
||||||
bitrate = prefs.getInt(BITRATE_PREF_STRING, DEFAULT_BITRATE);
|
bitrate = prefs.getInt(BITRATE_PREF_STRING, DEFAULT_BITRATE);
|
||||||
|
sops = prefs.getBoolean(SOPS_PREF_STRING, DEFAULT_SOPS);
|
||||||
|
|
||||||
Display display = getWindowManager().getDefaultDisplay();
|
Display display = getWindowManager().getDefaultDisplay();
|
||||||
display.getSize(screenSize);
|
display.getSize(screenSize);
|
||||||
@@ -160,13 +164,6 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
SurfaceView sv = (SurfaceView) findViewById(R.id.surfaceView);
|
SurfaceView sv = (SurfaceView) findViewById(R.id.surfaceView);
|
||||||
sv.setOnGenericMotionListener(this);
|
sv.setOnGenericMotionListener(this);
|
||||||
sv.setOnTouchListener(this);
|
sv.setOnTouchListener(this);
|
||||||
|
|
||||||
SurfaceHolder sh = sv.getHolder();
|
|
||||||
|
|
||||||
if (stretchToFit) {
|
|
||||||
// Set the surface to the size of the video
|
|
||||||
sh.setFixedSize(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Warn the user if they're on a metered connection
|
// Warn the user if they're on a metered connection
|
||||||
checkDataConnection();
|
checkDataConnection();
|
||||||
@@ -180,16 +177,22 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
String host = Game.this.getIntent().getStringExtra(EXTRA_HOST);
|
String host = Game.this.getIntent().getStringExtra(EXTRA_HOST);
|
||||||
String app = Game.this.getIntent().getStringExtra(EXTRA_APP);
|
String app = Game.this.getIntent().getStringExtra(EXTRA_APP);
|
||||||
String uniqueId = Game.this.getIntent().getStringExtra(EXTRA_UNIQUEID);
|
String uniqueId = Game.this.getIntent().getStringExtra(EXTRA_UNIQUEID);
|
||||||
boolean enableLargePackets = !Game.this.getIntent().getBooleanExtra(EXTRA_STREAMING_REMOTE, true);
|
|
||||||
LimeLog.info("Using large packets? "+enableLargePackets);
|
|
||||||
|
|
||||||
// Start the connection
|
// Start the connection
|
||||||
conn = new NvConnection(host, uniqueId, Game.this,
|
conn = new NvConnection(host, uniqueId, Game.this,
|
||||||
new StreamConfiguration(app, width, height, refreshRate, bitrate * 1000,
|
new StreamConfiguration(app, width, height, refreshRate, bitrate * 1000, sops),
|
||||||
enableLargePackets ? 1460 : 1024), PlatformBinding.getCryptoProvider(this));
|
PlatformBinding.getCryptoProvider(this));
|
||||||
keybTranslator = new KeyboardTranslator(conn);
|
keybTranslator = new KeyboardTranslator(conn);
|
||||||
controllerHandler = new ControllerHandler(conn);
|
controllerHandler = new ControllerHandler(conn);
|
||||||
|
|
||||||
decoderRenderer = new ConfigurableDecoderRenderer();
|
decoderRenderer = new ConfigurableDecoderRenderer();
|
||||||
|
decoderRenderer.initializeWithFlags(drFlags);
|
||||||
|
|
||||||
|
SurfaceHolder sh = sv.getHolder();
|
||||||
|
if (stretchToFit || !decoderRenderer.isHardwareAccelerated()) {
|
||||||
|
// Set the surface to the size of the video
|
||||||
|
sh.setFixedSize(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
// The connection will be started when the surface gets created
|
// The connection will be started when the surface gets created
|
||||||
sh.addCallback(this);
|
sh.addCallback(this);
|
||||||
@@ -252,7 +255,7 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
super.onStop();
|
super.onStop();
|
||||||
|
|
||||||
SpinnerDialog.closeDialogs();
|
SpinnerDialog.closeDialogs(this);
|
||||||
Dialog.closeDialogs();
|
Dialog.closeDialogs();
|
||||||
|
|
||||||
displayedFailureDialog = true;
|
displayedFailureDialog = true;
|
||||||
@@ -299,10 +302,6 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
return modifier;
|
return modifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isSourceFlagSet(int sourcesFlags, int flag) {
|
|
||||||
return (sourcesFlags & flag) == flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||||
InputDevice dev = event.getDevice();
|
InputDevice dev = event.getDevice();
|
||||||
@@ -310,16 +309,15 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
return super.onKeyDown(keyCode, event);
|
return super.onKeyDown(keyCode, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
int source = dev.getSources();
|
// Pass-through virtual navigation keys
|
||||||
boolean handled = false;
|
if ((event.getFlags() & KeyEvent.FLAG_VIRTUAL_HARD_KEY) != 0) {
|
||||||
if (isSourceFlagSet(source, InputDevice.SOURCE_DPAD) ||
|
return super.onKeyDown(keyCode, event);
|
||||||
isSourceFlagSet(source, InputDevice.SOURCE_GAMEPAD) ||
|
|
||||||
isSourceFlagSet(source, InputDevice.SOURCE_JOYSTICK))
|
|
||||||
{
|
|
||||||
handled = controllerHandler.handleButtonDown(keyCode, event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try the controller handler first
|
||||||
|
boolean handled = controllerHandler.handleButtonDown(keyCode, event);
|
||||||
if (!handled) {
|
if (!handled) {
|
||||||
|
// Try the keyboard handler
|
||||||
short translated = keybTranslator.translate(event.getKeyCode());
|
short translated = keybTranslator.translate(event.getKeyCode());
|
||||||
if (translated == 0) {
|
if (translated == 0) {
|
||||||
return super.onKeyDown(keyCode, event);
|
return super.onKeyDown(keyCode, event);
|
||||||
@@ -349,16 +347,15 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
return super.onKeyUp(keyCode, event);
|
return super.onKeyUp(keyCode, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
int source = dev.getSources();
|
// Pass-through virtual navigation keys
|
||||||
boolean handled = false;
|
if ((event.getFlags() & KeyEvent.FLAG_VIRTUAL_HARD_KEY) != 0) {
|
||||||
if (isSourceFlagSet(source, InputDevice.SOURCE_DPAD) ||
|
return super.onKeyUp(keyCode, event);
|
||||||
isSourceFlagSet(source, InputDevice.SOURCE_GAMEPAD) ||
|
|
||||||
isSourceFlagSet(source, InputDevice.SOURCE_JOYSTICK))
|
|
||||||
{
|
|
||||||
handled = controllerHandler.handleButtonUp(keyCode, event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Try the controller handler first
|
||||||
|
boolean handled = controllerHandler.handleButtonUp(keyCode, event);
|
||||||
if (!handled) {
|
if (!handled) {
|
||||||
|
// Try the keyboard handler
|
||||||
short translated = keybTranslator.translate(event.getKeyCode());
|
short translated = keybTranslator.translate(event.getKeyCode());
|
||||||
if (translated == 0) {
|
if (translated == 0) {
|
||||||
return super.onKeyUp(keyCode, event);
|
return super.onKeyUp(keyCode, event);
|
||||||
@@ -614,7 +611,7 @@ public class Game extends Activity implements SurfaceHolder.Callback, OnGenericM
|
|||||||
|
|
||||||
// Resize the surface to match the aspect ratio of the video
|
// Resize the surface to match the aspect ratio of the video
|
||||||
// This must be done after the surface is created.
|
// This must be done after the surface is created.
|
||||||
if (!stretchToFit) {
|
if (!stretchToFit && decoderRenderer.isHardwareAccelerated()) {
|
||||||
resizeSurfaceWithAspectRatio((SurfaceView) findViewById(R.id.surfaceView), width, height);
|
resizeSurfaceWithAspectRatio((SurfaceView) findViewById(R.id.surfaceView), width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ import android.widget.Toast;
|
|||||||
import android.widget.AdapterView.AdapterContextMenuInfo;
|
import android.widget.AdapterView.AdapterContextMenuInfo;
|
||||||
|
|
||||||
public class PcView extends Activity {
|
public class PcView extends Activity {
|
||||||
private Button settingsButton;
|
private Button settingsButton, addComputerButton;
|
||||||
private ListView pcList;
|
private ListView pcList;
|
||||||
private ArrayAdapter<ComputerObject> pcListAdapter;
|
private ArrayAdapter<ComputerObject> pcListAdapter;
|
||||||
private ComputerManagerService.ComputerManagerBinder managerBinder;
|
private ComputerManagerService.ComputerManagerBinder managerBinder;
|
||||||
@@ -85,6 +85,8 @@ public class PcView extends Activity {
|
|||||||
|
|
||||||
// Setup the list view
|
// Setup the list view
|
||||||
settingsButton = (Button)findViewById(R.id.settingsButton);
|
settingsButton = (Button)findViewById(R.id.settingsButton);
|
||||||
|
addComputerButton = (Button)findViewById(R.id.manuallyAddPc);
|
||||||
|
|
||||||
pcList = (ListView)findViewById(R.id.pcListView);
|
pcList = (ListView)findViewById(R.id.pcListView);
|
||||||
pcListAdapter = new ArrayAdapter<ComputerObject>(this, R.layout.simplerow, R.id.rowTextView);
|
pcListAdapter = new ArrayAdapter<ComputerObject>(this, R.layout.simplerow, R.id.rowTextView);
|
||||||
pcListAdapter.setNotifyOnChange(false);
|
pcListAdapter.setNotifyOnChange(false);
|
||||||
@@ -119,6 +121,13 @@ public class PcView extends Activity {
|
|||||||
startActivity(new Intent(PcView.this, StreamSettings.class));
|
startActivity(new Intent(PcView.this, StreamSettings.class));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
addComputerButton.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
Intent i = new Intent(PcView.this, AddComputerManually.class);
|
||||||
|
startActivity(i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
addListPlaceholder();
|
addListPlaceholder();
|
||||||
}
|
}
|
||||||
@@ -313,6 +322,11 @@ public class PcView extends Activity {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (computer.macAddress == null) {
|
||||||
|
Toast.makeText(PcView.this, "Unable to wake PC because GFE didn't send a MAC address", Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Toast.makeText(PcView.this, "Waking PC...", Toast.LENGTH_SHORT).show();
|
Toast.makeText(PcView.this, "Waking PC...", Toast.LENGTH_SHORT).show();
|
||||||
new Thread(new Runnable() {
|
new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
@@ -494,7 +508,7 @@ public class PcView extends Activity {
|
|||||||
private void addListPlaceholder() {
|
private void addListPlaceholder() {
|
||||||
pcListAdapter.add(new ComputerObject("Discovery is running. No computers found yet. " +
|
pcListAdapter.add(new ComputerObject("Discovery is running. No computers found yet. " +
|
||||||
"If your PC doesn't show up in about 15 seconds, " +
|
"If your PC doesn't show up in about 15 seconds, " +
|
||||||
"make sure your computer is running GFE or add your PC manually on the settings page.", null));
|
"make sure your computer is running GFE or add your PC manually using the button above.", null));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeListView(ComputerDetails details) {
|
private void removeListView(ComputerDetails details) {
|
||||||
|
|||||||
@@ -16,10 +16,10 @@ import android.content.Intent;
|
|||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
|
||||||
public class StreamSettings extends Activity {
|
public class StreamSettings extends Activity {
|
||||||
private Button advancedSettingsButton, addComputerButton;
|
private Button advancedSettingsButton;
|
||||||
private SharedPreferences prefs;
|
private SharedPreferences prefs;
|
||||||
private RadioButton rbutton720p30, rbutton720p60, rbutton1080p30, rbutton1080p60;
|
private RadioButton rbutton720p30, rbutton720p60, rbutton1080p30, rbutton1080p60;
|
||||||
private CheckBox stretchToFill;
|
private CheckBox stretchToFill, enableSops;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStop() {
|
protected void onStop() {
|
||||||
@@ -35,8 +35,8 @@ public class StreamSettings extends Activity {
|
|||||||
setContentView(R.layout.activity_stream_settings);
|
setContentView(R.layout.activity_stream_settings);
|
||||||
|
|
||||||
this.stretchToFill = (CheckBox) findViewById(R.id.stretchToFill);
|
this.stretchToFill = (CheckBox) findViewById(R.id.stretchToFill);
|
||||||
|
this.enableSops = (CheckBox) findViewById(R.id.enableSops);
|
||||||
this.advancedSettingsButton = (Button) findViewById(R.id.advancedSettingsButton);
|
this.advancedSettingsButton = (Button) findViewById(R.id.advancedSettingsButton);
|
||||||
this.addComputerButton = (Button) findViewById(R.id.manuallyAddPc);
|
|
||||||
this.rbutton720p30 = (RadioButton) findViewById(R.id.config720p30Selected);
|
this.rbutton720p30 = (RadioButton) findViewById(R.id.config720p30Selected);
|
||||||
this.rbutton720p60 = (RadioButton) findViewById(R.id.config720p60Selected);
|
this.rbutton720p60 = (RadioButton) findViewById(R.id.config720p60Selected);
|
||||||
this.rbutton1080p30 = (RadioButton) findViewById(R.id.config1080p30Selected);
|
this.rbutton1080p30 = (RadioButton) findViewById(R.id.config1080p30Selected);
|
||||||
@@ -48,6 +48,7 @@ public class StreamSettings extends Activity {
|
|||||||
boolean fps30 = prefs.getInt(Game.REFRESH_RATE_PREF_STRING, Game.DEFAULT_REFRESH_RATE) == 30;
|
boolean fps30 = prefs.getInt(Game.REFRESH_RATE_PREF_STRING, Game.DEFAULT_REFRESH_RATE) == 30;
|
||||||
|
|
||||||
stretchToFill.setChecked(prefs.getBoolean(Game.STRETCH_PREF_STRING, Game.DEFAULT_STRETCH));
|
stretchToFill.setChecked(prefs.getBoolean(Game.STRETCH_PREF_STRING, Game.DEFAULT_STRETCH));
|
||||||
|
enableSops.setChecked(prefs.getBoolean(Game.SOPS_PREF_STRING, Game.DEFAULT_SOPS));
|
||||||
|
|
||||||
rbutton720p30.setChecked(false);
|
rbutton720p30.setChecked(false);
|
||||||
rbutton720p60.setChecked(false);
|
rbutton720p60.setChecked(false);
|
||||||
@@ -117,13 +118,6 @@ public class StreamSettings extends Activity {
|
|||||||
startActivity(i);
|
startActivity(i);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
addComputerButton.setOnClickListener(new OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
|
||||||
Intent i = new Intent(StreamSettings.this, AddComputerManually.class);
|
|
||||||
startActivity(i);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
stretchToFill.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
stretchToFill.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(CompoundButton buttonView,
|
public void onCheckedChanged(CompoundButton buttonView,
|
||||||
@@ -131,5 +125,12 @@ public class StreamSettings extends Activity {
|
|||||||
prefs.edit().putBoolean(Game.STRETCH_PREF_STRING, isChecked).commit();
|
prefs.edit().putBoolean(Game.STRETCH_PREF_STRING, isChecked).commit();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
enableSops.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView,
|
||||||
|
boolean isChecked) {
|
||||||
|
prefs.edit().putBoolean(Game.SOPS_PREF_STRING, isChecked).commit();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -148,10 +148,6 @@ public class ControllerHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mapping.isDpad = (dev.getSources() & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD;
|
|
||||||
mapping.isGamepad = (dev.getSources() & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD ||
|
|
||||||
(dev.getSources() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK;
|
|
||||||
|
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,47 +177,6 @@ public class ControllerHandler {
|
|||||||
leftStickX, leftStickY, rightStickX, rightStickY);
|
leftStickX, leftStickY, rightStickX, rightStickY);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isEventExpected(ControllerMapping mapping, int keyCode) {
|
|
||||||
if (mapping.isDpad) {
|
|
||||||
switch (keyCode) {
|
|
||||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
|
||||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
|
||||||
case KeyEvent.KEYCODE_DPAD_CENTER:
|
|
||||||
case KeyEvent.KEYCODE_DPAD_UP:
|
|
||||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mapping.isGamepad) {
|
|
||||||
switch (keyCode) {
|
|
||||||
case KeyEvent.KEYCODE_BUTTON_MODE:
|
|
||||||
case KeyEvent.KEYCODE_BUTTON_START:
|
|
||||||
case KeyEvent.KEYCODE_MENU:
|
|
||||||
case KeyEvent.KEYCODE_BACK:
|
|
||||||
case KeyEvent.KEYCODE_BUTTON_SELECT:
|
|
||||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
|
||||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
|
||||||
case KeyEvent.KEYCODE_DPAD_UP:
|
|
||||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
|
||||||
case KeyEvent.KEYCODE_BUTTON_B:
|
|
||||||
case KeyEvent.KEYCODE_DPAD_CENTER:
|
|
||||||
case KeyEvent.KEYCODE_BUTTON_A:
|
|
||||||
case KeyEvent.KEYCODE_BUTTON_X:
|
|
||||||
case KeyEvent.KEYCODE_BUTTON_Y:
|
|
||||||
case KeyEvent.KEYCODE_BUTTON_L1:
|
|
||||||
case KeyEvent.KEYCODE_BUTTON_R1:
|
|
||||||
case KeyEvent.KEYCODE_BUTTON_THUMBL:
|
|
||||||
case KeyEvent.KEYCODE_BUTTON_THUMBR:
|
|
||||||
case KeyEvent.KEYCODE_BUTTON_L2:
|
|
||||||
case KeyEvent.KEYCODE_BUTTON_R2:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int handleRemapping(ControllerMapping mapping, int keyCode) {
|
private static int handleRemapping(ControllerMapping mapping, int keyCode) {
|
||||||
if (mapping.isDualShock4) {
|
if (mapping.isDualShock4) {
|
||||||
switch (keyCode) {
|
switch (keyCode) {
|
||||||
@@ -362,10 +317,6 @@ public class ControllerHandler {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isEventExpected(mapping, keyCode)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the button hasn't been down long enough, sleep for a bit before sending the up event
|
// If the button hasn't been down long enough, sleep for a bit before sending the up event
|
||||||
// This allows "instant" button presses (like OUYA's virtual menu button) to work. This
|
// This allows "instant" button presses (like OUYA's virtual menu button) to work. This
|
||||||
// path should not be triggered during normal usage.
|
// path should not be triggered during normal usage.
|
||||||
@@ -489,10 +440,6 @@ public class ControllerHandler {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isEventExpected(mapping, keyCode)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (keyCode) {
|
switch (keyCode) {
|
||||||
case KeyEvent.KEYCODE_BUTTON_MODE:
|
case KeyEvent.KEYCODE_BUTTON_MODE:
|
||||||
inputMap |= ControllerPacket.SPECIAL_BUTTON_FLAG;
|
inputMap |= ControllerPacket.SPECIAL_BUTTON_FLAG;
|
||||||
@@ -602,7 +549,5 @@ public class ControllerHandler {
|
|||||||
public float hatYDeadzone;
|
public float hatYDeadzone;
|
||||||
|
|
||||||
public boolean isDualShock4;
|
public boolean isDualShock4;
|
||||||
public boolean isDpad;
|
|
||||||
public boolean isGamepad;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -16,15 +16,28 @@ public class ConfigurableDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setup(int width, int height, int redrawRate, Object renderTarget, int drFlags) {
|
public boolean setup(int width, int height, int redrawRate, Object renderTarget, int drFlags) {
|
||||||
|
if (decoderRenderer == null) {
|
||||||
|
throw new IllegalStateException("ConfigurableDecoderRenderer not initialized");
|
||||||
|
}
|
||||||
|
return decoderRenderer.setup(width, height, redrawRate, renderTarget, drFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void initializeWithFlags(int drFlags) {
|
||||||
if ((drFlags & VideoDecoderRenderer.FLAG_FORCE_HARDWARE_DECODING) != 0 ||
|
if ((drFlags & VideoDecoderRenderer.FLAG_FORCE_HARDWARE_DECODING) != 0 ||
|
||||||
((drFlags & VideoDecoderRenderer.FLAG_FORCE_SOFTWARE_DECODING) == 0 &&
|
((drFlags & VideoDecoderRenderer.FLAG_FORCE_SOFTWARE_DECODING) == 0 &&
|
||||||
MediaCodecDecoderRenderer.findSafeDecoder() != null)) {
|
MediaCodecDecoderRenderer.findSafeDecoder() != null)) {
|
||||||
decoderRenderer = new MediaCodecDecoderRenderer();
|
decoderRenderer = new MediaCodecDecoderRenderer();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
decoderRenderer = new AndroidCpuDecoderRenderer();
|
decoderRenderer = new AndroidCpuDecoderRenderer();
|
||||||
}
|
}
|
||||||
return decoderRenderer.setup(width, height, redrawRate, renderTarget, drFlags);
|
}
|
||||||
|
|
||||||
|
public boolean isHardwareAccelerated() {
|
||||||
|
if (decoderRenderer == null) {
|
||||||
|
throw new IllegalStateException("ConfigurableDecoderRenderer not initialized");
|
||||||
|
}
|
||||||
|
return (decoderRenderer instanceof MediaCodecDecoderRenderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -48,12 +48,13 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
static {
|
static {
|
||||||
spsFixupBitsreamFixupDecoderPrefixes = new LinkedList<String>();
|
spsFixupBitsreamFixupDecoderPrefixes = new LinkedList<String>();
|
||||||
spsFixupBitsreamFixupDecoderPrefixes.add("omx.nvidia");
|
spsFixupBitsreamFixupDecoderPrefixes.add("omx.nvidia");
|
||||||
|
spsFixupBitsreamFixupDecoderPrefixes.add("omx.qcom");
|
||||||
|
|
||||||
spsFixupNumRefFixupDecoderPrefixes = new LinkedList<String>();
|
spsFixupNumRefFixupDecoderPrefixes = new LinkedList<String>();
|
||||||
spsFixupNumRefFixupDecoderPrefixes.add("omx.TI");
|
spsFixupNumRefFixupDecoderPrefixes.add("omx.TI");
|
||||||
spsFixupNumRefFixupDecoderPrefixes.add("omx.qcom");
|
spsFixupNumRefFixupDecoderPrefixes.add("omx.qcom");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isDecoderInList(List<String> decoderList, String decoderName) {
|
private static boolean isDecoderInList(List<String> decoderList, String decoderName) {
|
||||||
for (String badPrefix : decoderList) {
|
for (String badPrefix : decoderList) {
|
||||||
if (decoderName.length() >= badPrefix.length()) {
|
if (decoderName.length() >= badPrefix.length()) {
|
||||||
@@ -177,8 +178,14 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
{
|
{
|
||||||
du = depacketizer.pollNextDecodeUnit();
|
du = depacketizer.pollNextDecodeUnit();
|
||||||
if (du != null) {
|
if (du != null) {
|
||||||
submitDecodeUnit(du);
|
if (!submitDecodeUnit(du)) {
|
||||||
depacketizer.freeDecodeUnit(du);
|
// Thread was interrupted
|
||||||
|
depacketizer.freeDecodeUnit(du);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
depacketizer.freeDecodeUnit(du);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int outIndex = videoDecoder.dequeueOutputBuffer(info, 0);
|
int outIndex = videoDecoder.dequeueOutputBuffer(info, 0);
|
||||||
@@ -250,105 +257,111 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean submitDecodeUnit(DecodeUnit decodeUnit) {
|
private boolean submitDecodeUnit(DecodeUnit decodeUnit) {
|
||||||
int inputIndex = videoDecoder.dequeueInputBuffer(-1);
|
int inputIndex;
|
||||||
if (inputIndex >= 0)
|
|
||||||
{
|
do {
|
||||||
ByteBuffer buf = videoDecoderInputBuffers[inputIndex];
|
if (Thread.interrupted()) {
|
||||||
|
return false;
|
||||||
long currentTime = System.currentTimeMillis();
|
|
||||||
long delta = currentTime-decodeUnit.getReceiveTimestamp();
|
|
||||||
if (delta >= 0 && delta < 300) {
|
|
||||||
totalTimeMs += currentTime-decodeUnit.getReceiveTimestamp();
|
|
||||||
totalFrames++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear old input data
|
inputIndex = videoDecoder.dequeueInputBuffer(100000);
|
||||||
buf.clear();
|
} while (inputIndex < 0);
|
||||||
|
|
||||||
int codecFlags = 0;
|
ByteBuffer buf = videoDecoderInputBuffers[inputIndex];
|
||||||
int decodeUnitFlags = decodeUnit.getFlags();
|
|
||||||
if ((decodeUnitFlags & DecodeUnit.DU_FLAG_CODEC_CONFIG) != 0) {
|
|
||||||
codecFlags |= MediaCodec.BUFFER_FLAG_CODEC_CONFIG;
|
|
||||||
}
|
|
||||||
if ((decodeUnitFlags & DecodeUnit.DU_FLAG_SYNC_FRAME) != 0) {
|
|
||||||
codecFlags |= MediaCodec.BUFFER_FLAG_SYNC_FRAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((decodeUnitFlags & DecodeUnit.DU_FLAG_CODEC_CONFIG) != 0 &&
|
|
||||||
(needsSpsBitstreamFixup || needsSpsNumRefFixup)) {
|
|
||||||
ByteBufferDescriptor header = decodeUnit.getBufferList().get(0);
|
|
||||||
if (header.data[header.offset+4] == 0x67) {
|
|
||||||
byte last = header.data[header.length+header.offset-1];
|
|
||||||
|
|
||||||
// TI OMAP4 requires a reference frame count of 1 to decode successfully
|
long currentTime = System.currentTimeMillis();
|
||||||
if (needsSpsNumRefFixup) {
|
long delta = currentTime-decodeUnit.getReceiveTimestamp();
|
||||||
LimeLog.info("Fixing up num ref frames");
|
if (delta >= 0 && delta < 300) {
|
||||||
this.replace(header, 80, 9, new byte[] {0x40}, 3);
|
totalTimeMs += currentTime-decodeUnit.getReceiveTimestamp();
|
||||||
}
|
totalFrames++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear old input data
|
||||||
|
buf.clear();
|
||||||
|
|
||||||
|
int codecFlags = 0;
|
||||||
|
int decodeUnitFlags = decodeUnit.getFlags();
|
||||||
|
if ((decodeUnitFlags & DecodeUnit.DU_FLAG_CODEC_CONFIG) != 0) {
|
||||||
|
codecFlags |= MediaCodec.BUFFER_FLAG_CODEC_CONFIG;
|
||||||
|
}
|
||||||
|
if ((decodeUnitFlags & DecodeUnit.DU_FLAG_SYNC_FRAME) != 0) {
|
||||||
|
codecFlags |= MediaCodec.BUFFER_FLAG_SYNC_FRAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((decodeUnitFlags & DecodeUnit.DU_FLAG_CODEC_CONFIG) != 0 &&
|
||||||
|
(needsSpsBitstreamFixup || needsSpsNumRefFixup)) {
|
||||||
|
ByteBufferDescriptor header = decodeUnit.getBufferList().get(0);
|
||||||
|
if (header.data[header.offset+4] == 0x67) {
|
||||||
|
byte last = header.data[header.length+header.offset-1];
|
||||||
|
|
||||||
// The SPS that comes in the current H264 bytestream doesn't set bitstream_restriction_flag
|
// TI OMAP4 requires a reference frame count of 1 to decode successfully
|
||||||
// or max_dec_frame_buffering which increases decoding latency on Tegra.
|
if (needsSpsNumRefFixup) {
|
||||||
// We manually modify the SPS here to speed-up decoding if the decoder was flagged as needing it.
|
LimeLog.info("Fixing up num ref frames");
|
||||||
int spsLength;
|
this.replace(header, 80, 9, new byte[] {0x40}, 3);
|
||||||
if (needsSpsBitstreamFixup) {
|
}
|
||||||
if (!needsSpsNumRefFixup) {
|
|
||||||
switch (header.length) {
|
// The SPS that comes in the current H264 bytestream doesn't set bitstream_restriction_flag
|
||||||
case 26:
|
// or max_dec_frame_buffering which increases decoding latency on Tegra.
|
||||||
LimeLog.info("Adding bitstream restrictions to SPS (26)");
|
// We manually modify the SPS here to speed-up decoding if the decoder was flagged as needing it.
|
||||||
buf.put(header.data, header.offset, 24);
|
int spsLength;
|
||||||
buf.put((byte) 0x11);
|
if (needsSpsBitstreamFixup) {
|
||||||
buf.put((byte) 0xe3);
|
if (!needsSpsNumRefFixup) {
|
||||||
buf.put((byte) 0x06);
|
switch (header.length) {
|
||||||
buf.put((byte) 0x50);
|
case 26:
|
||||||
spsLength = header.length + 2;
|
LimeLog.info("Adding bitstream restrictions to SPS (26)");
|
||||||
break;
|
buf.put(header.data, header.offset, 24);
|
||||||
case 27:
|
buf.put((byte) 0x11);
|
||||||
LimeLog.info("Adding bitstream restrictions to SPS (27)");
|
buf.put((byte) 0xe3);
|
||||||
buf.put(header.data, header.offset, 25);
|
buf.put((byte) 0x06);
|
||||||
buf.put((byte) 0x04);
|
buf.put((byte) 0x50);
|
||||||
buf.put((byte) 0x78);
|
spsLength = header.length + 2;
|
||||||
buf.put((byte) 0xc1);
|
break;
|
||||||
buf.put((byte) 0x94);
|
case 27:
|
||||||
spsLength = header.length + 2;
|
LimeLog.info("Adding bitstream restrictions to SPS (27)");
|
||||||
break;
|
buf.put(header.data, header.offset, 25);
|
||||||
default:
|
buf.put((byte) 0x04);
|
||||||
LimeLog.warning("Unknown SPS of length "+header.length);
|
buf.put((byte) 0x78);
|
||||||
buf.put(header.data, header.offset, header.length);
|
buf.put((byte) 0xc1);
|
||||||
spsLength = header.length;
|
buf.put((byte) 0x94);
|
||||||
break;
|
spsLength = header.length + 2;
|
||||||
}
|
break;
|
||||||
}
|
default:
|
||||||
else {
|
LimeLog.warning("Unknown SPS of length "+header.length);
|
||||||
// Set bitstream restrictions to only buffer single frame
|
|
||||||
// (starts 9 bits before stop bit and 6 bits earlier because of the shortening above)
|
|
||||||
this.replace(header, header.length*8+Integer.numberOfLeadingZeros(last & - last)%8-9-6, 2, BITSTREAM_RESTRICTIONS, 3*8);
|
|
||||||
buf.put(header.data, header.offset, header.length);
|
buf.put(header.data, header.offset, header.length);
|
||||||
spsLength = header.length;
|
spsLength = header.length;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// Set bitstream restrictions to only buffer single frame
|
||||||
|
// (starts 9 bits before stop bit and 6 bits earlier because of the shortening above)
|
||||||
|
this.replace(header, header.length*8+Integer.numberOfLeadingZeros(last & - last)%8-9-6, 2, BITSTREAM_RESTRICTIONS, 3*8);
|
||||||
buf.put(header.data, header.offset, header.length);
|
buf.put(header.data, header.offset, header.length);
|
||||||
spsLength = header.length;
|
spsLength = header.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
videoDecoder.queueInputBuffer(inputIndex,
|
|
||||||
0, spsLength,
|
|
||||||
currentTime * 1000, codecFlags);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
|
buf.put(header.data, header.offset, header.length);
|
||||||
|
spsLength = header.length;
|
||||||
|
}
|
||||||
|
|
||||||
// Copy data from our buffer list into the input buffer
|
videoDecoder.queueInputBuffer(inputIndex,
|
||||||
for (ByteBufferDescriptor desc : decodeUnit.getBufferList())
|
0, spsLength,
|
||||||
{
|
currentTime * 1000, codecFlags);
|
||||||
buf.put(desc.data, desc.offset, desc.length);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
videoDecoder.queueInputBuffer(inputIndex,
|
|
||||||
0, decodeUnit.getDataLength(),
|
|
||||||
currentTime * 1000, codecFlags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy data from our buffer list into the input buffer
|
||||||
|
for (ByteBufferDescriptor desc : decodeUnit.getBufferList())
|
||||||
|
{
|
||||||
|
buf.put(desc.data, desc.offset, desc.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
videoDecoder.queueInputBuffer(inputIndex,
|
||||||
|
0, decodeUnit.getDataLength(),
|
||||||
|
currentTime * 1000, codecFlags);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,6 +109,8 @@ public class ComputerDatabaseManager {
|
|||||||
computerList.add(details);
|
computerList.add(details);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.close();
|
||||||
|
|
||||||
return computerList;
|
return computerList;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,6 +119,7 @@ public class ComputerDatabaseManager {
|
|||||||
ComputerDetails details = new ComputerDetails();
|
ComputerDetails details = new ComputerDetails();
|
||||||
if (!c.moveToFirst()) {
|
if (!c.moveToFirst()) {
|
||||||
// No matching computer
|
// No matching computer
|
||||||
|
c.close();
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,6 +149,8 @@ public class ComputerDatabaseManager {
|
|||||||
|
|
||||||
details.macAddress = c.getString(4);
|
details.macAddress = c.getString(4);
|
||||||
|
|
||||||
|
c.close();
|
||||||
|
|
||||||
// If a field is corrupt or missing, delete the database entry
|
// If a field is corrupt or missing, delete the database entry
|
||||||
if (details.uuid == null || details.localIp == null || details.remoteIp == null ||
|
if (details.uuid == null || details.localIp == null || details.remoteIp == null ||
|
||||||
details.macAddress == null) {
|
details.macAddress == null) {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import java.util.TimerTask;
|
|||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import com.limelight.LimeLog;
|
import com.limelight.LimeLog;
|
||||||
import com.limelight.binding.PlatformBinding;
|
import com.limelight.binding.PlatformBinding;
|
||||||
@@ -39,6 +40,8 @@ public class ComputerManagerService extends Service {
|
|||||||
private ComputerManagerBinder binder = new ComputerManagerBinder();
|
private ComputerManagerBinder binder = new ComputerManagerBinder();
|
||||||
|
|
||||||
private ComputerDatabaseManager dbManager;
|
private ComputerDatabaseManager dbManager;
|
||||||
|
private AtomicInteger dbRefCount = new AtomicInteger(0);
|
||||||
|
|
||||||
private IdentityManager idManager;
|
private IdentityManager idManager;
|
||||||
private ThreadPoolExecutor pollingPool;
|
private ThreadPoolExecutor pollingPool;
|
||||||
private Timer pollingTimer;
|
private Timer pollingTimer;
|
||||||
@@ -173,15 +176,41 @@ public class ComputerManagerService extends Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void removeComputer(String name) {
|
public void removeComputer(String name) {
|
||||||
|
if (!getLocalDatabaseReference()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Remove it from the database
|
// Remove it from the database
|
||||||
dbManager.deleteComputer(name);
|
dbManager.deleteComputer(name);
|
||||||
|
|
||||||
|
releaseLocalDatabaseReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean getLocalDatabaseReference() {
|
||||||
|
if (dbRefCount.get() == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
dbRefCount.incrementAndGet();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void releaseLocalDatabaseReference() {
|
||||||
|
if (dbRefCount.decrementAndGet() == 0) {
|
||||||
|
dbManager.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TimerTask getTimerTask() {
|
private TimerTask getTimerTask() {
|
||||||
return new TimerTask() {
|
return new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
if (!getLocalDatabaseReference()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
List<ComputerDetails> computerList = dbManager.getAllComputers();
|
List<ComputerDetails> computerList = dbManager.getAllComputers();
|
||||||
|
releaseLocalDatabaseReference();
|
||||||
|
|
||||||
for (ComputerDetails computer : computerList) {
|
for (ComputerDetails computer : computerList) {
|
||||||
pollingPool.execute(getPollingRunnable(computer));
|
pollingPool.execute(getPollingRunnable(computer));
|
||||||
}
|
}
|
||||||
@@ -356,6 +385,10 @@ public class ComputerManagerService extends Service {
|
|||||||
public void run() {
|
public void run() {
|
||||||
boolean newPc = (details.name == null);
|
boolean newPc = (details.name == null);
|
||||||
|
|
||||||
|
if (!getLocalDatabaseReference()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Poll the machine
|
// Poll the machine
|
||||||
if (!doPollMachine(details)) {
|
if (!doPollMachine(details)) {
|
||||||
details.state = ComputerDetails.State.OFFLINE;
|
details.state = ComputerDetails.State.OFFLINE;
|
||||||
@@ -369,6 +402,7 @@ public class ComputerManagerService extends Service {
|
|||||||
// removed after this was issued
|
// removed after this was issued
|
||||||
if (dbManager.getComputerByName(details.name) == null) {
|
if (dbManager.getComputerByName(details.name) == null) {
|
||||||
// It's gone
|
// It's gone
|
||||||
|
releaseLocalDatabaseReference();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -376,10 +410,12 @@ public class ComputerManagerService extends Service {
|
|||||||
dbManager.updateComputer(details);
|
dbManager.updateComputer(details);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update anyone listening
|
// Don't call the listener if this is a failed lookup of a new PC
|
||||||
if (listener != null) {
|
if ((!newPc || details.state == ComputerDetails.State.ONLINE) && listener != null) {
|
||||||
listener.notifyComputerUpdated(details);
|
listener.notifyComputerUpdated(details);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
releaseLocalDatabaseReference();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -391,14 +427,16 @@ public class ComputerManagerService extends Service {
|
|||||||
discoveryServiceConnection, Service.BIND_AUTO_CREATE);
|
discoveryServiceConnection, Service.BIND_AUTO_CREATE);
|
||||||
|
|
||||||
// Create the thread pool for updating computer state
|
// Create the thread pool for updating computer state
|
||||||
pollingPool = new ThreadPoolExecutor(1, MAX_CONCURRENT_REQUESTS, Long.MAX_VALUE, TimeUnit.DAYS,
|
pollingPool = new ThreadPoolExecutor(MAX_CONCURRENT_REQUESTS, MAX_CONCURRENT_REQUESTS,
|
||||||
new LinkedBlockingQueue<Runnable>(), new ThreadPoolExecutor.DiscardPolicy());
|
Long.MAX_VALUE, TimeUnit.DAYS, new LinkedBlockingQueue<Runnable>(),
|
||||||
|
new ThreadPoolExecutor.DiscardPolicy());
|
||||||
|
|
||||||
// Lookup or generate this device's UID
|
// Lookup or generate this device's UID
|
||||||
idManager = new IdentityManager(this);
|
idManager = new IdentityManager(this);
|
||||||
|
|
||||||
// Initialize the DB
|
// Initialize the DB
|
||||||
dbManager = new ComputerDatabaseManager(this);
|
dbManager = new ComputerDatabaseManager(this);
|
||||||
|
dbRefCount.set(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -410,12 +448,11 @@ public class ComputerManagerService extends Service {
|
|||||||
|
|
||||||
// Stop the thread pool
|
// Stop the thread pool
|
||||||
pollingPool.shutdownNow();
|
pollingPool.shutdownNow();
|
||||||
try {
|
|
||||||
pollingPool.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
|
|
||||||
} catch (InterruptedException e) {}
|
|
||||||
|
|
||||||
// Close the DB
|
// FIXME: Should await termination here but we have timeout issues in HttpURLConnection
|
||||||
dbManager.close();
|
|
||||||
|
// Remove the initial DB reference
|
||||||
|
releaseLocalDatabaseReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.limelight.utils;
|
package com.limelight.utils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
@@ -31,16 +32,19 @@ public class SpinnerDialog implements Runnable,OnCancelListener {
|
|||||||
return spinner;
|
return spinner;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void closeDialogs()
|
public static void closeDialogs(Activity activity)
|
||||||
{
|
{
|
||||||
synchronized (rundownDialogs) {
|
synchronized (rundownDialogs) {
|
||||||
for (SpinnerDialog d : rundownDialogs) {
|
Iterator<SpinnerDialog> i = rundownDialogs.iterator();
|
||||||
if (d.progress.isShowing()) {
|
while (i.hasNext()) {
|
||||||
d.progress.dismiss();
|
SpinnerDialog dialog = i.next();
|
||||||
|
if (dialog.activity == activity) {
|
||||||
|
i.remove();
|
||||||
|
if (dialog.progress.isShowing()) {
|
||||||
|
dialog.progress.dismiss();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rundownDialogs.clear();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,13 +66,14 @@ public class SpinnerDialog implements Runnable,OnCancelListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
||||||
|
// If we're dying, don't bother doing anything
|
||||||
|
if (activity.isFinishing()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (progress == null)
|
if (progress == null)
|
||||||
{
|
{
|
||||||
// If we're dying, don't bother creating a dialog
|
|
||||||
if (activity.isFinishing())
|
|
||||||
return;
|
|
||||||
|
|
||||||
progress = new ProgressDialog(activity);
|
progress = new ProgressDialog(activity);
|
||||||
|
|
||||||
progress.setTitle(title);
|
progress.setTitle(title);
|
||||||
|
|||||||
Reference in new issue
Block a user