From d8b1f9efccc09597fb426e39c11eba51aa3c028f Mon Sep 17 00:00:00 2001 From: Oliver Woodman Date: Mon, 26 Oct 2015 14:53:27 +0000 Subject: [PATCH] Add API to get the version of native decoders Add API to get the version of underlying libvpx and libopus decoders. Also update the demo app to show the version in the UI. --- .../exoplayer/demo/vp9opus/VideoPlayer.java | 43 ++++++++++++++----- .../main/res/layout/activity_video_player.xml | 26 ++--------- .../src/main/res/values/strings.xml | 6 +++ .../ext/opus/LibopusAudioTrackRenderer.java | 9 ++++ .../exoplayer/ext/opus/OpusDecoder.java | 5 +++ extensions/opus/src/main/jni/opus_jni.cc | 4 ++ .../ext/vp9/LibvpxVideoTrackRenderer.java | 9 ++++ .../android/exoplayer/ext/vp9/VpxDecoder.java | 5 +++ extensions/vp9/src/main/jni/vpx_jni.cc | 4 ++ 9 files changed, 78 insertions(+), 33 deletions(-) diff --git a/demo_misc/vp9_opus_sw/src/main/java/com/google/android/exoplayer/demo/vp9opus/VideoPlayer.java b/demo_misc/vp9_opus_sw/src/main/java/com/google/android/exoplayer/demo/vp9opus/VideoPlayer.java index b5adada15d..4733fc0f90 100644 --- a/demo_misc/vp9_opus_sw/src/main/java/com/google/android/exoplayer/demo/vp9opus/VideoPlayer.java +++ b/demo_misc/vp9_opus_sw/src/main/java/com/google/android/exoplayer/demo/vp9opus/VideoPlayer.java @@ -73,7 +73,8 @@ public class VideoPlayer extends Activity implements OnClickListener, private SurfaceView surfaceView; private VpxVideoSurfaceView vpxVideoSurfaceView; private TextView debugInfoView; - private TextView playerStateView; + private String debugInfo; + private String playerState; @Override public void onCreate(Bundle savedInstanceState) { @@ -106,7 +107,10 @@ public class VideoPlayer extends Activity implements OnClickListener, surfaceView = (SurfaceView) findViewById(R.id.surface_view); vpxVideoSurfaceView = (VpxVideoSurfaceView) findViewById(R.id.vpx_surface_view); debugInfoView = (TextView) findViewById(R.id.debug_info); - playerStateView = (TextView) findViewById(R.id.player_state); + debugInfo = ""; + playerState = ""; + filename = ""; + updateDebugInfoTextView(); // Set the buttons' onclick listeners. ((Button) findViewById(R.id.choose_file)).setOnClickListener(this); @@ -115,7 +119,6 @@ public class VideoPlayer extends Activity implements OnClickListener, // In case of DASH, start playback right away. if (isDash) { findViewById(R.id.buttons).setVisibility(View.GONE); - ((TextView) findViewById(R.id.filename)).setVisibility(View.GONE); startDashPlayback(); } } @@ -146,8 +149,7 @@ public class VideoPlayer extends Activity implements OnClickListener, case FILE_PICKER_REQUEST: if (resultCode == Activity.RESULT_OK) { filename = data.getStringExtra(FilePickerActivity.FILENAME_EXTRA_ID); - ((TextView) findViewById(R.id.filename)).setText( - getString(R.string.current_path, filename)); + updateDebugInfoTextView(); } break; } @@ -186,7 +188,8 @@ public class VideoPlayer extends Activity implements OnClickListener, } private void startDashPlayback() { - playerStateView.setText("Initializing"); + playerState = "Initializing"; + updateDebugInfoTextView(); final String userAgent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like" + " Gecko) Chrome/38.0.2125.104 Safari/537.36"; DashRendererBuilder rendererBuilder = new DashRendererBuilder(manifestUrl, userAgent, this); @@ -213,7 +216,8 @@ public class VideoPlayer extends Activity implements OnClickListener, @Override public void onVideoSizeChanged(int width, int height) { videoFrame.setAspectRatio(height == 0 ? 1 : (width * 1.0f) / height); - debugInfoView.setText("Video: " + width + " x " + height); + debugInfo = "Video: " + width + " x " + height; + updateDebugInfoTextView(); } @Override @@ -223,12 +227,12 @@ public class VideoPlayer extends Activity implements OnClickListener, @Override public void onDecoderError(VpxDecoderException e) { - debugInfoView.setText("Libvpx decode failure. Giving up."); + debugInfo = "Libvpx decode failure. Giving up."; + updateDebugInfoTextView(); } @Override public void onPlayerStateChanged(boolean playWhenReady, int state) { - String playerState = ""; switch (player.getPlaybackState()) { case ExoPlayer.STATE_BUFFERING: playerState = "buffering"; @@ -246,12 +250,13 @@ public class VideoPlayer extends Activity implements OnClickListener, playerState = "ready"; break; } - playerStateView.setText("Player State: " + playerState); + updateDebugInfoTextView(); } @Override public void onPlayerError(ExoPlaybackException exception) { - debugInfoView.setText("Exoplayer Playback error. Giving up."); + debugInfo = "Exoplayer Playback error. Giving up."; + updateDebugInfoTextView(); // TODO: show a retry button here. } @@ -282,4 +287,20 @@ public class VideoPlayer extends Activity implements OnClickListener, } } + private void updateDebugInfoTextView() { + StringBuilder debugInfoText = new StringBuilder(); + debugInfoText.append( + getString(R.string.libvpx_version, LibvpxVideoTrackRenderer.getLibvpxVersion())); + debugInfoText.append(" "); + debugInfoText.append( + getString(R.string.libopus_version, LibopusAudioTrackRenderer.getLibopusVersion())); + debugInfoText.append("\n"); + debugInfoText.append(getString(R.string.current_path, filename)); + debugInfoText.append(" "); + debugInfoText.append(debugInfo); + debugInfoText.append(" "); + debugInfoText.append(playerState); + debugInfoView.setText(debugInfoText.toString()); + } + } diff --git a/demo_misc/vp9_opus_sw/src/main/res/layout/activity_video_player.xml b/demo_misc/vp9_opus_sw/src/main/res/layout/activity_video_player.xml index f6f841b014..c6b2aea44d 100644 --- a/demo_misc/vp9_opus_sw/src/main/res/layout/activity_video_player.xml +++ b/demo_misc/vp9_opus_sw/src/main/res/layout/activity_video_player.xml @@ -64,28 +64,10 @@ - - - - - - - - - + diff --git a/demo_misc/vp9_opus_sw/src/main/res/values/strings.xml b/demo_misc/vp9_opus_sw/src/main/res/values/strings.xml index 45c9da513c..6be85034cf 100644 --- a/demo_misc/vp9_opus_sw/src/main/res/values/strings.xml +++ b/demo_misc/vp9_opus_sw/src/main/res/values/strings.xml @@ -22,5 +22,11 @@ Path: %1$s + + Libvpx: %1$s + + + Libopus: %1$s + diff --git a/extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/LibopusAudioTrackRenderer.java b/extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/LibopusAudioTrackRenderer.java index e8fd8c8306..5465d5e4c1 100644 --- a/extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/LibopusAudioTrackRenderer.java +++ b/extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/LibopusAudioTrackRenderer.java @@ -119,6 +119,15 @@ public final class LibopusAudioTrackRenderer extends SampleSourceTrackRenderer formatHolder = new MediaFormatHolder(); } + /** + * Get the version of underlying libopus library. + * + * @return version of the underlying libopus library. + */ + public static String getLibopusVersion() { + return OpusDecoder.getLibopusVersion(); + } + @Override protected MediaClock getMediaClock() { return this; diff --git a/extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/OpusDecoder.java b/extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/OpusDecoder.java index 6de3481c2a..7a5e2b8096 100644 --- a/extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/OpusDecoder.java +++ b/extensions/opus/src/main/java/com/google/android/exoplayer/ext/opus/OpusDecoder.java @@ -81,6 +81,11 @@ import java.nio.ByteBuffer; opusReset(nativeDecoderContext); } + /** + * Returns the version string of the underlying libopus decoder. + */ + public static native String getLibopusVersion(); + private native long opusInit(int sampleRate, int channelCount, int numStreams, int numCoupled, int gain, byte[] streamMap); private native int opusDecode(long decoder, ByteBuffer inputBuffer, int inputSize, diff --git a/extensions/opus/src/main/jni/opus_jni.cc b/extensions/opus/src/main/jni/opus_jni.cc index 0259592c94..e4ee1c60e3 100644 --- a/extensions/opus/src/main/jni/opus_jni.cc +++ b/extensions/opus/src/main/jni/opus_jni.cc @@ -91,6 +91,10 @@ FUNC(void, opusReset, jlong jDecoder) { opus_multistream_decoder_ctl(decoder, OPUS_RESET_STATE); } +FUNC(jstring, getLibopusVersion) { + return env->NewStringUTF(opus_get_version_string()); +} + FUNC(jstring, opusGetErrorMessage, jint errorCode) { return env->NewStringUTF(opus_strerror(errorCode)); } diff --git a/extensions/vp9/src/main/java/com/google/android/exoplayer/ext/vp9/LibvpxVideoTrackRenderer.java b/extensions/vp9/src/main/java/com/google/android/exoplayer/ext/vp9/LibvpxVideoTrackRenderer.java index d19a0992b9..a87a5e2590 100644 --- a/extensions/vp9/src/main/java/com/google/android/exoplayer/ext/vp9/LibvpxVideoTrackRenderer.java +++ b/extensions/vp9/src/main/java/com/google/android/exoplayer/ext/vp9/LibvpxVideoTrackRenderer.java @@ -150,6 +150,15 @@ public final class LibvpxVideoTrackRenderer extends SampleSourceTrackRenderer { formatHolder = new MediaFormatHolder(); } + /** + * Get the version of underlying libvpx library. + * + * @return version of the underlying libvpx library. + */ + public static String getLibvpxVersion() { + return VpxDecoder.getLibvpxVersion(); + } + @Override protected boolean handlesTrack(MediaFormat mediaFormat) { return MimeTypes.VIDEO_VP9.equalsIgnoreCase(mediaFormat.mimeType); diff --git a/extensions/vp9/src/main/java/com/google/android/exoplayer/ext/vp9/VpxDecoder.java b/extensions/vp9/src/main/java/com/google/android/exoplayer/ext/vp9/VpxDecoder.java index 3a65c9cf77..05cc243401 100644 --- a/extensions/vp9/src/main/java/com/google/android/exoplayer/ext/vp9/VpxDecoder.java +++ b/extensions/vp9/src/main/java/com/google/android/exoplayer/ext/vp9/VpxDecoder.java @@ -69,6 +69,11 @@ import java.nio.ByteBuffer; vpxClose(vpxDecContext); } + /** + * Returns the version string of the underlying libvpx decoder. + */ + public static native String getLibvpxVersion(); + private native long vpxInit(); private native long vpxClose(long context); private native long vpxDecode(long context, ByteBuffer encoded, int length); diff --git a/extensions/vp9/src/main/jni/vpx_jni.cc b/extensions/vp9/src/main/jni/vpx_jni.cc index 21a845d779..edaa53383c 100644 --- a/extensions/vp9/src/main/jni/vpx_jni.cc +++ b/extensions/vp9/src/main/jni/vpx_jni.cc @@ -143,6 +143,10 @@ FUNC(jint, vpxGetFrame, jlong jContext, jobject jOutputBuffer, jboolean isRGB) { return 0; } +FUNC(jstring, getLibvpxVersion) { + return env->NewStringUTF(vpx_codec_version_str()); +} + FUNC(jstring, vpxGetErrorMessage, jlong jContext) { vpx_codec_ctx_t* const context = reinterpret_cast(jContext); return env->NewStringUTF(vpx_codec_error(context));