diff --git a/talk/app/webrtc/java/jni/peerconnection_jni.cc b/talk/app/webrtc/java/jni/peerconnection_jni.cc index c15d28f71b..8eb5ff0426 100644 --- a/talk/app/webrtc/java/jni/peerconnection_jni.cc +++ b/talk/app/webrtc/java/jni/peerconnection_jni.cc @@ -81,8 +81,10 @@ #include "webrtc/base/logging.h" #include "webrtc/base/messagequeue.h" #include "webrtc/base/ssladapter.h" +#include "webrtc/base/stringutils.h" #include "webrtc/common_video/interface/texture_video_frame.h" #include "webrtc/modules/video_coding/codecs/interface/video_codec_interface.h" +#include "webrtc/system_wrappers/interface/field_trial_default.h" #include "webrtc/system_wrappers/interface/trace.h" #include "webrtc/video_engine/include/vie_base.h" #include "webrtc/voice_engine/include/voe_base.h" @@ -160,6 +162,9 @@ static pthread_once_t g_jni_ptr_once = PTHREAD_ONCE_INIT; // were attached by the JVM because of a Java->native call. static pthread_key_t g_jni_ptr; +// Field trials initialization string +static char *field_trials_init_string = NULL; + #if defined(ANDROID) && !defined(WEBRTC_CHROMIUM_BUILD) // Set in PeerConnectionFactory_initializeAndroidGlobals(). static bool factory_static_initialized = false; @@ -2837,6 +2842,21 @@ JOW(jboolean, PeerConnectionFactory_initializeAndroidGlobals)( } #endif // defined(ANDROID) && !defined(WEBRTC_CHROMIUM_BUILD) +JOW(void, PeerConnectionFactory_initializeFieldTrials)( + JNIEnv* jni, jclass, jstring j_trials_init_string) { + field_trials_init_string = NULL; + if (j_trials_init_string != NULL) { + const char* init_string = + jni->GetStringUTFChars(j_trials_init_string, NULL); + int init_string_length = jni->GetStringUTFLength(j_trials_init_string); + field_trials_init_string = new char[init_string_length + 1]; + rtc::strcpyn(field_trials_init_string, init_string_length + 1, init_string); + jni->ReleaseStringUTFChars(j_trials_init_string, init_string); + LOG(LS_INFO) << "initializeFieldTrials: " << field_trials_init_string ; + } + webrtc::field_trial::InitFieldTrialsFromString(field_trials_init_string); +} + // Helper struct for working around the fact that CreatePeerConnectionFactory() // comes in two flavors: either entirely automagical (constructing its own // threads and deleting them on teardown, but no external codec factory support) @@ -2898,6 +2918,11 @@ JOW(jlong, PeerConnectionFactory_nativeCreatePeerConnectionFactory)( JOW(void, PeerConnectionFactory_freeFactory)(JNIEnv*, jclass, jlong j_p) { delete reinterpret_cast(j_p); + if (field_trials_init_string) { + webrtc::field_trial::InitFieldTrialsFromString(NULL); + delete field_trials_init_string; + field_trials_init_string = NULL; + } webrtc::Trace::ReturnTrace(); } diff --git a/talk/app/webrtc/java/src/org/webrtc/PeerConnectionFactory.java b/talk/app/webrtc/java/src/org/webrtc/PeerConnectionFactory.java index 14fcdf9a30..3d2ec5f742 100644 --- a/talk/app/webrtc/java/src/org/webrtc/PeerConnectionFactory.java +++ b/talk/app/webrtc/java/src/org/webrtc/PeerConnectionFactory.java @@ -53,6 +53,10 @@ public class PeerConnectionFactory { Object context, boolean initializeAudio, boolean initializeVideo, boolean vp8HwAcceleration, Object renderEGLContext); + // Field trial initialization. Must be called before PeerConnectionFactory + // is created. + public static native void initializeFieldTrials(String fieldTrialsInitString); + public PeerConnectionFactory() { nativeFactory = nativeCreatePeerConnectionFactory(); if (nativeFactory == 0) { @@ -60,7 +64,6 @@ public class PeerConnectionFactory { } } - public PeerConnection createPeerConnection( List iceServers, MediaConstraints constraints, diff --git a/talk/app/webrtc/java/src/org/webrtc/VideoRenderer.java b/talk/app/webrtc/java/src/org/webrtc/VideoRenderer.java index 82b900203d..2dc9279ecf 100644 --- a/talk/app/webrtc/java/src/org/webrtc/VideoRenderer.java +++ b/talk/app/webrtc/java/src/org/webrtc/VideoRenderer.java @@ -28,7 +28,6 @@ package org.webrtc; import java.nio.ByteBuffer; -import java.util.Arrays; /** * Java version of VideoRendererInterface. In addition to allowing clients to diff --git a/talk/examples/android/res/values/arrays.xml b/talk/examples/android/res/values/arrays.xml index 057a033813..d6ec4d2522 100644 --- a/talk/examples/android/res/values/arrays.xml +++ b/talk/examples/android/res/values/arrays.xml @@ -25,4 +25,9 @@ Manual + + VP8 + VP9 + + diff --git a/talk/examples/android/res/values/strings.xml b/talk/examples/android/res/values/strings.xml index a1eea4b3e3..e63769286f 100644 --- a/talk/examples/android/res/values/strings.xml +++ b/talk/examples/android/res/values/strings.xml @@ -52,9 +52,14 @@ Enter video encoder start bitrate in kbps. 1000 + videocodec_preference + Default video codec. + Select default video codec. + VP8 + hwcodec_preference - VP8 hardware acceleration. - Use VP8 VP8 hardware accelerated codec (if available). + Video codec hardware acceleration. + Use hardware accelerated video codec (if available). true Enabled diff --git a/talk/examples/android/res/xml/preferences.xml b/talk/examples/android/res/xml/preferences.xml index 4ff79390bb..e491077108 100644 --- a/talk/examples/android/res/xml/preferences.xml +++ b/talk/examples/android/res/xml/preferences.xml @@ -31,6 +31,14 @@ android:defaultValue="@string/pref_startbitratevalue_default" android:dialogTitle="@string/pref_startbitratevalue_dlg" /> + + + diff --git a/talk/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java b/talk/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java index d027ae3805..4705df655f 100644 --- a/talk/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java +++ b/talk/examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java @@ -34,7 +34,6 @@ import android.app.AlertDialog; import android.app.Fragment; import android.content.DialogInterface; import android.content.Intent; -import android.content.pm.ActivityInfo; import android.graphics.Color; import android.net.Uri; import android.opengl.GLSurfaceView; @@ -93,7 +92,8 @@ public class AppRTCDemoActivity extends Activity private boolean activityRunning; private int runTimeMs; private int startBitrate; - private boolean hwCodec; + private String videoCodec; + private boolean hwCodecAcceleration; private boolean iceConnected; private boolean isError; @@ -216,7 +216,13 @@ public class AppRTCDemoActivity extends Activity ConnectActivity.EXTRA_CMDLINE, false); runTimeMs = intent.getIntExtra(ConnectActivity.EXTRA_RUNTIME, 0); startBitrate = intent.getIntExtra(ConnectActivity.EXTRA_BITRATE, 0); - hwCodec = intent.getBooleanExtra(ConnectActivity.EXTRA_HWCODEC, true); + if (intent.hasExtra(ConnectActivity.EXTRA_VIDEOCODEC)) { + videoCodec = intent.getStringExtra(ConnectActivity.EXTRA_VIDEOCODEC); + } else { + videoCodec = PeerConnectionClient.VIDEO_CODEC_VP8; // use VP8 by default. + } + hwCodecAcceleration = intent.getBooleanExtra( + ConnectActivity.EXTRA_HWCODEC, true); if (url != null) { if (loopback || (roomName != null && !roomName.equals(""))) { @@ -269,14 +275,14 @@ public class AppRTCDemoActivity extends Activity // Create peer connection factory when EGL context is ready. private void createPeerConnectionFactory() { - final AppRTCDemoActivity thisCopy = this; runOnUiThread(new Runnable() { @Override public void run() { if (pc == null) { pc = new PeerConnectionClient(); - pc.createPeerConnectionFactory( - thisCopy, hwCodec, VideoRendererGui.getEGLContext(), thisCopy); + pc.createPeerConnectionFactory(AppRTCDemoActivity.this, + videoCodec, hwCodecAcceleration, + VideoRendererGui.getEGLContext(), AppRTCDemoActivity.this); } if (signalingParameters != null) { Log.w(TAG, "EGL context is ready after room connection."); @@ -499,11 +505,6 @@ public class AppRTCDemoActivity extends Activity logAndToast("Creating peer connection..."); pc.createPeerConnection( localRender, remoteRender, signalingParameters, startBitrate); - if (pc.isHDVideo()) { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); - } else { - setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); - } // Schedule statistics display. final Runnable repeatedStatsLogger = new Runnable() { @@ -533,7 +534,8 @@ public class AppRTCDemoActivity extends Activity } }, null); if (!success) { - Log.e(TAG, "getStats() return false!"); + Log.w(TAG, "getStats() return false!"); + videoView.postDelayed(runnableThis, 1000); } } }; diff --git a/talk/examples/android/src/org/appspot/apprtc/ConnectActivity.java b/talk/examples/android/src/org/appspot/apprtc/ConnectActivity.java index 26a1422d5d..1f90f54e42 100644 --- a/talk/examples/android/src/org/appspot/apprtc/ConnectActivity.java +++ b/talk/examples/android/src/org/appspot/apprtc/ConnectActivity.java @@ -67,6 +67,7 @@ public class ConnectActivity extends Activity { public static final String EXTRA_CMDLINE = "org.appspot.apprtc.CMDLINE"; public static final String EXTRA_RUNTIME = "org.appspot.apprtc.RUNTIME"; public static final String EXTRA_BITRATE = "org.appspot.apprtc.BITRATE"; + public static final String EXTRA_VIDEOCODEC = "org.appspot.apprtc.VIDEOCODEC"; public static final String EXTRA_HWCODEC = "org.appspot.apprtc.HWCODEC"; private static final String TAG = "ConnectActivity"; private static final int CONNECTION_REQUEST = 1; @@ -83,7 +84,8 @@ public class ConnectActivity extends Activity { private String keyprefFps; private String keyprefBitrateType; private String keyprefBitrateValue; - private String keyprefHwCodec; + private String keyprefVideoCodec; + private String keyprefHwCodecAcceleration; private String keyprefCpuUsageDetection; private String keyprefRoomServerUrl; private String keyprefRoom; @@ -102,7 +104,8 @@ public class ConnectActivity extends Activity { keyprefFps = getString(R.string.pref_fps_key); keyprefBitrateType = getString(R.string.pref_startbitrate_key); keyprefBitrateValue = getString(R.string.pref_startbitratevalue_key); - keyprefHwCodec = getString(R.string.pref_hwcodec_key); + keyprefVideoCodec = getString(R.string.pref_videocodec_key); + keyprefHwCodecAcceleration = getString(R.string.pref_hwcodec_key); keyprefCpuUsageDetection = getString(R.string.pref_cpu_usage_detection_key); keyprefRoomServerUrl = getString(R.string.pref_room_server_url_key); keyprefRoom = getString(R.string.pref_room_key); @@ -256,8 +259,12 @@ public class ConnectActivity extends Activity { getString(R.string.pref_room_server_url_default)); url = WebSocketRTCClient.getGAEConnectionUrl(url, roomName); + // Get default video codec. + String videoCodec = sharedPref.getString(keyprefVideoCodec, + getString(R.string.pref_videocodec_default)); + // Check HW codec flag. - boolean hwCodec = sharedPref.getBoolean(keyprefHwCodec, + boolean hwCodec = sharedPref.getBoolean(keyprefHwCodecAcceleration, Boolean.valueOf(getString(R.string.pref_hwcodec_default))); // Add video resolution constraints. @@ -345,6 +352,7 @@ public class ConnectActivity extends Activity { intent.putExtra(EXTRA_CMDLINE, commandLineRun); intent.putExtra(EXTRA_RUNTIME, runTimeMs); intent.putExtra(EXTRA_BITRATE, startBitrate); + intent.putExtra(EXTRA_VIDEOCODEC, videoCodec); intent.putExtra(EXTRA_HWCODEC, hwCodec); startActivityForResult(intent, CONNECTION_REQUEST); } diff --git a/talk/examples/android/src/org/appspot/apprtc/PeerConnectionClient.java b/talk/examples/android/src/org/appspot/apprtc/PeerConnectionClient.java index b15e041b5c..11676c9f08 100644 --- a/talk/examples/android/src/org/appspot/apprtc/PeerConnectionClient.java +++ b/talk/examples/android/src/org/appspot/apprtc/PeerConnectionClient.java @@ -37,7 +37,6 @@ import android.util.Log; import org.webrtc.DataChannel; import org.webrtc.IceCandidate; import org.webrtc.MediaConstraints; -import org.webrtc.MediaConstraints.KeyValuePair; import org.webrtc.MediaStream; import org.webrtc.MediaStreamTrack; import org.webrtc.PeerConnection; @@ -64,6 +63,9 @@ import java.util.regex.Pattern; public class PeerConnectionClient { private static final String TAG = "PCRTCClient"; private static final boolean PREFER_ISAC = false; + public static final String VIDEO_CODEC_VP8 = "VP8"; + public static final String VIDEO_CODEC_VP9 = "VP9"; + private static final String FIELD_TRIAL_VP9 = "WebRTC-SupportVP9/Enabled/"; public static final String VIDEO_TRACK_ID = "ARDAMSv0"; public static final String AUDIO_TRACK_ID = "ARDAMSa0"; @@ -134,7 +136,8 @@ public class PeerConnectionClient { public void createPeerConnectionFactory( final Context context, - final boolean vp8HwAcceleration, + final String videoCodec, + final boolean videoCodecHwAcceleration, final EGLContext renderEGLContext, final PeerConnectionEvents events) { this.events = events; @@ -143,7 +146,7 @@ public class PeerConnectionClient { @Override public void run() { createPeerConnectionFactoryInternal( - context, vp8HwAcceleration, renderEGLContext); + context, videoCodec, videoCodecHwAcceleration, renderEGLContext); } }); } @@ -177,13 +180,19 @@ public class PeerConnectionClient { private void createPeerConnectionFactoryInternal( Context context, - boolean vp8HwAcceleration, + String videoCodec, + boolean videoCodecHwAcceleration, EGLContext renderEGLContext) { Log.d(TAG, "Create peer connection factory with EGLContext " + renderEGLContext); isError = false; + if (videoCodec.equals(VIDEO_CODEC_VP9)) { + PeerConnectionFactory.initializeFieldTrials(FIELD_TRIAL_VP9); + } else { + PeerConnectionFactory.initializeFieldTrials(null); + } if (!PeerConnectionFactory.initializeAndroidGlobals( - context, true, true, vp8HwAcceleration, renderEGLContext)) { + context, true, true, videoCodecHwAcceleration, renderEGLContext)) { events.onPeerConnectionError("Failed to initializeAndroidGlobals"); } factory = new PeerConnectionFactory(); @@ -252,35 +261,6 @@ public class PeerConnectionClient { events.onPeerConnectionClosed(); } - public boolean isHDVideo() { - if (signalingParameters.videoConstraints == null) { - return false; - } - int minWidth = 0; - int minHeight = 0; - for (KeyValuePair keyValuePair : - signalingParameters.videoConstraints.mandatory) { - if (keyValuePair.getKey().equals("minWidth")) { - try { - minWidth = Integer.parseInt(keyValuePair.getValue()); - } catch (NumberFormatException e) { - Log.e(TAG, "Can not parse video width from video constraints"); - } - } else if (keyValuePair.getKey().equals("minHeight")) { - try { - minHeight = Integer.parseInt(keyValuePair.getValue()); - } catch (NumberFormatException e) { - Log.e(TAG, "Can not parse video height from video constraints"); - } - } - } - if (minWidth * minHeight >= 1280 * 720) { - return true; - } else { - return false; - } - } - public boolean getStats(StatsObserver observer, MediaStreamTrack track) { if (pc != null && !isError) { return pc.getStats(observer, track); diff --git a/talk/examples/android/src/org/appspot/apprtc/RoomParametersFetcher.java b/talk/examples/android/src/org/appspot/apprtc/RoomParametersFetcher.java index 0362ca4087..4c26e07dc1 100644 --- a/talk/examples/android/src/org/appspot/apprtc/RoomParametersFetcher.java +++ b/talk/examples/android/src/org/appspot/apprtc/RoomParametersFetcher.java @@ -56,7 +56,6 @@ public class RoomParametersFetcher { private static final String TAG = "RoomRTCClient"; private final RoomParametersFetcherEvents events; private final boolean loopback; - private final String registerUrl; private AsyncHttpURLConnection httpConnection; /** @@ -79,7 +78,6 @@ public class RoomParametersFetcher { final RoomParametersFetcherEvents events) { Log.d(TAG, "Connecting to room: " + registerUrl); this.loopback = loopback; - this.registerUrl = registerUrl; this.events = events; httpConnection = new AsyncHttpURLConnection("POST", registerUrl, null, diff --git a/talk/examples/android/src/org/appspot/apprtc/SettingsActivity.java b/talk/examples/android/src/org/appspot/apprtc/SettingsActivity.java index 63f01e47ae..3d68cf7c0a 100644 --- a/talk/examples/android/src/org/appspot/apprtc/SettingsActivity.java +++ b/talk/examples/android/src/org/appspot/apprtc/SettingsActivity.java @@ -43,9 +43,9 @@ public class SettingsActivity extends Activity private String keyprefFps; private String keyprefStartBitrateType; private String keyprefStartBitrateValue; + private String keyPrefVideoCodec; private String keyprefHwCodec; private String keyprefCpuUsageDetection; - private String keyprefSignaling; private String keyPrefRoomServerUrl; @Override @@ -55,6 +55,7 @@ public class SettingsActivity extends Activity keyprefFps = getString(R.string.pref_fps_key); keyprefStartBitrateType = getString(R.string.pref_startbitrate_key); keyprefStartBitrateValue = getString(R.string.pref_startbitratevalue_key); + keyPrefVideoCodec = getString(R.string.pref_videocodec_key); keyprefHwCodec = getString(R.string.pref_hwcodec_key); keyprefCpuUsageDetection = getString(R.string.pref_cpu_usage_detection_key); keyPrefRoomServerUrl = getString(R.string.pref_room_server_url_key); @@ -76,12 +77,12 @@ public class SettingsActivity extends Activity updateSummary(sharedPreferences, keyprefResolution); updateSummary(sharedPreferences, keyprefFps); updateSummary(sharedPreferences, keyprefStartBitrateType); - updateSummary(sharedPreferences, keyPrefRoomServerUrl); updateSummaryBitrate(sharedPreferences, keyprefStartBitrateValue); setBitrateEnable(sharedPreferences); + updateSummary(sharedPreferences, keyPrefVideoCodec); updateSummaryB(sharedPreferences, keyprefHwCodec); updateSummaryB(sharedPreferences, keyprefCpuUsageDetection); - updateSummaryB(sharedPreferences, keyprefSignaling); + updateSummary(sharedPreferences, keyPrefRoomServerUrl); } @Override @@ -98,12 +99,13 @@ public class SettingsActivity extends Activity if (key.equals(keyprefResolution) || key.equals(keyprefFps) || key.equals(keyprefStartBitrateType) - || key.equals(keyPrefRoomServerUrl)) { + || key.equals(keyPrefRoomServerUrl) + || key.equals(keyPrefVideoCodec)) { updateSummary(sharedPreferences, key); } else if (key.equals(keyprefStartBitrateValue)) { updateSummaryBitrate(sharedPreferences, key); } else if (key.equals(keyprefCpuUsageDetection) - || key.equals(keyprefHwCodec) || key.equals(keyprefSignaling)) { + || key.equals(keyprefHwCodec)) { updateSummaryB(sharedPreferences, key); } if (key.equals(keyprefStartBitrateType)) { diff --git a/talk/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java b/talk/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java index 135f02a141..cb8e76cea4 100644 --- a/talk/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java +++ b/talk/examples/androidtests/src/org/appspot/apprtc/test/PeerConnectionClientTest.java @@ -99,7 +99,7 @@ public class PeerConnectionClientTest extends InstrumentationTestCase } public synchronized int getWidth() { return width; } - public synchronized int getHeight() { return width; } + public synchronized int getHeight() { return height; } public synchronized boolean setSizeCalledBeforeRenderFrame() { return setSizeCalledBeforeRenderFrame; } @@ -232,7 +232,7 @@ public class PeerConnectionClientTest extends InstrumentationTestCase PeerConnectionClient client = new PeerConnectionClient(); client.createPeerConnectionFactory( - getInstrumentation().getContext(), true, null, this); + getInstrumentation().getContext(), "VP8", true, null, this); client.createPeerConnection( localRenderer, remoteRenderer, signalingParameters, 1000); client.createOffer();