diff --git a/src/video_engine/main/test/android_test/jni/org_webrtc_videoengineapp_vie_android_java_api.h b/src/video_engine/main/test/android_test/jni/org_webrtc_videoengineapp_vie_android_java_api.h
index 28c2cd529..f2beb409a 100644
--- a/src/video_engine/main/test/android_test/jni/org_webrtc_videoengineapp_vie_android_java_api.h
+++ b/src/video_engine/main/test/android_test/jni/org_webrtc_videoengineapp_vie_android_java_api.h
@@ -219,6 +219,22 @@ JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_EnablePL
JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_SetCallback
(JNIEnv *, jobject, jint, jobject);
+/*
+ * Class: org_webrtc_videoengineapp_ViEAndroidJavaAPI
+ * Method: StartIncomingRTPDump
+ * Signature: (ILjava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_StartIncomingRTPDump
+ (JNIEnv *, jobject, jint, jstring);
+
+/*
+ * Class: org_webrtc_videoengineapp_ViEAndroidJavaAPI
+ * Method: StopIncomingRTPDump
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_StopIncomingRTPDump
+ (JNIEnv *, jobject, jint);
+
/*
* Class: org_webrtc_videoengineapp_ViEAndroidJavaAPI
* Method: VoE_Create
@@ -429,6 +445,38 @@ JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VoE_1Set
JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VoE_1SetNSStatus
(JNIEnv *, jobject, jboolean);
+/*
+ * Class: org_webrtc_videoengineapp_ViEAndroidJavaAPI
+ * Method: VoE_StartDebugRecording
+ * Signature: (Ljava/lang/String)I
+ */
+JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VoE_1StartDebugRecording
+ (JNIEnv *, jobject, jstring);
+
+/*
+ * Class: org_webrtc_videoengineapp_ViEAndroidJavaAPI
+ * Method: VoE_StopDebugRecording
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VoE_1StopDebugRecording
+ (JNIEnv *, jobject);
+
+/*
+ * Class: org_webrtc_videoengineapp_ViEAndroidJavaAPI
+ * Method: VoE_StartIncomingRTPDump
+ * Signature: (ILjava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VoE_1StartIncomingRTPDump
+ (JNIEnv *, jobject, jint, jstring);
+
+/*
+ * Class: org_webrtc_videoengineapp_ViEAndroidJavaAPI
+ * Method: VoE_StopIncomingRTPDump
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VoE_1StopIncomingRTPDump
+ (JNIEnv *, jobject, jint);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/video_engine/main/test/android_test/jni/vie_android_java_api.cc b/src/video_engine/main/test/android_test/jni/vie_android_java_api.cc
index 93e1e4486..4b44aa337 100644
--- a/src/video_engine/main/test/android_test/jni/vie_android_java_api.cc
+++ b/src/video_engine/main/test/android_test/jni/vie_android_java_api.cc
@@ -21,6 +21,7 @@
#include "voe_audio_processing.h"
#include "voe_volume_control.h"
#include "voe_hardware.h"
+#include "voe_rtp_rtcp.h"
#include "vie_base.h"
#include "vie_codec.h"
@@ -76,6 +77,14 @@
return -1; \
}
+#define VALIDATE_RTP_POINTER \
+ if (!voeData.rtp) \
+ { \
+ __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \
+ "rtp pointer doesn't exist"); \
+ return -1; \
+ }
+
using namespace webrtc;
//Forward declaration.
@@ -94,6 +103,7 @@ typedef struct
VoEAudioProcessing* apm;
VoEVolumeControl* volume;
VoEHardware* hardware;
+ VoERTP_RTCP* rtp;
JavaVM* jvm;
} VoiceEngineData;
@@ -1031,6 +1041,57 @@ JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_SetCallb
return 0;
}
+/*
+ * Class: org_webrtc_videoengineapp_ViEAndroidJavaAPI
+ * Method: StartIncomingRTPDump
+ * Signature: (ILjava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_StartIncomingRTPDump(
+ JNIEnv* env,
+ jobject,
+ jint channel,
+ jstring filename) {
+ if (NULL == vieData.rtp) {
+ __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+ "video RTP_RTCP interface is null");
+ return -1;
+ }
+ const char* file = env->GetStringUTFChars(filename, NULL);
+ if (!file) {
+ __android_log_print(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+ "Video StartRTPDump file name error");
+ return -1;
+ }
+ if (vieData.rtp->StartRTPDump(channel, file, kRtpIncoming) != 0) {
+ __android_log_print(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+ "Video StartRTPDump error");
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Class: org_webrtc_videoengineapp_ViEAndroidJavaAPI
+ * Method: StopIncomingRTPDump
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_StopIncomingRTPDump(
+ JNIEnv *,
+ jobject,
+ jint channel) {
+ if (NULL == vieData.rtp) {
+ __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+ "video RTP_RTCP interface is null");
+ return -1;
+ }
+ if (vieData.rtp->StopRTPDump(channel, kRtpIncoming) != 0) {
+ __android_log_print(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+ "Video StopRTPDump error");
+ return -1;
+ }
+ return 0;
+}
+
//
// VoiceEngine API wrapper functions
//
@@ -1569,6 +1630,91 @@ JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VoE_1Set
return 0;
}
+/*
+ * Class: org_webrtc_videoengineapp_ViEAndroidJavaAPI
+ * Method: VoE_StartDebugRecording
+ * Signature: (Ljava/lang/String)I
+ */
+JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VoE_1StartDebugRecording(
+ JNIEnv* env,
+ jobject,
+ jstring filename) {
+ VALIDATE_APM_POINTER;
+
+ const char* file = env->GetStringUTFChars(filename, NULL);
+ if (!file) {
+ __android_log_print(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+ "Voice StartDebugRecording file error");
+ return -1;
+ }
+ if (voeData.apm->StartDebugRecording(file) != 0) {
+ __android_log_print(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+ "Voice StartDebugRecording error");
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Class: org_webrtc_videoengineapp_ViEAndroidJavaAPI
+ * Method: VoE_StopDebugRecording
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VoE_1StopDebugRecording(
+ JNIEnv *,
+ jobject) {
+ VALIDATE_APM_POINTER;
+ if (voeData.apm->StopDebugRecording() < 0) {
+ __android_log_print(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+ "Voice StopDebugRecording error");
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Class: org_webrtc_videoengineapp_ViEAndroidJavaAPI
+ * Method: VoE_StartIncomingRTPDump
+ * Signature: (ILjava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VoE_1StartIncomingRTPDump(
+ JNIEnv* env,
+ jobject,
+ jint channel,
+ jstring filename) {
+ VALIDATE_RTP_POINTER;
+ const char* file = env->GetStringUTFChars(filename, NULL);
+ if (!file) {
+ __android_log_print(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+ "Voice StartRTPDump file error");
+ return -1;
+ }
+ if (voeData.rtp->StartRTPDump(channel, file, kRtpIncoming) != 0) {
+ __android_log_print(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+ "Voice StartRTPDump error");
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Class: org_webrtc_videoengineapp_ViEAndroidJavaAPI
+ * Method: VoE_StopRTPDump
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_org_webrtc_videoengineapp_ViEAndroidJavaAPI_VoE_1StopRTPDump(
+ JNIEnv *,
+ jobject,
+ jint channel) {
+ VALIDATE_RTP_POINTER;
+ if (voeData.rtp->StopRTPDump(channel) < 0) {
+ __android_log_print(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+ "Voice StopRTPDump error");
+ return -1;
+ }
+ return 0;
+}
+
//
// local function
//
@@ -1633,6 +1779,14 @@ bool VE_GetSubApis() {
getOK = false;
}
+ // RTP
+ voeData.rtp = VoERTP_RTCP::GetInterface(voeData.ve);
+ if (!voeData.rtp) {
+ __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+ "Get rtp sub-API failed");
+ getOK = false;
+ }
+
return getOK;
}
@@ -1724,5 +1878,16 @@ bool VE_ReleaseSubApis() {
}
}
+ if (voeData.rtp) {
+ if (0 != voeData.rtp->Release()) {
+ __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
+ "Release rtp sub-API failed");
+ releaseOK = false;
+ }
+ else {
+ voeData.rtp = NULL;
+ }
+ }
+
return releaseOK;
}
diff --git a/src/video_engine/main/test/android_test/res/layout/aconfig.xml b/src/video_engine/main/test/android_test/res/layout/aconfig.xml
index df6016f5a..5f995c6fb 100644
--- a/src/video_engine/main/test/android_test/res/layout/aconfig.xml
+++ b/src/video_engine/main/test/android_test/res/layout/aconfig.xml
@@ -71,6 +71,17 @@
android:id="@+id/cbSpeaker"
android:text="@string/speaker">
+
+
+
+
+
diff --git a/src/video_engine/main/test/android_test/res/layout/vconfig.xml b/src/video_engine/main/test/android_test/res/layout/vconfig.xml
index 5270c1080..d72f25720 100644
--- a/src/video_engine/main/test/android_test/res/layout/vconfig.xml
+++ b/src/video_engine/main/test/android_test/res/layout/vconfig.xml
@@ -62,6 +62,12 @@
android:layout_height="wrap_content"
android:id="@+id/cbNack"
android:text="@string/nack">
-
+
+
+
+
diff --git a/src/video_engine/main/test/android_test/res/values/strings.xml b/src/video_engine/main/test/android_test/res/values/strings.xml
index 796491b69..82760b0a3 100644
--- a/src/video_engine/main/test/android_test/res/values/strings.xml
+++ b/src/video_engine/main/test/android_test/res/values/strings.xml
@@ -33,6 +33,8 @@
StopCall
Exit
Speaker
+APMRecord
+rtpdump
SurfaceView
OpenGL
diff --git a/src/video_engine/main/test/android_test/src/org/webrtc/videoengineapp/ViEAndroidJavaAPI.java b/src/video_engine/main/test/android_test/src/org/webrtc/videoengineapp/ViEAndroidJavaAPI.java
index f4a8c7293..9fd060eeb 100644
--- a/src/video_engine/main/test/android_test/src/org/webrtc/videoengineapp/ViEAndroidJavaAPI.java
+++ b/src/video_engine/main/test/android_test/src/org/webrtc/videoengineapp/ViEAndroidJavaAPI.java
@@ -81,6 +81,9 @@ public class ViEAndroidJavaAPI {
// Enable stats callback
public native int SetCallback(int channel, IViEAndroidCallback callback);
+ public native int StartIncomingRTPDump(int channel, String file);
+ public native int StopIncomingRTPDump(int channel);
+
// Voice Engine API
// Create and Delete functions
public native boolean VoE_Create();
@@ -132,8 +135,12 @@ public class ViEAndroidJavaAPI {
public native String[] VoE_GetCodecs();
public native int VoE_SetSendCodec(int channel, int index);
- //VE funtions
+ //VoiceEngine funtions
public native int VoE_SetECStatus(boolean enable);
public native int VoE_SetAGCStatus(boolean enable);
public native int VoE_SetNSStatus(boolean enable);
+ public native int VoE_StartDebugRecording(String file);
+ public native int VoE_StopDebugRecording();
+ public native int VoE_StartIncomingRTPDump(int channel, String file);
+ public native int VoE_StopIncomingRTPDump(int channel);
}
diff --git a/src/video_engine/main/test/android_test/src/org/webrtc/videoengineapp/WebRTCDemo.java b/src/video_engine/main/test/android_test/src/org/webrtc/videoengineapp/WebRTCDemo.java
index 0db9fa88b..b5bbc93b6 100644
--- a/src/video_engine/main/test/android_test/src/org/webrtc/videoengineapp/WebRTCDemo.java
+++ b/src/video_engine/main/test/android_test/src/org/webrtc/videoengineapp/WebRTCDemo.java
@@ -10,6 +10,7 @@
package org.webrtc.videoengineapp;
+import java.io.File;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
@@ -34,6 +35,7 @@ import android.graphics.Rect;
import android.hardware.SensorManager;
import android.media.AudioManager;
import android.os.Bundle;
+import android.os.Environment;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
@@ -136,6 +138,7 @@ public class WebRTCDemo extends TabActivity implements IViEAndroidCallback,
private int destinationPortVideo = 11111;
private CheckBox cbEnableNack;
private boolean enableNack = false;
+ private CheckBox cbEnableVideoRTPDump;
// Audio settings
private Spinner spVoiceCodecType;
@@ -152,6 +155,8 @@ public class WebRTCDemo extends TabActivity implements IViEAndroidCallback,
private boolean enableAECM = false;
private CheckBox cbEnableNS;
private boolean enableNS = false;
+ private CheckBox cbEnableDebugAPM;
+ private CheckBox cbEnableVoiceRTPDump;
// Stats variables
private int frameRateI;
@@ -160,9 +165,13 @@ public class WebRTCDemo extends TabActivity implements IViEAndroidCallback,
private int frameRateO;
private int bitRateO;
+ // Variable for storing variables
+ private String webrtcName = "/webrtc";
+ private String webrtcDebugDir = null;
+
private WakeLock wakeLock;
- private boolean usingFrontCamera = false;
+ private boolean usingFrontCamera = true;
private String[] mVideoCodecsStrings = null;
private String[] mVideoCodecsSizeStrings = { "176x144", "320x240",
@@ -261,6 +270,18 @@ public class WebRTCDemo extends TabActivity implements IViEAndroidCallback,
};
orientationListener.enable ();
+ // Create a folder named webrtc in /scard for debugging
+ webrtcDebugDir = Environment.getExternalStorageDirectory().toString() +
+ webrtcName;
+ File webrtcDir = new File(webrtcDebugDir);
+ if (!webrtcDir.exists() && webrtcDir.mkdir() == false) {
+ Log.v(TAG, "Failed to create " + webrtcDebugDir);
+ }
+ else if (!webrtcDir.isDirectory()) {
+ Log.v(TAG, webrtcDebugDir + " exists but not a folder");
+ webrtcDebugDir = null;
+ }
+
StartMain();
return;
}
@@ -494,6 +515,15 @@ public class WebRTCDemo extends TabActivity implements IViEAndroidCallback,
cbEnableNS = (CheckBox) findViewById(R.id.cbNoiseSuppression);
cbEnableNS.setChecked(enableNS);
+ cbEnableDebugAPM = (CheckBox) findViewById(R.id.cbDebugRecording);
+ cbEnableDebugAPM.setChecked(false); // Disable APM debugging by default
+
+ cbEnableVideoRTPDump = (CheckBox) findViewById(R.id.cbVideoRTPDump);
+ cbEnableVideoRTPDump.setChecked(false); // Disable Video RTP Dump
+
+ cbEnableVoiceRTPDump = (CheckBox) findViewById(R.id.cbVoiceRTPDump);
+ cbEnableVoiceRTPDump.setChecked(false); // Disable Voice RTP Dump
+
etRemoteIp.setOnClickListener(this);
cbLoopback.setOnClickListener(this);
cbStats.setOnClickListener(this);
@@ -502,6 +532,9 @@ public class WebRTCDemo extends TabActivity implements IViEAndroidCallback,
cbEnableAECM.setOnClickListener(this);
cbEnableAGC.setOnClickListener(this);
cbEnableNS.setOnClickListener(this);
+ cbEnableDebugAPM.setOnClickListener(this);
+ cbEnableVideoRTPDump.setOnClickListener(this);
+ cbEnableVoiceRTPDump.setOnClickListener(this);
if (loopbackMode) {
remoteIp = LOOPBACK_IP;
@@ -807,6 +840,42 @@ public class WebRTCDemo extends TabActivity implements IViEAndroidCallback,
RouteAudio(enableSpeaker);
}
break;
+ case R.id.cbDebugRecording:
+ if(voERunning && webrtcDebugDir != null) {
+ if (cbEnableDebugAPM.isChecked() ) {
+ ViEAndroidAPI.VoE_StartDebugRecording(
+ webrtcDebugDir + String.format("/apm_%d.dat",
+ System.currentTimeMillis()));
+ }
+ else {
+ ViEAndroidAPI.VoE_StopDebugRecording();
+ }
+ }
+ break;
+ case R.id.cbVoiceRTPDump:
+ if(voERunning && webrtcDebugDir != null) {
+ if (cbEnableVoiceRTPDump.isChecked() ) {
+ ViEAndroidAPI.VoE_StartIncomingRTPDump(channel,
+ webrtcDebugDir + String.format("/voe_%d.rtp",
+ System.currentTimeMillis()));
+ }
+ else {
+ ViEAndroidAPI.VoE_StopIncomingRTPDump(channel);
+ }
+ }
+ break;
+ case R.id.cbVideoRTPDump:
+ if(viERunning && webrtcDebugDir != null) {
+ if (cbEnableVideoRTPDump.isChecked() ) {
+ ViEAndroidAPI.StartIncomingRTPDump(channel,
+ webrtcDebugDir + String.format("/vie_%d.rtp",
+ System.currentTimeMillis()));
+ }
+ else {
+ ViEAndroidAPI.StopIncomingRTPDump(channel);
+ }
+ }
+ break;
case R.id.cbAutoGainControl:
enableAGC=cbEnableAGC.isChecked();
if(voERunning) {