您当前的位置:首页 > 计算机 > 编程开发 > 安卓(android)开发

libyuv编译

时间:02-05来源:作者:点击数:

在Android项目中使用libyuv

1、下载:https://github.com/lemenkov/libyuv(我在码云上也做了备份:https://gitee.com/daizhufei/libyuv),虽然这个不是官网,但是内容都是官网里保存过来的。

2、创建一个新的Android项目,模板使用Native C++,如下:

在这里插入图片描述

其它都是下一步即可,这样就创建出了一个带NDK环境的项目了,可以直接运行,效果如下:

在这里插入图片描述

3、把下载到的libyuv解压,然后把所有内容复制到andrroid studio项目中的cpp目录下,如下:

在这里插入图片描述

4、打开CMakeLists.txt,把项目自带的native-lib.cpp添加到如下位置:

在这里插入图片描述

这里需要注意,此时的CMakeLists中声明的so的文件名为:yuv,所以在MainActivity中加载so时也要使用这个名字,如下:

在这里插入图片描述

5、运行,如果能正常运行,说明编译就没问题了。

6、libyuv并没有提供java直接调用的对应JNI函数,需要我们自己去写JNI,打开“native-lib.cpp”,导入头文件:#include “libyuv.h”,这样就可以调用这里面的相关函数了,如下:

#include <jni.h>
#include <string>
#include "libyuv.h"

void YV12ToI420(jbyte *src_yv12_data, jint width, jint height, jbyte *dst_i420_data) {
    jbyte *src_yplane = src_yv12_data;
    jbyte *src_uplane = src_yv12_data + width * height;
    jbyte *src_vplane = src_uplane + (width * height / 4);
    jbyte *dst_yplane = dst_i420_data;
    jbyte *dst_uplane = dst_i420_data + width * height;
    jbyte *dst_vplane = dst_uplane + (width * height / 4);
    // YV12 is YVU => Use I420(YUV) copy and flip U and V.
    libyuv::I420Copy(
            (const uint8_t *) src_yplane, width,
            (const uint8_t *) src_vplane, width / 2,
            (const uint8_t *) src_uplane, width / 2,
            (uint8_t *) dst_yplane, width,
            (uint8_t *) dst_uplane, width / 2,
            (uint8_t *) dst_vplane, width / 2,
            width, height);
}

extern "C"
JNIEXPORT void JNICALL
Java_a_a_libyuv_MainActivity_YV12ToI420(JNIEnv *env, jobject thiz, jbyteArray yv12_bytes,
                                        jbyteArray i420_bytes, jint width, jint height) {
    jbyte *srcP = env->GetByteArrayElements(yv12_bytes, NULL);
    jbyte *destP = env->GetByteArrayElements(i420_bytes, NULL);
    YV12ToI420(srcP, width, height, destP);
    env->ReleaseByteArrayElements(yv12_bytes, srcP, 0);
    env->ReleaseByteArrayElements(i420_bytes, destP, 0);
}

extern "C" JNIEXPORT jstring JNICALL
Java_a_a_libyuv_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

MainActivity中的代码如下:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Example of a call to a native method
        findViewById<TextView>(R.id.sample_text).text = stringFromJNI()
    }

    /**
     * A native method that is implemented by the 'native-lib' native library,
     * which is packaged with this application.
     */
    external fun stringFromJNI(): String

    external fun YV12ToI420(yv12Bytes: ByteArray, i420Bytes: ByteArray, width: Int, height: Int)

    companion object {
        // Used to load the 'native-lib' library on application startup.
        init {
            System.loadLibrary("yuv")
        }
    }
}

说明:这里我们声明了一个YV12ToI420方法,我们把yv12的数据传到第1个参数中,创建一个新的空的数组,长度要与参数1的数组一样,传到参数2中,用于接收转换后的结果,参数3和4为视频的宽和高。

在libyuv中使用Logcat

在C中使用Logcat可参考另一篇文章:点此跳转

CMakeLists.txt中的相关设置如下:

在这里插入图片描述
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门