Skip to content

Commit

Permalink
Add experimental support for Java bindings for libopenshot. This gene…
Browse files Browse the repository at this point in the history
…rates the *.class and *.java files, and a JNI library (libopenshot-java.so) to invoke the actual C++ openshot library, and a openshotJNI.jar which contains all of these files.
  • Loading branch information
jonoomph committed Jun 8, 2024
1 parent d73763f commit c889996
Show file tree
Hide file tree
Showing 5 changed files with 287 additions and 13 deletions.
9 changes: 8 additions & 1 deletion bindings/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#
# @section LICENSE
#
# Copyright (c) 2008-2019 OpenShot Studios, LLC
# Copyright (c) 2008-2024 OpenShot Studios, LLC
#
# SPDX-License-Identifier: LGPL-3.0-or-later

Expand All @@ -16,6 +16,10 @@ IF(NOT DEFINED ENABLE_RUBY)
SET(ENABLE_RUBY 1)
ENDIF()

IF(NOT DEFINED ENABLE_JAVA)
SET(ENABLE_JAVA 0)
ENDIF()

############### INCLUDE EACH LANGUAGE BINDING ################
IF (ENABLE_PYTHON)
add_subdirectory(python)
Expand All @@ -25,3 +29,6 @@ IF (ENABLE_RUBY)
add_subdirectory(ruby)
ENDIF (ENABLE_RUBY)

IF (ENABLE_JAVA)
add_subdirectory(java)
ENDIF (ENABLE_JAVA)
86 changes: 86 additions & 0 deletions bindings/java/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
####################### CMakeLists.txt (libopenshot) #########################
# @brief CMake build file for libopenshot (used to generate Java SWIG bindings)
# @author Jonathan Thomas <[email protected]>
#
# @section LICENSE
#
# Copyright (c) 2008-2024 OpenShot Studios, LLC
#
# SPDX-License-Identifier: LGPL-3.0-or-later

############### JAVA BINDINGS ################
find_package(SWIG 4.0 REQUIRED)
include(${SWIG_USE_FILE})

### Enable some legacy SWIG behaviors in newer CMake versions
if (POLICY CMP0078)
cmake_policy(SET CMP0078 OLD)
endif()
if (POLICY CMP0086)
cmake_policy(SET CMP0086 OLD)
endif()

find_package(Java REQUIRED)
include(UseJava)

find_package(JNI REQUIRED)
include_directories(${JNI_INCLUDE_DIRS})
message(STATUS "JNI_INCLUDE_DIRS=${JNI_INCLUDE_DIRS}")
message(STATUS "JNI_LIBRARIES=${JNI_LIBRARIES}")

### Enable C++ in SWIG
set_property(SOURCE openshot.i PROPERTY CPLUSPLUS ON)
set_property(SOURCE openshot.i PROPERTY SWIG_MODULE_NAME openshot)

### Suppress a ton of warnings in the generated SWIG C++ code
set(SWIG_CXX_FLAGS "-Wno-unused-variable -Wno-unused-function \
-Wno-deprecated-copy -Wno-class-memaccess -Wno-cast-function-type \
-Wno-unused-parameter -Wno-catch-value -Wno-sign-compare -Wno-ignored-qualifiers")
separate_arguments(sw_flags UNIX_COMMAND ${SWIG_CXX_FLAGS})
set_property(SOURCE openshot.i PROPERTY GENERATED_COMPILE_OPTIONS ${sw_flags})

### Take include dirs from target
if(CMAKE_VERSION VERSION_GREATER 3.15)
set(_inc $<REMOVE_DUPLICATES:$<TARGET_PROPERTY:openshot,INCLUDE_DIRECTORIES>>)
elseif(CMAKE_VERSION VERSION_GREATER 3.12)
set(_inc $<TARGET_PROPERTY:openshot,INCLUDE_DIRECTORIES>)
endif()
if (DEFINED _inc)
message(STATUS "Include directories: ${_inc}")
set_property(SOURCE openshot.i PROPERTY INCLUDE_DIRECTORIES ${_inc})
endif()

### Properly manage dependencies (regenerate bindings after changes)
if (CMAKE_VERSION VERSION_GREATER 3.20)
set_property(SOURCE openshot.i PROPERTY USE_SWIG_DEPENDENCIES TRUE)
endif()

### Add the SWIG interface file (which defines all the SWIG methods)
if (CMAKE_VERSION VERSION_LESS 3.8.0)
swig_add_module(openshot-java java openshot.i)
else()
swig_add_library(openshot-java LANGUAGE java SOURCES openshot.i)
endif()

