package org.linphone.core;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.opengl.GLSurfaceView;
import android.view.Surface;
import android.view.Surface.OutOfResourcesException;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import org.linphone.OpenGLESDisplay;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class AndroidVideoWindowImpl {
private boolean useGLrendering;
private Bitmap mBitmap;
private SurfaceView mView;
private Surface mSurface;
private VideoWindowListener mListener;
private Renderer renderer;
public static interface VideoWindowListener{
void onSurfaceReady(AndroidVideoWindowImpl vw);
void onSurfaceDestroyed(AndroidVideoWindowImpl vw);
};
public AndroidVideoWindowImpl(SurfaceView view){
useGLrendering = (view instanceof GLSurfaceView);
mView=view;
mBitmap=null;
mSurface=null;
mListener=null;
view.getHolder().addCallback(new Callback(){
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
Log.i("Surface is being changed.");
if (!useGLrendering) {
synchronized(AndroidVideoWindowImpl.this){
mBitmap=Bitmap.createBitmap(width,height,Config.RGB_565);
mSurface=holder.getSurface();
}
}
if (mListener!=null) mListener.onSurfaceReady(AndroidVideoWindowImpl.this);
Log.w("Video display surface changed");
}
public void surfaceCreated(SurfaceHolder holder) {
Log.w("Video display surface created");
}
public void surfaceDestroyed(SurfaceHolder holder) {
if (!useGLrendering) {
synchronized(AndroidVideoWindowImpl.this){
mSurface=null;
mBitmap=null;
}
}
if (mListener!=null)
mListener.onSurfaceDestroyed(AndroidVideoWindowImpl.this);
Log.d("Video display surface destroyed");
}
});
if (useGLrendering) {
renderer = new Renderer();
((GLSurfaceView)mView).setRenderer(renderer);
((GLSurfaceView)mView).setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
}
static final int LANDSCAPE=0;
static final int PORTRAIT=1;
public void requestOrientation(int orientation){
//Surface.setOrientation(0, orientation==LANDSCAPE ? 1 : 0);
//Log.d("Orientation changed.");
}
public void setListener(VideoWindowListener l){
mListener=l;
}
public Surface getSurface(){
if (useGLrendering)
Log.e("View class does not match Video display filter used (you must use a non-GL View)");
return mView.getHolder().getSurface();
}
public Bitmap getBitmap(){
if (useGLrendering)
Log.e("View class does not match Video display filter used (you must use a non-GL View)");
return mBitmap;
}
public void setOpenGLESDisplay(int ptr) {
if (!useGLrendering)
Log.e("View class does not match Video display filter used (you must use a GL View)");
renderer.setOpenGLESDisplay(ptr);
}
public void requestRender() {
((GLSurfaceView)mView).requestRender();
}
//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();
}
}
}
private static class Renderer implements GLSurfaceView.Renderer {
int ptr;
boolean initPending;
int width, height;
public Renderer() {
ptr = 0;
initPending = false;
}
public void setOpenGLESDisplay(int ptr) {
this.ptr = ptr;
}
public void onDrawFrame(GL10 gl) {
if (ptr == 0)
return;
if (initPending) {
OpenGLESDisplay.init(ptr, width, height);
initPending = false;
}
OpenGLESDisplay.render(ptr);
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
/* delay init until ptr is set */
this.width = width;
this.height = height;
initPending = true;
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}
}
}