Merge branch 'master' into root

Conflicts:
	AndroidManifest.xml
	libs/limelight-common.jar
	res/values/strings.xml
This commit is contained in:
Cameron Gutman 2014-10-17 13:55:45 -07:00
commit a18aa51f5a
92 changed files with 417 additions and 273 deletions

View File

@ -1,12 +1,12 @@
<?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.root" package="com.limelight.root"
android:versionCode="35" android:versionCode="36"
android:versionName="2.5.6" > android:versionName="2.5.7" >
<uses-sdk <uses-sdk
android:minSdkVersion="16" android:minSdkVersion="16"
android:targetSdkVersion="19" /> android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
@ -19,22 +19,39 @@
<uses-feature android:name="android.hardware.touchscreen" android:required="false" /> <uses-feature android:name="android.hardware.touchscreen" android:required="false" />
<uses-feature android:name="android.hardware.wifi" android:required="false" /> <uses-feature android:name="android.hardware.wifi" android:required="false" />
<uses-feature android:name="android.hardware.gamepad" android:required="false" />
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@drawable/ic_launcher" android:icon="@drawable/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/AppTheme" > android:theme="@style/AppTheme" >
<!-- Launcher for traditional devices -->
<activity <activity
android:name="com.limelight.PcView" android:name="com.limelight.PcView"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection"
android:label="@string/app_name" > android:label="@string/app_name">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
<category android:name="tv.ouya.intent.category.APP" /> <category android:name="tv.ouya.intent.category.APP" />
</intent-filter> </intent-filter>
</activity> </activity>
<!-- Launcher for Android TV devices -->
<activity
android:name="com.limelight.PcViewTv"
android:logo="@drawable/atv_banner"
android:icon="@drawable/atv_banner"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity>
<activity <activity
android:name="com.limelight.AppView" android:name="com.limelight.AppView"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection"
@ -68,8 +85,6 @@
android:name="com.limelight.Game" android:name="com.limelight.Game"
android:screenOrientation="sensorLandscape" android:screenOrientation="sensorLandscape"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|screenLayout|fontScale|uiMode|orientation|screenSize|smallestScreenSize|layoutDirection"
android:label="@string/title_activity_game"
android:parentActivityName="com.limelight.Connection"
android:theme="@style/FullscreenTheme" > android:theme="@style/FullscreenTheme" >
<meta-data <meta-data
android:name="android.support.PARENT_ACTIVITY" android:name="android.support.PARENT_ACTIVITY"

View File

@ -1,7 +1,7 @@
This file serves to document some of the decoder errata when using MediaCodec hardware decoders on certain devices. This file serves to document some of the decoder errata when using MediaCodec hardware decoders on certain devices.
1. num_ref_frames is set to 16 by NVENC which causes decoders to allocate 16+ buffers. This can cause an OOM error on some devices. 1. num_ref_frames is set to 16 by NVENC which causes decoders to allocate 16+ buffers. This can cause an error on some devices.
- Affected decoders: TI OMAP4 - Affected decoders: TI OMAP4, Exynos 4
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
@ -10,4 +10,10 @@ This file serves to document some of the decoder errata when using MediaCodec ha
- 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 or first I-frame
- Affected decoders: Qualcomm in GS3 on 4.3+, Exynos 4 - Affected decoders: Qualcomm in GS3 on 4.3+
5. Some decoders will hang if max_dec_frame_buffering is not present
- Affected decoders: MediaTek decoder in Fire HD 7 (2014)
6. Some decoders will hang if max_dec_frame_buffering IS present
- Affected decoders: Exynos 5 in Galaxy Note 10.1 (2014)

View File

