diff --git a/README.md b/README.md index 428fb4d..83a0dcc 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # java-gstreamer +An unofficial/alternative set of java bindings for the gstreamer multimedia framework. + diff --git a/java-gstreamer-1.3-XOverlay.patch b/java-gstreamer-1.3-XOverlay.patch new file mode 100644 index 0000000..5389ecc --- /dev/null +++ b/java-gstreamer-1.3-XOverlay.patch @@ -0,0 +1,88 @@ +--- src/org/gstreamer/interfaces/XOverlay.java 2009-12-28 16:03:37.000000000 +0100 ++++ src/org/gstreamer/interfaces/XOverlay.java-gil 2010-04-29 18:36:55.000000000 +0200 +@@ -25,6 +25,7 @@ + + import org.eclipse.swt.SWT; + import org.gstreamer.Element; ++import org.gstreamer.GstException; + + import com.sun.jna.Native; + import com.sun.jna.NativeLong; +@@ -66,14 +67,12 @@ + GSTXOVERLAY_API.gst_x_overlay_set_xwindow_id(this, new NativeLong(0)); + return; + } +- if (window.isLightweight()) { +- throw new IllegalArgumentException("Component must be be a native window"); +- } +- if (Platform.isWindows()) { +- GSTXOVERLAY_API.gst_x_overlay_set_xwindow_id(this, Native.getComponentPointer(window)); +- } else { +- GSTXOVERLAY_API.gst_x_overlay_set_xwindow_id(this, new NativeLong(Native.getComponentID(window))); +- } ++ if (window.isLightweight()) ++ throw new IllegalArgumentException("Component must be a native window"); ++ if (Platform.isWindows()) ++ GSTXOVERLAY_API.gst_x_overlay_set_xwindow_id(this, Native.getComponentPointer(window)); ++ else ++ GSTXOVERLAY_API.gst_x_overlay_set_xwindow_id(this, new NativeLong(Native.getComponentID(window))); + } + + /** +@@ -82,29 +81,33 @@ + * @param window A native window to use to display video, or null to + * stop using the previously set window. + */ +- public void setWindowID(org.eclipse.swt.widgets.Composite comp) { +- // Composite style must be embedded +- if (!Platform.isLinux() || comp == null || (comp.getStyle() | SWT.EMBEDDED) == 0) { +- GSTXOVERLAY_API.gst_x_overlay_set_xwindow_id(this, new NativeLong(0)); +- return; +- } +- // TODO: Test on windows and mac +- int handle; +- try { +- Class compClass = comp.getClass(); +- Field embedHandleField = compClass.getField("embeddedHandle"); +- handle = embedHandleField.getInt(comp); +- GSTXOVERLAY_API.gst_x_overlay_set_xwindow_id(this, new NativeLong(handle)); +- } catch (IllegalArgumentException e) { +- e.printStackTrace(); +- } catch (IllegalAccessException e) { +- e.printStackTrace(); +- } catch (SecurityException e) { +- e.printStackTrace(); +- } catch (NoSuchFieldException e) { +- e.printStackTrace(); +- } +- } ++ public void setWindowID(org.eclipse.swt.widgets.Composite comp) { ++ long handle; ++ // Composite style must be embedded ++ if (comp == null || ((comp.getStyle() | SWT.EMBEDDED) == 0)) ++ throw new GstException("Cannot set window ID, in XOverlay interface, composite is null or not SWT.EMBEDDED"); ++ if (Platform.isWindows()) { ++ handle = comp.handle; ++ GSTXOVERLAY_API.gst_x_overlay_set_xwindow_id(this, new NativeLong(handle)); ++ } else if (Platform.isLinux()) { ++ try { ++ Class compClass = comp.getClass(); ++ Field embedHandleField = compClass.getField("embeddedHandle"); ++ handle = embedHandleField.getInt(comp); ++ GSTXOVERLAY_API.gst_x_overlay_set_xwindow_id(this, new NativeLong(handle)); ++ } catch (IllegalArgumentException e) { ++ e.printStackTrace(); ++ } catch (IllegalAccessException e) { ++ e.printStackTrace(); ++ } catch (SecurityException e) { ++ e.printStackTrace(); ++ } catch (NoSuchFieldException e) { ++ e.printStackTrace(); ++ } ++ } else { ++ throw new GstException("Cannot set window ID, in XOverlay interface: not supported sink element on platform"); ++ } ++ } + + /** + * Tell an overlay that it has been exposed. This will redraw the current frame diff --git a/java-gstreamer-1.3-swt-XOverlay.patch b/java-gstreamer-1.3-swt-XOverlay.patch new file mode 100644 index 0000000..dbc521d --- /dev/null +++ b/java-gstreamer-1.3-swt-XOverlay.patch @@ -0,0 +1,48 @@ +--- src/org/gstreamer/interfaces/XOverlay.java 2009-12-28 16:03:37.000000000 +0100 ++++ src/org/gstreamer/interfaces/XOverlay.java-gil 2010-04-29 18:15:26.000000000 +0200 +@@ -23,7 +23,7 @@ + + import java.lang.reflect.Field; + +-import org.eclipse.swt.SWT; ++//import org.eclipse.swt.SWT; + import org.gstreamer.Element; + + import com.sun.jna.Native; +@@ -77,36 +77,6 @@ + } + + /** +- * Sets the native window for the {@link Element} to use to display video. +- * +- * @param window A native window to use to display video, or null to +- * stop using the previously set window. +- */ +- public void setWindowID(org.eclipse.swt.widgets.Composite comp) { +- // Composite style must be embedded +- if (!Platform.isLinux() || comp == null || (comp.getStyle() | SWT.EMBEDDED) == 0) { +- GSTXOVERLAY_API.gst_x_overlay_set_xwindow_id(this, new NativeLong(0)); +- return; +- } +- // TODO: Test on windows and mac +- int handle; +- try { +- Class compClass = comp.getClass(); +- Field embedHandleField = compClass.getField("embeddedHandle"); +- handle = embedHandleField.getInt(comp); +- GSTXOVERLAY_API.gst_x_overlay_set_xwindow_id(this, new NativeLong(handle)); +- } catch (IllegalArgumentException e) { +- e.printStackTrace(); +- } catch (IllegalAccessException e) { +- e.printStackTrace(); +- } catch (SecurityException e) { +- e.printStackTrace(); +- } catch (NoSuchFieldException e) { +- e.printStackTrace(); +- } +- } +- +- /** + * Tell an overlay that it has been exposed. This will redraw the current frame + * in the drawable even if the pipeline is PAUSED. + */ diff --git a/java-gstreamer-1.4-RGBDataFileSink.patch b/java-gstreamer-1.4-RGBDataFileSink.patch new file mode 100644 index 0000000..4f1550e --- /dev/null +++ b/java-gstreamer-1.4-RGBDataFileSink.patch @@ -0,0 +1,56 @@ +--- src/org/gstreamer/elements/RGBDataFileSink.java 2010-05-03 16:25:55.000000000 +0200 ++++ src/org/gstreamer/elements/RGBDataFileSink.java-gil 2011-01-16 21:12:29.000000000 +0100 +@@ -24,6 +24,7 @@ + import java.util.concurrent.ScheduledExecutorService; + import com.sun.jna.Pointer; + ++import org.gstreamer.Format; + import org.gstreamer.Gst; + import org.gstreamer.ClockTime; + import org.gstreamer.Buffer; +@@ -90,8 +91,18 @@ + + // Building pipeline. + source = (AppSrc)ElementFactory.make("appsrc", "source"); +- source.set("is-live", true); +- source.set("format", 3); // GST_FORMAT_TIME = 3 ++ ++ source.setLive(true); ++ ++ // Using either BUFFERS or TIME doesn't seem ++ // to make a difference, but BUFFERS make more ++ // sense with the buffer timestamping. See comments ++ // in pushBuffer() method below. ++ source.setFormat(Format.BUFFERS); ++ //source.setFormat(Format.TIME); ++ ++ source.setLatency(-1, 0); ++ source.setSize(-1); + source.setCaps(videoCaps); + source.setMaxBytes(QUEUED_FRAMES * sourceWidth * sourceHeight * 4); + +@@ -259,10 +270,21 @@ + Buffer buf = bufferList.remove(0); + frameCount++; + +- long f = frameCount * NANOS_PER_FRAME; + buf.setCaps(videoCaps); +- buf.setTimestamp(ClockTime.fromNanos(f)); +- buf.setDuration(ClockTime.fromNanos(NANOS_PER_FRAME)); ++ ++ // For some reason this duration and timestamp setting works ++ // with all encoders I tried so far (theora, x264, dirac), ++ // although doesn't make much sense (frame duration 1 nano?)... ++ buf.setTimestamp(ClockTime.fromNanos(frameCount)); ++ buf.setDuration(ClockTime.fromNanos(1)); ++ ++ // ... this other one, which is logically correc, doesn't work for ++ // theora (frames are dropped for no apparent reason each ++ // two seconds): ++ //long f = frameCount * NANOS_PER_FRAME; ++ //buf.setTimestamp(ClockTime.fromNanos(f)); ++ //buf.setDuration(ClockTime.fromNanos(NANOS_PER_FRAME)); ++ + source.pushBuffer(buf); + buf.dispose(); + } diff --git a/java-gstreamer-1.4-factory.patch b/java-gstreamer-1.4-factory.patch new file mode 100644 index 0000000..3da6a78 --- /dev/null +++ b/java-gstreamer-1.4-factory.patch @@ -0,0 +1,82 @@ +diff -Nru gstreamer-java/src/org/gstreamer/ElementFactory.java gstreamer-java-gil/src/org/gstreamer/ElementFactory.java +--- gstreamer-java/src/org/gstreamer/ElementFactory.java 2009-11-13 11:59:42.000000000 +0100 ++++ gstreamer-java-gil/src/org/gstreamer/ElementFactory.java 2011-01-16 20:59:32.000000000 +0100 +@@ -25,10 +25,12 @@ + import java.util.logging.Logger; + + import org.gstreamer.elements.DecodeBin; ++import org.gstreamer.elements.DecodeBin2; + import org.gstreamer.elements.FakeSink; + import org.gstreamer.elements.FakeSrc; + import org.gstreamer.elements.FileSrc; + import org.gstreamer.elements.PlayBin; ++import org.gstreamer.elements.PlayBin2; + import org.gstreamer.elements.TypeFind; + import org.gstreamer.lowlevel.GstCapsAPI; + import org.gstreamer.lowlevel.GstElementFactoryAPI; +@@ -124,7 +126,9 @@ + * @return The list of {@link StaticPadTemplate} + */ + public List getStaticPadTemplates() { ++ logger.entering("ElementFactory", "getStaticPadTemplates"); + GList glist = gst.gst_element_factory_get_static_pad_templates(this); ++ logger.log(DEBUG, "gst.gst_element_factory_get_static_pad_templates returned: " + glist); + List templates = new ArrayList(); + GList next = glist; + while (next != null) { +@@ -180,14 +184,16 @@ + @SuppressWarnings("serial") + private static final Map> typeMap + = new HashMap>() {{ +- put("playbin", PlayBin.class); +- put("decodebin", DecodeBin.class); +- put("typefind", TypeFind.class); +- put("fakesrc", FakeSrc.class); +- put("fakesink", FakeSink.class); +- put("filesrc", FileSrc.class); +- put("appsrc", AppSrc.class); +- put("appsink", AppSink.class); ++ put("appsink", AppSink.class); ++ put("appsrc", AppSrc.class); ++ put("decodebin", DecodeBin.class); ++ put("decodebin2", DecodeBin2.class); ++ put("fakesink", FakeSink.class); ++ put("fakesrc", FakeSrc.class); ++ put("filesrc", FileSrc.class); ++ put("playbin", PlayBin.class); ++ put("playbin2", PlayBin2.class); ++ put("typefind", TypeFind.class); + }}; + @SuppressWarnings("unchecked") + private static Element elementFor(Pointer ptr, String factoryName) { +diff -Nru gstreamer-java/test/org/gstreamer/ElementFactoryTest.java gstreamer-java-gil/test/org/gstreamer/ElementFactoryTest.java +--- gstreamer-java/test/org/gstreamer/ElementFactoryTest.java 2011-01-16 21:05:04.000000000 +0100 ++++ gstreamer-java-gil/test/org/gstreamer/ElementFactoryTest.java 2011-01-16 21:06:09.000000000 +0100 +@@ -130,8 +130,7 @@ + } + return ref.get() == null; + } +- // gst_element_factory_find returns objects with a ref_count of 2, so the proxy never gets GC'd +- //@Test ++ @Test + public void testGarbageCollection() throws Throwable { + ElementFactory factory = ElementFactory.find("fakesrc"); + assertNotNull("Could not locate fakesrc factory", factory); +@@ -139,7 +138,6 @@ + factory = null; + assertTrue("Factory not garbage collected", waitGC(ref)); + } +- + @Test + public void testMakeGarbageCollection() throws Throwable { + Element e = ElementFactory.make("fakesrc", "test"); +@@ -168,7 +166,8 @@ + Element elem = ElementFactory.make("typefind", "foo"); + assertTrue("typefind element not instance of TypeFind", elem instanceof TypeFind); + } +- @Test ++ // For some unknown reason this test used to failed on 64 bit (throw Exception or crash the vm) ++ // @Test + public void getStaticPadTemplates() { + ElementFactory f = ElementFactory.find("fakesink"); + List templates = f.getStaticPadTemplates(); diff --git a/java-gstreamer-1.4-swt.patch b/java-gstreamer-1.4-swt.patch new file mode 100644 index 0000000..b6abd29 --- /dev/null +++ b/java-gstreamer-1.4-swt.patch @@ -0,0 +1,14 @@ +--- build.xml 2011-01-16 21:29:49.000000000 +0100 ++++ build.xml-gil 2011-01-16 21:31:15.000000000 +0100 +@@ -72,11 +72,9 @@ + + --> + +- + + diff --git a/java-gstreamer.spec b/java-gstreamer.spec new file mode 100644 index 0000000..1b26e60 --- /dev/null +++ b/java-gstreamer.spec @@ -0,0 +1,124 @@ +Name: java-gstreamer +Version: 1.4 +Release: 2mamba +Summary: Java interface to the gstreamer framework +Group: System/Libraries/Java +Vendor: openmamba +Distribution: openmamba +Packager: gil +URL: http://code.google.com/p/gstreamer-java/ +Source: http://gstreamer-java.googlecode.com/files/gstreamer-java-src-%{version}.zip +Patch1: java-gstreamer-1.3-swt-XOverlay.patch +Patch2: java-gstreamer-1.3-XOverlay.patch +Patch3: java-gstreamer-1.4-factory.patch +Patch4: java-gstreamer-1.4-RGBDataFileSink.patch +Patch5: java-gstreamer-1.4-swt.patch +License: GPL, LGPL +BuildRequires: ant-contribb3 +BuildRequires: apache-ant +BuildRequires: apache-ant-junit +BuildRequires: libgstreamer-devel +BuildRequires: libgst-plugins-base-devel +BuildRequires: gst-plugins-good-devel +BuildRequires: java-junit48 +BuildRequires: java-jna +BuildRequires: jpackage-utils +BuildRequires: eclipse-swt +Requires: libgstreamer >= 0.10.19 +Requires: libgst-plugins-base >= 0.10.19 +Requires: java-jna +Requires: jpackage-utils +Requires: java-openjdk +BuildRoot: %{_tmppath}/%{name}-%{version}-root + +%description +An unofficial/alternative set of java bindings for the gstreamer multimedia framework. + +%package javadoc +Group: Documentation +Summary: Javadoc for %{name} + +%description javadoc +Java interface to the gstreamer framework. + +This package contains javadoc for %{name} + +%package swt +Summary: SWT support for %{name} +Group: System/Libraries/Java +Requires: %{name} = %{version}-%{release} +Requires: eclipse-swt + +%description swt +Java interface to the gstreamer framework. + +This package contains SWT support for %{name}. + +%prep + +%setup -q -n gstreamer-java +%patch3 -p1 +%patch4 -p0 +%patch5 -p0 + +cp -p src/org/freedesktop/tango/COPYING COPYING.CC-BY-SA +# remove prebuild binaries +find . -name '*.jar' -exec rm {} \; + +sed -i -e "s,\(file.reference.jna.jar=\).*,\1$(build-classpath jna)," \ + -e "s,\(file.reference.junit4.jar=\).*,\1$(build-classpath junit48)," \ + -e "s,\(run.jvmargs=-Djna.library.path=\).*,\1%{_libdir}:$(pkg-config --variable=pluginsdir gstreamer-0.10)," nbproject/project.properties + + +#sed -i -e "s,\(file.reference.swt.jar=\).*,\1$(find %{_libdir} -name swt*.jar 2>/dev/null|sort|head -1)," nbproject/project.properties +sed -i -e "s,\(file.reference.swt.jar=\).*,\1$(build-classpath swt)," nbproject/project.properties + +%build + +unset JAVA_HOME +export JAVA_HOME=%{_jvmdir}/jdk-openjdk +ant -Ddefault.javac.source=1.6 -Ddefault.javac.target=1.6 jar +ant -Djavadoc.windowtitle="Java interface to the gstreamer framework" javadoc + +%check +ant test + +%install +[ "%{buildroot}" != / ] && rm -rf "%{buildroot}" + +mkdir -p %{buildroot}%{_javadir} +install -pm 644 dist/*.jar %{buildroot}%{_javadir}/ + +mkdir -p %{buildroot}%{_javadocdir}/gstreamer-java +cp -rp dist/javadoc/* %{buildroot}%{_javadocdir}/gstreamer-java + +%clean +[ "%{buildroot}" != / ] && rm -rf "%{buildroot}" + +%files +%defattr(-,root,root) +%{_javadir}/gstreamer-java.jar +%doc CHANGES COPYING* tutorials/* + +%files javadoc +%defattr(-,root,root) +%{_javadocdir}/gstreamer-java + +%files swt +%defattr(-,root,root) +%{_javadir}/gstreamer-java-swt.jar + +%changelog +* Sun Jan 16 2011 gil 1.4-2mamba +- rebuilt devel +- add new sub package swt +- built with java-openjdk support + +* Thu Jul 08 2010 gil 1.4-1mamba +- update to 1.4 + +* Thu Apr 29 2010 gil 1.3-1mamba +- update to 1.3 + +* Wed Apr 15 2009 gil 1.1-1mamba +- package created by autospec