mirror of
https://github.com/moonlight-stream/moonlight-android.git
synced 2026-06-17 14:21:08 +00:00
Add UI elements and backend code for manually overriding the default decoder choice. Redraw at the specified refresh rate.
This commit is contained in:
@@ -35,16 +35,20 @@ or to a theme attribute in the form "<code>?[<i>package</i>:][<i>type</i>:]<i>na
|
|||||||
public static final int ic_launcher=0x7f020000;
|
public static final int ic_launcher=0x7f020000;
|
||||||
}
|
}
|
||||||
public static final class id {
|
public static final class id {
|
||||||
|
public static final int autoDec=0x7f080005;
|
||||||
|
public static final int hardwareDec=0x7f080006;
|
||||||
public static final int hostTextView=0x7f080000;
|
public static final int hostTextView=0x7f080000;
|
||||||
public static final int imageQualityCheckbox=0x7f080002;
|
public static final int imageQualityCheckbox=0x7f08000a;
|
||||||
public static final int pairButton=0x7f080003;
|
public static final int pairButton=0x7f080002;
|
||||||
public static final int res1080pSelected=0x7f080006;
|
public static final int res1080pSelected=0x7f08000c;
|
||||||
public static final int res720pSelected=0x7f080005;
|
public static final int res720pSelected=0x7f08000b;
|
||||||
public static final int resolutionGroup=0x7f080004;
|
public static final int resolutionGroup=0x7f080007;
|
||||||
public static final int rr30Selected=0x7f080007;
|
public static final int rr30Selected=0x7f080008;
|
||||||
public static final int rr60Selected=0x7f080008;
|
public static final int rr60Selected=0x7f080009;
|
||||||
|
public static final int rrGroup=0x7f080003;
|
||||||
|
public static final int softwareDec=0x7f080004;
|
||||||
public static final int statusButton=0x7f080001;
|
public static final int statusButton=0x7f080001;
|
||||||
public static final int surfaceView=0x7f080009;
|
public static final int surfaceView=0x7f08000d;
|
||||||
}
|
}
|
||||||
public static final class layout {
|
public static final class layout {
|
||||||
public static final int activity_connection=0x7f030000;
|
public static final int activity_connection=0x7f030000;
|
||||||
|
|||||||
Binary file not shown.
@@ -32,14 +32,6 @@
|
|||||||
|
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<CheckBox
|
|
||||||
android:id="@+id/imageQualityCheckbox"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignLeft="@+id/hostTextView"
|
|
||||||
android:layout_below="@+id/pairButton"
|
|
||||||
android:text="Prefer image quality over performance" />
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/pairButton"
|
android:id="@+id/pairButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@@ -48,36 +40,84 @@
|
|||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:text="Pair with PC" />
|
android:text="Pair with PC" />
|
||||||
|
|
||||||
<RadioGroup android:id="@+id/resolutionGroup"
|
<RadioGroup
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_alignLeft="@+id/rrGroup"
|
||||||
android:layout_below="@+id/imageQualityCheckbox"
|
android:layout_below="@+id/rrGroup"
|
||||||
|
android:layout_marginTop="25dp"
|
||||||
|
android:orientation="vertical" >
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/softwareDec"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Force Software Decoding" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/autoDec"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Auto-select Decoder" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/hardwareDec"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Force Hardware Decoding" />
|
||||||
|
</RadioGroup>
|
||||||
|
|
||||||
|
<RadioGroup
|
||||||
|
android:id="@+id/rrGroup"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignLeft="@+id/resolutionGroup"
|
||||||
|
android:layout_below="@+id/resolutionGroup"
|
||||||
|
android:layout_marginTop="15dp"
|
||||||
android:orientation="horizontal" >
|
android:orientation="horizontal" >
|
||||||
<RadioButton android:id="@+id/res720pSelected"
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rr30Selected"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="30 FPS" />
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/rr60Selected"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="60 FPS (may increase lag)" />
|
||||||
|
</RadioGroup>
|
||||||
|
|
||||||
|
<RadioGroup
|
||||||
|
android:id="@+id/resolutionGroup"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignLeft="@+id/imageQualityCheckbox"
|
||||||
|
android:layout_below="@+id/imageQualityCheckbox"
|
||||||
|
android:layout_marginTop="17dp"
|
||||||
|
android:orientation="horizontal" >
|
||||||
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/res720pSelected"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="720p" />
|
android:text="720p" />
|
||||||
<RadioButton android:id="@+id/res1080pSelected"
|
|
||||||
|
<RadioButton
|
||||||
|
android:id="@+id/res1080pSelected"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="1080p (may increase lag)" />
|
android:text="1080p (may increase lag)" />
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
|
|
||||||
<RadioGroup
|
<CheckBox
|
||||||
android:layout_width="fill_parent"
|
android:id="@+id/imageQualityCheckbox"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@+id/pairButton"
|
||||||
android:layout_centerHorizontal="true"
|
android:layout_centerHorizontal="true"
|
||||||
android:layout_below="@+id/resolutionGroup"
|
android:layout_marginTop="16dp"
|
||||||
android:orientation="horizontal">
|
android:text="Prefer image quality over performance" />
|
||||||
<RadioButton android:id="@+id/rr30Selected"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="30 FPS"/>
|
|
||||||
<RadioButton android:id="@+id/rr60Selected"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="60 FPS"/>
|
|
||||||
</RadioGroup>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ public class Connection extends Activity {
|
|||||||
private SharedPreferences prefs;
|
private SharedPreferences prefs;
|
||||||
private CheckBox qualityCheckbox;
|
private CheckBox qualityCheckbox;
|
||||||
private RadioButton rbutton720p, rbutton1080p, rbutton30fps, rbutton60fps;
|
private RadioButton rbutton720p, rbutton1080p, rbutton30fps, rbutton60fps;
|
||||||
|
private RadioButton forceSoftDec, autoDec, forceHardDec;
|
||||||
|
|
||||||
private static final String DEFAULT_HOST = "";
|
private static final String DEFAULT_HOST = "";
|
||||||
public static final String HOST_KEY = "hostText";
|
public static final String HOST_KEY = "hostText";
|
||||||
@@ -61,6 +62,9 @@ public class Connection extends Activity {
|
|||||||
this.rbutton1080p = (RadioButton) findViewById(R.id.res1080pSelected);
|
this.rbutton1080p = (RadioButton) findViewById(R.id.res1080pSelected);
|
||||||
this.rbutton30fps = (RadioButton) findViewById(R.id.rr30Selected);
|
this.rbutton30fps = (RadioButton) findViewById(R.id.rr30Selected);
|
||||||
this.rbutton60fps = (RadioButton) findViewById(R.id.rr60Selected);
|
this.rbutton60fps = (RadioButton) findViewById(R.id.rr60Selected);
|
||||||
|
this.forceSoftDec = (RadioButton) findViewById(R.id.softwareDec);
|
||||||
|
this.autoDec = (RadioButton) findViewById(R.id.autoDec);
|
||||||
|
this.forceHardDec = (RadioButton) findViewById(R.id.hardwareDec);
|
||||||
|
|
||||||
prefs = getSharedPreferences(Game.PREFS_FILE_NAME, Context.MODE_MULTI_PROCESS);
|
prefs = getSharedPreferences(Game.PREFS_FILE_NAME, Context.MODE_MULTI_PROCESS);
|
||||||
this.hostText.setText(prefs.getString(Connection.HOST_KEY, Connection.DEFAULT_HOST));
|
this.hostText.setText(prefs.getString(Connection.HOST_KEY, Connection.DEFAULT_HOST));
|
||||||
@@ -84,6 +88,24 @@ public class Connection extends Activity {
|
|||||||
rbutton30fps.setChecked(false);
|
rbutton30fps.setChecked(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (prefs.getInt(Game.DECODER_PREF_STRING, Game.DEFAULT_DECODER)) {
|
||||||
|
case Game.FORCE_SOFTWARE_DECODER:
|
||||||
|
forceSoftDec.setChecked(true);
|
||||||
|
autoDec.setChecked(false);
|
||||||
|
forceHardDec.setChecked(false);
|
||||||
|
break;
|
||||||
|
case Game.AUTOSELECT_DECODER:
|
||||||
|
forceSoftDec.setChecked(false);
|
||||||
|
autoDec.setChecked(true);
|
||||||
|
forceHardDec.setChecked(false);
|
||||||
|
break;
|
||||||
|
case Game.FORCE_HARDWARE_DECODER:
|
||||||
|
forceSoftDec.setChecked(false);
|
||||||
|
autoDec.setChecked(false);
|
||||||
|
forceHardDec.setChecked(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
OnCheckedChangeListener occl = new OnCheckedChangeListener() {
|
OnCheckedChangeListener occl = new OnCheckedChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(CompoundButton buttonView,
|
public void onCheckedChanged(CompoundButton buttonView,
|
||||||
@@ -107,12 +129,24 @@ public class Connection extends Activity {
|
|||||||
prefs.edit().putInt(Game.WIDTH_PREF_STRING, 1920).
|
prefs.edit().putInt(Game.WIDTH_PREF_STRING, 1920).
|
||||||
putInt(Game.HEIGHT_PREF_STRING, 1080).commit();
|
putInt(Game.HEIGHT_PREF_STRING, 1080).commit();
|
||||||
}
|
}
|
||||||
|
else if (buttonView == forceSoftDec) {
|
||||||
|
prefs.edit().putInt(Game.DECODER_PREF_STRING, Game.FORCE_SOFTWARE_DECODER).commit();
|
||||||
|
}
|
||||||
|
else if (buttonView == forceHardDec) {
|
||||||
|
prefs.edit().putInt(Game.DECODER_PREF_STRING, Game.FORCE_HARDWARE_DECODER).commit();
|
||||||
|
}
|
||||||
|
else if (buttonView == autoDec) {
|
||||||
|
prefs.edit().putInt(Game.DECODER_PREF_STRING, Game.AUTOSELECT_DECODER).commit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
rbutton720p.setOnCheckedChangeListener(occl);
|
rbutton720p.setOnCheckedChangeListener(occl);
|
||||||
rbutton1080p.setOnCheckedChangeListener(occl);
|
rbutton1080p.setOnCheckedChangeListener(occl);
|
||||||
rbutton30fps.setOnCheckedChangeListener(occl);
|
rbutton30fps.setOnCheckedChangeListener(occl);
|
||||||
rbutton60fps.setOnCheckedChangeListener(occl);
|
rbutton60fps.setOnCheckedChangeListener(occl);
|
||||||
|
forceSoftDec.setOnCheckedChangeListener(occl);
|
||||||
|
forceHardDec.setOnCheckedChangeListener(occl);
|
||||||
|
autoDec.setOnCheckedChangeListener(occl);
|
||||||
|
|
||||||
this.qualityCheckbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
this.qualityCheckbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.limelight;
|
package com.limelight;
|
||||||
|
|
||||||
import com.limelight.binding.PlatformBinding;
|
import com.limelight.binding.PlatformBinding;
|
||||||
|
import com.limelight.binding.video.ConfigurableDecoderRenderer;
|
||||||
import com.limelight.nvstream.NvConnection;
|
import com.limelight.nvstream.NvConnection;
|
||||||
import com.limelight.nvstream.NvConnectionListener;
|
import com.limelight.nvstream.NvConnectionListener;
|
||||||
import com.limelight.nvstream.StreamConfiguration;
|
import com.limelight.nvstream.StreamConfiguration;
|
||||||
@@ -52,10 +53,16 @@ public class Game extends Activity implements OnGenericMotionListener, OnTouchLi
|
|||||||
public static final String WIDTH_PREF_STRING = "Width";
|
public static final String WIDTH_PREF_STRING = "Width";
|
||||||
public static final String HEIGHT_PREF_STRING = "Height";
|
public static final String HEIGHT_PREF_STRING = "Height";
|
||||||
public static final String REFRESH_RATE_PREF_STRING = "RefreshRate";
|
public static final String REFRESH_RATE_PREF_STRING = "RefreshRate";
|
||||||
|
public static final String DECODER_PREF_STRING = "Decoder";
|
||||||
|
|
||||||
public static final int DEFAULT_WIDTH = 1280;
|
public static final int DEFAULT_WIDTH = 1280;
|
||||||
public static final int DEFAULT_HEIGHT = 720;
|
public static final int DEFAULT_HEIGHT = 720;
|
||||||
public static final int DEFAULT_REFRESH_RATE = 30;
|
public static final int DEFAULT_REFRESH_RATE = 30;
|
||||||
|
public static final int DEFAULT_DECODER = 0;
|
||||||
|
|
||||||
|
public static final int FORCE_HARDWARE_DECODER = -1;
|
||||||
|
public static final int AUTOSELECT_DECODER = 0;
|
||||||
|
public static final int FORCE_SOFTWARE_DECODER = 1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -91,6 +98,17 @@ public class Game extends Activity implements OnGenericMotionListener, OnTouchLi
|
|||||||
if (prefs.getBoolean(QUALITY_PREF_STRING, false)) {
|
if (prefs.getBoolean(QUALITY_PREF_STRING, false)) {
|
||||||
drFlags |= VideoDecoderRenderer.FLAG_PREFER_QUALITY;
|
drFlags |= VideoDecoderRenderer.FLAG_PREFER_QUALITY;
|
||||||
}
|
}
|
||||||
|
switch (prefs.getInt(Game.DECODER_PREF_STRING, Game.DEFAULT_DECODER)) {
|
||||||
|
case Game.FORCE_SOFTWARE_DECODER:
|
||||||
|
drFlags |= VideoDecoderRenderer.FLAG_FORCE_SOFTWARE_DECODING;
|
||||||
|
break;
|
||||||
|
case Game.AUTOSELECT_DECODER:
|
||||||
|
break;
|
||||||
|
case Game.FORCE_HARDWARE_DECODER:
|
||||||
|
drFlags |= VideoDecoderRenderer.FLAG_FORCE_HARDWARE_DECODING;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
int width, height, refreshRate;
|
int width, height, refreshRate;
|
||||||
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);
|
||||||
@@ -104,7 +122,7 @@ public class Game extends Activity implements OnGenericMotionListener, OnTouchLi
|
|||||||
conn = new NvConnection(Game.this.getIntent().getStringExtra("host"), Game.this,
|
conn = new NvConnection(Game.this.getIntent().getStringExtra("host"), Game.this,
|
||||||
new StreamConfiguration(width, height, refreshRate));
|
new StreamConfiguration(width, height, refreshRate));
|
||||||
conn.start(PlatformBinding.getDeviceName(), sv.getHolder(), drFlags,
|
conn.start(PlatformBinding.getDeviceName(), sv.getHolder(), drFlags,
|
||||||
PlatformBinding.getAudioRenderer(), PlatformBinding.chooseDecoderRenderer());
|
PlatformBinding.getAudioRenderer(), new ConfigurableDecoderRenderer());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkDataConnection()
|
private void checkDataConnection()
|
||||||
|
|||||||
@@ -1,29 +1,9 @@
|
|||||||
package com.limelight.binding;
|
package com.limelight.binding;
|
||||||
|
|
||||||
import android.os.Build;
|
|
||||||
|
|
||||||
import com.limelight.binding.audio.AndroidAudioRenderer;
|
import com.limelight.binding.audio.AndroidAudioRenderer;
|
||||||
import com.limelight.binding.video.AndroidCpuDecoderRenderer;
|
|
||||||
import com.limelight.binding.video.MediaCodecDecoderRenderer;
|
|
||||||
import com.limelight.nvstream.av.audio.AudioRenderer;
|
import com.limelight.nvstream.av.audio.AudioRenderer;
|
||||||
import com.limelight.nvstream.av.video.VideoDecoderRenderer;
|
|
||||||
|
|
||||||
public class PlatformBinding {
|
public class PlatformBinding {
|
||||||
public static VideoDecoderRenderer chooseDecoderRenderer() {
|
|
||||||
if (Build.HARDWARE.equals("goldfish")) {
|
|
||||||
// Emulator - don't render video (it's slow!)
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
else if (MediaCodecDecoderRenderer.findSafeDecoder() != null) {
|
|
||||||
// Hardware decoding
|
|
||||||
return new MediaCodecDecoderRenderer();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Software decoding
|
|
||||||
return new AndroidCpuDecoderRenderer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getDeviceName() {
|
public static String getDeviceName() {
|
||||||
String deviceName = android.os.Build.MODEL;
|
String deviceName = android.os.Build.MODEL;
|
||||||
deviceName = deviceName.replace(" ", "");
|
deviceName = deviceName.replace(" ", "");
|
||||||
|
|||||||
@@ -78,8 +78,8 @@ public class AndroidCpuDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setup(int width, int height, Object renderTarget, int drFlags) {
|
public void setup(int width, int height, int redrawRate, Object renderTarget, int drFlags) {
|
||||||
this.targetFps = 30;
|
this.targetFps = redrawRate;
|
||||||
|
|
||||||
int perfLevel = findOptimalPerformanceLevel();
|
int perfLevel = findOptimalPerformanceLevel();
|
||||||
int threadCount;
|
int threadCount;
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.limelight.binding.video;
|
||||||
|
|
||||||
|
import com.limelight.nvstream.av.DecodeUnit;
|
||||||
|
import com.limelight.nvstream.av.video.VideoDecoderRenderer;
|
||||||
|
|
||||||
|
public class ConfigurableDecoderRenderer implements VideoDecoderRenderer {
|
||||||
|
|
||||||
|
private VideoDecoderRenderer decoderRenderer;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void release() {
|
||||||
|
decoderRenderer.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setup(int width, int height, int redrawRate, Object renderTarget, int drFlags) {
|
||||||
|
if ((drFlags & VideoDecoderRenderer.FLAG_FORCE_HARDWARE_DECODING) != 0 ||
|
||||||
|
((drFlags & VideoDecoderRenderer.FLAG_FORCE_SOFTWARE_DECODING) == 0 &&
|
||||||
|
MediaCodecDecoderRenderer.findSafeDecoder() != null)) {
|
||||||
|
decoderRenderer = new MediaCodecDecoderRenderer();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
decoderRenderer = new AndroidCpuDecoderRenderer();
|
||||||
|
}
|
||||||
|
decoderRenderer.setup(width, height, redrawRate, renderTarget, drFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
decoderRenderer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
decoderRenderer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean submitDecodeUnit(DecodeUnit du) {
|
||||||
|
return decoderRenderer.submitDecodeUnit(du);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
private ByteBuffer[] videoDecoderInputBuffers;
|
private ByteBuffer[] videoDecoderInputBuffers;
|
||||||
private MediaCodec videoDecoder;
|
private MediaCodec videoDecoder;
|
||||||
private Thread rendererThread;
|
private Thread rendererThread;
|
||||||
|
private int redrawRate;
|
||||||
|
|
||||||
public static final List<String> blacklistedDecoderPrefixes;
|
public static final List<String> blacklistedDecoderPrefixes;
|
||||||
|
|
||||||
@@ -71,14 +72,20 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setup(int width, int height, Object renderTarget, int drFlags) {
|
public void setup(int width, int height, int redrawRate, Object renderTarget, int drFlags) {
|
||||||
videoDecoder = MediaCodec.createByCodecName(findSafeDecoder().getName());
|
this.redrawRate = redrawRate;
|
||||||
|
|
||||||
|
MediaCodecInfo safeDecoder = findSafeDecoder();
|
||||||
|
if (safeDecoder != null) {
|
||||||
|
videoDecoder = MediaCodec.createByCodecName(safeDecoder.getName());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
videoDecoder = MediaCodec.createDecoderByType("video/avc");
|
||||||
|
}
|
||||||
|
|
||||||
MediaFormat videoFormat = MediaFormat.createVideoFormat("video/avc", width, height);
|
MediaFormat videoFormat = MediaFormat.createVideoFormat("video/avc", width, height);
|
||||||
|
|
||||||
videoDecoder.configure(videoFormat, ((SurfaceHolder)renderTarget).getSurface(), null, 0);
|
videoDecoder.configure(videoFormat, ((SurfaceHolder)renderTarget).getSurface(), null, 0);
|
||||||
|
|
||||||
videoDecoder.setVideoScalingMode(MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT);
|
videoDecoder.setVideoScalingMode(MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT);
|
||||||
|
|
||||||
videoDecoder.start();
|
videoDecoder.start();
|
||||||
|
|
||||||
videoDecoderInputBuffers = videoDecoder.getInputBuffers();
|
videoDecoderInputBuffers = videoDecoder.getInputBuffers();
|
||||||
@@ -112,7 +119,7 @@ public class MediaCodecDecoderRenderer implements VideoDecoderRenderer {
|
|||||||
|
|
||||||
if (currentTimeUs() >= nextFrameTimeUs) {
|
if (currentTimeUs() >= nextFrameTimeUs) {
|
||||||
render = true;
|
render = true;
|
||||||
nextFrameTimeUs = computePresentationTime(60);
|
nextFrameTimeUs = computePresentationTime(redrawRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
videoDecoder.releaseOutputBuffer(outIndex, render);
|
videoDecoder.releaseOutputBuffer(outIndex, render);
|
||||||
|
|||||||
Reference in New Issue
Block a user