下载源码(需翻墙),Android Studio 新建一个 NDK 项目,源码拷贝到 cpp 目录下。
include 下面是头文件, source 下面是源码,其它文件基本用不到不用管。CMakeLists.txt 是 cmake 编译脚本, 现在android ndk 默认都是用 cmake 编译。
// 格式转换(NV21、NV12、I420等格式互转)
libyuv\include\libyuv\convert.h
libyuv\include\libyuv\convert_from.h
// 图像处理(镜像、旋转、缩放、裁剪)
libyuv\include\libyuv\planar_functions.h
libyuv\include\libyuv\rotate.h
libyuv\include\libyuv\scale.h
下面编写我们自己的 CMakeLists , libyuv 作为一个子项目单独编译,按下面修改
cmake_minimum_required(VERSION 3.4.1)
include_directories(libyuv/include) #add
add_subdirectory(libyuv ./build) #add
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
native-lib.cpp )
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
target_link_libraries( # Specifies the target library.
native-lib
# Links the target library to the log library
# included in the NDK.
${log-lib}
yuv) #add
这个时候点击Make Project,应该就可以得到.so文件了。
YuvJni.cpp 是JNI源码,包装一下 libyuv 的代码。需要对各种 YUV 格式比较熟悉,否则也包装不出来。
#include <jni.h>
#include "libyuv.h"
/**
* NV21 -> I420
*/
extern "C"
JNIEXPORT void JNICALL
Java_com_libyuv_util_YuvUtil_NV21ToI420(JNIEnv *env, jclass clazz, jbyteArray src_nv21_array,
jint width, jint height, jbyteArray dst_i420_array) {
jbyte *src_nv21_data = env->GetByteArrayElements(src_nv21_array, JNI_FALSE);
jbyte *dst_i420_data = env->GetByteArrayElements(dst_i420_array, JNI_FALSE);
jint src_y_size = width * height;
jint src_u_size = (width >> 1) * (height >> 1);
jbyte *src_nv21_y_data = src_nv21_data;
jbyte *src_nv21_vu_data = src_nv21_data + src_y_size;
jbyte *dst_i420_y_data = dst_i420_data;
jbyte *dst_i420_u_data = dst_i420_data + src_y_size;
jbyte *dst_i420_v_data = dst_i420_data + src_y_size + src_u_size;
libyuv::NV21ToI420((const uint8_t *) src_nv21_y_data, width,
(const uint8_t *) src_nv21_vu_data, width,
(uint8_t *) dst_i420_y_data, width,
(uint8_t *) dst_i420_u_data, width >> 1,
(uint8_t *) dst_i420_v_data, width >> 1,
width, height);
env->ReleaseByteArrayElements(src_nv21_array, src_nv21_data, 0);
env->ReleaseByteArrayElements(dst_i420_array, dst_i420_data, 0);
}
YUVUtil.java 定义了 native 方法
package com.example.YuvLib;
public class YuvUtil {
static {
System.loadLibrary("yuvutil");
}
/**
* NV21 -> I420
*
* @param src_nv21_data 原始NV21数据
* @param width 原始宽
* @param height 原始高
* @param dst_i420_data 目前I420数据
*/
public static native void NV21ToI420(byte[] src_nv21_data, int width, int height, byte[] dst_i420_data);
/**
* I420 -> NV21
*
* @param src_i420_data
* @param width
* @param height
* @param dst_nv21_data
*/
public static native void I420ToNV21(byte[] src_i420_data, int width, int height, byte[] dst_nv21_data);
}