Camera Display Using JNI

Objective

This document explains how to code a Port-Based Agent with native methods in legacy C code by way of JNI technology.

This is not intended to be a JNI tutorial. If you are not familiar with JNI technology, you can take a look at the JNI Sun Tutorial page.

Table of Contents

Introduction

For our robotics examples we have been using the Pioneer robots. They have a Sony camera and a frame grabber installed. C code is available to control the frame grabber features and for image processing. Since C code can deal with hardware and it is faster than Java code, it does not make sense to rewrite this code in Java. We developed a Java wrapper for the C code using Java Native Interface (JNI) technology.

Camera Display Example

In this example we develop a PBA driver agent (PBD) that samples the video camera and displays it.

C code is available to initialize the frame grabber and sample the video images in different formats. To hide implementation representations from the PBD, we develop a Java class JNIcamera that contains all the native method definitions and calls. This class is instantiated in the PBD and becomes an internal variable of the agent. The C code is compiled as a dynamic library that gets loaded at runtime, when the PBD is instantiated. Java Details

Here is a section of the JNIcamera source:

public class JNIcamera { //Native method declarations native int grabSingleFrame(); native int grabContFrame(); native int initFrameGrabber(); native void closeFrameGrabber(); native int startContCapture(); native int stopCapture(); // last display additions to library native void getByteFrame(byte[] frame); native void getIntFrame(int[] frame); public JNIcamera() { System.loadLibrary("JNIcamera"); System.err.println("Loading JNI library for camera-grabber"); } public synchronized int JNIgrabSingleFrame() { return grabSingleFrame(); } public synchronized int JNIgrabContFrame() { return grabContFrame(); } public synchronized int JNIinitFrameGrabber() { return initFrameGrabber(); } public synchronized void JNIgetByteFrame(byte[] frame) { getByteFrame(frame); } public synchronized void JNIgetIntFrame(int[] frame) { getIntFrame(frame); } }

A JNIcamera.so library file has to be created and setup in the library path for this class to load correctly. The library is created using the header file created from JNIcamera.class by java_h , that looks like this:

/* * Class: adaptive_support_vision_JNIcamera * Method: initFrameGrabber * Signature: ()I */ JNIEXPORT jint JNICALL Java_adaptive_support_vision_JNIcamera_initFrameGrabber (JNIEnv, jobject); /* * Class: adaptive_support_vision_JNIcamera * Method: grabSingleFrame * Signature: ()I */ JNIEXPORT jint JNICALL Java_adaptive_support_vision_JNIcamera_grabSingleFrame(JNIEnv, jobject); /* * Class: adaptive_support_vision_JNIcamera * Method: getIntFrame * Signature: ([I)V */ JNIEXPORT void JNICALL Java_adaptive_support_vision_JNIcamera_getIntFrame (JNIEnv, jobject, jintArray);

Therefore, the original C code has to be wrapped around these calls to be understandable by the Java Virtual Machine.

Note: The long names are due to the fact that JNIcamera is included in our package adaptive.support.vision.

Finally, the PBD main steps look like this: