void CallbackPipeline::do_capture(JNIEnv *env) { ENTER(); uvc_frame_t *frame; uvc_frame_t *temp = get_frame(default_frame_size); uvc_frame_t *callback_frame; uint32_t width = 0, height = 0; size_t sz = default_frame_size; if (LIKELY(temp)) { for (; isRunning() && isCapturing();) { frame = waitCaptureFrame(); if ((LIKELY(frame))) { if (UNLIKELY((width != frame->width) || (height != frame->height))) { width = frame->width; height = frame->height; callbackPixelFormatChanged(width, height); uvc_ensure_frame_size(temp, callbackPixelBytes); sz = callbackPixelBytes; } if (mFrameCallbackObj) { callback_frame = frame; sz = frame->actual_bytes; if (mFrameCallbackFunc) { callback_frame = temp; sz = callbackPixelBytes; int b = mFrameCallbackFunc(frame, temp); if (UNLIKELY(b)) { LOGW("failed to convert to callback frame"); goto SKIP; } } jobject buf = env->NewDirectByteBuffer(callback_frame->data, callbackPixelBytes); env->CallVoidMethod(mFrameCallbackObj, iframecallback_fields.onFrame, buf); env->ExceptionClear(); env->DeleteLocalRef(buf); } SKIP: recycle_frame(frame); } } recycle_frame(temp); } EXIT(); }
int UVCPreview::setFrameCallback(JNIEnv *env, jobject frame_callback_obj, int pixel_format) { ENTER(); pthread_mutex_lock(&capture_mutex); { if (isRunning() && isCapturing()) { mIsCapturing = false; if (mFrameCallbackObj) { pthread_cond_signal(&capture_sync); pthread_cond_wait(&capture_sync, &capture_mutex); // wait finishing capturing } } if (!env->IsSameObject(mFrameCallbackObj, frame_callback_obj)) { iframecallback_fields.onFrame = NULL; if (mFrameCallbackObj) { env->DeleteGlobalRef(mFrameCallbackObj); } mFrameCallbackObj = frame_callback_obj; if (frame_callback_obj) { // get method IDs of Java object for callback jclass clazz = env->GetObjectClass(frame_callback_obj); if (LIKELY(clazz)) { iframecallback_fields.onFrame = env->GetMethodID(clazz, "onFrame", "(Ljava/nio/ByteBuffer;)V"); } else { LOGW("failed to get object class"); } env->ExceptionClear(); if (!iframecallback_fields.onFrame) { LOGE("Can't find IFrameCallback#onFrame"); env->DeleteGlobalRef(frame_callback_obj); mFrameCallbackObj = frame_callback_obj = NULL; } } } if (frame_callback_obj) { mPixelFormat = pixel_format; callbackPixelFormatChanged(); } } pthread_mutex_unlock(&capture_mutex); RETURN(0, int); }