Filter performance tests.

Change-Id: Ic1c898ac41372da7b0a25ebb4c83b075c7467e35
This commit is contained in:
Jason Sams
2012-06-13 14:40:03 -07:00
parent 4d7d5268ba
commit 0cb555ffcc
11 changed files with 1101 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
#
# Copyright (C) 2012 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
LOCAL_PACKAGE_NAME := PreviewRS
include $(BUILD_PACKAGE)

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.rs.livepreview">
<uses-sdk android:minSdkVersion="14" />
<uses-permission android:name="android.permission.CAMERA" />
<application android:label="Preview FS"
android:hardwareAccelerated="true">
<activity android:name="CameraPreviewActivity"
android:label="Preview FS"
android:screenOrientation="landscape">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 KiB

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp"
/>

View File

@@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" >
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="3" >
<TextureView
android:id="@+id/preview_view"
android:layout_height="0dp"
android:layout_width="fill_parent"
android:layout_weight="3" />
<TextView
android:id="@+id/preview_label"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="@string/cf_preview_label"
android:padding="2dp"
android:textSize="16sp"
android:gravity="center" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="3" >
<ImageView
android:id="@+id/format_view"
android:layout_height="0dp"
android:layout_width="fill_parent"
android:layout_weight="3" />
<TextView
android:id="@+id/format_label"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="@string/cf_format_label"
android:padding="2dp"
android:textSize="16sp"
android:gravity="center" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="2" >
<Spinner
android:id="@+id/cameras_selection"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<Spinner
android:id="@+id/resolution_selection"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<Spinner
android:id="@+id/format_selection"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>

View File

@@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/toplevel">
<SurfaceView
android:id="@+id/surface"
android:layout_width="1dip"
android:layout_height="1dip" />
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:id="@+id/display"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/benchmark"
android:onClick="benchmark"/>
<TextView
android:id="@+id/benchmarkText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="8pt"
android:text="@string/saturation"/>
</LinearLayout>
<TextView
android:id="@+id/inSaturationText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="8pt"
android:layout_marginLeft="10sp"
android:layout_marginTop="15sp"
android:text="@string/saturation"/>
<SeekBar
android:id="@+id/inSaturation"
android:layout_marginLeft="10sp"
android:layout_marginRight="10sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/outWhiteText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10sp"
android:layout_marginTop="15sp"
android:textSize="8pt"
android:text="@string/out_white"/>
<SeekBar
android:id="@+id/outWhite"
android:layout_marginLeft="10sp"
android:layout_marginRight="10sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/inWhiteText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="8pt"
android:layout_marginLeft="10sp"
android:layout_marginTop="15sp"
android:text="@string/in_white"/>
<SeekBar
android:id="@+id/inWhite"
android:layout_marginLeft="10sp"
android:layout_marginRight="10sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/outBlackText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="8pt"
android:layout_marginLeft="10sp"
android:layout_marginTop="15sp"
android:text="@string/out_black"/>
<SeekBar
android:id="@+id/outBlack"
android:layout_marginLeft="10sp"
android:layout_marginRight="10sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/inBlackText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="8pt"
android:layout_marginLeft="10sp"
android:layout_marginTop="15sp"
android:text="@string/in_black"/>
<SeekBar
android:id="@+id/inBlack"
android:layout_marginLeft="10sp"
android:layout_marginRight="10sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/inGammaText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="8pt"
android:layout_marginLeft="10sp"
android:layout_marginTop="15sp"
android:text="@string/gamma"/>
<SeekBar
android:id="@+id/inGamma"
android:layout_marginLeft="10sp"
android:layout_marginRight="10sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</ScrollView>
</LinearLayout>

View File

