diff --git a/AndroidManifest.xml b/AndroidManifest.xml index b2279146a..818704e35 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -21,7 +21,9 @@ + android:label="Video test" android:enabled="true" + android:theme="@android:style/Theme.NoTitleBar" + android:launchMode="singleTask"> diff --git a/res/layout/videotest.xml b/res/layout/videotest.xml index eafbbde1b..a1a269a06 100644 --- a/res/layout/videotest.xml +++ b/res/layout/videotest.xml @@ -1,14 +1,35 @@ - - - - - + + + + + + + + + + + - diff --git a/src/org/linphone/core/tutorials/JavaCameraRecordImpl.java b/src/org/linphone/core/tutorials/JavaCameraRecordImpl.java index 12594ccef..33cc6b22e 100644 --- a/src/org/linphone/core/tutorials/JavaCameraRecordImpl.java +++ b/src/org/linphone/core/tutorials/JavaCameraRecordImpl.java @@ -22,6 +22,7 @@ import org.linphone.core.AndroidCameraRecord; import android.hardware.Camera; import android.hardware.Camera.PreviewCallback; +import android.hardware.Camera.Size; import android.util.Log; import android.widget.TextView; @@ -49,6 +50,14 @@ public class JavaCameraRecordImpl extends AndroidCameraRecord implements Preview public void onPreviewFrame(byte[] data, Camera camera) { + Size s = camera.getParameters().getPreviewSize(); + int expectedBuffLength = s.width * s.height * 3 /2; + if (expectedBuffLength != data.length) { + Log.e("Linphone", "onPreviewFrame called with bad buffer length " + data.length + + " whereas expected is " + expectedBuffLength + " don't calling putImage"); + return; + } + if ((count % 2 * fps) == 0) { endTime = System.currentTimeMillis(); averageCalledRate = (100000 * 2 * fps) / (endTime - startTime); diff --git a/src/org/linphone/core/tutorials/TestVideoActivity.java b/src/org/linphone/core/tutorials/TestVideoActivity.java index 4b4ccc09e..971b8f73f 100644 --- a/src/org/linphone/core/tutorials/TestVideoActivity.java +++ b/src/org/linphone/core/tutorials/TestVideoActivity.java @@ -15,16 +15,27 @@ 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 java.util.Stack; + import org.linphone.R; import org.linphone.core.AndroidCameraRecord; +import org.linphone.core.VideoSize; import android.app.Activity; import android.os.Bundle; +import android.util.Log; +import android.view.SurfaceHolder; import android.view.SurfaceView; +import android.view.View; +import android.view.SurfaceHolder.Callback; +import android.view.View.OnClickListener; +import android.view.ViewGroup.LayoutParams; +import android.widget.Button; import android.widget.TextView; +import static org.linphone.core.VideoSize.*; /** * Activity for displaying and starting the HelloWorld example on Android phone. @@ -32,38 +43,149 @@ import android.widget.TextView; * @author Guillaume Beraudo * */ -public class TestVideoActivity extends Activity { +public class TestVideoActivity extends Activity implements Callback, OnClickListener { private SurfaceView surfaceView; private static final int rate = 7; + private JavaCameraRecordImpl recorder; + private static String tag = "Linphone"; + private TextView debugView; + private Button nextSize; + private Button changeCamera; + private Button changeOrientation; + private AndroidCameraRecord.RecorderParams params; + + private Stack videoSizes = createSizesToTest(); + private int currentCameraId = 2; + private boolean currentOrientationIsPortrait = false; + private int width; + private int height; + private boolean started; + + - - - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.videotest); surfaceView=(SurfaceView)findViewById(R.id.videotest_surfaceView); + + nextSize = (Button) findViewById(R.id.test_video_size); + nextSize.setOnClickListener(this); + + changeCamera = (Button) findViewById(R.id.test_video_camera); + changeCamera.setText("Cam"+otherCameraId(currentCameraId)); + changeCamera.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + changeCamera.setText("Cam"+currentCameraId); + currentCameraId = otherCameraId(currentCameraId); + updateRecording(); + } + }); -// SurfaceHolder holder=surfaceView.getHolder(); -// holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); - - AndroidCameraRecord.RecorderParams params = new AndroidCameraRecord.RecorderParams(0); - params.surfaceView = surfaceView; - params.width = 352; - params.height = 288; - params.fps = rate; + changeOrientation = (Button) findViewById(R.id.test_video_orientation); + changeOrientation.setText(orientationToString(!currentOrientationIsPortrait)); + changeOrientation.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + currentOrientationIsPortrait = !currentOrientationIsPortrait; + changeOrientation.setText(orientationToString(!currentOrientationIsPortrait)); - JavaCameraRecordImpl recorder = new JavaCameraRecordImpl(params); - recorder.setDebug((TextView) findViewById(R.id.videotest_debug)); - + if (width == 0 || height == 0) return; + int newWidth = currentOrientationIsPortrait? Math.min(height, width) : Math.max(height, width); + int newHeight = currentOrientationIsPortrait? Math.max(height, width) : Math.min(height, width); + changeSurfaceViewLayout(newWidth, newHeight); // will change width and height on surfaceChanged + } + }); + + SurfaceHolder holder = surfaceView.getHolder(); + holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); + holder.addCallback(this); + + + debugView = (TextView) findViewById(R.id.videotest_debug); + } + + protected void updateRecording() { + if (width == 0 || height == 0) return; + if (recorder != null) recorder.stopPreview(); + + params = new AndroidCameraRecord.RecorderParams(0); + params.surfaceView = surfaceView; + params.width = width; + params.height = height; + params.fps = rate; + params.cameraId = currentCameraId; + + recorder = new JavaCameraRecordImpl(params); +// recorder.setDebug(debugView); + debugView.setText(orientationToString(currentOrientationIsPortrait) + + " w="+width + " h="+height+ " cam"+currentCameraId); + recorder.startPreview(); + + } + + private String orientationToString(boolean orientationIsPortrait) { + return orientationIsPortrait? "Por" : "Lan"; + } + private int otherCameraId(int currentId) { + return (currentId == 2) ? 1 : 2; + } + public void onClick(View v) { + nextSize.setText("Next"); + started=true; + if (videoSizes.isEmpty()) { + videoSizes = createSizesToTest(); + } + + VideoSize size = videoSizes.pop(); + changeSurfaceViewLayout(size.getWidth(), size.getHeight()); + + // on surface changed the recorder will be restarted with new values + // and the surface will be resized } - - - + private void changeSurfaceViewLayout(int width, int height) { + LayoutParams params = surfaceView.getLayoutParams(); + params.height = height; + params.width = width; + surfaceView.setLayoutParams(params); + + } + private Stack createSizesToTest() { + Stack stack = new Stack(); + + stack.push(VideoSize.createStandard(QCIF, false)); + stack.push(VideoSize.createStandard(CIF, false)); + stack.push(VideoSize.createStandard(QVGA, false)); + stack.push(VideoSize.createStandard(HVGA, false)); + stack.push(new VideoSize(640,480)); + stack.push(new VideoSize(800,480)); + return stack; + } + + + + + public void surfaceDestroyed(SurfaceHolder holder) { + surfaceView = null; + Log.d(tag , "Video capture surface destroyed"); + if (recorder != null) recorder.stopPreview(); + } + + public void surfaceCreated(SurfaceHolder holder) { + Log.d(tag , "Video capture surface created"); + } + + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + if (!started) return; + if (recorder != null) recorder.stopPreview(); + + this.width = width; + this.height = height; + + updateRecording(); + } }