chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1 @@
|
||||
misc/java/src/cpp/videoio_converters.hpp
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"ManualFuncs" : {
|
||||
"IStreamReader" : {
|
||||
"IStreamReader" : {
|
||||
"j_code" : [
|
||||
"\n",
|
||||
"/**",
|
||||
" * Constructor of streaming callback object with abstract 'read' and 'seek' methods that should be implemented in Java code.<br>",
|
||||
" * <b>NOTE</b>: Implemented callbacks should be called from the creation thread to avoid JNI performance degradation",
|
||||
"*/",
|
||||
"protected IStreamReader() { nativeObj = 0; }",
|
||||
"\n"
|
||||
],
|
||||
"jn_code": [],
|
||||
"cpp_code": []
|
||||
}
|
||||
}
|
||||
},
|
||||
"func_arg_fix" : {
|
||||
"read": { "buffer": {"ctype" : "byte[]"} }
|
||||
},
|
||||
"type_dict": {
|
||||
"Ptr_IStreamReader": {
|
||||
"j_type": "IStreamReader",
|
||||
"jn_type": "IStreamReader",
|
||||
"jni_name": "n_%(n)s",
|
||||
"jni_type": "jobject",
|
||||
"jni_var": "auto n_%(n)s = makePtr<JavaStreamReader>(env, source)",
|
||||
"j_import": "org.opencv.videoio.IStreamReader"
|
||||
},
|
||||
"vector_VideoCaptureAPIs": {
|
||||
"j_type": "List<Integer>",
|
||||
"jn_type": "List<Integer>",
|
||||
"jni_type": "jobject",
|
||||
"jni_var": "std::vector< cv::VideoCaptureAPIs > %(n)s",
|
||||
"suffix": "Ljava_util_List",
|
||||
"v_type": "vector_VideoCaptureAPIs"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
#include "videoio_converters.hpp"
|
||||
|
||||
class JNIEnvHandler
|
||||
{
|
||||
public:
|
||||
JNIEnvHandler(JavaVM* _vm) : vm(_vm)
|
||||
{
|
||||
jint res = vm->GetEnv((void**)&env, JNI_VERSION_1_6);
|
||||
if (res == JNI_EDETACHED)
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
res = vm->AttachCurrentThread(&env, NULL);
|
||||
#else
|
||||
res = vm->AttachCurrentThread((void**)&env, NULL);
|
||||
#endif // __ANDROID__
|
||||
detach = true;
|
||||
}
|
||||
}
|
||||
|
||||
~JNIEnvHandler()
|
||||
{
|
||||
if (env && detach)
|
||||
{
|
||||
vm->DetachCurrentThread();
|
||||
}
|
||||
}
|
||||
|
||||
JavaVM* vm;
|
||||
JNIEnv* env = nullptr;
|
||||
bool detach = false;
|
||||
};
|
||||
|
||||
JavaStreamReader::JavaStreamReader(JNIEnv* env, jobject _obj)
|
||||
{
|
||||
obj = env->NewGlobalRef(_obj);
|
||||
jclass cls = env->GetObjectClass(obj);
|
||||
m_read = env->GetMethodID(cls, "read", "([BJ)J");
|
||||
m_seek = env->GetMethodID(cls, "seek", "(JI)J");
|
||||
env->GetJavaVM(&vm);
|
||||
}
|
||||
|
||||
JavaStreamReader::~JavaStreamReader()
|
||||
{
|
||||
JNIEnvHandler handler(vm);
|
||||
JNIEnv* env = handler.env;
|
||||
if (!env)
|
||||
return;
|
||||
env->DeleteGlobalRef(obj);
|
||||
}
|
||||
|
||||
long long JavaStreamReader::read(char* buffer, long long size)
|
||||
{
|
||||
if (!m_read)
|
||||
return 0;
|
||||
JNIEnvHandler handler(vm);
|
||||
JNIEnv* env = handler.env;
|
||||
if (!env)
|
||||
return 0;
|
||||
jbyteArray jBuffer = env->NewByteArray(static_cast<jsize>(size));
|
||||
if (!jBuffer)
|
||||
return 0;
|
||||
jlong res = env->CallLongMethod(obj, m_read, jBuffer, size);
|
||||
env->GetByteArrayRegion(jBuffer, 0, static_cast<jsize>(size), reinterpret_cast<jbyte*>(buffer));
|
||||
env->DeleteLocalRef(jBuffer);
|
||||
return res;
|
||||
}
|
||||
|
||||
long long JavaStreamReader::seek(long long offset, int way)
|
||||
{
|
||||
JNIEnvHandler handler(vm);
|
||||
JNIEnv* env = handler.env;
|
||||
if (!env)
|
||||
return 0;
|
||||
if (!m_seek)
|
||||
return 0;
|
||||
return env->CallLongMethod(obj, m_seek, offset, way);
|
||||
}
|
||||
|
||||
// Same as dnn::vector_Target_to_List
|
||||
jobject vector_VideoCaptureAPIs_to_List(JNIEnv* env, std::vector<cv::VideoCaptureAPIs>& vs)
|
||||
{
|
||||
static jclass juArrayList = ARRAYLIST(env);
|
||||
static jmethodID m_create = CONSTRUCTOR(env, juArrayList);
|
||||
jmethodID m_add = LIST_ADD(env, juArrayList);
|
||||
|
||||
static jclass jInteger = env->FindClass("java/lang/Integer");
|
||||
static jmethodID m_create_Integer = env->GetMethodID(jInteger, "<init>", "(I)V");
|
||||
|
||||
jobject result = env->NewObject(juArrayList, m_create, vs.size());
|
||||
for (size_t i = 0; i < vs.size(); ++i)
|
||||
{
|
||||
jobject element = env->NewObject(jInteger, m_create_Integer, vs[i]);
|
||||
env->CallBooleanMethod(result, m_add, element);
|
||||
env->DeleteLocalRef(element);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef VIDEOIO_CONVERTERS_HPP
|
||||
#define VIDEOIO_CONVERTERS_HPP
|
||||
|
||||
#include <jni.h>
|
||||
#include "opencv_java.hpp"
|
||||
#include "opencv2/core.hpp"
|
||||
#include "opencv2/videoio.hpp"
|
||||
|
||||
class JavaStreamReader : public cv::IStreamReader
|
||||
{
|
||||
public:
|
||||
JavaStreamReader(JNIEnv* env, jobject obj);
|
||||
~JavaStreamReader();
|
||||
long long read(char* buffer, long long size) CV_OVERRIDE;
|
||||
long long seek(long long offset, int way) CV_OVERRIDE;
|
||||
|
||||
private:
|
||||
JavaVM* vm;
|
||||
jobject obj;
|
||||
jmethodID m_read, m_seek;
|
||||
};
|
||||
|
||||
jobject vector_VideoCaptureAPIs_to_List(JNIEnv* env, std::vector<cv::VideoCaptureAPIs>& vs);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,148 @@
|
||||
package org.opencv.test.videoio;
|
||||
|
||||
import java.util.List;
|
||||
import java.io.File;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.io.IOException;
|
||||
import java.io.FileNotFoundException;
|
||||
|
||||
import org.opencv.core.Mat;
|
||||
import org.opencv.core.Size;
|
||||
import org.opencv.core.MatOfInt;
|
||||
import org.opencv.videoio.Videoio;
|
||||
import org.opencv.videoio.VideoCapture;
|
||||
import org.opencv.videoio.IStreamReader;
|
||||
|
||||
import org.opencv.test.OpenCVTestCase;
|
||||
|
||||
public class VideoCaptureTest extends OpenCVTestCase {
|
||||
private final static String ENV_OPENCV_TEST_DATA_PATH = "OPENCV_TEST_DATA_PATH";
|
||||
|
||||
private VideoCapture capture;
|
||||
private boolean isOpened;
|
||||
private boolean isSucceed;
|
||||
private File testDataPath;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
capture = null;
|
||||
isSucceed = false;
|
||||
isOpened = false;
|
||||
|
||||
String envTestDataPath = System.getenv(ENV_OPENCV_TEST_DATA_PATH);
|
||||
|
||||
if(envTestDataPath == null) throw new Exception(ENV_OPENCV_TEST_DATA_PATH + " has to be defined!");
|
||||
|
||||
testDataPath = new File(envTestDataPath);
|
||||
}
|
||||
|
||||
public void testGrab() {
|
||||
capture = new VideoCapture();
|
||||
isSucceed = capture.grab();
|
||||
assertFalse(isSucceed);
|
||||
}
|
||||
|
||||
public void testIsOpened() {
|
||||
capture = new VideoCapture();
|
||||
assertFalse(capture.isOpened());
|
||||
}
|
||||
|
||||
public void testDefaultConstructor() {
|
||||
capture = new VideoCapture();
|
||||
assertNotNull(capture);
|
||||
assertFalse(capture.isOpened());
|
||||
}
|
||||
|
||||
public void testConstructorWithFilename() {
|
||||
capture = new VideoCapture("some_file.avi");
|
||||
assertNotNull(capture);
|
||||
}
|
||||
|
||||
public void testConstructorWithFilenameAndExplicitlySpecifiedAPI() {
|
||||
capture = new VideoCapture("some_file.avi", Videoio.CAP_ANY);
|
||||
assertNotNull(capture);
|
||||
}
|
||||
|
||||
public void testConstructorWithIndex() {
|
||||
capture = new VideoCapture(0);
|
||||
assertNotNull(capture);
|
||||
}
|
||||
|
||||
public void testConstructorWithIndexAndExplicitlySpecifiedAPI() {
|
||||
capture = new VideoCapture(0, Videoio.CAP_ANY);
|
||||
assertNotNull(capture);
|
||||
}
|
||||
|
||||
public void testConstructorStream() throws FileNotFoundException {
|
||||
// Check backend is available
|
||||
Integer apiPref = Videoio.CAP_ANY;
|
||||
for (Integer backend : Videoio.getStreamBufferedBackends())
|
||||
{
|
||||
if (!Videoio.hasBackend(backend))
|
||||
continue;
|
||||
if (!Videoio.isBackendBuiltIn(backend))
|
||||
{
|
||||
int[] abi = new int[1], api = new int[1];
|
||||
Videoio.getStreamBufferedBackendPluginVersion(backend, abi, api);
|
||||
if (abi[0] < 1 || (abi[0] == 1 && api[0] < 2))
|
||||
continue;
|
||||
}
|
||||
apiPref = backend;
|
||||
break;
|
||||
}
|
||||
if (apiPref == Videoio.CAP_ANY)
|
||||
{
|
||||
throw new TestSkipException();
|
||||
}
|
||||
|
||||
RandomAccessFile f = new RandomAccessFile(new File(testDataPath, "cv/video/768x576.avi"), "r");
|
||||
|
||||
IStreamReader stream = new IStreamReader()
|
||||
{
|
||||
@Override
|
||||
public long read(byte[] buffer, long size)
|
||||
{
|
||||
assertEquals(buffer.length, size);
|
||||
try
|
||||
{
|
||||
return Math.max(f.read(buffer), 0);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.out.println(e.getMessage());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long seek(long offset, int origin)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (origin == 0)
|
||||
f.seek(offset);
|
||||
else if (origin == 1)
|
||||
f.seek(f.getFilePointer() + offset);
|
||||
else if (origin == 2)
|
||||
f.seek(f.length() + offset);
|
||||
return f.getFilePointer();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
System.out.println(e.getMessage());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
capture = new VideoCapture(stream, apiPref, new MatOfInt());
|
||||
assertNotNull(capture);
|
||||
assertTrue(capture.isOpened());
|
||||
|
||||
Mat frame = new Mat();
|
||||
assertTrue(capture.read(frame));
|
||||
assertEquals(frame.rows(), 576);
|
||||
assertEquals(frame.cols(), 768);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user