From 75654d6b5620c297b8850ad00968d7a890a83f60 Mon Sep 17 00:00:00 2001 From: Guillaume Beraudo Date: Fri, 12 Nov 2010 14:16:01 +0100 Subject: [PATCH] Draft for Android video capture. --- AndroidManifest.xml | 16 ++- res/layout/videotest.xml | 14 ++ .../linphone/core/AndroidCameraRecord.java | 127 ++++++++++++++++++ .../core/AndroidCameraRecordImpl.java | 49 +++++++ .../core/tutorials/JavaCameraRecordImpl.java | 69 ++++++++++ .../core/tutorials/TestVideoActivity.java | 70 ++++++++++ 6 files changed, 344 insertions(+), 1 deletion(-) create mode 100644 res/layout/videotest.xml create mode 100644 src/org/linphone/core/AndroidCameraRecord.java create mode 100644 src/org/linphone/core/AndroidCameraRecordImpl.java create mode 100644 src/org/linphone/core/tutorials/JavaCameraRecordImpl.java create mode 100644 src/org/linphone/core/tutorials/TestVideoActivity.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 77a1c1e62..1a97c69a5 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -20,6 +20,13 @@ + + + + + + @@ -60,7 +67,11 @@ - + + + + + @@ -103,5 +114,8 @@ + + + diff --git a/res/layout/videotest.xml b/res/layout/videotest.xml new file mode 100644 index 000000000..eafbbde1b --- /dev/null +++ b/res/layout/videotest.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/src/org/linphone/core/AndroidCameraRecord.java b/src/org/linphone/core/AndroidCameraRecord.java new file mode 100644 index 000000000..ae07c6d56 --- /dev/null +++ b/src/org/linphone/core/AndroidCameraRecord.java @@ -0,0 +1,127 @@ +/* +AndroidCameraRecordImpl.java +Copyright (C) 2010 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +package org.linphone.core; + +import android.hardware.Camera; +import android.hardware.Camera.PreviewCallback; +import android.util.Log; +import android.view.SurfaceHolder; +import android.view.SurfaceView; + + +public abstract class AndroidCameraRecord implements SurfaceHolder.Callback { + + protected Camera camera; + private static SurfaceView surfaceView; // should be initialized first... + protected int rate; + private int visibility = SurfaceView.GONE; // Automatically hidden + private boolean visibilityChangeable = false; + + protected final SurfaceView getSurfaceView() { + return surfaceView; + } + + /** + * AndroidCameraRecord.setSurfaceView() should be called first. + * @param rate + */ + public AndroidCameraRecord(int rate) { + camera=Camera.open(); + SurfaceHolder holder = surfaceView.getHolder(); + holder.addCallback(this); + + this.rate = rate; + } + + + /** + * AndroidCameraRecord.setSurfaceView() should be called first. + * @param rate + * @param visilibity + */ + public AndroidCameraRecord(int rate, int visilibity) { + this(rate); + this.visibility = visilibity; + } + + + public void surfaceCreated(SurfaceHolder holder) { + try { + camera.setPreviewDisplay(holder); + } + catch (Throwable t) { + Log.e("PictureDemo-surfaceCallback", "Exception in setPreviewDisplay()", t); + } + + + } + + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + Camera.Parameters parameters=camera.getParameters(); + + parameters.setPreviewSize(width, height); + parameters.setPreviewFrameRate(rate); + camera.setParameters(parameters); + + camera.startPreview(); + + visibilityChangeable = true; + if (surfaceView.getVisibility() != visibility) { + updateVisibility(); + } + + } + + public void surfaceDestroyed(SurfaceHolder holder) { + camera.stopPreview(); + camera.release(); + camera=null; + } + + public void setPreviewCallBack(PreviewCallback cb) { + camera.setPreviewCallback(cb); + } + + private void updateVisibility() { + if (!visibilityChangeable) { + throw new IllegalStateException("Visilibity not changeable now"); + } + + surfaceView.setVisibility(visibility); + } + + public void setVisibility(int visibility) { + if (visibility == this.visibility) return; + + this.visibility = visibility; + updateVisibility(); + } + + public static final void setSurfaceView(SurfaceView sv) { + AndroidCameraRecord.surfaceView = sv; + } + + + /** + * Hook to add back a buffer for reuse in capture. + * Override in a version supporting addPreviewCallBackWithBuffer() + * @param buffer buffer to reuse + */ + public void addBackCaptureBuffer(byte[] buffer) {} +} diff --git a/src/org/linphone/core/AndroidCameraRecordImpl.java b/src/org/linphone/core/AndroidCameraRecordImpl.java new file mode 100644 index 000000000..c9173d1da --- /dev/null +++ b/src/org/linphone/core/AndroidCameraRecordImpl.java @@ -0,0 +1,49 @@ +/* +AndroidCameraRecordImpl.java +Copyright (C) 2010 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +package org.linphone.core; + +import android.hardware.Camera; +import android.hardware.Camera.PreviewCallback; +import android.util.Log; + +/** + * Record from Android camera. + * + * @author Guillaume Beraudo + * + */ +public class AndroidCameraRecordImpl extends AndroidCameraRecord implements PreviewCallback { + + private long filterCtxPtr; + + public AndroidCameraRecordImpl(long filterCtxPtr, int rate) { + super(rate); + this.filterCtxPtr = filterCtxPtr; + setPreviewCallBack(this); + } + + + private native void putImage(long filterCtxPtr, byte[] buffer); + + public void onPreviewFrame(byte[] data, Camera camera) { + Log.d("onPreviewFrame: ", Integer.toString(data.length)); + putImage(filterCtxPtr, data); + } + +} diff --git a/src/org/linphone/core/tutorials/JavaCameraRecordImpl.java b/src/org/linphone/core/tutorials/JavaCameraRecordImpl.java new file mode 100644 index 000000000..45499db78 --- /dev/null +++ b/src/org/linphone/core/tutorials/JavaCameraRecordImpl.java @@ -0,0 +1,69 @@ +/* +JavaCameraRecordImpl.java +Copyright (C) 2010 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +package org.linphone.core.tutorials; + +import org.linphone.core.AndroidCameraRecord; + +import android.hardware.Camera; +import android.hardware.Camera.PreviewCallback; +import android.util.Log; +import android.widget.TextView; + +public class JavaCameraRecordImpl extends AndroidCameraRecord implements PreviewCallback { + + private TextView debug; + private long count = 0; + private float averageCalledRate; + private int averageWindowSize = 2 * rate; + + private long startTime; + private long endTime; + + + public JavaCameraRecordImpl(int rate) { + super(rate); + setPreviewCallBack(this); + } + + public JavaCameraRecordImpl(int rate, int visilibity) { + super(rate, visilibity); + setPreviewCallBack(this); + } + + public void setDebug(TextView debug) { + this.debug = debug; + } + + public void onPreviewFrame(byte[] data, Camera camera) { + + if ((count % averageWindowSize) == 0) { + endTime = System.currentTimeMillis(); + averageCalledRate = (100000 * averageWindowSize) / (endTime - startTime); + averageCalledRate /= 100f; + startTime = endTime; + } + + count++; + + String msg = "Frame " + count + ": " + data.length + "bytes (avg="+averageCalledRate+"frames/s)"; + if (debug != null) debug.setText(msg); + Log.d("onPreviewFrame:", msg); + } + +} diff --git a/src/org/linphone/core/tutorials/TestVideoActivity.java b/src/org/linphone/core/tutorials/TestVideoActivity.java new file mode 100644 index 000000000..6526e1cce --- /dev/null +++ b/src/org/linphone/core/tutorials/TestVideoActivity.java @@ -0,0 +1,70 @@ +/* +TutorialHelloWorldActivity.java +Copyright (C) 2010 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +package org.linphone.core.tutorials; + +import org.linphone.R; +import org.linphone.core.AndroidCameraRecord; + +import android.app.Activity; +import android.os.Bundle; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.widget.TextView; + +/** + * Activity for displaying and starting the HelloWorld example on Android phone. + * + * @author Guillaume Beraudo + * + */ +public class TestVideoActivity extends Activity { + + private SurfaceView surfaceView; + private static final int rate = 15; + + + + + + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.videotest); + + surfaceView=(SurfaceView)findViewById(R.id.videotest_surfaceView); + + SurfaceHolder holder=surfaceView.getHolder(); + holder.setFixedSize(320, 240); + holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); + + AndroidCameraRecord.setSurfaceView(surfaceView); + + JavaCameraRecordImpl manager = new JavaCameraRecordImpl(rate, SurfaceView.VISIBLE); + manager.setDebug((TextView) findViewById(R.id.videotest_debug)); + + } + + + + + + +}