/* 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.video; import android.hardware.Camera; import android.hardware.Camera.Parameters; import android.hardware.Camera.PreviewCallback; import android.hardware.Camera.Size; import org.linphone.core.Log; import org.linphone.core.video.AndroidCameraRecord.RecorderParams.MirrorType; import java.util.Arrays; import java.util.List; /** * Record from Android camera. * Android >= 5 (2.0) version. * * @author Guillaume Beraudo * */ class AndroidCameraRecord5 extends AndroidCameraRecord implements PreviewCallback { private long filterCtxPtr; private double timeElapsedBetweenFrames = 0; private long lastFrameTime = 0; private final double expectedTimeBetweenFrames; protected final int rotation; private MirrorType mirror; // private boolean isUsingFrontCamera; public AndroidCameraRecord5(RecorderParams parameters) { super(parameters); expectedTimeBetweenFrames = 1d / Math.round(parameters.fps); filterCtxPtr = parameters.filterDataNativePtr; rotation = parameters.rotation; mirror = parameters.mirror; // isUsingFrontCamera = parameters.isFrontCamera; storePreviewCallBack(this); } private native void putImage(long filterCtxPtr, byte[] buffer, int rotate, int mirror); public void onPreviewFrame(byte[] data, Camera camera) { if (data == null) { Log.e("onPreviewFrame Called with null buffer"); return; } if (filterCtxPtr == 0l) { Log.e("onPreviewFrame Called with no filterCtxPtr set"); return; } int expectedBuffLength = getExpectedBufferLength(); if (expectedBuffLength != data.length) { Log.e("onPreviewFrame called with bad buffer length ", data.length, " whereas expected is ", expectedBuffLength, " don't calling putImage"); return; } long curTime = System.currentTimeMillis(); if (lastFrameTime == 0) { lastFrameTime = curTime; putImage(filterCtxPtr, data, rotation, mirror.ordinal()); return; } double currentTimeElapsed = 0.8 * (curTime - lastFrameTime) / 1000 + 0.2 * timeElapsedBetweenFrames; if (currentTimeElapsed < expectedTimeBetweenFrames) { // Log.d("Clipping frame ", Math.round(1 / currentTimeElapsed), " > ", fps); return; } lastFrameTime = curTime; timeElapsedBetweenFrames = currentTimeElapsed; // Log.d("onPreviewFrame: ", Integer.toString(data.length)); putImage(filterCtxPtr, data, rotation, mirror.ordinal()); } protected String selectFocusMode(final List<String> supportedFocusModes) {/* if (isUsingFrontCamera && supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_FIXED)) { return Camera.Parameters.FOCUS_MODE_FIXED; } if (!isUsingFrontCamera && supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_INFINITY)) { return Camera.Parameters.FOCUS_MODE_INFINITY; }*/ if (supportedFocusModes.contains(Parameters.FOCUS_MODE_AUTO)) { return Parameters.FOCUS_MODE_AUTO; } return null; // Should not occur? } @Override protected void onSettingCameraParameters(Parameters parameters) { super.onSettingCameraParameters(parameters); List<String> supportedFocusModes = parameters.getSupportedFocusModes(); String focusMode = selectFocusMode(supportedFocusModes); if (focusMode != null) { Log.w("Selected focus mode: ", focusMode); parameters.setFocusMode(focusMode); } else { Log.i("No suitable focus mode found in : ", Arrays.toString(supportedFocusModes.toArray())); } } @Override protected List<Size> getSupportedPreviewSizes(Parameters parameters) { return parameters.getSupportedPreviewSizes(); } @Override protected void lowLevelSetPreviewCallback(Camera camera, PreviewCallback cb) { camera.setPreviewCallback(cb); } }