@@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/toplevel">
<SurfaceView
android:id="@+id/surface"
android:layout_width="1dip"
android:layout_height="1dip" />
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextureView
android:id="@+id/display"
android:layout_width="800sp"
android:layout_height="423sp" />
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/benchmark"
android:onClick="benchmark"/>
<TextView
android:id="@+id/benchmarkText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="8pt"
android:text="@string/saturation"/>
</LinearLayout>
<TextView
android:id="@+id/inSaturationText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="8pt"
android:layout_marginLeft="10sp"
android:layout_marginTop="15sp"
android:text="@string/saturation"/>
<SeekBar
android:id="@+id/inSaturation"
android:layout_marginLeft="10sp"
android:layout_marginRight="10sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/outWhiteText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10sp"
android:layout_marginTop="15sp"
android:textSize="8pt"
android:text="@string/out_white"/>
<SeekBar
android:id="@+id/outWhite"
android:layout_marginLeft="10sp"
android:layout_marginRight="10sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/inWhiteText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="8pt"
android:layout_marginLeft="10sp"
android:layout_marginTop="15sp"
android:text="@string/in_white"/>
<SeekBar
android:id="@+id/inWhite"
android:layout_marginLeft="10sp"
android:layout_marginRight="10sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/outBlackText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="8pt"
android:layout_marginLeft="10sp"
android:layout_marginTop="15sp"
android:text="@string/out_black"/>
<SeekBar
android:id="@+id/outBlack"
android:layout_marginLeft="10sp"
android:layout_marginRight="10sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/inBlackText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="8pt"
android:layout_marginLeft="10sp"
android:layout_marginTop="15sp"
android:text="@string/in_black"/>
<SeekBar
android:id="@+id/inBlack"
android:layout_marginLeft="10sp"
android:layout_marginRight="10sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/inGammaText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="8pt"
android:layout_marginLeft="10sp"
android:layout_marginTop="15sp"
android:text="@string/gamma"/>
<SeekBar
android:id="@+id/inGamma"
android:layout_marginLeft="10sp"
android:layout_marginRight="10sp"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
</ScrollView>
</LinearLayout>

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string name="in_white">In White</string>
<string name="out_white">Out White</string>
<string name="in_black">In Black</string>
<string name="out_black">Out Black</string>
<string name="gamma">Gamma</string>
<string name="saturation">Saturation</string>
<string name="benchmark">Benchmark</string>
<string name="app_name">CTS Verifier</string>
<string name="welcome_text">Welcome to the CTS Verifier!</string>
<string name="version_text">%1$s</string>
<string name="continue_button_text">Continue</string>
<string name="cf_preview_label">Normal preview</string>
<string name="cf_format_label">Processed callback data</string>
<string name="camera_format">Camera Formats</string>
</resources>

View File

