diff --git a/AndroidVideoWindowImpl.java b/AndroidVideoWindowImpl.java new file mode 100644 index 000000000..f1927e184 --- /dev/null +++ b/AndroidVideoWindowImpl.java @@ -0,0 +1,75 @@ +package org.linphone.core; + +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Bitmap.Config; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.Surface.OutOfResourcesException; +import android.view.SurfaceHolder.Callback; + +public class AndroidVideoWindowImpl implements VideoWindow { + private Bitmap mBitmap; + private SurfaceView mView; + private Surface mSurface; + private VideoWindowListener mListener; + public static interface VideoWindowListener{ + void onSurfaceReady(AndroidVideoWindowImpl vw); + void onSurfaceDestroyed(AndroidVideoWindowImpl vw); + }; + public AndroidVideoWindowImpl(SurfaceView view){ + mView=view; + mBitmap=null; + mSurface=null; + mListener=null; + view.getHolder().addCallback(new Callback(){ + public void surfaceChanged(SurfaceHolder holder, int format, + int width, int height) { + synchronized(AndroidVideoWindowImpl.this){ + mBitmap=Bitmap.createBitmap(width,height,Config.RGB_565); + if (mListener!=null) mListener.onSurfaceReady(AndroidVideoWindowImpl.this); + mSurface=holder.getSurface(); + } + } + + public void surfaceCreated(SurfaceHolder holder) { + } + + public void surfaceDestroyed(SurfaceHolder holder) { + synchronized(AndroidVideoWindowImpl.this){ + mBitmap=null; + if (mListener!=null) + mListener.onSurfaceDestroyed(AndroidVideoWindowImpl.this); + mSurface=null; + } + } + }); + } + public void setListener(VideoWindowListener l){ + mListener=l; + } + public Surface getSurface(){ + return mView.getHolder().getSurface(); + } + public Bitmap getBitmap(){ + return mBitmap; + } + //Called by the mediastreamer2 android display filter + public synchronized void update(){ + if (mSurface!=null){ + try { + Canvas canvas=mSurface.lockCanvas(null); + canvas.drawBitmap(mBitmap, 0, 0, null); + mSurface.unlockCanvasAndPost(canvas); + + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (OutOfResourcesException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } +} diff --git a/LinphoneCoreImpl.java b/LinphoneCoreImpl.java index 223a52fdc..aad67304a 100644 --- a/LinphoneCoreImpl.java +++ b/LinphoneCoreImpl.java @@ -63,6 +63,10 @@ class LinphoneCoreImpl implements LinphoneCore { private native long getCurrentCall(long nativePtr) ; private native void playDtmf(long nativePtr,char dtmf,int duration); private native void stopDtmf(long nativePtr); + private native void setVideoWindowId(long nativePtr, Object wid); + private native void setPreviewWindowId(long nativePtr, Object wid); + private AndroidVideoWindowImpl mVideoWindow; + private AndroidVideoWindowImpl mPreviewWindow; LinphoneCoreImpl(LinphoneCoreListener listener, File userConfig,File factoryConfig,Object userdata) throws IOException { mListener=listener; @@ -283,5 +287,33 @@ class LinphoneCoreImpl implements LinphoneCore { // TODO Auto-generated method stub } + public void setPreviewWindow(VideoWindow w) { + if (mPreviewWindow!=null) + mPreviewWindow.setListener(null); + mPreviewWindow=(AndroidVideoWindowImpl)w; + mPreviewWindow.setListener(new AndroidVideoWindowImpl.VideoWindowListener(){ + public void onSurfaceDestroyed(AndroidVideoWindowImpl vw) { + setPreviewWindowId(nativePtr,null); + } + + public void onSurfaceReady(AndroidVideoWindowImpl vw) { + setPreviewWindowId(nativePtr,vw); + } + }); + } + public void setVideoWindow(VideoWindow w) { + if (mVideoWindow!=null) + mVideoWindow.setListener(null); + mVideoWindow=(AndroidVideoWindowImpl)w; + mVideoWindow.setListener(new AndroidVideoWindowImpl.VideoWindowListener(){ + public void onSurfaceDestroyed(AndroidVideoWindowImpl vw) { + setVideoWindowId(nativePtr,null); + } + + public void onSurfaceReady(AndroidVideoWindowImpl vw) { + setVideoWindowId(nativePtr,vw); + } + }); + } }