@ -18,9 +18,6 @@ or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>na
*/ */
public static final int buttonBarStyle=0x7f010000; public static final int buttonBarStyle=0x7f010000;
} }
public static final class color {
public static final int black_overlay=0x7f040000;
}
public static final class dimen { public static final class dimen {
/** Default screen margins, per the Android Design guidelines. /** Default screen margins, per the Android Design guidelines.
@ -28,40 +25,43 @@ or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>na
screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here. screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here.
*/ */
public static final int activity_horizontal_margin=0x7f050000; public static final int activity_horizontal_margin=0x7f040000;
public static final int activity_vertical_margin=0x7f050001; public static final int activity_vertical_margin=0x7f040001;
} }
public static final class drawable { public static final class drawable {
public static final int app_icon=0x7f020000; public static final int app_icon=0x7f020000;
public static final int ic_launcher=0x7f020001; public static final int atv_banner=0x7f020001;
public static final int list_view_unselected=0x7f020002; public static final int ic_launcher=0x7f020002;
public static final int ouya_icon=0x7f020003; public static final int list_view_unselected=0x7f020003;
public static final int ouya_icon=0x7f020004;
} }
public static final class id { public static final class id {
public static final int addPc=0x7f080001; public static final int addPc=0x7f070001;
public static final int advancedSettingsButton=0x7f080013; public static final int advancedSettingsButton=0x7f070015;
public static final int appListText=0x7f080009; public static final int advancedSettingsText=0x7f070002;
public static final int autoDec=0x7f080004; public static final int appListText=0x7f07000a;
public static final int bitrateLabel=0x7f080006; public static final int autoDec=0x7f070005;
public static final int bitrateSeekBar=0x7f080007; public static final int bitrateLabel=0x7f070007;
public static final int config1080p30Selected=0x7f080011; public static final int bitrateSeekBar=0x7f070008;
public static final int config1080p60Selected=0x7f080012; public static final int config1080p30Selected=0x7f070013;
public static final int config720p30Selected=0x7f08000f; public static final int config1080p60Selected=0x7f070014;
public static final int config720p60Selected=0x7f080010; public static final int config720p30Selected=0x7f070011;
public static final int decoderConfigGroup=0x7f080002; public static final int config720p60Selected=0x7f070012;
public static final int disableToasts=0x7f080014; public static final int decoderConfigGroup=0x7f070003;
public static final int discoveryText=0x7f08000b; public static final int disableToasts=0x7f070016;
public static final int enableSops=0x7f080016; public static final int discoveryText=0x7f07000c;
public static final int hardwareDec=0x7f080005; public static final int enableSops=0x7f070018;
public static final int hostTextView=0x7f080000; public static final int hardwareDec=0x7f070006;
public static final int manuallyAddPc=0x7f08000c; public static final int hostTextView=0x7f070000;
public static final int pcListView=0x7f080008; public static final int manuallyAddPc=0x7f07000d;
public static final int rowTextView=0x7f080017; public static final int pcListView=0x7f070009;
public static final int settingsButton=0x7f08000d; public static final int rowTextView=0x7f070019;
public static final int softwareDec=0x7f080003; public static final int settingsButton=0x7f07000e;
public static final int streamConfigGroup=0x7f08000e; public static final int softwareDec=0x7f070004;
public static final int stretchToFill=0x7f080015; public static final int streamConfigGroup=0x7f070010;
public static final int surfaceView=0x7f08000a; public static final int streamSettingsText=0x7f07000f;
public static final int stretchToFill=0x7f070017;
public static final int surfaceView=0x7f07000b;
} }
public static final class layout { public static final class layout {
public static final int activity_add_computer_manually=0x7f030000; public static final int activity_add_computer_manually=0x7f030000;
@ -73,8 +73,34 @@ or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>na
public static final int simplerow=0x7f030006; public static final int simplerow=0x7f030006;
} }
public static final class string { public static final class string {
public static final int app_name=0x7f060000; /** General strings
public static final int title_activity_game=0x7f060001; */
public static final int app_name=0x7f050000;
/** Add computer manually activity
*/
public static final int button_add_pc=0x7f050005;
public static final int button_add_pc_manually=0x7f050004;
public static final int button_advanced_settings=0x7f050007;
public static final int button_stream_settings=0x7f050003;
public static final int check_disableToasts=0x7f05000e;
public static final int check_enableSops=0x7f05000d;
public static final int check_stretchToFill=0x7f05000c;
public static final int ip_hint=0x7f050001;
public static final int radio_1080p30=0x7f05000a;
public static final int radio_1080p60=0x7f05000b;
public static final int radio_720p30=0x7f050008;
public static final int radio_720p60=0x7f050009;
public static final int radio_autoSelect=0x7f050010;
public static final int radio_forceHardware=0x7f050011;
/** Advanced settings activity
*/
public static final int radio_forceSoftware=0x7f05000f;
/** PC view activity
*/
public static final int title_pc_view=0x7f050002;
/** Stream settings activity
*/
public static final int title_streaming_settings=0x7f050006;
} }
public static final class style { public static final class style {
/** /**
@ -89,27 +115,25 @@ or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>na
Base application theme for API 11+. This theme completely replaces
AppBaseTheme from res/values/styles.xml on API 11+ devices.
API 11 theme customizations can go here.
Base application theme for API 14+. This theme completely replaces Base application theme for API 14+. This theme completely replaces
AppBaseTheme from BOTH res/values/styles.xml and AppBaseTheme from BOTH res/values/styles.xml and
res/values-v11/styles.xml on API 14+ devices. res/values-v11/styles.xml on API 14+ devices.
API 14 theme customizations can go here. API 14 theme customizations can go here.
Base application theme for API 21+. This theme completely replaces
AppBaseTheme from BOTH res/values/styles.xml and
res/values-v11/styles.xml on API 21+ devices.
API 21 theme customizations can go here.
*/ */
public static final int AppBaseTheme=0x7f070000; public static final int AppBaseTheme=0x7f060000;
/** Application theme. /** Application theme.
All customizations that are NOT specific to a particular API-level can go here.
*/ */
public static final int AppTheme=0x7f070001; public static final int AppTheme=0x7f060001;
public static final int ButtonBar=0x7f070003; public static final int ButtonBar=0x7f060003;
public static final int ButtonBarButton=0x7f070004; public static final int ButtonBarButton=0x7f060004;
public static final int FullscreenActionBarStyle=0x7f070005; public static final int FullscreenTheme=0x7f060002;
public static final int FullscreenTheme=0x7f070002;
} }
public static final class styleable { public static final class styleable {
/** /**

View File

@ -1,4 +1,4 @@
ANDROID_API_TARGET=L ANDROID_API_TARGET=21
PARALLEL_JOBS=$(nproc) PARALLEL_JOBS=$(nproc)
rm -r ./android rm -r ./android

View File

@ -1,4 +1,4 @@
ANDROID_API_TARGET=L ANDROID_API_TARGET=21
PARALLEL_JOBS=$(nproc) PARALLEL_JOBS=$(nproc)
rm -r ./android rm -r ./android

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -8,6 +8,8 @@
</issue> </issue>
<issue id="InvalidPackage"> <issue id="InvalidPackage">
<ignore path="libs/bcprov-jdk15on-150.jar" /> <ignore path="libs/bcprov-jdk15on-150.jar" />
<ignore path="libs/bcprov-jdk15on-151.jar" />
<ignore path="libs/jcodec-0.1.5.jar" />
</issue> </issue>
<issue id="UnusedResources"> <issue id="UnusedResources">
<ignore path="res/drawable-xhdpi/ouya_icon.png" /> <ignore path="res/drawable-xhdpi/ouya_icon.png" />

View File

@ -11,4 +11,4 @@
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target. # Project target.
target=android-19 target=android-21

BIN
res/drawable/atv_banner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

View File

@ -0,0 +1,55 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".PcView" >
<ListView
android:id="@+id/pcListView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/settingsButton"
android:background="@drawable/list_view_unselected"
android:fastScrollEnabled="true"
android:longClickable="false"
android:stackFromBottom="false" >
</ListView>
<TextView
android:id="@+id/discoveryText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_centerHorizontal="true"
android:layout_alignBaseline="@+id/settingsButton"
android:text="@string/title_pc_view" />
<Button
android:id="@+id/settingsButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/pcListView"
android:layout_alignParentTop="true"
android:layout_marginTop="10dp"
android:layout_marginBottom="15dp"
android:text="@string/button_stream_settings" />
<Button
android:id="@+id/manuallyAddPc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="@+id/pcListView"
android:layout_alignParentTop="true"
android:layout_marginTop="10dp"
android:layout_marginBottom="15dp"
android:text="@string/button_add_pc_manually" />
</RelativeLayout>

View File

@ -32,7 +32,7 @@
android:layout_below="@+id/manuallyAddPc" android:layout_below="@+id/manuallyAddPc"
android:paddingTop="10dp" android:paddingTop="10dp"
android:paddingBottom="10dp" android:paddingBottom="10dp"
android:text="Discovered PC List" /> android:text="@string/title_pc_view" />
<Button <Button
android:id="@+id/settingsButton" android:id="@+id/settingsButton"
@ -40,7 +40,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:text="Streaming Settings" /> android:text="@string/button_stream_settings" />
<Button <Button
android:id="@+id/manuallyAddPc" android:id="@+id/manuallyAddPc"
@ -48,6 +48,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/settingsButton" android:layout_below="@+id/settingsButton"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:text="Add PC Manually" /> android:text="@string/button_add_pc_manually" />
</RelativeLayout> </RelativeLayout>

View File

@ -18,7 +18,7 @@
android:ems="10" android:ems="10"
android:singleLine="true" android:singleLine="true"
android:inputType="textNoSuggestions" android:inputType="textNoSuggestions"
android:hint="IP address of GeForce PC" > android:hint="@string/ip_hint" >
<requestFocus /> <requestFocus />
</EditText> </EditText>
@ -29,6 +29,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/hostTextView" android:layout_below="@+id/hostTextView"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:text="Manually Add PC" /> android:text="@string/button_add_pc" />
</RelativeLayout> </RelativeLayout>

View File

@ -12,10 +12,22 @@
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" > android:layout_height="wrap_content" >
<TextView
android:id="@+id/advancedSettingsText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_alignParentTop="true"
android:paddingTop="0dp"
android:paddingBottom="10dp"
android:text="@string/button_advanced_settings" />
<RadioGroup <RadioGroup
android:id="@+id/decoderConfigGroup" android:id="@+id/decoderConfigGroup"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/advancedSettingsText"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_marginTop="15dp" android:layout_marginTop="15dp"
@ -25,19 +37,19 @@
android:id="@+id/softwareDec" android:id="@+id/softwareDec"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Force Software Decoding" /> android:text="@string/radio_forceSoftware" />
<RadioButton <RadioButton
android:id="@+id/autoDec" android:id="@+id/autoDec"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Auto-select Decoder (Recommended)" /> android:text="@string/radio_autoSelect" />
<RadioButton <RadioButton
android:id="@+id/hardwareDec" android:id="@+id/hardwareDec"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="Force Hardware Decoding" /> android:text="@string/radio_forceHardware" />
</RadioGroup> </RadioGroup>
<TextView <TextView

View File

@ -30,7 +30,6 @@
android:textAppearance="?android:attr/textAppearanceLarge" android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_alignParentTop="true" android:layout_alignParentTop="true"
android:paddingTop="0dp" android:paddingTop="0dp"
android:paddingBottom="10dp" android:paddingBottom="10dp" />
android:text="Applications" />
</RelativeLayout> </RelativeLayout>

View File

@ -12,10 +12,22 @@
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" > android:layout_height="wrap_content" >
<TextView
android:id="@+id/streamSettingsText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_alignParentTop="true"
android:paddingTop="0dp"
android:paddingBottom="10dp"
android:text="@string/title_streaming_settings" />
<RadioGroup <RadioGroup
android:id="@+id/streamConfigGroup" android:id="@+id/streamConfigGroup"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/streamSettingsText"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
@ -25,28 +37,28 @@
android:id="@+id/config720p30Selected" android:id="@+id/config720p30Selected"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="720p 30 FPS (Only recommended for poor devices or networks)" /> android:text="@string/radio_720p30" />
<RadioButton <RadioButton
android:id="@+id/config720p60Selected" android:id="@+id/config720p60Selected"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="7dp" android:layout_marginTop="7dp"
android:text="720p 60 FPS (Recommended for most devices and networks)" /> android:text="@string/radio_720p60" />
<RadioButton <RadioButton
android:id="@+id/config1080p30Selected" android:id="@+id/config1080p30Selected"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="7dp" android:layout_marginTop="7dp"
android:text="1080p 30 FPS (Recommended for most devices if 1080p streaming is desired)" /> android:text="@string/radio_1080p30" />
<RadioButton <RadioButton
android:id="@+id/config1080p60Selected" android:id="@+id/config1080p60Selected"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="7dp" android:layout_marginTop="7dp"
android:text="1080p 60 FPS (Requires extremely fast device and network)" /> android:text="@string/radio_1080p60" />
</RadioGroup> </RadioGroup>
@ -57,7 +69,7 @@
android:layout_below="@+id/disableToasts" android:layout_below="@+id/disableToasts"
android:layout_centerHorizontal="true" android:layout_centerHorizontal="true"
android:layout_marginTop="15dp" android:layout_marginTop="15dp"
android:text="Advanced Settings" /> android:text="@string/button_advanced_settings" />
<CheckBox <CheckBox
android:id="@+id/stretchToFill" android:id="@+id/stretchToFill"
@ -65,7 +77,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
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="@string/check_stretchToFill" />
<CheckBox <CheckBox
android:id="@+id/enableSops" android:id="@+id/enableSops"
@ -73,7 +85,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/stretchToFill" android:layout_below="@+id/stretchToFill"
android:layout_marginTop="15dp" android:layout_marginTop="15dp"
android:text="Allow GFE to modify game settings for optimal streaming" /> android:text="@string/check_enableSops" />
<CheckBox <CheckBox
android:id="@+id/disableToasts" android:id="@+id/disableToasts"
@ -81,8 +93,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_below="@+id/enableSops" android:layout_below="@+id/enableSops"
android:layout_marginTop="15dp" android:layout_marginTop="15dp"
android:text="Disable on-screen connection warning messages" /> android:text="@string/check_disableToasts" />
</RelativeLayout> </RelativeLayout>
</ScrollView> </ScrollView>

View File

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!--
Base application theme for API 11+. This theme completely replaces
AppBaseTheme from res/values/styles.xml on API 11+ devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Holo">
<!-- API 11 theme customizations can go here. -->
</style>
<style name="FullscreenTheme" parent="android:Theme.Holo">
<item name="android:actionBarStyle">@style/FullscreenActionBarStyle</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:windowBackground">@null</item>
<item name="buttonBarStyle">?android:attr/buttonBarStyle</item>
<item name="buttonBarButtonStyle">?android:attr/buttonBarButtonStyle</item>
</style>
<style name="FullscreenActionBarStyle" parent="android:Widget.Holo.ActionBar">
<item name="android:background">@color/black_overlay</item>
</style>
</resources>

12
res/values-v21/styles.xml Normal file
View File

@ -0,0 +1,12 @@
<resources>
<!--
Base application theme for API 21+. This theme completely replaces
AppBaseTheme from BOTH res/values/styles.xml and
res/values-v11/styles.xml on API 21+ devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Material">
<!-- API 21 theme customizations can go here. -->
</style>
</resources>

View File

@ -1,5 +0,0 @@
<resources>
<color name="black_overlay">#66000000</color>
</resources>

View File

@ -1,7 +1,32 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- General strings -->
<string name="app_name">Limelight (Root)</string> <string name="app_name">Limelight (Root)</string>
<string name="title_activity_game">Game</string> <string name="ip_hint">IP address of GeForce PC</string>
<!-- PC view activity -->
<string name="title_pc_view">PC List</string>
<string name="button_stream_settings">Streaming Settings</string>
<string name="button_add_pc_manually">Add PC Manually</string>
<!-- Add computer manually activity -->
<string name="button_add_pc">Manually Add PC</string>
<!-- Stream settings activity -->
<string name="title_streaming_settings">Streaming Settings</string>
<string name="button_advanced_settings">Advanced Settings</string>
<string name="radio_720p30">720p 30 FPS (Only recommended for poor devices or networks)</string>
<string name="radio_720p60">720p 60 FPS (Recommended for most devices and networks)</string>
<string name="radio_1080p30">1080p 30 FPS (Recommended for most devices if 1080p streaming is desired)</string>
<string name="radio_1080p60">1080p 60 FPS (Requires extremely fast device and network)</string>
<string name="check_stretchToFill">Stretch video to fill screen</string>
<string name="check_enableSops">Allow GFE to modify game settings for optimal streaming</string>
<string name="check_disableToasts">Disable on-screen connection warning messages"</string>
<!-- Advanced settings activity -->
<string name="radio_forceSoftware">Force Software Decoding</string>
<string name="radio_autoSelect">Auto-select Decoder (Recommended)</string>
<string name="radio_forceHardware">Force Hardware Decoding</string>
</resources> </resources>

View File

@ -16,6 +16,8 @@
<!-- Application theme. --> <!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme"> <style name="AppTheme" parent="AppBaseTheme">
<!-- All customizations that are NOT specific to a particular API-level can go here. --> <!-- All customizations that are NOT specific to a particular API-level can go here. -->
<item name="android:windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
</style> </style>
<style name="FullscreenTheme" parent="android:Theme.NoTitleBar"> <style name="FullscreenTheme" parent="android:Theme.NoTitleBar">

View File

@ -28,6 +28,7 @@ import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener; import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.ListView; import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo; import android.widget.AdapterView.AdapterContextMenuInfo;
@ -59,7 +60,10 @@ public class AppView extends Activity {
return; return;
} }
setTitle("App List for "+getIntent().getStringExtra(NAME_EXTRA)); String labelText = "App List for "+getIntent().getStringExtra(NAME_EXTRA);
TextView label = (TextView) findViewById(R.id.appListText);
setTitle(labelText);
label.setText(labelText);
try { try {
ipAddress = InetAddress.getByAddress(address); ipAddress = InetAddress.getByAddress(address);

View File

@ -22,6 +22,7 @@ import android.app.Service;
import android.content.ComponentName; import android.content.ComponentName;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.content.res.Configuration;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder; import android.os.IBinder;
import android.view.ContextMenu; import android.view.ContextMenu;
@ -73,28 +74,27 @@ public class PcView extends Activity {
} }
}; };
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Reinitialize views just in case orientation changed
initializeViews();
}
private final static int APP_LIST_ID = 1; private final static int APP_LIST_ID = 1;
private final static int PAIR_ID = 2; private final static int PAIR_ID = 2;
private final static int UNPAIR_ID = 3; private final static int UNPAIR_ID = 3;
private final static int WOL_ID = 4; private final static int WOL_ID = 4;
private final static int DELETE_ID = 5; private final static int DELETE_ID = 5;
@Override private void initializeViews() {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pc_view); setContentView(R.layout.activity_pc_view);
// Bind to the computer manager service
bindService(new Intent(PcView.this, ComputerManagerService.class), serviceConnection,
Service.BIND_AUTO_CREATE);
// 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); 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.setNotifyOnChange(false);
pcList.setAdapter(pcListAdapter); pcList.setAdapter(pcListAdapter);
pcList.setItemsCanFocus(true); pcList.setItemsCanFocus(true);
pcList.setOnItemClickListener(new OnItemClickListener() { pcList.setOnItemClickListener(new OnItemClickListener() {
@ -134,8 +134,27 @@ public class PcView extends Activity {
} }
}); });
if (pcListAdapter.isEmpty()) {
addListPlaceholder(); addListPlaceholder();
} }
else {
pcListAdapter.notifyDataSetChanged();
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Bind to the computer manager service
bindService(new Intent(PcView.this, ComputerManagerService.class), serviceConnection,
Service.BIND_AUTO_CREATE);
pcListAdapter = new ArrayAdapter<ComputerObject>(this, R.layout.simplerow, R.id.rowTextView);
pcListAdapter.setNotifyOnChange(false);
initializeViews();
}
private void startComputerUpdates() { private void startComputerUpdates() {
if (managerBinder != null) { if (managerBinder != null) {

View File

@ -0,0 +1,6 @@
package com.limelight;
/* This is a dummy class to allow for a separate icon
* and launcher for TV.
*/
public class PcViewTv extends PcView {}

View File

@ -52,16 +52,29 @@ public class ControllerHandler {
ControllerPacket.enableAxisScaling = true; ControllerPacket.enableAxisScaling = true;
} }
private static InputDevice.MotionRange getMotionRangeForJoystickAxis(InputDevice dev, int axis) {
InputDevice.MotionRange range;
// First get the axis for SOURCE_JOYSTICK
range = dev.getMotionRange(axis, InputDevice.SOURCE_JOYSTICK);
if (range == null) {
// Now try the axis for SOURCE_GAMEPAD
range = dev.getMotionRange(axis, InputDevice.SOURCE_GAMEPAD);
}
return range;
}
private ControllerMapping createMappingForDevice(InputDevice dev) { private ControllerMapping createMappingForDevice(InputDevice dev) {
ControllerMapping mapping = new ControllerMapping(); ControllerMapping mapping = new ControllerMapping();
mapping.leftStickXAxis = MotionEvent.AXIS_X; mapping.leftStickXAxis = MotionEvent.AXIS_X;
mapping.leftStickYAxis = MotionEvent.AXIS_Y; mapping.leftStickYAxis = MotionEvent.AXIS_Y;
InputDevice.MotionRange leftTriggerRange = dev.getMotionRange(MotionEvent.AXIS_LTRIGGER); InputDevice.MotionRange leftTriggerRange = getMotionRangeForJoystickAxis(dev, MotionEvent.AXIS_LTRIGGER);
InputDevice.MotionRange rightTriggerRange = dev.getMotionRange(MotionEvent.AXIS_RTRIGGER); InputDevice.MotionRange rightTriggerRange = getMotionRangeForJoystickAxis(dev, MotionEvent.AXIS_RTRIGGER);
InputDevice.MotionRange brakeRange = dev.getMotionRange(MotionEvent.AXIS_BRAKE); InputDevice.MotionRange brakeRange = getMotionRangeForJoystickAxis(dev, MotionEvent.AXIS_BRAKE);
InputDevice.MotionRange gasRange = dev.getMotionRange(MotionEvent.AXIS_GAS); InputDevice.MotionRange gasRange = getMotionRangeForJoystickAxis(dev, MotionEvent.AXIS_GAS);
if (leftTriggerRange != null && rightTriggerRange != null) if (leftTriggerRange != null && rightTriggerRange != null)
{ {
// Some controllers use LTRIGGER and RTRIGGER (like Ouya) // Some controllers use LTRIGGER and RTRIGGER (like Ouya)
@ -76,8 +89,8 @@ public class ControllerHandler {
} }
else else
{ {
InputDevice.MotionRange rxRange = dev.getMotionRange(MotionEvent.AXIS_RX); InputDevice.MotionRange rxRange = getMotionRangeForJoystickAxis(dev, MotionEvent.AXIS_RX);
InputDevice.MotionRange ryRange = dev.getMotionRange(MotionEvent.AXIS_RY); InputDevice.MotionRange ryRange = getMotionRangeForJoystickAxis(dev, MotionEvent.AXIS_RY);
if (rxRange != null && ryRange != null) { if (rxRange != null && ryRange != null) {
String devName = dev.getName(); String devName = dev.getName();
if (devName.contains("Xbox") || devName.contains("XBox") || devName.contains("X-Box")) { if (devName.contains("Xbox") || devName.contains("XBox") || devName.contains("X-Box")) {
@ -89,6 +102,7 @@ public class ControllerHandler {
mapping.leftTriggerAxis = MotionEvent.AXIS_Z; mapping.leftTriggerAxis = MotionEvent.AXIS_Z;
mapping.rightTriggerAxis = MotionEvent.AXIS_RZ; mapping.rightTriggerAxis = MotionEvent.AXIS_RZ;
mapping.triggersIdleNegative = true; mapping.triggersIdleNegative = true;
mapping.isXboxController = true;
} }
else { else {
// DS4 controller uses RX and RY for triggers // DS4 controller uses RX and RY for triggers
@ -102,8 +116,8 @@ public class ControllerHandler {
} }
if (mapping.rightStickXAxis == -1 && mapping.rightStickYAxis == -1) { if (mapping.rightStickXAxis == -1 && mapping.rightStickYAxis == -1) {
InputDevice.MotionRange zRange = dev.getMotionRange(MotionEvent.AXIS_Z); InputDevice.MotionRange zRange = getMotionRangeForJoystickAxis(dev, MotionEvent.AXIS_Z);
InputDevice.MotionRange rzRange = dev.getMotionRange(MotionEvent.AXIS_RZ); InputDevice.MotionRange rzRange = getMotionRangeForJoystickAxis(dev, MotionEvent.AXIS_RZ);
// Most other controllers use Z and RZ for the right stick // Most other controllers use Z and RZ for the right stick
if (zRange != null && rzRange != null) { if (zRange != null && rzRange != null) {
@ -111,8 +125,8 @@ public class ControllerHandler {
mapping.rightStickYAxis = MotionEvent.AXIS_RZ; mapping.rightStickYAxis = MotionEvent.AXIS_RZ;
} }
else { else {
InputDevice.MotionRange rxRange = dev.getMotionRange(MotionEvent.AXIS_RX); InputDevice.MotionRange rxRange = getMotionRangeForJoystickAxis(dev, MotionEvent.AXIS_RX);
InputDevice.MotionRange ryRange = dev.getMotionRange(MotionEvent.AXIS_RY); InputDevice.MotionRange ryRange = getMotionRangeForJoystickAxis(dev, MotionEvent.AXIS_RY);
// Try RX and RY now // Try RX and RY now
if (rxRange != null && ryRange != null) { if (rxRange != null && ryRange != null) {
@ -123,8 +137,8 @@ public class ControllerHandler {
} }
// Some devices have "hats" for d-pads // Some devices have "hats" for d-pads
InputDevice.MotionRange hatXRange = dev.getMotionRange(MotionEvent.AXIS_HAT_X); InputDevice.MotionRange hatXRange = getMotionRangeForJoystickAxis(dev, MotionEvent.AXIS_HAT_X);
InputDevice.MotionRange hatYRange = dev.getMotionRange(MotionEvent.AXIS_HAT_Y); InputDevice.MotionRange hatYRange = getMotionRangeForJoystickAxis(dev, MotionEvent.AXIS_HAT_Y);
if (hatXRange != null && hatYRange != null) { if (hatXRange != null && hatYRange != null) {
mapping.hatXAxis = MotionEvent.AXIS_HAT_X; mapping.hatXAxis = MotionEvent.AXIS_HAT_X;
mapping.hatYAxis = MotionEvent.AXIS_HAT_Y; mapping.hatYAxis = MotionEvent.AXIS_HAT_Y;
@ -134,8 +148,8 @@ public class ControllerHandler {
} }
if (mapping.leftStickXAxis != -1 && mapping.leftStickYAxis != -1) { if (mapping.leftStickXAxis != -1 && mapping.leftStickYAxis != -1) {
InputDevice.MotionRange lsXRange = dev.getMotionRange(mapping.leftStickXAxis); InputDevice.MotionRange lsXRange = getMotionRangeForJoystickAxis(dev, mapping.leftStickXAxis);
InputDevice.MotionRange lsYRange = dev.getMotionRange(mapping.leftStickYAxis); InputDevice.MotionRange lsYRange = getMotionRangeForJoystickAxis(dev, mapping.leftStickYAxis);
if (lsXRange != null && lsYRange != null) { if (lsXRange != null && lsYRange != null) {
// The flat values should never be negative but we'll deal with it if they are // The flat values should never be negative but we'll deal with it if they are
mapping.leftStickDeadzoneRadius = Math.max(Math.abs(lsXRange.getFlat()), mapping.leftStickDeadzoneRadius = Math.max(Math.abs(lsXRange.getFlat()),
@ -152,16 +166,16 @@ public class ControllerHandler {
if (mapping.leftStickDeadzoneRadius < 0.02f) { if (mapping.leftStickDeadzoneRadius < 0.02f) {
mapping.leftStickDeadzoneRadius = 0.20f; mapping.leftStickDeadzoneRadius = 0.20f;
} }
// Check that the deadzone is 12% at minimum // Check that the deadzone is 15% at minimum
else if (mapping.leftStickDeadzoneRadius < 0.12f) { else if (mapping.leftStickDeadzoneRadius < 0.15f) {
mapping.leftStickDeadzoneRadius = 0.12f; mapping.leftStickDeadzoneRadius = 0.15f;
} }
} }
} }
if (mapping.rightStickXAxis != -1 && mapping.rightStickYAxis != -1) { if (mapping.rightStickXAxis != -1 && mapping.rightStickYAxis != -1) {
InputDevice.MotionRange rsXRange = dev.getMotionRange(mapping.rightStickXAxis); InputDevice.MotionRange rsXRange = getMotionRangeForJoystickAxis(dev, mapping.rightStickXAxis);
InputDevice.MotionRange rsYRange = dev.getMotionRange(mapping.rightStickYAxis); InputDevice.MotionRange rsYRange = getMotionRangeForJoystickAxis(dev, mapping.rightStickYAxis);
if (rsXRange != null && rsYRange != null) { if (rsXRange != null && rsYRange != null) {
// The flat values should never be negative but we'll deal with it if they are // The flat values should never be negative but we'll deal with it if they are
mapping.rightStickDeadzoneRadius = Math.max(Math.abs(rsXRange.getFlat()), mapping.rightStickDeadzoneRadius = Math.max(Math.abs(rsXRange.getFlat()),
@ -178,9 +192,9 @@ public class ControllerHandler {
if (mapping.rightStickDeadzoneRadius < 0.02f) { if (mapping.rightStickDeadzoneRadius < 0.02f) {
mapping.rightStickDeadzoneRadius = 0.20f; mapping.rightStickDeadzoneRadius = 0.20f;
} }
// Check that the deadzone is 12% at minimum // Check that the deadzone is 15% at minimum
else if (mapping.rightStickDeadzoneRadius < 0.12f) { else if (mapping.rightStickDeadzoneRadius < 0.15f) {
mapping.rightStickDeadzoneRadius = 0.12f; mapping.rightStickDeadzoneRadius = 0.15f;
} }
} }
} }
@ -214,9 +228,9 @@ public class ControllerHandler {
leftStickX, leftStickY, rightStickX, rightStickY); leftStickX, leftStickY, rightStickX, rightStickY);
} }
private static int handleRemapping(ControllerMapping mapping, int keyCode) { private static int handleRemapping(ControllerMapping mapping, KeyEvent event) {
if (mapping.isDualShock4) { if (mapping.isDualShock4) {
switch (keyCode) { switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_BUTTON_Y: case KeyEvent.KEYCODE_BUTTON_Y:
return KeyEvent.KEYCODE_BUTTON_L1; return KeyEvent.KEYCODE_BUTTON_L1;
@ -255,7 +269,7 @@ public class ControllerHandler {
} }
if (mapping.hatXAxis != -1 && mapping.hatYAxis != -1) { if (mapping.hatXAxis != -1 && mapping.hatYAxis != -1) {
switch (keyCode) { switch (event.getKeyCode()) {
// These are duplicate dpad events for hat input // These are duplicate dpad events for hat input
case KeyEvent.KEYCODE_DPAD_LEFT: case KeyEvent.KEYCODE_DPAD_LEFT:
case KeyEvent.KEYCODE_DPAD_RIGHT: case KeyEvent.KEYCODE_DPAD_RIGHT:
@ -265,8 +279,26 @@ public class ControllerHandler {
return 0; return 0;
} }
} }
else if (mapping.hatXAxis == -1 &&
mapping.hatYAxis == -1 &&
mapping.isXboxController &&
event.getKeyCode() == KeyEvent.KEYCODE_UNKNOWN) {
// If there's not a proper Xbox controller mapping, we'll translate the raw d-pad
// scan codes into proper key codes
switch (event.getScanCode())
{
case 704:
return KeyEvent.KEYCODE_DPAD_LEFT;
case 705:
return KeyEvent.KEYCODE_DPAD_RIGHT;
case 706:
return KeyEvent.KEYCODE_DPAD_UP;
case 707:
return KeyEvent.KEYCODE_DPAD_DOWN;
}
}
return keyCode; return event.getKeyCode();
} }
private Vector2d handleDeadZone(float x, float y, float deadzoneRadius) { private Vector2d handleDeadZone(float x, float y, float deadzoneRadius) {
@ -372,7 +404,7 @@ public class ControllerHandler {
return false; return false;
} }
keyCode = handleRemapping(mapping, keyCode); keyCode = handleRemapping(mapping, event);
if (keyCode == 0) { if (keyCode == 0) {
return true; return true;
} }
@ -495,7 +527,7 @@ public class ControllerHandler {
return false; return false;
} }
keyCode = handleRemapping(mapping, keyCode); keyCode = handleRemapping(mapping, event);
if (keyCode == 0) { if (keyCode == 0) {
return true; return true;
} }
@ -605,5 +637,6 @@ public class ControllerHandler {
public float hatYDeadzone; public float hatYDeadzone;
public boolean isDualShock4; public boolean isDualShock4;
public boolean isXboxController;
} }
} }

View File

@ -32,9 +32,9 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
private MediaCodec videoDecoder; private MediaCodec videoDecoder;
private Thread rendererThread; private Thread rendererThread;
private boolean needsSpsBitstreamFixup; private boolean needsSpsBitstreamFixup;
private boolean needsSpsNumRefFixup;
private VideoDepacketizer depacketizer; private VideoDepacketizer depacketizer;
private boolean adaptivePlayback; private boolean adaptivePlayback;
private int initialWidth, initialHeight;
private long totalTimeMs; private long totalTimeMs;
private long decoderTimeMs; private long decoderTimeMs;
@ -49,7 +49,6 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
public static final List<String> blacklistedDecoderPrefixes; public static final List<String> blacklistedDecoderPrefixes;
public static final List<String> spsFixupBitstreamFixupDecoderPrefixes; public static final List<String> spsFixupBitstreamFixupDecoderPrefixes;
public static final List<String> spsFixupNumRefFixupDecoderPrefixes;
public static final List<String> whitelistedAdaptiveResolutionPrefixes; public static final List<String> whitelistedAdaptiveResolutionPrefixes;
static { static {
@ -68,12 +67,7 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
spsFixupBitstreamFixupDecoderPrefixes = new LinkedList<String>(); spsFixupBitstreamFixupDecoderPrefixes = new LinkedList<String>();
spsFixupBitstreamFixupDecoderPrefixes.add("omx.nvidia"); spsFixupBitstreamFixupDecoderPrefixes.add("omx.nvidia");
spsFixupBitstreamFixupDecoderPrefixes.add("omx.qcom"); spsFixupBitstreamFixupDecoderPrefixes.add("omx.qcom");
spsFixupBitstreamFixupDecoderPrefixes.add("omx.sec"); spsFixupBitstreamFixupDecoderPrefixes.add("omx.mtk");
spsFixupNumRefFixupDecoderPrefixes = new LinkedList<String>();
spsFixupNumRefFixupDecoderPrefixes.add("omx.TI");
spsFixupNumRefFixupDecoderPrefixes.add("omx.qcom");
spsFixupNumRefFixupDecoderPrefixes.add("omx.sec");
whitelistedAdaptiveResolutionPrefixes = new LinkedList<String>(); whitelistedAdaptiveResolutionPrefixes = new LinkedList<String>();
whitelistedAdaptiveResolutionPrefixes.add("omx.nvidia"); whitelistedAdaptiveResolutionPrefixes.add("omx.nvidia");
@ -120,13 +114,9 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
} }
needsSpsBitstreamFixup = isDecoderInList(spsFixupBitstreamFixupDecoderPrefixes, decoderName); needsSpsBitstreamFixup = isDecoderInList(spsFixupBitstreamFixupDecoderPrefixes, decoderName);
needsSpsNumRefFixup = isDecoderInList(spsFixupNumRefFixupDecoderPrefixes, decoderName);
if (needsSpsBitstreamFixup) { if (needsSpsBitstreamFixup) {
LimeLog.info("Decoder "+decoderName+" needs SPS bitstream restrictions fixup"); LimeLog.info("Decoder "+decoderName+" needs SPS bitstream restrictions fixup");
} }
if (needsSpsNumRefFixup) {
LimeLog.info("Decoder "+decoderName+" needs SPS ref num fixup");
}
} }
private static boolean isDecoderInList(List<String> decoderList, String decoderName) { private static boolean isDecoderInList(List<String> decoderList, String decoderName) {
@ -279,6 +269,9 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
@TargetApi(Build.VERSION_CODES.KITKAT) @TargetApi(Build.VERSION_CODES.KITKAT)
@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) {
this.initialWidth = width;
this.initialHeight = height;
if (decoderName == null) { if (decoderName == null) {
LimeLog.severe("No available hardware decoder!"); LimeLog.severe("No available hardware decoder!");
return false; return false;
@ -485,7 +478,6 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
if (header.data[header.offset+4] == 0x67) { if (header.data[header.offset+4] == 0x67) {
numSpsIn++; numSpsIn++;
if (needsSpsBitstreamFixup || needsSpsNumRefFixup) {
ByteBuffer spsBuf = ByteBuffer.wrap(header.data); ByteBuffer spsBuf = ByteBuffer.wrap(header.data);
// Skip to the start of the NALU data // Skip to the start of the NALU data
@ -493,15 +485,18 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
SeqParameterSet sps = SeqParameterSet.read(spsBuf); SeqParameterSet sps = SeqParameterSet.read(spsBuf);
// TI OMAP4 requires a reference frame count of 1 to decode successfully // TI OMAP4 requires a reference frame count of 1 to decode successfully. Exynos 4
if (needsSpsNumRefFixup) { // also requires this fixup.
LimeLog.info("Fixing up num ref frames"); //
// I'm doing this fixup for all devices because I haven't seen any devices that
// this causes issues for. At worst, it seems to do nothing and at best it fixes
// issues with video lag, hangs, and crashes.
LimeLog.info("Patching num_ref_frames in SPS");
sps.num_ref_frames = 1; sps.num_ref_frames = 1;
}
if (needsSpsBitstreamFixup) {
// The SPS that comes in the current H264 bytestream doesn't set bitstream_restriction_flag // The SPS that comes in the current H264 bytestream doesn't set bitstream_restriction_flag
// or max_dec_frame_buffering which increases decoding latency on Tegra. // or max_dec_frame_buffering which increases decoding latency on Tegra.
if (needsSpsBitstreamFixup) {
LimeLog.info("Adding bitstream restrictions"); LimeLog.info("Adding bitstream restrictions");
sps.vuiParams.bitstreamRestriction = new VUIParameters.BitstreamRestriction(); sps.vuiParams.bitstreamRestriction = new VUIParameters.BitstreamRestriction();
@ -530,7 +525,6 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
depacketizer.freeDecodeUnit(decodeUnit); depacketizer.freeDecodeUnit(decodeUnit);
return; return;
}
} else if (header.data[header.offset+4] == 0x68) { } else if (header.data[header.offset+4] == 0x68) {
numPpsIn++; numPpsIn++;
} }
@ -600,6 +594,7 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
String str = ""; String str = "";
str += "Decoder: "+renderer.decoderName+"\n"; str += "Decoder: "+renderer.decoderName+"\n";
str += "Initial video dimensions: "+renderer.initialWidth+"x"+renderer.initialHeight+"\n";
str += "In stats: "+renderer.numSpsIn+", "+renderer.numPpsIn+", "+renderer.numIframeIn+"\n"; str += "In stats: "+renderer.numSpsIn+", "+renderer.numPpsIn+", "+renderer.numIframeIn+"\n";
str += "Total frames: "+renderer.totalFrames+"\n"; str += "Total frames: "+renderer.totalFrames+"\n";

View File

@ -1,47 +0,0 @@
package com.limelight.utils;
public class Vector2d {
private float x;
private float y;
private double magnitude;
public static final Vector2d ZERO = new Vector2d();
public Vector2d() {
initialize(0, 0);
}
public void initialize(float x, float y) {
this.x = x;
this.y = y;
this.magnitude = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
}
public double getMagnitude() {
return magnitude;
}
public void getNormalized(Vector2d vector) {
vector.initialize((float)(x / magnitude), (float)(y / magnitude));
}
public void scalarMultiply(double factor) {
initialize((float)(x * factor), (float)(y * factor));
}
public void setX(float x) {
initialize(x, this.y);
}
public void setY(float y) {
initialize(this.x, y);
}
public float getX() {
return x;
}
public float getY() {
return y;
}
}