@@ -0,0 +1,362 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.rs.livepreview;
//import com.android.cts.verifier.PassFailButtons;
//import com.android.cts.verifier.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.view.TextureView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.Spinner;
import java.io.IOException;
import java.lang.InterruptedException;
import java.lang.Math;
import java.lang.Thread;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;
import android.renderscript.*;
/**
* Tests for manual verification of the CDD-required camera output formats
* for preview callbacks
*/
public class CameraPreviewActivity extends Activity
implements TextureView.SurfaceTextureListener, Camera.PreviewCallback {
private static final String TAG = "CameraFormats";
private TextureView mPreviewView;
private SurfaceTexture mPreviewTexture;
private int mPreviewTexWidth;
private int mPreviewTexHeight;
private ImageView mFormatView;
private Spinner mCameraSpinner;
private Spinner mResolutionSpinner;
private int mCurrentCameraId = -1;
private Camera mCamera;
private List<Camera.Size> mPreviewSizes;
private Camera.Size mNextPreviewSize;
private Camera.Size mPreviewSize;
private Bitmap mCallbackBitmap;
private static final int STATE_OFF = 0;
private static final int STATE_PREVIEW = 1;
private static final int STATE_NO_CALLBACKS = 2;
private int mState = STATE_OFF;
private boolean mProcessInProgress = false;
private boolean mProcessingFirstFrame = false;
private RenderScript mRS;
private RsYuv mFilterYuv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cf_main);
mPreviewView = (TextureView) findViewById(R.id.preview_view);
mFormatView = (ImageView) findViewById(R.id.format_view);
mPreviewView.setSurfaceTextureListener(this);
int numCameras = Camera.getNumberOfCameras();
String[] cameraNames = new String[numCameras];
for (int i = 0; i < numCameras; i++) {
cameraNames[i] = "Camera " + i;
}
mCameraSpinner = (Spinner) findViewById(R.id.cameras_selection);
mCameraSpinner.setAdapter(
new ArrayAdapter<String>(
this, R.layout.cf_format_list_item, cameraNames));
mCameraSpinner.setOnItemSelectedListener(mCameraSpinnerListener);
mResolutionSpinner = (Spinner) findViewById(R.id.resolution_selection);
mResolutionSpinner.setOnItemSelectedListener(mResolutionSelectedListener);
mRS = RenderScript.create(this);
}
@Override
public void onResume() {
super.onResume();
setUpCamera(mCameraSpinner.getSelectedItemPosition());
}
@Override
public void onPause() {
super.onPause();
shutdownCamera();
}
public void onSurfaceTextureAvailable(SurfaceTexture surface,
int width, int height) {
mPreviewTexture = surface;
mPreviewTexWidth = width;
mPreviewTexHeight = height;
if (mCamera != null) {
startPreview();
}
}
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
// Ignored, Camera does all the work for us
}
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return true;
}
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
// Invoked every time there's a new Camera preview frame
}
private AdapterView.OnItemSelectedListener mCameraSpinnerListener =
new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent,
View view, int pos, long id) {
if (mCurrentCameraId != pos) {
setUpCamera(pos);
}
}
public void onNothingSelected(AdapterView parent) {
}
};
private AdapterView.OnItemSelectedListener mResolutionSelectedListener =
new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent,
View view, int position, long id) {
if (mPreviewSizes.get(position) != mPreviewSize) {
mNextPreviewSize = mPreviewSizes.get(position);
startPreview();
}
}
public void onNothingSelected(AdapterView parent) {
}
};
private void setUpCamera(int id) {
shutdownCamera();
mCurrentCameraId = id;
mCamera = Camera.open(id);
Camera.Parameters p = mCamera.getParameters();
// Get preview resolutions
List<Camera.Size> unsortedSizes = p.getSupportedPreviewSizes();
class SizeCompare implements Comparator<Camera.Size> {
public int compare(Camera.Size lhs, Camera.Size rhs) {
if (lhs.width < rhs.width) return -1;
if (lhs.width > rhs.width) return 1;
if (lhs.height < rhs.height) return -1;
if (lhs.height > rhs.height) return 1;
return 0;
}
};
SizeCompare s = new SizeCompare();
TreeSet<Camera.Size> sortedResolutions = new TreeSet<Camera.Size>(s);
sortedResolutions.addAll(unsortedSizes);
mPreviewSizes = new ArrayList<Camera.Size>(sortedResolutions);
String[] availableSizeNames = new String[mPreviewSizes.size()];
for (int i = 0; i < mPreviewSizes.size(); i++) {
availableSizeNames[i] =
Integer.toString(mPreviewSizes.get(i).width) + " x " +
Integer.toString(mPreviewSizes.get(i).height);
}
mResolutionSpinner.setAdapter(
new ArrayAdapter<String>(
this, R.layout.cf_format_list_item, availableSizeNames));
// Set initial values
mNextPreviewSize = mPreviewSizes.get(0);
mResolutionSpinner.setSelection(0);
if (mPreviewTexture != null) {
startPreview();
}
}
private void shutdownCamera() {
if (mCamera != null) {
mCamera.setPreviewCallbackWithBuffer(null);
mCamera.stopPreview();
mCamera.release();
mCamera = null;
mState = STATE_OFF;
}
}
private void startPreview() {
if (mState != STATE_OFF) {
// Stop for a while to drain callbacks
mCamera.setPreviewCallbackWithBuffer(null);
mCamera.stopPreview();
mState = STATE_OFF;
Handler h = new Handler();
Runnable mDelayedPreview = new Runnable() {
public void run() {
startPreview();
}
};
h.postDelayed(mDelayedPreview, 300);
return;
}
mState = STATE_PREVIEW;
Matrix transform = new Matrix();
float widthRatio = mNextPreviewSize.width / (float)mPreviewTexWidth;
float heightRatio = mNextPreviewSize.height / (float)mPreviewTexHeight;
transform.setScale(1, heightRatio/widthRatio);
transform.postTranslate(0,
mPreviewTexHeight * (1 - heightRatio/widthRatio)/2);
mPreviewView.setTransform(transform);
mPreviewSize = mNextPreviewSize;
Camera.Parameters p = mCamera.getParameters();
p.setPreviewFormat(ImageFormat.NV21);
p.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
mCamera.setParameters(p);
mCamera.setPreviewCallbackWithBuffer(this);
int expectedBytes = mPreviewSize.width * mPreviewSize.height *
ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8;
for (int i=0; i < 4; i++) {
mCamera.addCallbackBuffer(new byte[expectedBytes]);
}
//mFormatView.setColorFilter(mYuv2RgbFilter);
mProcessingFirstFrame = true;
try {
mCamera.setPreviewTexture(mPreviewTexture);
mCamera.startPreview();
} catch (IOException ioe) {
// Something bad happened
Log.e(TAG, "Unable to start up preview");
}
}
private long mTiming[] = new long[50];
private int mTimingSlot = 0;
public void onPreviewFrame(byte[] data, Camera camera) {
if (mProcessInProgress || mState != STATE_PREVIEW) {
mCamera.addCallbackBuffer(data);
return;
}
int expectedBytes = mPreviewSize.width * mPreviewSize.height *
ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8;
if (expectedBytes != data.length) {
Log.e(TAG, "Mismatched size of buffer! Expected ");
mState = STATE_NO_CALLBACKS;
mCamera.setPreviewCallbackWithBuffer(null);
return;
}
mProcessInProgress = true;
if (mCallbackBitmap == null ||
mPreviewSize.width != mCallbackBitmap.getWidth() ||
mPreviewSize.height != mCallbackBitmap.getHeight() ) {
mCallbackBitmap =
Bitmap.createBitmap(
mPreviewSize.width, mPreviewSize.height,
Bitmap.Config.ARGB_8888);
mFormatView.setImageBitmap(mCallbackBitmap);
mFilterYuv = new RsYuv(mRS, getResources(), mPreviewSize.width, mPreviewSize.height);
mFormatView.setImageBitmap(mCallbackBitmap);
}
long t1 = java.lang.System.currentTimeMillis();
mFilterYuv.execute(data);
mFilterYuv.copyOut(mCallbackBitmap);
long t2 = java.lang.System.currentTimeMillis();
mTiming[mTimingSlot++] = t2 - t1;
if (mTimingSlot >= mTiming.length) {
float total = 0;
for (int i=0; i<mTiming.length; i++) {
total += (float)mTiming[i];
}
total /= mTiming.length;
Log.e(TAG, "time + " + total);
mTimingSlot = 0;
}
mFormatView.invalidate();
mCamera.addCallbackBuffer(data);
mProcessInProgress = false;
}
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.rs.livepreview;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.os.Bundle;
import android.graphics.SurfaceTexture;
import android.renderscript.Allocation;
import android.renderscript.Matrix3f;
import android.renderscript.RenderScript;
import android.util.Log;
import android.view.TextureView;
import android.view.View;
import android.content.res.Resources;
import android.renderscript.*;
import android.graphics.Bitmap;
public class RsYuv
{
private int mHeight;
private int mWidth;
private RenderScript mRS;
private Allocation mAllocationOut;
private Allocation mAllocationIn;
private ScriptC_yuv mScript;
RsYuv(RenderScript rs, Resources res, int width, int height) {
mHeight = height;
mWidth = width;
mRS = rs;
mScript = new ScriptC_yuv(mRS, res, R.raw.yuv);
mScript.invoke_setSize(mWidth, mHeight);
Type.Builder tb = new Type.Builder(mRS, Element.RGBA_8888(mRS));
tb.setX(mWidth);
tb.setY(mHeight);
mAllocationOut = Allocation.createTyped(rs, tb.create());
mAllocationIn = Allocation.createSized(rs, Element.U8(mRS), (mHeight * mWidth) +
((mHeight / 2) * (mWidth / 2) * 2));
mScript.bind_gYuvIn(mAllocationIn);
}
private long mTiming[] = new long[50];
private int mTimingSlot = 0;
void execute(byte[] yuv) {
mAllocationIn.copyFrom(yuv);
mRS.finish();
long t1 = java.lang.System.currentTimeMillis();
mScript.forEach_root(mAllocationOut);
mRS.finish();
long t2 = java.lang.System.currentTimeMillis();
mTiming[mTimingSlot++] = t2 - t1;
if (mTimingSlot >= mTiming.length) {
float total = 0;
for (int i=0; i<mTiming.length; i++) {
total += (float)mTiming[i];
}
total /= mTiming.length;
Log.e("yuv", "core time = " + total);
mTimingSlot = 0;
}
}
void copyOut(Bitmap b) {
mAllocationOut.copyTo(b);
}
}

