C/C++&java communicate with each other 之 video snapshot
场景: android应用层间隔1秒调用底层driver上C API,获取到framebuffer, 提供给android layer业务分析。
TvVideoRecord 主要功能
1. 申请一个ByteBuffer对象frameBuffer
2. 将frameBuffer传给底层c接口jni_getFrameBuffer, 该函数会将TV画面帧填充进去
3. 最后调用接口ITVCaptureVideoListener onSuccess方法,将frameBuffer传给应用层的TvCaptureVideolistenerDemo
做相应处理,如save, 识别等等。
ITVCaptureVideoListener 功能:
业务层TVCaptureVideoListenerDemo实现该接口,可以监听底层capture的情况,获取到frameBuffer并做相应处理,或获知错误情况进行处理
而在jni层处理时,应注意的一些性能和内存泄漏问题
1.
JNI层主动更新java层对象,通过cache jfield来优化频繁调用例如GetFieldID映射java字段到jni.
只需SetIntField。
static int cacheVRegFieldID(JNIEnv* env)
{
jclass clazz = (*env)->FindClass(env, "com/smarttv/tvshare/TvVideoRecord$VideoRegion");
if (0 == clazz) {
__android_log_print(ANDROID_LOG_ERROR, TAGSTR, "FindClass VideoRegion returned 0\n");
return -1;
}
wid = (*env)->GetFieldID(env, clazz, "mWidth", "I");
hid = (*env)->GetFieldID(env, clazz, "mHeight", "I");
if (0 == wid || 0 == hid)
{
__android_log_print(ANDROID_LOG_ERROR, TAGSTR, "GetFieldID returned 0\n");
return -1;
}
return 0;
}
2. 容易发生jni层 内存泄漏,如java对象转为C处理时
如GetByteArrayElements, 对应ReleaseByteArrayElements需要调用来释放资源。
GetStringUTFChars-ReleaseStringUTFChars。