Draft for Android video capture.

This commit is contained in:
Guillaume Beraudo 2010-11-12 14:16:01 +01:00
parent c77cf319ad
commit 75654d6b56
6 changed files with 344 additions and 1 deletions

View file

@ -20,6 +20,13 @@
<data android:scheme="tel" />
</intent-filter>
</activity>
<activity android:name=".core.tutorials.TestVideoActivity"
android:label="Video test" android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".core.tutorials.TutorialHelloWorldActivity"
android:label="Hello World" android:enabled="false">
<intent-filter>
@ -60,7 +67,11 @@
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity android:name=".VideoCallActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity android:name=".ContactPickerActivity">
<intent-filter>
@ -103,5 +114,8 @@
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
<uses-permission android:name="android.permission.BOOT_COMPLETED"></uses-permission>
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
</manifest>

14
res/layout/videotest.xml Normal file
View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="vertical">
<!--<LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content">-->
<!--<Button android:text="TEST" android:id="@+id/videotest_test" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"></Button>-->
<!--<Button android:text="EXIT" android:id="@+id/videotest_exit" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"></Button>-->
<!--</LinearLayout>-->
<SurfaceView android:layout_weight="5" android:id="@+id/videotest_surfaceView" android:layout_width="fill_parent" android:layout_height="fill_parent"></SurfaceView><TextView android:id="@+id/videotest_debug" android:layout_width="fill_parent" android:layout_height="wrap_content"></TextView>
</LinearLayout>

View file

@ -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) {}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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));
}
}