195 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			195 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
/*
 | 
						|
 * Copyright (C) 2008 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.
 | 
						|
 */
 | 
						|
 | 
						|
#define APK_VERSION	"V1.3"
 | 
						|
#define LOG_TAG "HdmiInput-navtive"
 | 
						|
//#define LOG_NDEBUG 0
 | 
						|
 | 
						|
#include <utils/Log.h>
 | 
						|
#include <jni.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
#include <utils/Log.h>
 | 
						|
#include <unistd.h>
 | 
						|
#include <fcntl.h>
 | 
						|
#include <errno.h>
 | 
						|
#include <sys/ioctl.h>
 | 
						|
#include <sys/mman.h>
 | 
						|
#include <linux/videodev2.h>
 | 
						|
#include <sys/stat.h>
 | 
						|
#include <sys/types.h>
 | 
						|
#include <linux/v4l2-subdev.h>
 | 
						|
 | 
						|
#define LOGE(msg,...)   ALOGE("%s(%d): " msg ,__FUNCTION__,__LINE__,##__VA_ARGS__)
 | 
						|
#define LOGD(msg,...)   ALOGD("%s(%d): " msg ,__FUNCTION__,__LINE__,##__VA_ARGS__)
 | 
						|
#define LOGV(msg,...)   ALOGV("%s(%d): " msg ,__FUNCTION__,__LINE__,##__VA_ARGS__)
 | 
						|
 | 
						|
 | 
						|
static int camFd;
 | 
						|
static void getDeviceFormat(int *format)
 | 
						|
{
 | 
						|
    struct v4l2_control control;
 | 
						|
    memset(&control, 0, sizeof(struct v4l2_control));
 | 
						|
    control.id = V4L2_CID_DV_RX_POWER_PRESENT;
 | 
						|
    int err = ioctl(camFd, VIDIOC_G_CTRL, &control);
 | 
						|
    if (err < 0) {
 | 
						|
        LOGV("Set POWER_PRESENT failed ,%d(%s)", errno, strerror(errno));
 | 
						|
    }
 | 
						|
 | 
						|
    unsigned int noSignalAndSync = 0;
 | 
						|
    ioctl(camFd, VIDIOC_G_INPUT, &noSignalAndSync);
 | 
						|
    LOGV("noSignalAndSync ? %s",noSignalAndSync?"YES":"NO");
 | 
						|
 | 
						|
    struct v4l2_dv_timings dv_timings;
 | 
						|
    memset(&dv_timings, 0 ,sizeof(struct v4l2_dv_timings));
 | 
						|
    err = ioctl(camFd, VIDIOC_SUBDEV_QUERY_DV_TIMINGS, &dv_timings);
 | 
						|
    if (err < 0) {
 | 
						|
        LOGV("Set VIDIOC_SUBDEV_QUERY_DV_TIMINGS failed ,%d(%s)", errno, strerror(errno));
 | 
						|
    }
 | 
						|
 | 
						|
    format[0] = dv_timings.bt.width;
 | 
						|
    format[1] = dv_timings.bt.height;
 | 
						|
    format[2] = control.value && !noSignalAndSync;
 | 
						|
}
 | 
						|
 | 
						|
static jintArray getFormat(JNIEnv *env, jobject thiz)
 | 
						|
{
 | 
						|
    (void)thiz;
 | 
						|
    jintArray array = env->NewIntArray(3);
 | 
						|
    jint *result = new jint[3];
 | 
						|
    getDeviceFormat(result);
 | 
						|
    env->SetIntArrayRegion(array, 0, 3, result);
 | 
						|
    delete[] result;
 | 
						|
    return array;
 | 
						|
}
 | 
						|
 | 
						|
