Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Libraries and executables have been labeled in the list below to help distinguis
#### Qt 5 (libqt5)
* <http://www.qt.io/qt5/> **(Library)**

* Qt5 is used to display video, store image data, composite images,
* Qt5/Qt6 is used to display video, store image data, composite images,
apply image effects, and many other utility functions,
such as file system manipulation, high resolution timers, etc.

Expand Down Expand Up @@ -201,6 +201,7 @@ Following are some of the flags you might need to set when generating your build
* `-DCMAKE_PREFIX_PATH=/extra/path/to/search/for/libraries/`
* `-DUSE_SYSTEM_JSONCPP=0` (default: auto if discovered)
* `-DENABLE_MAGICK=0` (default: auto if discovered)
* `-DUSE_QT6=AUTO|ON|OFF` (default: `AUTO`; prefers Qt6 when available and CMake ≥3.16, `ON` forces Qt6, `OFF` forces Qt5)

#### Options to compile bindings for a specific Python installation
* `-DPYTHON_INCLUDE_DIR=/location/of/python/includes/`
Expand Down
71 changes: 71 additions & 0 deletions bindings/java/openshot.i
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
%include "std_vector.i"
%include "std_map.i"
%include <stdint.i>
%apply uint64_t { uintptr_t };

// Ignore QWidget overloads (Qt types are not wrapped in Java bindings)
%ignore openshot::QtPlayer::SetQWidget(QWidget *);

/* Unhandled STL Exception Handling */
%include <std_except.i>
Expand All @@ -52,6 +56,34 @@
#%template() std::vector<std::pair<std::string, std::string>>;
%template() std::vector<std::vector<float>>;

%inline %{
typedef struct OpenShotByteBuffer {
const unsigned char* data;
int size;
} OpenShotByteBuffer;
%}

%typemap(jni) OpenShotByteBuffer "jbyteArray"
%typemap(jstype) OpenShotByteBuffer "byte[]"
%typemap(jtype) OpenShotByteBuffer "byte[]"
%typemap(javaout) OpenShotByteBuffer {
return $jnicall;
}
%typemap(out) OpenShotByteBuffer {
if ($1.data && $1.size > 0) {
jbyteArray jarr = jenv->NewByteArray($1.size);
if (jarr == NULL) {
SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "Unable to allocate byte array");
return NULL;
}
jenv->SetByteArrayRegion(jarr, 0, $1.size,
reinterpret_cast<const jbyte*>($1.data));
$result = jarr;
} else {
$result = NULL;
}
}

%{
#include "OpenShotVersion.h"
#include "ReaderBase.h"
Expand Down Expand Up @@ -118,6 +150,45 @@
/* Deprecated */
%template(AudioDeviceInfoVector) std::vector<openshot::AudioDeviceInfo>;

%extend openshot::Frame {
OpenShotByteBuffer GetPixelsBytes() {
OpenShotByteBuffer out = {NULL, 0};
std::shared_ptr<QImage> img = $self->GetImage();
if (!img) return out;

const int size = img->bytesPerLine() * img->height();

const unsigned char* p = $self->GetPixels();
if (!p || size <= 0) return out;

out.data = p;
out.size = size;
return out;
}

OpenShotByteBuffer GetPixelsRowBytes(int row) {
OpenShotByteBuffer out = {NULL, 0};
std::shared_ptr<QImage> img = $self->GetImage();
if (!img) return out;

if (row < 0 || row >= img->height()) {
return out;
}

const unsigned char* p = $self->GetPixels(row);
if (!p) return out;

out.data = p;
out.size = img->bytesPerLine();
return out;
}

int GetBytesPerLine() {
std::shared_ptr<QImage> img = $self->GetImage();
return img ? img->bytesPerLine() : 0;
}
}

%include "OpenShotVersion.h"
%include "ReaderBase.h"
%include "WriterBase.h"
Expand Down
183 changes: 183 additions & 0 deletions bindings/python/openshot.i
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,18 @@
%include "std_vector.i"
%include "std_map.i"
%include <stdint.i>
%apply uint64_t { uintptr_t };

class QWidget;

/* Unhandled STL Exception Handling */
%include <std_except.i>

/* Include shared pointer code */
%include <std_shared_ptr.i>

%typemap(in) QWidget *;

/* Mark these classes as shared_ptr classes */
#ifdef USE_IMAGEMAGICK
%shared_ptr(Magick::Image)
Expand Down Expand Up @@ -98,6 +103,100 @@
#include "Timeline.h"
#include "Qt/VideoCacheThread.h"
#include "ZmqLogger.h"
#include <QtWidgets/QWidget>

static void *openshot_swig_pylong_as_ptr(PyObject *obj) {
if (!obj) {
return nullptr;
}

unsigned long long ull = PyLong_AsUnsignedLongLong(obj);
if (!PyErr_Occurred()) {
return reinterpret_cast<void*>(static_cast<uintptr_t>(ull));
}
PyErr_Clear();

long long ll = PyLong_AsLongLong(obj);
if (!PyErr_Occurred()) {
return reinterpret_cast<void*>(static_cast<intptr_t>(ll));
}
PyErr_Clear();

return nullptr;
}

static void *openshot_swig_get_qwidget_ptr(PyObject *obj) {
if (!obj || obj == Py_None) {
return nullptr;
}

if (PyLong_Check(obj)) {
void *ptr = openshot_swig_pylong_as_ptr(obj);
return ptr;
}

const char *sip_modules[] = {"sip", "PyQt6.sip", "PyQt5.sip"};
for (size_t i = 0; i < (sizeof(sip_modules) / sizeof(sip_modules[0])); ++i) {
PyObject *mod = PyImport_ImportModule(sip_modules[i]);
if (!mod) {
PyErr_Clear();
continue;
}
PyObject *unwrap = PyObject_GetAttrString(mod, "unwrapinstance");
if (unwrap && PyCallable_Check(unwrap)) {
PyObject *addr = PyObject_CallFunctionObjArgs(unwrap, obj, NULL);
if (addr) {
void *ptr = openshot_swig_pylong_as_ptr(addr);
Py_DECREF(addr);
if (ptr) {
Py_DECREF(unwrap);
Py_DECREF(mod);
return ptr;
}
}
}
Py_XDECREF(unwrap);
Py_DECREF(mod);
}

const char *shiboken_modules[] = {"shiboken6", "shiboken2"};
for (size_t i = 0; i < (sizeof(shiboken_modules) / sizeof(shiboken_modules[0])); ++i) {
PyObject *mod = PyImport_ImportModule(shiboken_modules[i]);
if (!mod) {
PyErr_Clear();
continue;
}
PyObject *get_ptr = PyObject_GetAttrString(mod, "getCppPointer");
if (get_ptr && PyCallable_Check(get_ptr)) {
PyObject *ptrs = PyObject_CallFunctionObjArgs(get_ptr, obj, NULL);
if (ptrs) {
PyObject *addr = ptrs;
if (PyTuple_Check(ptrs) && PyTuple_Size(ptrs) > 0) {
addr = PyTuple_GetItem(ptrs, 0);
}
void *ptr = openshot_swig_pylong_as_ptr(addr);
Py_DECREF(ptrs);
if (ptr) {
Py_DECREF(get_ptr);
Py_DECREF(mod);
return ptr;
}
}
}
Py_XDECREF(get_ptr);
Py_DECREF(mod);
}

return nullptr;
}

static int openshot_swig_is_qwidget(PyObject *obj) {
void *ptr = openshot_swig_get_qwidget_ptr(obj);
if (ptr) {
return 1;
}
return obj == Py_None ? 1 : 0;
}

%}

Expand Down Expand Up @@ -138,6 +237,22 @@
}
}

%typemap(in) QWidget * {
void *ptr = openshot_swig_get_qwidget_ptr($input);
if (!ptr && $input != Py_None) {
SWIG_exception_fail(SWIG_TypeError, "Expected QWidget or Qt binding widget");
}
$1 = reinterpret_cast<QWidget*>(ptr);
}

%typemap(typecheck) QWidget * {
$1 = openshot_swig_is_qwidget($input);
}

%typemap(out) uintptr_t openshot::QtPlayer::GetRendererQObject {
$result = PyLong_FromLongLong((long long)(intptr_t)$1);
}



/* Wrap std templates (list, vector, etc...) */
Expand Down Expand Up @@ -284,6 +399,74 @@
}
}

%extend openshot::Frame {
PyObject* GetPixelsBytes() {
PyGILState_STATE gstate = PyGILState_Ensure();
PyObject* result = NULL;

std::shared_ptr<QImage> img = $self->GetImage();
if (!img) {
Py_INCREF(Py_None);
result = Py_None;
PyGILState_Release(gstate);
return result;
}

const Py_ssize_t size =
static_cast<Py_ssize_t>(img->bytesPerLine()) *
static_cast<Py_ssize_t>(img->height());

const unsigned char* p = img->constBits();
if (!p || size <= 0) {
Py_INCREF(Py_None);
result = Py_None;
PyGILState_Release(gstate);
return result;
}

result = PyBytes_FromStringAndSize(reinterpret_cast<const char*>(p), size);
PyGILState_Release(gstate);
return result;
}

PyObject* GetPixelsRowBytes(int row) {
PyGILState_STATE gstate = PyGILState_Ensure();
PyObject* result = NULL;

std::shared_ptr<QImage> img = $self->GetImage();
if (!img) {
Py_INCREF(Py_None);
result = Py_None;
PyGILState_Release(gstate);
return result;
}

if (row < 0 || row >= img->height()) {
PyErr_SetString(PyExc_IndexError, "row out of range");
PyGILState_Release(gstate);
return NULL;
}

const unsigned char* p = img->constScanLine(row);
if (!p) {
Py_INCREF(Py_None);
result = Py_None;
PyGILState_Release(gstate);
return result;
}

const Py_ssize_t row_bytes = static_cast<Py_ssize_t>(img->bytesPerLine());
result = PyBytes_FromStringAndSize(reinterpret_cast<const char*>(p), row_bytes);
PyGILState_Release(gstate);
return result;
}

int GetBytesPerLine() {
std::shared_ptr<QImage> img = $self->GetImage();
return img ? img->bytesPerLine() : 0;
}
}

%include "OpenShotVersion.h"
%include "ReaderBase.h"
%include "WriterBase.h"
Expand Down
Loading