CameraPreviewActivity.java revision ea550700420926696c4bc7b92d0f89fbc32c58d7
1572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams/*
2572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * Copyright (C) 2013 The Android Open Source Project
3572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams *
4572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * you may not use this file except in compliance with the License.
6572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * You may obtain a copy of the License at
7572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams *
8572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams *
10572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * Unless required by applicable law or agreed to in writing, software
11572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * See the License for the specific language governing permissions and
14572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * limitations under the License.
15572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams */
16572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samspackage com.android.rs.livepreview;
17572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
18572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams//import com.android.cts.verifier.PassFailButtons;
19572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams//import com.android.cts.verifier.R;
20572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
21572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.app.Activity;
22572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.app.AlertDialog;
23572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.graphics.Bitmap;
24572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.graphics.Color;
25572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.graphics.ColorMatrix;
26572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.graphics.ColorMatrixColorFilter;
27572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.graphics.ImageFormat;
28572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.graphics.Matrix;
29572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.graphics.SurfaceTexture;
30572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.hardware.Camera;
31572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.os.AsyncTask;
32572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.os.Bundle;
33572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.os.Handler;
34572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.util.Log;
35572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.util.SparseArray;
36572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.view.View;
37572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.view.TextureView;
38572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.widget.AdapterView;
39572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.widget.ArrayAdapter;
40572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.widget.ImageView;
41572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.widget.Spinner;
42572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
43572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport java.io.IOException;
44572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport java.lang.InterruptedException;
45572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport java.lang.Math;
46572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport java.lang.Thread;
47572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport java.util.ArrayList;
48572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport java.util.Comparator;
49572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport java.util.List;
50572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport java.util.TreeSet;
51572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
52572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samsimport android.renderscript.*;
53572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
54572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams/**
55572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * Tests for manual verification of the CDD-required camera output formats
56572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams * for preview callbacks
57572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams */
58572a5031a5d8602db0bec0b253428a034bd4dd59Jason Samspublic class CameraPreviewActivity extends Activity
59572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        implements TextureView.SurfaceTextureListener, Camera.PreviewCallback {
60572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
61572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private static final String TAG = "CameraFormats";
62572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
63572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private TextureView mPreviewView;
64572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private SurfaceTexture mPreviewTexture;
65572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private int mPreviewTexWidth;
66572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private int mPreviewTexHeight;
67572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
68572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    //private TextureView mFormatView;
69572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
70572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private Spinner mCameraSpinner;
71572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private Spinner mResolutionSpinner;
72572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
73572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private int mCurrentCameraId = -1;
74572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private Camera mCamera;
75572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
76572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private List<Camera.Size> mPreviewSizes;
77572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private Camera.Size mNextPreviewSize;
78572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private Camera.Size mPreviewSize;
79572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
80572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private TextureView mOutputView;
81572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    //private Bitmap mCallbackBitmap;
82572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
83572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private static final int STATE_OFF = 0;
84572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private static final int STATE_PREVIEW = 1;
85572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private static final int STATE_NO_CALLBACKS = 2;
86572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private int mState = STATE_OFF;
87572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private boolean mProcessInProgress = false;
88572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private boolean mProcessingFirstFrame = false;
89572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
90572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
91572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private RenderScript mRS;
92572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private RsYuv mFilterYuv;
93572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
94572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    @Override
95572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    public void onCreate(Bundle savedInstanceState) {
96572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        super.onCreate(savedInstanceState);
97572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
98572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        setContentView(R.layout.cf_main);
99572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
100572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPreviewView = (TextureView) findViewById(R.id.preview_view);
101572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mOutputView = (TextureView) findViewById(R.id.format_view);
102572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
103572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPreviewView.setSurfaceTextureListener(this);
104572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
105572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        int numCameras = Camera.getNumberOfCameras();
106572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        String[] cameraNames = new String[numCameras];
107572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        for (int i = 0; i < numCameras; i++) {
108572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            cameraNames[i] = "Camera " + i;
109572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        }
110572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mCameraSpinner = (Spinner) findViewById(R.id.cameras_selection);
111572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mCameraSpinner.setAdapter(
112572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            new ArrayAdapter<String>(
113572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                this, R.layout.cf_format_list_item, cameraNames));
114572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mCameraSpinner.setOnItemSelectedListener(mCameraSpinnerListener);
115572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
116572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mResolutionSpinner = (Spinner) findViewById(R.id.resolution_selection);
117572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mResolutionSpinner.setOnItemSelectedListener(mResolutionSelectedListener);
118572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
119572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mRS = RenderScript.create(this);
120572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mFilterYuv = new RsYuv(mRS);
121572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mOutputView.setSurfaceTextureListener(mFilterYuv);
122572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
123572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
124572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    @Override
125572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    public void onResume() {
126572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        super.onResume();
127572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
128572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        setUpCamera(mCameraSpinner.getSelectedItemPosition());
129572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
130572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
131572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    @Override
132572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    public void onPause() {
133572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        super.onPause();
134572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
135572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        shutdownCamera();
136572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
137572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
138572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    public void onSurfaceTextureAvailable(SurfaceTexture surface,
139572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            int width, int height) {
140572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPreviewTexture = surface;
141572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPreviewTexWidth = width;
142572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPreviewTexHeight = height;
143572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        if (mCamera != null) {
144572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            startPreview();
145572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        }
146572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
147572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
148572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
149572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        // Ignored, Camera does all the work for us
150572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
151572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
152572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
153572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        return true;
154572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
155572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
156572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
157572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        // Invoked every time there's a new Camera preview frame
158572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
159572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
160572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private AdapterView.OnItemSelectedListener mCameraSpinnerListener =
161572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            new AdapterView.OnItemSelectedListener() {
162572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                public void onItemSelected(AdapterView<?> parent,
163572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                        View view, int pos, long id) {
164572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    if (mCurrentCameraId != pos) {
165572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                        setUpCamera(pos);
166572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    }
167572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                }
168572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
169572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                public void onNothingSelected(AdapterView parent) {
170572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
171572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                }
172572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
173572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            };
174572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
175572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private AdapterView.OnItemSelectedListener mResolutionSelectedListener =
176572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            new AdapterView.OnItemSelectedListener() {
177572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                public void onItemSelected(AdapterView<?> parent,
178572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                        View view, int position, long id) {
179572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    if (mPreviewSizes.get(position) != mPreviewSize) {
180572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                        mNextPreviewSize = mPreviewSizes.get(position);
181572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                        startPreview();
182572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    }
183572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                }
184572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
185572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                public void onNothingSelected(AdapterView parent) {
186572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
187572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                }
188572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
189572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            };
190572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
191572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
192572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private void setUpCamera(int id) {
193572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        shutdownCamera();
194572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
195572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mCurrentCameraId = id;
196572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mCamera = Camera.open(id);
197572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        Camera.Parameters p = mCamera.getParameters();
198572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
199572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        // Get preview resolutions
200572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
201572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        List<Camera.Size> unsortedSizes = p.getSupportedPreviewSizes();
202572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
203572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        class SizeCompare implements Comparator<Camera.Size> {
204572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            public int compare(Camera.Size lhs, Camera.Size rhs) {
205572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                if (lhs.width < rhs.width) return -1;
206572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                if (lhs.width > rhs.width) return 1;
207572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                if (lhs.height < rhs.height) return -1;
208572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                if (lhs.height > rhs.height) return 1;
209572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                return 0;
210572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            }
211572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        };
212572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
213572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        SizeCompare s = new SizeCompare();
214572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        TreeSet<Camera.Size> sortedResolutions = new TreeSet<Camera.Size>(s);
215572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        sortedResolutions.addAll(unsortedSizes);
216572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
217572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPreviewSizes = new ArrayList<Camera.Size>(sortedResolutions);
218572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
219572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        String[] availableSizeNames = new String[mPreviewSizes.size()];
220572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        for (int i = 0; i < mPreviewSizes.size(); i++) {
221572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            availableSizeNames[i] =
222572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    Integer.toString(mPreviewSizes.get(i).width) + " x " +
223572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    Integer.toString(mPreviewSizes.get(i).height);
224572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        }
225572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mResolutionSpinner.setAdapter(
226572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            new ArrayAdapter<String>(
227572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                this, R.layout.cf_format_list_item, availableSizeNames));
228572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
229572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
230572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        // Set initial values
231ea550700420926696c4bc7b92d0f89fbc32c58d7sakshia	//
232ea550700420926696c4bc7b92d0f89fbc32c58d7sakshia        int initialSize = mPreviewSizes.size() - 1;
233572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
234ea550700420926696c4bc7b92d0f89fbc32c58d7sakshia	mNextPreviewSize = mPreviewSizes.get(initialSize);
235ea550700420926696c4bc7b92d0f89fbc32c58d7sakshia        mResolutionSpinner.setSelection(initialSize);
236572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
237ea550700420926696c4bc7b92d0f89fbc32c58d7sakshia	if(mPreviewTexture != null)
238ea550700420926696c4bc7b92d0f89fbc32c58d7sakshia	{
239572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            startPreview();
240572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        }
241572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
242572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
243572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private void shutdownCamera() {
244572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        if (mCamera != null) {
245572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            mCamera.setPreviewCallbackWithBuffer(null);
246572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            mCamera.stopPreview();
247572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            mCamera.release();
248572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            mCamera = null;
249572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            mState = STATE_OFF;
250572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        }
251572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
252572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
253572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private void startPreview() {
254572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        if (mState != STATE_OFF) {
255572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            // Stop for a while to drain callbacks
256572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            mCamera.setPreviewCallbackWithBuffer(null);
257572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            mCamera.stopPreview();
258572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            mState = STATE_OFF;
259572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            Handler h = new Handler();
260572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            Runnable mDelayedPreview = new Runnable() {
261572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                public void run() {
262572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    startPreview();
263572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                }
264572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            };
265572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            h.postDelayed(mDelayedPreview, 300);
266572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            return;
267572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        }
268572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mState = STATE_PREVIEW;
269572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
270572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        Matrix transform = new Matrix();
271572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        float widthRatio = mNextPreviewSize.width / (float)mPreviewTexWidth;
272572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        float heightRatio = mNextPreviewSize.height / (float)mPreviewTexHeight;
273572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
274572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        transform.setScale(1, heightRatio/widthRatio);
275572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        transform.postTranslate(0,
276572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                mPreviewTexHeight * (1 - heightRatio/widthRatio)/2);
277572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
278572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPreviewView.setTransform(transform);
279572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mOutputView.setTransform(transform);
280572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
281572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mPreviewSize   = mNextPreviewSize;
282572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
283572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        Camera.Parameters p = mCamera.getParameters();
284572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        p.setPreviewFormat(ImageFormat.NV21);
285572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        p.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
286572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mCamera.setParameters(p);
287572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
288572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mCamera.setPreviewCallbackWithBuffer(this);
289572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        int expectedBytes = mPreviewSize.width * mPreviewSize.height *
290572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8;
291572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        for (int i=0; i < 4; i++) {
292572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            mCamera.addCallbackBuffer(new byte[expectedBytes]);
293572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        }
294572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        //mFormatView.setColorFilter(mYuv2RgbFilter);
295572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
296572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mProcessingFirstFrame = true;
297572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        try {
298572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            mCamera.setPreviewTexture(mPreviewTexture);
299572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            mCamera.startPreview();
300572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        } catch (IOException ioe) {
301572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            // Something bad happened
302572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            Log.e(TAG, "Unable to start up preview");
303572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        }
304572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
305572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
306572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
307572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
308572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private class ProcessPreviewDataTask extends AsyncTask<byte[], Void, Boolean> {
309572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        protected Boolean doInBackground(byte[]... datas) {
310572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            byte[] data = datas[0];
311572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
312572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            long t1 = java.lang.System.currentTimeMillis();
313572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
314572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            mFilterYuv.execute(data);
315572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
316572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            long t2 = java.lang.System.currentTimeMillis();
317572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            mTiming[mTimingSlot++] = t2 - t1;
318572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            if (mTimingSlot >= mTiming.length) {
319572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                float total = 0;
320572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                for (int i=0; i<mTiming.length; i++) {
321572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                    total += (float)mTiming[i];
322572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                }
323572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                total /= mTiming.length;
324572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                Log.e(TAG, "time + " + total);
325572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                mTimingSlot = 0;
326572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            }
327572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
328572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            mCamera.addCallbackBuffer(data);
329572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            mProcessInProgress = false;
330572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            return true;
331572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        }
332572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
333572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        protected void onPostExecute(Boolean result) {
334572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            mOutputView.invalidate();
335572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        }
336572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
337572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
338572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
339572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private long mTiming[] = new long[50];
340572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    private int mTimingSlot = 0;
341572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
342572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    public void onPreviewFrame(byte[] data, Camera camera) {
343572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        if (mProcessInProgress || mState != STATE_PREVIEW) {
344572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            mCamera.addCallbackBuffer(data);
345572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            return;
346572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        }
347572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        if (data == null) {
348572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            return;
349572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        }
350572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
351572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        int expectedBytes = mPreviewSize.width * mPreviewSize.height *
352572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams                ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8;
353572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
354572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        if (expectedBytes != data.length) {
355572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            Log.e(TAG, "Mismatched size of buffer! Expected ");
356572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
357572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            mState = STATE_NO_CALLBACKS;
358572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            mCamera.setPreviewCallbackWithBuffer(null);
359572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            return;
360572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        }
361572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
362572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mProcessInProgress = true;
363572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
364572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        if ((mFilterYuv == null) ||
365572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            (mPreviewSize.width != mFilterYuv.getWidth()) ||
366572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            (mPreviewSize.height != mFilterYuv.getHeight()) ) {
367572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
368572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams            mFilterYuv.reset(mPreviewSize.width, mPreviewSize.height);
369572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        }
370572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
371572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        mProcessInProgress = true;
372572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams        new ProcessPreviewDataTask().execute(data);
373572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams    }
374572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
375572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
376572a5031a5d8602db0bec0b253428a034bd4dd59Jason Sams
377ea550700420926696c4bc7b92d0f89fbc32c58d7sakshia}
378