10cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams/* 20cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams * Copyright (C) 2012 The Android Open Source Project 30cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams * 40cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams * Licensed under the Apache License, Version 2.0 (the "License"); 50cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams * you may not use this file except in compliance with the License. 60cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams * You may obtain a copy of the License at 70cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams * 80cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams * http://www.apache.org/licenses/LICENSE-2.0 90cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams * 100cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams * Unless required by applicable law or agreed to in writing, software 110cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams * distributed under the License is distributed on an "AS IS" BASIS, 120cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams * See the License for the specific language governing permissions and 140cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams * limitations under the License. 150cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams */ 160cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samspackage com.android.rs.livepreview; 170cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 180cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams//import com.android.cts.verifier.PassFailButtons; 190cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams//import com.android.cts.verifier.R; 200cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 210cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.app.Activity; 220cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.app.AlertDialog; 230cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.graphics.Bitmap; 240cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.graphics.Color; 250cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.graphics.ColorMatrix; 260cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.graphics.ColorMatrixColorFilter; 270cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.graphics.ImageFormat; 280cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.graphics.Matrix; 290cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.graphics.SurfaceTexture; 300cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.hardware.Camera; 310cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.os.AsyncTask; 320cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.os.Bundle; 330cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.os.Handler; 340cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.util.Log; 350cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.util.SparseArray; 360cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.view.View; 370cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.view.TextureView; 380cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.widget.AdapterView; 390cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.widget.ArrayAdapter; 400cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.widget.ImageView; 410cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.widget.Spinner; 420cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 430cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport java.io.IOException; 440cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport java.lang.InterruptedException; 450cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport java.lang.Math; 460cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport java.lang.Thread; 470cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport java.util.ArrayList; 480cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport java.util.Comparator; 490cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport java.util.List; 500cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport java.util.TreeSet; 510cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 520cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samsimport android.renderscript.*; 530cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 540cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams/** 550cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams * Tests for manual verification of the CDD-required camera output formats 560cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams * for preview callbacks 570cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams */ 580cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Samspublic class CameraPreviewActivity extends Activity 590cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams implements TextureView.SurfaceTextureListener, Camera.PreviewCallback { 600cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 610cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private static final String TAG = "CameraFormats"; 620cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 630cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private TextureView mPreviewView; 640cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private SurfaceTexture mPreviewTexture; 650cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private int mPreviewTexWidth; 660cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private int mPreviewTexHeight; 670cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 680cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private ImageView mFormatView; 690cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 700cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private Spinner mCameraSpinner; 710cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private Spinner mResolutionSpinner; 720cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 730cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private int mCurrentCameraId = -1; 740cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private Camera mCamera; 750cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 760cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private List<Camera.Size> mPreviewSizes; 770cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private Camera.Size mNextPreviewSize; 780cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private Camera.Size mPreviewSize; 790cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 800cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private Bitmap mCallbackBitmap; 810cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 820cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private static final int STATE_OFF = 0; 830cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private static final int STATE_PREVIEW = 1; 840cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private static final int STATE_NO_CALLBACKS = 2; 850cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private int mState = STATE_OFF; 860cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private boolean mProcessInProgress = false; 870cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private boolean mProcessingFirstFrame = false; 880cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 890cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 900cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private RenderScript mRS; 910cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private RsYuv mFilterYuv; 920cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 930cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams @Override 940cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams public void onCreate(Bundle savedInstanceState) { 950cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams super.onCreate(savedInstanceState); 960cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 970cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams setContentView(R.layout.cf_main); 980cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 990cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mPreviewView = (TextureView) findViewById(R.id.preview_view); 1000cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mFormatView = (ImageView) findViewById(R.id.format_view); 1010cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1020cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mPreviewView.setSurfaceTextureListener(this); 1030cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1040cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams int numCameras = Camera.getNumberOfCameras(); 1050cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams String[] cameraNames = new String[numCameras]; 1060cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams for (int i = 0; i < numCameras; i++) { 1070cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams cameraNames[i] = "Camera " + i; 1080cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 1090cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mCameraSpinner = (Spinner) findViewById(R.id.cameras_selection); 1100cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mCameraSpinner.setAdapter( 1110cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams new ArrayAdapter<String>( 1120cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams this, R.layout.cf_format_list_item, cameraNames)); 1130cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mCameraSpinner.setOnItemSelectedListener(mCameraSpinnerListener); 1140cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1150cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mResolutionSpinner = (Spinner) findViewById(R.id.resolution_selection); 1160cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mResolutionSpinner.setOnItemSelectedListener(mResolutionSelectedListener); 1170cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1180cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1190cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mRS = RenderScript.create(this); 1200cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 1210cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1220cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams @Override 1230cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams public void onResume() { 1240cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams super.onResume(); 1250cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1260cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams setUpCamera(mCameraSpinner.getSelectedItemPosition()); 1270cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 1280cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1290cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams @Override 1300cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams public void onPause() { 1310cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams super.onPause(); 1320cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1330cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams shutdownCamera(); 1340cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 1350cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1360cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams public void onSurfaceTextureAvailable(SurfaceTexture surface, 1370cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams int width, int height) { 1380cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mPreviewTexture = surface; 1390cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mPreviewTexWidth = width; 1400cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mPreviewTexHeight = height; 1410cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams if (mCamera != null) { 1420cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams startPreview(); 1430cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 1440cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 1450cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1460cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 1470cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams // Ignored, Camera does all the work for us 1480cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 1490cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1500cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 1510cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams return true; 1520cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 1530cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1540cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams public void onSurfaceTextureUpdated(SurfaceTexture surface) { 1550cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams // Invoked every time there's a new Camera preview frame 1560cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 1570cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1580cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private AdapterView.OnItemSelectedListener mCameraSpinnerListener = 1590cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams new AdapterView.OnItemSelectedListener() { 1600cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams public void onItemSelected(AdapterView<?> parent, 1610cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams View view, int pos, long id) { 1620cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams if (mCurrentCameraId != pos) { 1630cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams setUpCamera(pos); 1640cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 1650cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 1660cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1670cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams public void onNothingSelected(AdapterView parent) { 1680cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1690cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 1700cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1710cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams }; 1720cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1730cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private AdapterView.OnItemSelectedListener mResolutionSelectedListener = 1740cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams new AdapterView.OnItemSelectedListener() { 1750cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams public void onItemSelected(AdapterView<?> parent, 1760cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams View view, int position, long id) { 1770cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams if (mPreviewSizes.get(position) != mPreviewSize) { 1780cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mNextPreviewSize = mPreviewSizes.get(position); 1790cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams startPreview(); 1800cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 1810cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 1820cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1830cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams public void onNothingSelected(AdapterView parent) { 1840cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1850cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 1860cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1870cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams }; 1880cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1890cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1900cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private void setUpCamera(int id) { 1910cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams shutdownCamera(); 1920cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1930cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mCurrentCameraId = id; 1940cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mCamera = Camera.open(id); 1950cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams Camera.Parameters p = mCamera.getParameters(); 1960cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1970cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams // Get preview resolutions 1980cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 1990cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams List<Camera.Size> unsortedSizes = p.getSupportedPreviewSizes(); 2000cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 2010cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams class SizeCompare implements Comparator<Camera.Size> { 2020cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams public int compare(Camera.Size lhs, Camera.Size rhs) { 2030cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams if (lhs.width < rhs.width) return -1; 2040cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams if (lhs.width > rhs.width) return 1; 2050cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams if (lhs.height < rhs.height) return -1; 2060cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams if (lhs.height > rhs.height) return 1; 2070cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams return 0; 2080cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 2090cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams }; 2100cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 2110cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams SizeCompare s = new SizeCompare(); 2120cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams TreeSet<Camera.Size> sortedResolutions = new TreeSet<Camera.Size>(s); 2130cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams sortedResolutions.addAll(unsortedSizes); 2140cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 2150cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mPreviewSizes = new ArrayList<Camera.Size>(sortedResolutions); 2160cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 2170cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams String[] availableSizeNames = new String[mPreviewSizes.size()]; 2180cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams for (int i = 0; i < mPreviewSizes.size(); i++) { 2190cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams availableSizeNames[i] = 2200cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams Integer.toString(mPreviewSizes.get(i).width) + " x " + 2210cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams Integer.toString(mPreviewSizes.get(i).height); 2220cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 2230cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mResolutionSpinner.setAdapter( 2240cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams new ArrayAdapter<String>( 2250cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams this, R.layout.cf_format_list_item, availableSizeNames)); 2260cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 2270cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 2280cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams // Set initial values 2290cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 2300cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mNextPreviewSize = mPreviewSizes.get(0); 2310cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mResolutionSpinner.setSelection(0); 2320cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 2330cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams if (mPreviewTexture != null) { 2340cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams startPreview(); 2350cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 2360cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 2370cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 2380cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private void shutdownCamera() { 2390cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams if (mCamera != null) { 2400cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mCamera.setPreviewCallbackWithBuffer(null); 2410cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mCamera.stopPreview(); 2420cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mCamera.release(); 2430cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mCamera = null; 2440cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mState = STATE_OFF; 2450cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 2460cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 2470cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 2480cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private void startPreview() { 2490cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams if (mState != STATE_OFF) { 2500cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams // Stop for a while to drain callbacks 2510cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mCamera.setPreviewCallbackWithBuffer(null); 2520cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mCamera.stopPreview(); 2530cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mState = STATE_OFF; 2540cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams Handler h = new Handler(); 2550cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams Runnable mDelayedPreview = new Runnable() { 2560cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams public void run() { 2570cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams startPreview(); 2580cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 2590cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams }; 2600cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams h.postDelayed(mDelayedPreview, 300); 2610cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams return; 2620cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 2630cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mState = STATE_PREVIEW; 2640cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 2650cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams Matrix transform = new Matrix(); 2660cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams float widthRatio = mNextPreviewSize.width / (float)mPreviewTexWidth; 2670cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams float heightRatio = mNextPreviewSize.height / (float)mPreviewTexHeight; 2680cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 2690cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams transform.setScale(1, heightRatio/widthRatio); 2700cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams transform.postTranslate(0, 2710cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mPreviewTexHeight * (1 - heightRatio/widthRatio)/2); 2720cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 2730cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mPreviewView.setTransform(transform); 2740cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 2750cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mPreviewSize = mNextPreviewSize; 2760cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 2770cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams Camera.Parameters p = mCamera.getParameters(); 2780cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams p.setPreviewFormat(ImageFormat.NV21); 2790cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams p.setPreviewSize(mPreviewSize.width, mPreviewSize.height); 2800cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mCamera.setParameters(p); 2810cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 2820cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mCamera.setPreviewCallbackWithBuffer(this); 2830cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams int expectedBytes = mPreviewSize.width * mPreviewSize.height * 2840cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8; 2850cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams for (int i=0; i < 4; i++) { 2860cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mCamera.addCallbackBuffer(new byte[expectedBytes]); 2870cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 2880cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams //mFormatView.setColorFilter(mYuv2RgbFilter); 2890cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 2900cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mProcessingFirstFrame = true; 2910cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams try { 2920cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mCamera.setPreviewTexture(mPreviewTexture); 2930cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mCamera.startPreview(); 2940cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } catch (IOException ioe) { 2950cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams // Something bad happened 2960cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams Log.e(TAG, "Unable to start up preview"); 2970cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 2980cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 2990cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 3000cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 3010cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 302702fb2c502ee6bab5cced1835005e0e225533751Jason Sams private class ProcessPreviewDataTask extends AsyncTask<byte[], Void, Boolean> { 303702fb2c502ee6bab5cced1835005e0e225533751Jason Sams protected Boolean doInBackground(byte[]... datas) { 304702fb2c502ee6bab5cced1835005e0e225533751Jason Sams byte[] data = datas[0]; 305702fb2c502ee6bab5cced1835005e0e225533751Jason Sams 306702fb2c502ee6bab5cced1835005e0e225533751Jason Sams long t1 = java.lang.System.currentTimeMillis(); 307702fb2c502ee6bab5cced1835005e0e225533751Jason Sams 3081ebb7202b68d18025de8755d4f1df0c6544397e3Jason Sams mFilterYuv.execute(data, mCallbackBitmap); 309702fb2c502ee6bab5cced1835005e0e225533751Jason Sams 310702fb2c502ee6bab5cced1835005e0e225533751Jason Sams long t2 = java.lang.System.currentTimeMillis(); 311702fb2c502ee6bab5cced1835005e0e225533751Jason Sams mTiming[mTimingSlot++] = t2 - t1; 312702fb2c502ee6bab5cced1835005e0e225533751Jason Sams if (mTimingSlot >= mTiming.length) { 313702fb2c502ee6bab5cced1835005e0e225533751Jason Sams float total = 0; 314702fb2c502ee6bab5cced1835005e0e225533751Jason Sams for (int i=0; i<mTiming.length; i++) { 315702fb2c502ee6bab5cced1835005e0e225533751Jason Sams total += (float)mTiming[i]; 316702fb2c502ee6bab5cced1835005e0e225533751Jason Sams } 317702fb2c502ee6bab5cced1835005e0e225533751Jason Sams total /= mTiming.length; 318702fb2c502ee6bab5cced1835005e0e225533751Jason Sams Log.e(TAG, "time + " + total); 319702fb2c502ee6bab5cced1835005e0e225533751Jason Sams mTimingSlot = 0; 320702fb2c502ee6bab5cced1835005e0e225533751Jason Sams } 321702fb2c502ee6bab5cced1835005e0e225533751Jason Sams 322702fb2c502ee6bab5cced1835005e0e225533751Jason Sams mCamera.addCallbackBuffer(data); 323702fb2c502ee6bab5cced1835005e0e225533751Jason Sams mProcessInProgress = false; 324702fb2c502ee6bab5cced1835005e0e225533751Jason Sams return true; 325702fb2c502ee6bab5cced1835005e0e225533751Jason Sams } 326702fb2c502ee6bab5cced1835005e0e225533751Jason Sams 327702fb2c502ee6bab5cced1835005e0e225533751Jason Sams protected void onPostExecute(Boolean result) { 328702fb2c502ee6bab5cced1835005e0e225533751Jason Sams mFormatView.invalidate(); 329702fb2c502ee6bab5cced1835005e0e225533751Jason Sams } 330702fb2c502ee6bab5cced1835005e0e225533751Jason Sams 331702fb2c502ee6bab5cced1835005e0e225533751Jason Sams } 332702fb2c502ee6bab5cced1835005e0e225533751Jason Sams 3330cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private long mTiming[] = new long[50]; 3340cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams private int mTimingSlot = 0; 3350cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 3360cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams public void onPreviewFrame(byte[] data, Camera camera) { 3370cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams if (mProcessInProgress || mState != STATE_PREVIEW) { 3380cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mCamera.addCallbackBuffer(data); 3390cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams return; 3400cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 341702fb2c502ee6bab5cced1835005e0e225533751Jason Sams if (data == null) { 342702fb2c502ee6bab5cced1835005e0e225533751Jason Sams return; 343702fb2c502ee6bab5cced1835005e0e225533751Jason Sams } 3440cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 3450cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams int expectedBytes = mPreviewSize.width * mPreviewSize.height * 3460cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8; 3470cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 3480cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams if (expectedBytes != data.length) { 3490cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams Log.e(TAG, "Mismatched size of buffer! Expected "); 3500cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 3510cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mState = STATE_NO_CALLBACKS; 3520cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mCamera.setPreviewCallbackWithBuffer(null); 3530cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams return; 3540cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 3550cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 3560cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mProcessInProgress = true; 3570cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 3580cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams if (mCallbackBitmap == null || 3590cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mPreviewSize.width != mCallbackBitmap.getWidth() || 3600cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mPreviewSize.height != mCallbackBitmap.getHeight() ) { 3610cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mCallbackBitmap = 3620cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams Bitmap.createBitmap( 3630cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mPreviewSize.width, mPreviewSize.height, 3640cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams Bitmap.Config.ARGB_8888); 3650cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mFilterYuv = new RsYuv(mRS, getResources(), mPreviewSize.width, mPreviewSize.height); 3660cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mFormatView.setImageBitmap(mCallbackBitmap); 3670cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 3680cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 3690cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 3700cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mFormatView.invalidate(); 3710cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 3720cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams mCamera.addCallbackBuffer(data); 373702fb2c502ee6bab5cced1835005e0e225533751Jason Sams mProcessInProgress = true; 374702fb2c502ee6bab5cced1835005e0e225533751Jason Sams new ProcessPreviewDataTask().execute(data); 3750cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams } 3760cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 3770cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 3780cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams 3790cb555ffcc30b79ae04a4dc6089863da4bb54852Jason Sams}