View File

@@ -0,0 +1,149 @@
#pragma version(1)
#pragma rs java_package_name(com.android.rs.livepreview)
#pragma rs_fp_relaxed
uchar *gYuvIn;
static int gWidth;
static int gHeight;
static uchar crossProcess_tableR[256];
static uchar crossProcess_tableG[256];
static uchar crossProcess_tableB[256];
static uchar vignette_table[512];
static float4 crossProcess(float4 color) {
float4 ncolor = 0.f;
float v;
if (color.r < 0.5f) {
v = color.r;
ncolor.r = 4.0f * v * v * v;
} else {
v = 1.0f - color.r;
ncolor.r = 1.0f - (4.0f * v * v * v);
}
if (color.g < 0.5f) {
v = color.g;
ncolor.g = 2.0f * v * v;
} else {
v = 1.0f - color.g;
ncolor.g = 1.0f - (2.0f * v * v);
}
ncolor.b = color.b * 0.5f + 0.25f;
ncolor.a = color.a;
return ncolor;
}
static uchar4 crossProcess_i(uchar4 color) {
uchar4 ncolor = color;
ncolor.r = crossProcess_tableR[color.r];
ncolor.g = crossProcess_tableG[color.g];
ncolor.b = crossProcess_tableB[color.b];
return ncolor;
}
float temp = 0.2f;
static float4 colortemp(float4 color) {
float4 new_color = color;
float4 t = color * ((float4)1.0f - color) * temp;
new_color.r = color.r + t.r;
new_color.b = color.b - t.b;
if (temp > 0.0f) {
color.g = color.g + t.g * 0.25f;
}
float max_value = max(new_color.r, max(new_color.g, new_color.b));
if (max_value > 1.0f) {
new_color /= max_value;
}
return new_color;
}
//float vignetteCenter = (img_width/2.0, img_height/2.0)
static float vignette_dist_mod;
static uchar4 vignette(uchar4 color, uint32_t x, uint32_t y) {
x -= gWidth >> 1;
y -= gHeight >> 1;
uint32_t dist = (x * x + y * y);
//float d = sqrt((float)dist) * vignette_dist_mod;
float d = vignette_dist_mod * dist;
//RS_DEBUG(d);
ushort4 c = convert_ushort4(color);
c *= vignette_table[(int)d];
c >>= (ushort4)8;
return convert_uchar4(c);
}
void root(uchar4 *out, uint32_t x, uint32_t y) {
uchar Y = gYuvIn[(y * gWidth) + x];
uchar *uv = &gYuvIn[gWidth * gHeight];
uv += (((x>>1)<<1) + (y>>1) * gWidth);
#if 0
float4 p = toRGB_F(Y, uv[1], uv[0]);
p = crossProcess(p);
p = colortemp(p);
out->rgba = rsPackColorTo8888(p);
#else
uchar4 p = rsYuvToRGBA_uchar4(Y, uv[1], uv[0]);
p = crossProcess_i(p);
p = vignette(p, x, y);
out->rgba = p;
#endif
out->a = 0xff;
}
float vignetteScale = 0.5f;
float vignetteShade = 0.85f;
static void precompute() {
for(int i=0; i <256; i++) {
float4 f = ((float)i) / 255.f;
float4 res = crossProcess(f);
res = colortemp(res);
crossProcess_tableR[i] = (uchar)(res.r * 255.f);
crossProcess_tableG[i] = (uchar)(res.g * 255.f);
crossProcess_tableB[i] = (uchar)(res.b * 255.f);
}
for(int i=0; i <512; i++) {
const float slope = 20.0f;
float f = ((float)i) / 511.f;
float range = 1.30f - sqrt(vignetteScale) * 0.7f;
float lumen = vignetteShade / (1.0f + exp((sqrt(f) - range) * slope)) + (1.0f - vignetteShade);
lumen = clamp(lumen, 0.f, 1.f);
vignette_table[i] = (uchar)(lumen * 255.f + 0.5f);
RS_DEBUG(lumen);
}
}
void init() {
precompute();
}
void setSize(int w, int h) {
gWidth = w;
gHeight = h;
vignette_dist_mod = 512.f;
vignette_dist_mod /= (float)(w*w + h*h) / 4.f;
}