Skip to content

Commit

Permalink
Enhancement: WYSIWYG Filter Configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
olir committed Mar 24, 2018
1 parent 7d421fe commit f77a8fe
Show file tree
Hide file tree
Showing 19 changed files with 146 additions and 83 deletions.
22 changes: 16 additions & 6 deletions app/src/main/java/de/screenflow/frankenstein/MovieProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import de.screenflow.frankenstein.task.TaskHandler;
import de.screenflow.frankenstein.task.TimeTaskHandler;
import de.screenflow.frankenstein.vf.FilterElement;
import de.screenflow.frankenstein.vf.SegmentVideoFilter;
import de.screenflow.frankenstein.vf.VideoFilter;
import de.screenflow.frankenstein.vf.VideoStreamSource;
import de.screenflow.frankenstein.vf.input.VideoInput;
Expand Down Expand Up @@ -61,6 +62,8 @@ public class MovieProcessor {

private File ffmpeg;

private SegmentVideoFilter previewFilter=null;

public MovieProcessor(Configuration configuration) {
this.ffmpegPath = configuration.getFFmpegPath();
this.tempPath = new File(configuration.getTempPath());
Expand Down Expand Up @@ -427,6 +430,7 @@ public void closeOutput() {
}

public void seek(final ProcessingListener l, int frameId) {
// System.out.println("MovieProcessor.seek @"+frameId);
if (configuration.doInput && frameId < currentPos) {
if (l != null)
l.seeking(0);
Expand All @@ -439,23 +443,25 @@ public void seek(final ProcessingListener l, int frameId) {
if (frame != null && !frame.empty()) {
Mat newFrame = frame;
for (VideoFilter filter : filters) {
// System.out.println("MovieProcessor process
// "+filter.getClass().getName());
// System.out.println("MovieProcessor process "+filter.getClass().getName());
newFrame = filter.process(newFrame, frameId);
}
if (localFilters != null && !localFilters.isEmpty()) {
for (FilterElement element : localFilters) {
if (element.filter != null) {
if (element.r.start <= currentPos && currentPos < element.r.end) {
// System.out.println("MovieProcessor
// processStreamFrame
// " +
// element.filter);
// System.out.println("MovieProcessor processStreamFrame " +
// element.filter);
newFrame = element.filter.process(newFrame, currentPos);
}
}
}
}
if (previewFilter!=null) {
System.out.println("MovieProcessor processStreamFrame " +
previewFilter);
newFrame = previewFilter.process(newFrame, currentPos);
}
if (l != null)
l.nextFrameProcessed(newFrame, currentPos);
} else {
Expand Down Expand Up @@ -535,4 +541,8 @@ public void handleLine(String line) {
return devices;
return devices;
}

public void setPreviewFilter(SegmentVideoFilter selectedFilter) {
previewFilter = selectedFilter;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@

import org.opencv.core.Mat;

import de.screenflow.frankenstein.vf.SegmentVideoFilter;
import de.screenflow.frankenstein.vf.VideoStreamSource;
import de.screenflow.frankenstein.vf.segment.SegmentConfigController;

public interface ProcessingListener {
void videoStarted(int frames, double fps);
Expand All @@ -28,4 +30,5 @@ public interface ProcessingListener {
void prematureEnd(int realFrameCount);
void taskUpdate(String timeStamp, String message);
void taskError(String errorMessage);
void configChanged(SegmentConfigController segmentConfigController, SegmentVideoFilter selectedFilter);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import java.net.URL;

import de.screenflow.frankenstein.vf.SegmentVideoFilter;
import de.screenflow.frankenstein.vf.segment.NativeSegmentFilter;
import de.screenflow.frankenstein.vf.segment.SegmentConfigController;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
Expand Down Expand Up @@ -40,7 +42,10 @@ public void configure(ProcessingSceneController parent, Stage stage) {
URL url = getClass().getResource("application.css");
String stylesheet = url.toExternalForm();
Scene scene = selectedFilter.createConfigurationScene(stylesheet);
bpContainer.setCenter(scene.getRoot());
bpContainer.setCenter(scene.getRoot());
SegmentConfigController c = ((SegmentVideoFilter)selectedFilter).getConfigController();
c.bind(parent, selectedFilter);
c.fireChange();
}
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import de.screenflow.frankenstein.vf.SegmentVideoFilter;
import de.screenflow.frankenstein.vf.VideoFilter;
import de.screenflow.frankenstein.vf.VideoStreamSource;
import de.screenflow.frankenstein.vf.segment.SegmentConfigController;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
Expand Down Expand Up @@ -842,6 +843,13 @@ public void filterSetup() {
SegmentVideoFilter f = controller.getSelectedFilterInstance();
selectedFilter.setType(f);
processor.applyLocalFilters(filterListData);
Runnable r = new Runnable() {
public void run() {
processor.setPreviewFilter(null);
processor.seek(ProcessingSceneController.this, position);
}
};
new Thread(r).start();
Platform.runLater(() -> {
listViewFilter.refresh();
drawEditCanvas();
Expand Down Expand Up @@ -920,6 +928,17 @@ public void run() {
public List<SegmentVideoFilter> getLocalFilters() {
return main.getLocalFilters();
}

@Override
public void configChanged(SegmentConfigController segmentConfigController, SegmentVideoFilter selectedFilter) {
Runnable r = new Runnable() {
public void run() {
processor.setPreviewFilter(selectedFilter);
processor.seek(ProcessingSceneController.this, position);
}
};
new Thread(r).start();
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@
*/
package de.screenflow.frankenstein.vf;

import de.screenflow.frankenstein.vf.segment.SegmentConfigController;
import javafx.scene.Scene;

public interface SegmentVideoFilter extends VideoFilter {
SegmentVideoFilter createInstance();

Scene createConfigurationScene(String stylesheet);

SegmentConfigController getConfigController();
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,12 @@ public void open(ProcessingListener l) {
movie = new VideoCapture(videofile);
if (!movie.isOpened()) {
String path = System.getProperty("OPENH264_LIBRARY_PATH");
if (path==null)
System.out.println("Warning: OPENH264_LIBRARY_PATH not set. Input Movie Opening Error for " + videofile);
if (path == null)
System.out
.println("Warning: OPENH264_LIBRARY_PATH not set. Input Movie Opening Error for " + videofile);

throw new RuntimeException("Input Movie Opening Error for " + videofile+". Current path="+new File(".").getAbsolutePath());
throw new RuntimeException(
"Input Movie Opening Error for " + videofile + ". Current path=" + new File(".").getAbsolutePath());
}
currentFrame = new Mat();
currentPos = 0;
Expand Down Expand Up @@ -106,12 +108,25 @@ public Mat getFrame() {
return currentFrame;
}

private Mat currentFrameCopy = null;

@Override
public int seek(int pos, ProcessingListener l) {
if (pos == currentPos) {
if (currentFrameCopy==null)
currentFrameCopy = currentFrame.clone();
else
currentFrame = currentFrameCopy.clone();
return currentPos;
}

if (pos < currentPos) {
reopen(l);
currentFrameCopy = null;
}

if (pos > currentPos) {
currentFrameCopy = null;
for (int i = currentPos + 1; i <= pos; i++) {
if (l != null)
l.seeking(i);
Expand All @@ -124,6 +139,7 @@ public int seek(int pos, ProcessingListener l) {
}
currentFrame = retrieve(currentFrame, l);
}

return currentPos;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package de.screenflow.frankenstein.vf.segment;

public class BWConfigController {
public class BWConfigController extends SegmentConfigController {

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;

public class BWFilter extends DefaultSegmentFilter<BWConfigController> {
public class BWFilter extends DefaultSegmentFilter {

Mat grayFrame;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;

public abstract class DefaultSegmentFilter<C> implements SegmentVideoFilter {
private C configController = null;
public abstract class DefaultSegmentFilter implements SegmentVideoFilter {
private SegmentConfigController configController = null;

private final String identifier;
private final PropertyResourceBundle bundleConfiguration;
Expand Down Expand Up @@ -69,7 +69,7 @@ public final Scene createConfigurationScene(String stylesheet) {

abstract protected void initializeController();

protected final C getConfigController() {
public SegmentConfigController getConfigController() {
return configController;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package de.screenflow.frankenstein.vf.segment;

public class NativeExampleConfigController {
public class NativeExampleConfigController extends SegmentConfigController {

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package de.screenflow.frankenstein.vf.segment;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
Expand All @@ -25,29 +24,18 @@
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

import org.opencv.core.Mat;

import de.screenflow.frankenstein.fxml.FxMain;
import de.screenflow.frankenstein.vf.SegmentVideoFilter;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;

public abstract class NativeSegmentFilter<C> implements SegmentVideoFilter {
public abstract class NativeSegmentFilter<C> extends DefaultSegmentFilter implements SegmentVideoFilter {
private static URLClassLoader loader = null;

private C configController = null;

private final String identifier;
private final PropertyResourceBundle bundleConfiguration;
private final Class jniProxyClass;
private final Object jniProxy;
private final Method jniProxyInitMethod;

protected NativeSegmentFilter(String identifier, String proxyClassName) {
this.identifier = identifier;

bundleConfiguration = (PropertyResourceBundle) ResourceBundle
.getBundle(getClass().getPackage().getName().replace('.', '/') + '/' + identifier, FxMain.getLocale());
super(identifier);

try {
// use dynamic loading and reflection when loading jni proxy class
Expand All @@ -59,7 +47,9 @@ protected NativeSegmentFilter(String identifier, String proxyClassName) {
jniProxyInitMethod.invoke(jniProxy);
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException
| SecurityException | IllegalArgumentException | InvocationTargetException | MalformedURLException e) {
throw new RuntimeException("jni wrapper creation failed. Bug-Mining: Ensure the wrapper was added to the javahClassNames in pom.xml. Check NativeCode.h for existing and proper signatures.", e);
throw new RuntimeException(
"jni wrapper creation failed. Bug-Mining: Ensure the wrapper was added to the javahClassNames in pom.xml. Check NativeCode.h for existing and proper signatures.",
e);
}
}

Expand All @@ -74,45 +64,6 @@ static synchronized URLClassLoader getLoader() throws MalformedURLException {
return loader;
}

public final String toString() {
return bundleConfiguration.getString("name");
}

@Override
public final SegmentVideoFilter createInstance() {
try {
return getClass().newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}

@Override
public final Scene createConfigurationScene(String stylesheet) {
FXMLLoader loader = new FXMLLoader(getClass().getResource(identifier + ".fxml"), bundleConfiguration);
try {
loader.load();
} catch (IOException e) {
throw new RuntimeException("Failed to create configuration scene for video filter '" + this + "'", e);
}
Scene scene = new Scene(loader.getRoot());
scene.getStylesheets().add(stylesheet);
configController = loader.getController();
initializeController(); // custom initialization possible here
return scene;
}

abstract protected void initializeController();

protected final C getConfigController() {
return configController;
}

@Override
public final Mat configure(Mat firstFrame) {
return firstFrame;
}

protected Class getJniProxyClass() {
return jniProxyClass;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package de.screenflow.frankenstein.vf.segment;

import de.screenflow.frankenstein.ProcessingListener;
import de.screenflow.frankenstein.vf.SegmentVideoFilter;

public class SegmentConfigController {

private ProcessingListener processingListener = null;
private SegmentVideoFilter filter = null;

public void bind(ProcessingListener l, SegmentVideoFilter filter) {
this.processingListener = l;
this.filter = filter;
}

public void fireChange() {
processingListener.configChanged(this, filter);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,25 @@
import javafx.fxml.FXML;
import javafx.scene.control.Slider;

public class StereoDistanceConfigController {
public class StereoDistanceConfigController extends SegmentConfigController {

@FXML Slider sliderStereoPerspective;
@FXML
Slider sliderStereoPerspective;

public void initialize() {
sliderStereoPerspective.setValue(perspective);
sliderStereoPerspective.valueProperty().addListener((observable, oldvalue, newvalue) -> {
perspective = newvalue.intValue();
fireChange();
});
}

/**
* -2n ... -4,-2,0,2,4, ... +2n : Negative values for farer away, positive
* for closer
*/
private int perspective = 0;

public int getPerspective() {
return perspective;
}
Expand Down

0 comments on commit f77a8fe

Please sign in to comment.