diff options
author | Liong Sauw Ming <ming@teluu.com> | 2015-03-18 12:02:51 +0000 |
---|---|---|
committer | Liong Sauw Ming <ming@teluu.com> | 2015-03-18 12:02:51 +0000 |
commit | d1a26ccd59251d2e42edd4019fad40e87b1365fc (patch) | |
tree | a0dd44a4463f9f66801979acfe4867d05f46048a /pjsip-apps/src | |
parent | 18061c77b205207a29aeb61414c1040affeeae3b (diff) |
Re #1823 (pjsua2 video api): sample usage of Video Window API in pjsua2 app for android
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4997 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip-apps/src')
7 files changed, 92 insertions, 7 deletions
diff --git a/pjsip-apps/src/pjsua/android/.classpath b/pjsip-apps/src/pjsua/android/.classpath index 3f9691c5..d57ec025 100644 --- a/pjsip-apps/src/pjsua/android/.classpath +++ b/pjsip-apps/src/pjsua/android/.classpath @@ -1,8 +1,9 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> - <classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/> + <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/> <classpathentry kind="src" path="src"/> <classpathentry kind="src" path="gen"/> + <classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/> <classpathentry kind="output" path="bin/classes"/> </classpath> diff --git a/pjsip-apps/src/swig/java/android/AndroidManifest.xml b/pjsip-apps/src/swig/java/android/AndroidManifest.xml index 63986c42..bb2eb28a 100644 --- a/pjsip-apps/src/swig/java/android/AndroidManifest.xml +++ b/pjsip-apps/src/swig/java/android/AndroidManifest.xml @@ -9,6 +9,7 @@ android:targetSdkVersion="15" /> <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /> diff --git a/pjsip-apps/src/swig/java/android/res/layout/activity_call.xml b/pjsip-apps/src/swig/java/android/res/layout/activity_call.xml index 3745eb39..63d90a02 100644 --- a/pjsip-apps/src/swig/java/android/res/layout/activity_call.xml +++ b/pjsip-apps/src/swig/java/android/res/layout/activity_call.xml @@ -38,4 +38,9 @@ android:onClick="hangupCall"
android:text="Reject" />
+ <SurfaceView
+ android:id="@+id/surfaceIncomingVideo"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
</LinearLayout>
\ No newline at end of file diff --git a/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/CallActivity.java b/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/CallActivity.java index aa749002..9a057778 100644 --- a/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/CallActivity.java +++ b/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/CallActivity.java @@ -21,6 +21,8 @@ package org.pjsip.pjsua2.app; import android.os.Bundle; import android.os.Handler; import android.os.Message; +import android.view.SurfaceHolder; +import android.view.SurfaceView; import android.view.View; import android.widget.Button; import android.widget.TextView; @@ -28,7 +30,9 @@ import android.app.Activity; import org.pjsip.pjsua2.*; -public class CallActivity extends Activity implements Handler.Callback { +public class CallActivity extends Activity + implements Handler.Callback, SurfaceHolder.Callback +{ public static Handler handler_; @@ -40,6 +44,14 @@ public class CallActivity extends Activity implements Handler.Callback { super.onCreate(savedInstanceState); setContentView(R.layout.activity_call); + SurfaceView surfaceView = (SurfaceView)findViewById(R.id.surfaceIncomingVideo); + if (MainActivity.currentCall == null || + MainActivity.currentCall.vidWin == null) + { + surfaceView.setVisibility(View.GONE); + } + surfaceView.getHolder().addCallback(this); + handler_ = handler; if (MainActivity.currentCall != null) { try { @@ -58,7 +70,33 @@ public class CallActivity extends Activity implements Handler.Callback { super.onDestroy(); handler_ = null; } - + + private void updateVideoWindow(SurfaceHolder holder) { + if (MainActivity.currentCall != null && + MainActivity.currentCall.vidWin != null) + { + VideoWindowHandle vidWH = new VideoWindowHandle(); + if (holder == null) + vidWH.getHandle().setWindow(null); + else + vidWH.getHandle().setWindow(pjsua2.android_opengl_get_surface(holder.getSurface())); + try { + MainActivity.currentCall.vidWin.setWindow(vidWH); + } catch (Exception e) {} + } + } + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + updateVideoWindow(holder); + } + + public void surfaceCreated(SurfaceHolder holder) { + } + + public void surfaceDestroyed(SurfaceHolder holder) { + updateVideoWindow(null); + } + public void acceptCall(View view) { CallOpParam prm = new CallOpParam(); prm.setStatusCode(pjsip_status_code.PJSIP_SC_OK); @@ -86,6 +124,14 @@ public class CallActivity extends Activity implements Handler.Callback { } } + private void setupVideoSurface() { + + SurfaceView surfaceView = (SurfaceView)findViewById(R.id.surfaceIncomingVideo); + surfaceView.setVisibility(View.VISIBLE); + updateVideoWindow(surfaceView.getHolder()); + + } + @Override public boolean handleMessage(Message m) { @@ -94,6 +140,13 @@ public class CallActivity extends Activity implements Handler.Callback { lastCallInfo = (CallInfo) m.obj; updateCallState(lastCallInfo); + } else if (m.what == MainActivity.MSG_TYPE.CALL_MEDIA_STATE) { + + if (MainActivity.currentCall.vidWin != null) { + /* If there's incoming video, display it. */ + setupVideoSurface(); + } + } else { /* Message not handled */ diff --git a/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MainActivity.java b/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MainActivity.java index 3d16caff..e0d87c04 100644 --- a/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MainActivity.java +++ b/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MainActivity.java @@ -61,6 +61,7 @@ public class MainActivity extends Activity implements Handler.Callback, MyAppObs public final static int CALL_STATE = 2; public final static int REG_STATE = 3; public final static int BUDDY_STATE = 4; + public final static int CALL_MEDIA_STATE = 5; } private HashMap<String, String> putData(String uri, String status) { @@ -173,6 +174,14 @@ public class MainActivity extends Activity implements Handler.Callback, MyAppObs m2.sendToTarget(); } + } else if (m.what == MSG_TYPE.CALL_MEDIA_STATE) { + + /* Forward the message to CallActivity */ + if (CallActivity.handler_ != null) { + Message m2 = Message.obtain(CallActivity.handler_, MSG_TYPE.CALL_MEDIA_STATE, null); + m2.sendToTarget(); + } + } else if (m.what == MSG_TYPE.BUDDY_STATE) { MyBuddy buddy = (MyBuddy) m.obj; @@ -332,10 +341,7 @@ public class MainActivity extends Activity implements Handler.Callback, MyAppObs String buddy_uri = item.get("uri"); MyCall call = new MyCall(account, -1); - CallOpParam prm = new CallOpParam(); - CallSetting opt = prm.getOpt(); - opt.setAudioCount(1); - opt.setVideoCount(0); + CallOpParam prm = new CallOpParam(true); try { call.makeCall(buddy_uri, prm); @@ -502,6 +508,11 @@ public class MainActivity extends Activity implements Handler.Callback, MyAppObs } } + public void notifyCallMediaState(MyCall call) { + Message m = Message.obtain(handler, MSG_TYPE.CALL_MEDIA_STATE, null); + m.sendToTarget(); + } + public void notifyBuddyState(MyBuddy buddy) { Message m = Message.obtain(handler, MSG_TYPE.BUDDY_STATE, buddy); m.sendToTarget(); diff --git a/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MyApp.java b/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MyApp.java index 9a5b2464..92cc66bb 100644 --- a/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MyApp.java +++ b/pjsip-apps/src/swig/java/android/src/org/pjsip/pjsua2/app/MyApp.java @@ -28,6 +28,7 @@ interface MyAppObserver { abstract void notifyRegState(pjsip_status_code code, String reason, int expiration); abstract void notifyIncomingCall(MyCall call); abstract void notifyCallState(MyCall call); + abstract void notifyCallMediaState(MyCall call); abstract void notifyBuddyState(MyBuddy buddy); } @@ -41,8 +42,11 @@ class MyLogWriter extends LogWriter { class MyCall extends Call { + public VideoWindow vidWin; + MyCall(MyAccount acc, int call_id) { super(acc, call_id); + vidWin = null; } @Override @@ -86,8 +90,15 @@ class MyCall extends Call { } catch (Exception e) { continue; } + } else if (cmi.getType() == pjmedia_type.PJMEDIA_TYPE_VIDEO && + cmi.getStatus() == pjsua_call_media_status.PJSUA_CALL_MEDIA_ACTIVE && + cmi.getVideoIncomingWindowId() != pjsua2.INVALID_ID) + { + vidWin = cmi.getVideoWindow(); } } + + MyApp.observer.notifyCallMediaState(this); } } diff --git a/pjsip-apps/src/swig/java/sample.java b/pjsip-apps/src/swig/java/sample.java index 0f6a243d..7f77dd2c 100644 --- a/pjsip-apps/src/swig/java/sample.java +++ b/pjsip-apps/src/swig/java/sample.java @@ -44,6 +44,9 @@ class MyObserver implements MyAppObserver { } @Override + public void notifyCallMediaState(MyCall call) { + } + public void notifyCallState(MyCall call) { if (currentCall == null || call.getId() != currentCall.getId()) return; |