static void openDevice(JNIEnv *env, jobject thiz)
 | 
						|
{
 | 
						|
    (void)*env;
 | 
						|
    (void)thiz;
 | 
						|
 | 
						|
    char video_name[64];
 | 
						|
    memset(video_name, 0, sizeof(video_name));
 | 
						|
    strcat(video_name, "/dev/v4l-subdev2");
 | 
						|
 | 
						|
    camFd = open(video_name, O_RDWR);
 | 
						|
    if (camFd < 0) {
 | 
						|
        LOGE("open %s failed,erro=%s",video_name,strerror(errno));
 | 
						|
    } else {
 | 
						|
        LOGD("open %s success,fd=%d",video_name,camFd);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static void closeDevice(JNIEnv *env, jobject thiz)
 | 
						|
{
 | 
						|
    (void)*env;
 | 
						|
    (void)thiz;
 | 
						|
    LOGD("close device");
 | 
						|
    if(camFd > 0) {
 | 
						|
        close(camFd);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static const char *classPathName = "com/android/rockchip/camera2/util/JniCameraCall";
 | 
						|
 | 
						|
static JNINativeMethod methods[] = {
 | 
						|
    {"getFormat", "()[I", (void *)getFormat},
 | 
						|
    {"openDevice", "()V", (void *)openDevice},
 | 
						|
    {"closeDevice", "()V", (void *)closeDevice},
 | 
						|
};
 | 
						|
 | 
						|
/*
 | 
						|
 * Register several native methods for one class.
 | 
						|
 */
 | 
						|
static int registerNativeMethods(JNIEnv *env, const char *className,
 | 
						|
                                JNINativeMethod *gMethods, int numMethods)
 | 
						|
{
 | 
						|
    jclass clazz;
 | 
						|
 | 
						|
    clazz = env->FindClass(className);
 | 
						|
    if (clazz == NULL)
 | 
						|
    {
 | 
						|
        ALOGE("Native registration unable to find class '%s'", className);
 | 
						|
        return JNI_FALSE;
 | 
						|
    }
 | 
						|
    if (env->RegisterNatives(clazz, gMethods, numMethods) < 0)
 | 
						|
    {
 | 
						|
        ALOGE("RegisterNatives failed for '%s'", className);
 | 
						|
        return JNI_FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    return JNI_TRUE;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Register native methods for all classes we know about.
 | 
						|
 *
 | 
						|
 * returns JNI_TRUE on success.
 | 
						|
 */
 | 
						|
static int registerNatives(JNIEnv *env)
 | 
						|
{
 | 
						|
    if (!registerNativeMethods(env, classPathName,
 | 
						|
            methods, sizeof(methods) / sizeof(methods[0])))
 | 
						|
    {
 | 
						|
        return JNI_FALSE;
 | 
						|
    }
 | 
						|
 | 
						|
    return JNI_TRUE;
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
/*
 | 
						|
 * This is called by the VM when the shared library is first loaded.
 | 
						|
 */
 | 
						|
 | 
						|
typedef union {
 | 
						|
    JNIEnv *env;
 | 
						|
    void *venv;
 | 
						|
} UnionJNIEnvToVoid;
 | 
						|
 | 
						|
jint JNI_OnLoad(JavaVM *vm, void *reserved)
 | 
						|
{
 | 
						|
    (void)reserved;
 | 
						|
    UnionJNIEnvToVoid uenv;
 | 
						|
    uenv.venv = NULL;
 | 
						|
    jint result = -1;
 | 
						|
    JNIEnv *env = NULL;
 | 
						|
 | 
						|
    ALOGI("JNI_OnLoad");
 | 
						|
    ALOGI("Apk Version: %s", APK_VERSION);
 | 
						|
 | 
						|
    if (vm->GetEnv(&uenv.venv, JNI_VERSION_1_4) != JNI_OK)
 | 
						|
    {
 | 
						|
        ALOGE("ERROR: GetEnv failed");
 | 
						|
        goto bail;
 | 
						|
    }
 | 
						|
    env = uenv.env;
 | 
						|
 | 
						|
    if (registerNatives(env) != JNI_TRUE)
 | 
						|
    {
 | 
						|
        ALOGE("ERROR: registerNatives failed");
 | 
						|
        goto bail;
 | 
						|
    }
 | 
						|
 | 
						|
    result = JNI_VERSION_1_4;
 | 
						|
 | 
						|
bail:
 | 
						|
    return result;
 | 
						|
}
 | 
						|
 |