概述
最近做項目的時候,領導安排一個任務,讓測試一下,用ffmpeg中的yuv轉bgr函數的速度。之前編譯so庫大部分都是用eclipse,本次博主花了兩天時間,在Android studio上編譯並運行,在此做一下記錄。
設置Android Studio ndk
1、打開setings->Tools->External Toos 點擊+號新建NDK分組及javah 與ndk-build項。
2、javah 及ndk-build配置如下圖
配置完畢後點擊apply->Ok,配置完畢後,在項目上點擊右鍵便能看到NDK命令組和javah 及ndk-build命令。
說明:javah 命令使用來生成頭文件,ndk-build 命令使用編譯原生代碼生成so。
新建編譯項目並配置Gradle
1、在src main下面新建jni目錄,目錄如下
2、gradle的android域中配置不使用Android studio自動生成的.mk文件
sourceSets {
main {
//禁用as自動生成mk
jni.srcDirs = []
jniLibs.srcDirs = ['src/main/libs']
}
}
編譯生成so
點擊項目右鍵NDK->ndk-build (左鍵點擊)
此時便生成了so 。希望對您有所幫助!
補充:jni目錄內容
Android項目測試代碼
MainActivity.java
package cm.opengles;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import com.interjoy.skfaceproject_zwc.utils.Utils;
import java.io.IOException;
import java.util.List;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class MainActivity extends AppCompatActivity implements Camera.PreviewCallback{
private final String TAG = Main1Activity.class.getSimpleName();
public final static int WIDTH = 1920;
public final static int HEIGHT = 1080;
public final static int SIZE = WIDTH * HEIGHT * 3 / 2;
private static int CAMERA_FACING_BACK_FRONT = 0;//默認是後置camera
private static final boolean DEBUG = false;
public byte[] mData;
private GLSurfaceView view;
private Camera mCamera;
private WakeLock wlock;
private int wView;
private int hView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 採集圖像是640*480,所以預覽窗口保證4:3
int wScreen = Utils.getScreenWidth(this);
int hScreen = Utils.getScreenHeight(this);
float ratio = 1.0f * wScreen / hScreen;
if (ratio >= 0.75f) {
wView = wScreen;
hView = (int) (0.75f * wScreen + 0.5f);
} else {
hView = hScreen;
wView = (int) (1.25f * hScreen + 0.5f);
}
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
wlock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, "fb");
wlock.acquire();
view = new GLSurfaceView(Main1Activity.this);
view.setEGLContextClientVersion(2);
view.setRenderer(new GLSurfaceView.Renderer() {
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
openCamera(0);
mCamera.startPreview();
CmOpenGLES.init(WIDTH, HEIGHT);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
//CmOpenGLES.changeLayout(width, height);
GLES20.glViewport(0, 0,wView , hView);
}
@Override
public void onDrawFrame(GL10 gl) {
if (mData != null)
{
CmOpenGLES.drawFrame(mData, SIZE);
}
}
});
setContentView(view);
}
/**
* 相機初始化
*/
private void initCamera() {
if (mCamera != null) {
try {
Camera.Parameters params = mCamera.getParameters();
params.setExposureCompensation(0);
if (getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
params.set("orientation", "portrait");
mCamera.setDisplayOrientation(90);
params.setRotation(90);
} else {
params.set("orientation", "landscape");
mCamera.setDisplayOrientation(0);
params.setRotation(0);
}
params.setPreviewSize(WIDTH, HEIGHT);
// 實現自動對焦
List<String> focusModes = params.getSupportedFocusModes();
if (focusModes.contains("continuous-video")) {
params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
}
mCamera.setParameters(params);
mCamera.getParameters().setPreviewFormat(ImageFormat.NV21);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 打開攝像頭
*/
public void openCamera(int id) {
int mCameraCount = Camera.getNumberOfCameras();
int curCameraIndex;
if (mCameraCount > 1) {
curCameraIndex = Camera.CameraInfo.CAMERA_FACING_FRONT;
CAMERA_FACING_BACK_FRONT = 1;
} else {
curCameraIndex = Camera.CameraInfo.CAMERA_FACING_BACK;
CAMERA_FACING_BACK_FRONT = 0;
}
mCamera = Camera.open(curCameraIndex);
initCamera();
try {
mCamera.addCallbackBuffer(mData);
mCamera.setPreviewCallback(Main1Activity.this);
mCamera.setPreviewTexture(new SurfaceTexture(10));
} catch (IOException e) {
Log.w(TAG, "setPreviewTexture error e = " + e.getMessage());
}
}
@Override
protected void onResume() {
super.onResume();
view.onResume();
}
@Override
protected void onPause() {
super.onPause();
view.onPause();
mCamera.stopPreview();
wlock.release();
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
if (DEBUG)
{
Log.i(TAG, "onPreviewFrame()");
}
mData = data;
camera.addCallbackBuffer(data);
}
}
CmOpenGLES.java
package cm.opengles;
public class CmOpenGLES {
static {
System.loadLibrary("CameraOpenGLES");
}
public static native void init(int width, int height);
public static native void release();
public static native void changeLayout(int width, int height);
public static native void drawFrame(byte[] data, int size);
}