### Set the prefix for the library to 'lib'
#set_target_properties(${SWIG_MODULE_openshot-java_REAL_NAME} PROPERTIES PREFIX "lib")

### Compile the generated wrapper file
get_property(_java_files TARGET openshot-java PROPERTY SWIG_SUPPORT_FILES)
message("_java_files: ${_java_files}")

### Link the new Java wrapper library with libopenshot
target_link_libraries(${SWIG_MODULE_openshot-java_REAL_NAME} PUBLIC
${JNI_LIBRARIES} openshot)

### Create a custom target for the JAR file
add_custom_command(
OUTPUT ${CMAKE_BINARY_DIR}/bindings/java/openshotJNI.jar
COMMAND ${Java_JAVAC_EXECUTABLE} -d ${CMAKE_BINARY_DIR}/bindings/java ${CMAKE_BINARY_DIR}/bindings/java/*.java
COMMAND ${Java_JAR_EXECUTABLE} -cf ${CMAKE_BINARY_DIR}/bindings/java/openshotJNI.jar -C ${CMAKE_BINARY_DIR}/bindings/java .
DEPENDS openshot-java
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bindings/java
COMMENT "Creating openshotJNI.jar"
)

add_custom_target(openshotJNIJar ALL DEPENDS ${CMAKE_BINARY_DIR}/bindings/java/openshotJNI.jar)
180 changes: 180 additions & 0 deletions bindings/java/openshot.i
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
/**
* @file
* @brief SWIG configuration for libopenshot (to generate Java SWIG bindings)
* @author Jonathan Thomas <[email protected]>
*
* @section LICENSE
*/
// Copyright (c) 2008-2024 OpenShot Studios, LLC
//
// SPDX-License-Identifier: LGPL-3.0-or-later

%module("threads"=1) openshot

/* Suppress warnings about ignored operator= */
%warnfilter(362);

/* Don't generate multiple wrappers for functions with default args */
%feature("compactdefaultargs", "1");

/* Enable inline documentation */
%feature("autodoc", "1");

/* Include various SWIG helpers */
%include "typemaps.i"
%include "std_string.i"
#%include "std_list.i"
%include "std_vector.i"
%include "std_map.i"
%include <stdint.i>

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

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

/* Mark these classes as shared_ptr classes */
#ifdef USE_IMAGEMAGICK
#%shared_ptr(Magick::Image)
#endif
#%shared_ptr(juce::AudioBuffer<float>)
#%shared_ptr(openshot::Frame)

/* Instantiate the required template specializations */
%template() std::map<std::string, int>;
#%template() std::pair<int, int>;
%template() std::vector<int>;
%template() std::vector<float>;
#%template() std::pair<double, double>;
#%template() std::pair<float, float>;
#%template() std::pair<std::string, std::string>;
#%template() std::vector<std::pair<std::string, std::string>>;
%template() std::vector<std::vector<float>>;

%{
#include "OpenShotVersion.h"
#include "ReaderBase.h"
#include "WriterBase.h"
#include "AudioDevices.h"
#include "AudioWaveformer.h"
#include "CacheBase.h"
#include "CacheDisk.h"
#include "CacheMemory.h"
#include "ChannelLayouts.h"
#include "ChunkReader.h"
#include "ChunkWriter.h"
#include "ClipBase.h"
#include "Clip.h"
#include "Coordinate.h"
#include "Color.h"
#include "DummyReader.h"
#include "EffectBase.h"
#include "Effects.h"
#include "EffectInfo.h"
#include "Enums.h"
#include "Exceptions.h"
#include "FFmpegReader.h"
#include "FFmpegWriter.h"
#include "Fraction.h"
#include "Frame.h"
#include "FrameMapper.h"
#include "PlayerBase.h"
#include "Point.h"
#include "Profiles.h"
#include "QtHtmlReader.h"
#include "QtImageReader.h"
#include "QtPlayer.h"
#include "QtTextReader.h"
#include "KeyFrame.h"
#include "RendererBase.h"
#include "Settings.h"
#include "TimelineBase.h"
#include "Timeline.h"
#include "ZmqLogger.h"
%}

#ifdef USE_IMAGEMAGICK
%{
#include "ImageReader.h"
#include "ImageWriter.h"
#include "TextReader.h"
%}
#endif

/* Wrap std templates (list, vector, etc...) */
#%template(ClipList) std::list<openshot::Clip *>;
#%template(EffectBaseList) std::list<openshot::EffectBase *>;
%template(CoordinateVector) std::vector<openshot::Coordinate>;
%template(PointsVector) std::vector<openshot::Point>;
%template(FieldVector) std::vector<openshot::Field>;
%template(MappedFrameVector) std::vector<openshot::MappedFrame>;
%template(MetadataMap) std::map<std::string, std::string>;

/* Deprecated */
%template(AudioDeviceInfoVector) std::vector<openshot::AudioDeviceInfo>;

%include "OpenShotVersion.h"
%include "ReaderBase.h"
%include "WriterBase.h"
%include "AudioDevices.h"
%include "AudioWaveformer.h"
%include "CacheBase.h"
%include "CacheDisk.h"
%include "CacheMemory.h"
%include "ChannelLayouts.h"
%include "ChunkReader.h"
%include "ChunkWriter.h"
%include "ClipBase.h"
%include "Clip.h"
%include "Coordinate.h"
%include "Color.h"
%include "DummyReader.h"
%include "EffectBase.h"
%include "Effects.h"
%include "EffectInfo.h"
%include "Enums.h"
%include "Exceptions.h"
%include "FFmpegReader.h"
%include "FFmpegWriter.h"
%include "Fraction.h"
%include "Frame.h"
%include "FrameMapper.h"
%include "PlayerBase.h"
%include "Point.h"
%include "Profiles.h"
%include "QtHtmlReader.h"
%include "QtImageReader.h"
%include "QtPlayer.h"
%include "QtTextReader.h"
%include "KeyFrame.h"
%include "RendererBase.h"
%include "Settings.h"
%include "TimelineBase.h"
%include "Timeline.h"
%include "ZmqLogger.h"

#ifdef USE_IMAGEMAGICK
%include "ImageReader.h"
%include "ImageWriter.h"
%include "TextReader.h"
#endif

/* Effects */
%include "effects/Bars.h"
%include "effects/Blur.h"
%include "effects/Brightness.h"
%include "effects/Caption.h"
%include "effects/ChromaKey.h"
%include "effects/ColorShift.h"
%include "effects/Crop.h"
%include "effects/Deinterlace.h"
%include "effects/Hue.h"
%include "effects/Mask.h"
%include "effects/Negate.h"
%include "effects/Pixelate.h"
%include "effects/Saturation.h"
%include "effects/Shift.h"
%include "effects/Wave.h"


16 changes: 12 additions & 4 deletions src/FrameMapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,15 @@ ReaderBase* FrameMapper::Reader()
void FrameMapper::AddField(int64_t frame)
{
// Add a field, and toggle the odd / even field
AddField(Field(frame, field_toggle));
Field f = { frame, bool(field_toggle) };
AddField(f);
}

void FrameMapper::AddField(int64_t frame, bool isOdd)
{
// Add a field, and toggle the odd / even field
Field f = { frame, isOdd };
AddField(f);
}

void FrameMapper::AddField(Field field)
Expand Down Expand Up @@ -183,7 +191,7 @@ void FrameMapper::Init()

if (frame + 1 <= info.video_length)
// add field for next frame (if the next frame exists)
AddField(Field(frame + 1, field_toggle));
AddField(frame + 1, field_toggle);
}
else if (pulldown == PULLDOWN_NONE && field % frame_interval == 0)
{
Expand Down Expand Up @@ -244,8 +252,8 @@ void FrameMapper::Init()
}

// Loop through the target frames again (combining fields into frames)
Field Odd(0, true); // temp field used to track the ODD field
Field Even(0, true); // temp field used to track the EVEN field
Field Odd = {0, true}; // temp field used to track the ODD field
Field Even = {0, true}; // temp field used to track the EVEN field

// Variables used to remap audio samples
int64_t start_samples_frame = 1;
Expand Down
9 changes: 1 addition & 8 deletions src/FrameMapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,6 @@ namespace openshot
{
int64_t Frame;
bool isOdd;

Field() : Frame(0), isOdd(true) { };

Field(int64_t frame, bool isodd)
{
Frame = frame;
isOdd = isodd;
}
};

/**
Expand Down Expand Up @@ -217,6 +209,7 @@ namespace openshot

// Internal methods used by init
void AddField(int64_t frame);
void AddField(int64_t frame, bool isOdd);
void AddField(Field field);

// Clear both the fields & frames lists
Expand Down

0 comments on commit c889996

Please sign in to comment.