Repository: gstreamer-java/gst1-java-core Branch: master Commit: cc825482753f Files: 328 Total size: 1.4 MB Directory structure: gitextract_bvcbp9wz/ ├── .github/ │ ├── FUNDING.yml │ └── workflows/ │ └── maven.yml ├── .gitignore ├── .mvn/ │ └── wrapper/ │ └── maven-wrapper.properties ├── LICENSE.md ├── README.md ├── mvnw ├── mvnw.cmd ├── nbactions.xml ├── pom.xml ├── src/ │ └── org/ │ └── freedesktop/ │ └── gstreamer/ │ ├── Bin.java │ ├── Buffer.java │ ├── BufferFlags.java │ ├── BufferPool.java │ ├── Bus.java │ ├── BusSyncHandler.java │ ├── BusSyncReply.java │ ├── Caps.java │ ├── Clock.java │ ├── ClockID.java │ ├── ClockReturn.java │ ├── ClockTime.java │ ├── Context.java │ ├── ControlBinding.java │ ├── ControlSource.java │ ├── DateTime.java │ ├── Element.java │ ├── ElementFactory.java │ ├── FlowReturn.java │ ├── Format.java │ ├── Fraction.java │ ├── GhostPad.java │ ├── Gst.java │ ├── GstException.java │ ├── GstIterator.java │ ├── GstObject.java │ ├── Meta.java │ ├── MetaFlags.java │ ├── MiniObject.java │ ├── MiniObjectFlags.java │ ├── Pad.java │ ├── PadDirection.java │ ├── PadLinkException.java │ ├── PadLinkReturn.java │ ├── PadMode.java │ ├── PadPresence.java │ ├── PadProbeInfo.java │ ├── PadProbeReturn.java │ ├── PadProbeType.java │ ├── PadTemplate.java │ ├── Pipeline.java │ ├── Plugin.java │ ├── PluginFeature.java │ ├── Promise.java │ ├── PromiseResult.java │ ├── Range.java │ ├── Registry.java │ ├── SDPMessage.java │ ├── SDPResult.java │ ├── Sample.java │ ├── Segment.java │ ├── SegmentFlags.java │ ├── State.java │ ├── StateChangeReturn.java │ ├── StaticPadTemplate.java │ ├── Structure.java │ ├── Tag.java │ ├── TagFlag.java │ ├── TagList.java │ ├── TagMergeMode.java │ ├── Version.java │ ├── controller/ │ │ ├── ARGBControlBinding.java │ │ ├── Controllers.java │ │ ├── DirectControlBinding.java │ │ ├── InterpolationControlSource.java │ │ ├── InterpolationMode.java │ │ ├── LFOControlSource.java │ │ ├── LFOWaveform.java │ │ ├── ProxyControlBinding.java │ │ ├── TimedValueControlSource.java │ │ └── TriggerControlSource.java │ ├── device/ │ │ ├── Device.java │ │ ├── DeviceMonitor.java │ │ ├── DeviceProvider.java │ │ └── DeviceProviderFactory.java │ ├── elements/ │ │ ├── AppSink.java │ │ ├── AppSrc.java │ │ ├── BaseSink.java │ │ ├── BaseSrc.java │ │ ├── BaseTransform.java │ │ ├── DecodeBin.java │ │ ├── Elements.java │ │ ├── PlayBin.java │ │ ├── PlayFlags.java │ │ └── URIDecodeBin.java │ ├── event/ │ │ ├── BufferSizeEvent.java │ │ ├── CapsEvent.java │ │ ├── EOSEvent.java │ │ ├── Event.java │ │ ├── EventType.java │ │ ├── FlushStartEvent.java │ │ ├── FlushStopEvent.java │ │ ├── LatencyEvent.java │ │ ├── NavigationEvent.java │ │ ├── QOSEvent.java │ │ ├── QOSType.java │ │ ├── ReconfigureEvent.java │ │ ├── SeekEvent.java │ │ ├── SeekFlags.java │ │ ├── SeekType.java │ │ ├── SegmentEvent.java │ │ ├── StepEvent.java │ │ ├── StreamStartEvent.java │ │ └── TagEvent.java │ ├── glib/ │ │ ├── GCancellable.java │ │ ├── GDate.java │ │ ├── GError.java │ │ ├── GInetAddress.java │ │ ├── GInetSocketAddress.java │ │ ├── GLib.java │ │ ├── GLibException.java │ │ ├── GMainContext.java │ │ ├── GObject.java │ │ ├── GQuark.java │ │ ├── GSocket.java │ │ ├── GSocketAddress.java │ │ ├── GSocketFamily.java │ │ ├── GSocketProtocol.java │ │ ├── GSocketType.java │ │ ├── GSource.java │ │ ├── MainContextExecutorService.java │ │ ├── NativeEnum.java │ │ ├── NativeFlags.java │ │ ├── NativeObject.java │ │ ├── Natives.java │ │ └── RefCountedObject.java │ ├── interfaces/ │ │ ├── ColorBalance.java │ │ ├── ColorBalanceChannel.java │ │ ├── GstInterface.java │ │ ├── Navigation.java │ │ ├── VideoOrientation.java │ │ └── VideoOverlay.java │ ├── lowlevel/ │ │ ├── AppAPI.java │ │ ├── BaseSinkAPI.java │ │ ├── BaseSrcAPI.java │ │ ├── BaseTransformAPI.java │ │ ├── EnumMapper.java │ │ ├── GBoolean.java │ │ ├── GFunctionMapper.java │ │ ├── GNative.java │ │ ├── GObjectAPI.java │ │ ├── GObjectPtr.java │ │ ├── GPointer.java │ │ ├── GSignalAPI.java │ │ ├── GType.java │ │ ├── GTypeMapper.java │ │ ├── GTypedPtr.java │ │ ├── GValueAPI.java │ │ ├── GValueStruct.java │ │ ├── GioAPI.java │ │ ├── GlibAPI.java │ │ ├── GstAPI.java │ │ ├── GstARGBControlBindingPtr.java │ │ ├── GstBinAPI.java │ │ ├── GstBufferAPI.java │ │ ├── GstBufferPoolAPI.java │ │ ├── GstBusAPI.java │ │ ├── GstBusPtr.java │ │ ├── GstCapsAPI.java │ │ ├── GstClockAPI.java │ │ ├── GstColorBalanceAPI.java │ │ ├── GstContextAPI.java │ │ ├── GstContextPtr.java │ │ ├── GstControlBindingAPI.java │ │ ├── GstControlBindingPtr.java │ │ ├── GstControlSourceAPI.java │ │ ├── GstControlSourcePtr.java │ │ ├── GstControllerAPI.java │ │ ├── GstDateTimeAPI.java │ │ ├── GstDeviceAPI.java │ │ ├── GstDeviceMonitorAPI.java │ │ ├── GstDeviceProviderAPI.java │ │ ├── GstDeviceProviderFactoryAPI.java │ │ ├── GstDirectControlBindingPtr.java │ │ ├── GstElementAPI.java │ │ ├── GstElementFactoryAPI.java │ │ ├── GstEventAPI.java │ │ ├── GstGhostPadAPI.java │ │ ├── GstInterpolationControlSourceAPI.java │ │ ├── GstInterpolationControlSourcePtr.java │ │ ├── GstIteratorAPI.java │ │ ├── GstIteratorPtr.java │ │ ├── GstLFOControlSourcePtr.java │ │ ├── GstMessageAPI.java │ │ ├── GstMessagePtr.java │ │ ├── GstMetaAPI.java │ │ ├── GstMetaPtr.java │ │ ├── GstMiniObjectAPI.java │ │ ├── GstMiniObjectPtr.java │ │ ├── GstNative.java │ │ ├── GstNavigationAPI.java │ │ ├── GstObjectAPI.java │ │ ├── GstObjectPtr.java │ │ ├── GstPadAPI.java │ │ ├── GstPadProbeInfo.java │ │ ├── GstPadPtr.java │ │ ├── GstPadTemplateAPI.java │ │ ├── GstParseAPI.java │ │ ├── GstPipelineAPI.java │ │ ├── GstPluginAPI.java │ │ ├── GstPluginFeatureAPI.java │ │ ├── GstPromiseAPI.java │ │ ├── GstProxyControlBindingPtr.java │ │ ├── GstQueryAPI.java │ │ ├── GstRegistryAPI.java │ │ ├── GstSDPMessageAPI.java │ │ ├── GstSampleAPI.java │ │ ├── GstStructureAPI.java │ │ ├── GstStructurePtr.java │ │ ├── GstTagAPI.java │ │ ├── GstTagListAPI.java │ │ ├── GstTimedValueControlSourcePtr.java │ │ ├── GstTriggerControlSourcePtr.java │ │ ├── GstTypes.java │ │ ├── GstValueAPI.java │ │ ├── GstVideoAPI.java │ │ ├── GstVideoOrientationAPI.java │ │ ├── GstVideoOverlayAPI.java │ │ ├── GstWebRTCSessionDescriptionAPI.java │ │ ├── IntPtr.java │ │ ├── MainLoop.java │ │ ├── README │ │ ├── ReferenceManager.java │ │ └── annotations/ │ │ ├── CallerOwnsReturn.java │ │ ├── Const.java │ │ ├── ConstField.java │ │ ├── ConstReturn.java │ │ ├── DefaultEnumValue.java │ │ ├── FreeReturnValue.java │ │ ├── HasSubtype.java │ │ ├── IncRef.java │ │ └── Invalidate.java │ ├── message/ │ │ ├── BufferingMessage.java │ │ ├── DurationChangedMessage.java │ │ ├── EOSMessage.java │ │ ├── ErrorMessage.java │ │ ├── GErrorMessage.java │ │ ├── InfoMessage.java │ │ ├── LatencyMessage.java │ │ ├── Message.java │ │ ├── MessageType.java │ │ ├── NeedContextMessage.java │ │ ├── SegmentDoneMessage.java │ │ ├── StateChangedMessage.java │ │ ├── TagMessage.java │ │ └── WarningMessage.java │ ├── query/ │ │ ├── AllocationQuery.java │ │ ├── ConvertQuery.java │ │ ├── DurationQuery.java │ │ ├── FormatsQuery.java │ │ ├── LatencyQuery.java │ │ ├── PositionQuery.java │ │ ├── Query.java │ │ ├── QueryType.java │ │ ├── SeekingQuery.java │ │ └── SegmentQuery.java │ ├── video/ │ │ ├── Video.java │ │ ├── VideoTimeCode.java │ │ ├── VideoTimeCodeConfig.java │ │ ├── VideoTimeCodeFlags.java │ │ └── VideoTimeCodeMeta.java │ └── webrtc/ │ ├── WebRTC.java │ ├── WebRTCBin.java │ ├── WebRTCICEGatheringState.java │ ├── WebRTCPeerConnectionState.java │ ├── WebRTCSDPType.java │ └── WebRTCSessionDescription.java └── test/ └── org/ └── freedesktop/ └── gstreamer/ ├── BinTest.java ├── BufferFieldsTest.java ├── BufferProbeTester.java ├── BusTest.java ├── CapsTest.java ├── ClockTest.java ├── ClockTimeTest.java ├── ContextTest.java ├── ElementFactoryTest.java ├── ElementTest.java ├── EnumTest.java ├── ExecutorServiceTest.java ├── GCTracker.java ├── GLibTest.java ├── GarbageCollectionEDTTest.java ├── GarbageCollectionTest.java ├── GhostPadTest.java ├── GobjectSubclassTest.java ├── GstTypesTest.java ├── InitTest.java ├── MessageTest.java ├── PadProbeTypeTest.java ├── PadTemplateTest.java ├── PadTest.java ├── PipelineTest.java ├── PluginFeatureTest.java ├── PluginTest.java ├── ProbeTester.java ├── PromiseTest.java ├── PropertyTypeTest.java ├── QueryTest.java ├── RegistryTest.java ├── SampleTest.java ├── SampleTester.java ├── StreamInfoTest.java ├── StructureTest.java ├── TestPipe.java ├── WebRTCBinTest.java ├── controller/ │ ├── InterpolationControlSourceTest.java │ └── TriggerControlSourceTest.java ├── elements/ │ └── PlayBinTest.java ├── event/ │ └── EventTest.java ├── lowlevel/ │ ├── GValueTest.java │ ├── LowLevelStructureTest.java │ └── ReferenceManagerTest.java ├── util/ │ └── TestAssumptions.java └── video/ ├── VideoCropMetaTest.java ├── VideoTimeCodeConfigTest.java ├── VideoTimeCodeFlagsTest.java ├── VideoTimeCodeMetaTest.java └── VideoTimeCodeTest.java ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/FUNDING.yml ================================================ github: neilcsmith-net ================================================ FILE: .github/workflows/maven.yml ================================================ name: Test on Maven on: [push, pull_request] jobs: test-1-24-jdk25: runs-on: ubuntu-24.04 steps: - name: Checkout uses: actions/checkout@v5 - name: Set up JDK 25 uses: actions/setup-java@v5 with: java-version: '25' distribution: 'temurin' - name: Install GStreamer run: sudo apt-get update && sudo apt-get install gstreamer1.0-plugins-good gstreamer1.0-plugins-bad - name: Build with Maven run: ./mvnw --batch-mode verify test-1-20-jdk8: runs-on: ubuntu-22.04 steps: - name: Checkout uses: actions/checkout@v5 - name: Set up JDK 8 uses: actions/setup-java@v5 with: java-version: '8' distribution: 'temurin' - name: Install GStreamer run: sudo apt-get update && sudo apt-get install gstreamer1.0-plugins-good gstreamer1.0-plugins-bad - name: Build with Maven run: ./mvnw --batch-mode verify ================================================ FILE: .gitignore ================================================ *.class # Package Files # *.jar *.war *.ear /target/ # Eclipse Files # .classpath .project .settings # NetBeans Files # /nbproject/ nb-configuration.xml .idea ================================================ FILE: .mvn/wrapper/maven-wrapper.properties ================================================ wrapperVersion=3.3.4 distributionType=only-script distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.11/apache-maven-3.9.11-bin.zip distributionSha256Sum=0d7125e8c91097b36edb990ea5934e6c68b4440eef4ea96510a0f6815e7eeadb ================================================ FILE: LICENSE.md ================================================ GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. "The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. 1. Exception to Section 3 of the GNU GPL. You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. 2. Conveying Modified Versions. If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. 3. Object Code Incorporating Material from Library Header Files. The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the object code with a copy of the GNU GPL and this license document. 4. Combined Works. You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. b) Accompany the Combined Work with a copy of the GNU GPL and this license document. c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. d) Do one of the following: 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) 5. Combined Libraries. You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 6. Revised Versions of the GNU Lesser General Public License. The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. ================================================ FILE: README.md ================================================ GStreamer 1.x Java Core (gst1-java-core) ======================================== gst1-java-core is a set of Java bindings for [GStreamer 1.x][gstreamer]. GStreamer is an open-source, pipeline-based multimedia framework written in C. It allows a programmer to create a wide variety of media-handling pipelines inside applications, from simple media playback, to encoding, live-streaming, analysis, machine learning, WebRTC and more. GStreamer is designed to be cross-platform, and binaries are provided for a range of operating systems. gst1-java-core is actively tested on Linux (x86 and Arm), Windows and macOS, but should work on any OS with Java, JNA and GStreamer support. The bindings are in use in a wide variety of commercial and open-source projects, across desktop, server and embedded. ## Usage See the [examples repository][gst1-examples] for some self-contained projects to get you started. Use the [Javadoc][gst1-javadoc]! - all classes are documented, and include links to the relevant native documentation where appropriate. Please use the [GStreamer-Java mailing list][gstreamer-java-group] to ask questions. To try the examples you will need [GStreamer installed][gstreamer-download] on your system. Other options for deployment are possible - see requirements below. Please note, this is not an easy-to-use multimedia framework for beginners. It currently requires people to know the Java language and be familiar with the GStreamer framework (and possibly be prepared to apply things from tutorials on GStreamer programming in other languages to the Java bindings). ## History and status Releases are available via Maven Central (under the `org.freedesktop.gstreamer` group ID), or can be downloaded from the GitHub [release page][gst1-releases]. Since v1.0.0 the bindings are functionally and API stable, but note that the lowlevel packages are _effectively_ non-public and subject to change at any time. The lead maintainer of the bindings is Neil C Smith at [Codelerity Ltd.][codelerity]. The project began in 2015 as a fork of the original [GStreamer-Java][gstreamer-java] bindings for GStreamer 0.10 started by Wayne Meissner. Numerous other people have made valuable contributions to the original project and the 1.x fork over the years. ## Help and support Help on getting started, and support for open-source projects, can be obtained from the [GStreamer-Java mailing list][gstreamer-java-group]. Commercial support and custom development is available, and sponsorship of additional features is also welcome - please email info@codelerity.com to discuss. ## Requirements The bindings are tested on Linux, Windows and macOS. Windows and macOS installers for GStreamer are available from the [GStreamer project itself][gstreamer-download]. Linux users should be able to get GStreamer from their distribution repository if it isn't already installed. You will need to have the GStreamer 1.x native libraries available in your system path in order to use the bindings, and may also need to set up environment variables depending on how GStreamer is installed. See the `Utils` class in each example project for one possible way to configure this inside your Java code. It is possible to ship GStreamer with your application should you want your users not to have to install it separately. There are various ways to achieve this - see the [upstream documentation][gstreamer-deploy]. Advice is also available via the support options above. The minimum supported version of GStreamer is 1.8.x. If you require access to features related to later GStreamer versions (eg. WebRTC support), make sure to request the version you need when calling `Gst.init(..)` You will also need the [JNA (Java Native Access)][jna] library, minimum version 5.2.0. The minimum required Java version is Java 8. ## Contributions Contributions to the library are welcomed, either to fix / enhance current features, or bring in new ones. There is also ongoing work to rework the lowlevel bindings. **Before opening a Pull Request** please raise an issue or discuss your contribution on the mailing list. New features must have tests, selectively applied if targeting features in versions of GStreamer above 1.8. All Pull Requests will be automatically tested via CI, and all tests must pass before merging will be considered. If you are making a large contribution to benefit a commercial project, sponsorship of integration and support time would be appreciated. [gstreamer]: https://gstreamer.freedesktop.org/ [gstreamer-download]: https://gstreamer.freedesktop.org/download/ [gstreamer-deploy]: https://gstreamer.freedesktop.org/documentation/deploying/index.html [gstreamer-java]: https://github.com/gstreamer-java/gstreamer-java [gst1-examples]: https://github.com/gstreamer-java/gst1-java-examples [gst1-javadoc]: https://javadoc.io/doc/org.freedesktop.gstreamer/gst1-java-core [gst1-releases]: https://github.com/gstreamer-java/gst1-java-core/releases [gstreamer-java-group]: https://groups.google.com/forum/#!forum/gstreamer-java [jna]: https://github.com/java-native-access/jna [codelerity]: https://www.codelerity.com ================================================ FILE: mvnw ================================================ #!/bin/sh # ---------------------------------------------------------------------------- # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- # Apache Maven Wrapper startup batch script, version 3.3.4 # # Optional ENV vars # ----------------- # JAVA_HOME - location of a JDK home dir, required when download maven via java source # MVNW_REPOURL - repo url base for downloading maven distribution # MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven # MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output # ---------------------------------------------------------------------------- set -euf [ "${MVNW_VERBOSE-}" != debug ] || set -x # OS specific support. native_path() { printf %s\\n "$1"; } case "$(uname)" in CYGWIN* | MINGW*) [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" native_path() { cygpath --path --windows "$1"; } ;; esac # set JAVACMD and JAVACCMD set_java_home() { # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched if [ -n "${JAVA_HOME-}" ]; then if [ -x "$JAVA_HOME/jre/sh/java" ]; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" JAVACCMD="$JAVA_HOME/jre/sh/javac" else JAVACMD="$JAVA_HOME/bin/java" JAVACCMD="$JAVA_HOME/bin/javac" if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 return 1 fi fi else JAVACMD="$( 'set' +e 'unset' -f command 2>/dev/null 'command' -v java )" || : JAVACCMD="$( 'set' +e 'unset' -f command 2>/dev/null 'command' -v javac )" || : if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 return 1 fi fi } # hash string like Java String::hashCode hash_string() { str="${1:-}" h=0 while [ -n "$str" ]; do char="${str%"${str#?}"}" h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) str="${str#?}" done printf %x\\n $h } verbose() { :; } [ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } die() { printf %s\\n "$1" >&2 exit 1 } trim() { # MWRAPPER-139: # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. # Needed for removing poorly interpreted newline sequences when running in more # exotic environments such as mingw bash on Windows. printf "%s" "${1}" | tr -d '[:space:]' } scriptDir="$(dirname "$0")" scriptName="$(basename "$0")" # parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties while IFS="=" read -r key value; do case "${key-}" in distributionUrl) distributionUrl=$(trim "${value-}") ;; distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; esac done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" [ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" case "${distributionUrl##*/}" in maven-mvnd-*bin.*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; :Linux*x86_64*) distributionPlatform=linux-amd64 ;; *) echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 distributionPlatform=linux-amd64 ;; esac distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" ;; maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; *) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; esac # apply MVNW_REPOURL and calculate MAVEN_HOME # maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ [ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" distributionUrlName="${distributionUrl##*/}" distributionUrlNameMain="${distributionUrlName%.*}" distributionUrlNameMain="${distributionUrlNameMain%-bin}" MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" exec_maven() { unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" } if [ -d "$MAVEN_HOME" ]; then verbose "found existing MAVEN_HOME at $MAVEN_HOME" exec_maven "$@" fi case "${distributionUrl-}" in *?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; *) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; esac # prepare tmp dir if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } trap clean HUP INT TERM EXIT else die "cannot create temp dir" fi mkdir -p -- "${MAVEN_HOME%/*}" # Download and Install Apache Maven verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." verbose "Downloading from: $distributionUrl" verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" # select .zip or .tar.gz if ! command -v unzip >/dev/null; then distributionUrl="${distributionUrl%.zip}.tar.gz" distributionUrlName="${distributionUrl##*/}" fi # verbose opt __MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' [ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v # normalize http auth case "${MVNW_PASSWORD:+has-password}" in '') MVNW_USERNAME='' MVNW_PASSWORD='' ;; has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; esac if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then verbose "Found wget ... using wget" wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then verbose "Found curl ... using curl" curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" elif set_java_home; then verbose "Falling back to use Java to download" javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" cat >"$javaSource" <<-END public class Downloader extends java.net.Authenticator { protected java.net.PasswordAuthentication getPasswordAuthentication() { return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); } public static void main( String[] args ) throws Exception { setDefault( new Downloader() ); java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); } } END # For Cygwin/MinGW, switch paths to Windows format before running javac and java verbose " - Compiling Downloader.java ..." "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" verbose " - Running Downloader.java ..." "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" fi # If specified, validate the SHA-256 sum of the Maven distribution zip file if [ -n "${distributionSha256Sum-}" ]; then distributionSha256Result=false if [ "$MVN_CMD" = mvnd.sh ]; then echo "Checksum validation is not supported for maven-mvnd." >&2 echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 exit 1 elif command -v sha256sum >/dev/null; then if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then distributionSha256Result=true fi elif command -v shasum >/dev/null; then if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then distributionSha256Result=true fi else echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 exit 1 fi if [ $distributionSha256Result = false ]; then echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 exit 1 fi fi # unzip and move if command -v unzip >/dev/null; then unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" else tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" fi # Find the actual extracted directory name (handles snapshots where filename != directory name) actualDistributionDir="" # First try the expected directory name (for regular distributions) if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then actualDistributionDir="$distributionUrlNameMain" fi fi # If not found, search for any directory with the Maven executable (for snapshots) if [ -z "$actualDistributionDir" ]; then # enable globbing to iterate over items set +f for dir in "$TMP_DOWNLOAD_DIR"/*; do if [ -d "$dir" ]; then if [ -f "$dir/bin/$MVN_CMD" ]; then actualDistributionDir="$(basename "$dir")" break fi fi done set -f fi if [ -z "$actualDistributionDir" ]; then verbose "Contents of $TMP_DOWNLOAD_DIR:" verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" die "Could not find Maven distribution directory in extracted archive" fi verbose "Found extracted Maven distribution directory: $actualDistributionDir" printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" clean || : exec_maven "$@" ================================================ FILE: mvnw.cmd ================================================ <# : batch portion @REM ---------------------------------------------------------------------------- @REM Licensed to the Apache Software Foundation (ASF) under one @REM or more contributor license agreements. See the NOTICE file @REM distributed with this work for additional information @REM regarding copyright ownership. The ASF licenses this file @REM to you under the Apache License, Version 2.0 (the @REM "License"); you may not use this file except in compliance @REM with the License. You may obtain a copy of the License at @REM @REM http://www.apache.org/licenses/LICENSE-2.0 @REM @REM Unless required by applicable law or agreed to in writing, @REM software distributed under the License is distributed on an @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY @REM KIND, either express or implied. See the License for the @REM specific language governing permissions and limitations @REM under the License. @REM ---------------------------------------------------------------------------- @REM ---------------------------------------------------------------------------- @REM Apache Maven Wrapper startup batch script, version 3.3.4 @REM @REM Optional ENV vars @REM MVNW_REPOURL - repo url base for downloading maven distribution @REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven @REM MVNW_VERBOSE - true: enable verbose log; others: silence the output @REM ---------------------------------------------------------------------------- @IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) @SET __MVNW_CMD__= @SET __MVNW_ERROR__= @SET __MVNW_PSMODULEP_SAVE=%PSModulePath% @SET PSModulePath= @FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) ) @SET PSModulePath=%__MVNW_PSMODULEP_SAVE% @SET __MVNW_PSMODULEP_SAVE= @SET __MVNW_ARG0_NAME__= @SET MVNW_USERNAME= @SET MVNW_PASSWORD= @IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) @echo Cannot start maven from wrapper >&2 && exit /b 1 @GOTO :EOF : end batch / begin powershell #> $ErrorActionPreference = "Stop" if ($env:MVNW_VERBOSE -eq "true") { $VerbosePreference = "Continue" } # calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties $distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl if (!$distributionUrl) { Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" } switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { "maven-mvnd-*" { $USE_MVND = $true $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" $MVN_CMD = "mvnd.cmd" break } default { $USE_MVND = $false $MVN_CMD = $script -replace '^mvnw','mvn' break } } # apply MVNW_REPOURL and calculate MAVEN_HOME # maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ if ($env:MVNW_REPOURL) { $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" } $distributionUrlName = $distributionUrl -replace '^.*/','' $distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' $MAVEN_M2_PATH = "$HOME/.m2" if ($env:MAVEN_USER_HOME) { $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" } if (-not (Test-Path -Path $MAVEN_M2_PATH)) { New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null } $MAVEN_WRAPPER_DISTS = $null if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" } else { $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" } $MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" $MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' $MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" exit $? } if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" } # prepare tmp dir $TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile $TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" $TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null trap { if ($TMP_DOWNLOAD_DIR.Exists) { try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } } } New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null # Download and Install Apache Maven Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." Write-Verbose "Downloading from: $distributionUrl" Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" $webclient = New-Object System.Net.WebClient if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) } [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 $webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null # If specified, validate the SHA-256 sum of the Maven distribution zip file $distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum if ($distributionSha256Sum) { if ($USE_MVND) { Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." } Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." } } # unzip and move Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null # Find the actual extracted directory name (handles snapshots where filename != directory name) $actualDistributionDir = "" # First try the expected directory name (for regular distributions) $expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" $expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { $actualDistributionDir = $distributionUrlNameMain } # If not found, search for any directory with the Maven executable (for snapshots) if (!$actualDistributionDir) { Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { $testPath = Join-Path $_.FullName "bin/$MVN_CMD" if (Test-Path -Path $testPath -PathType Leaf) { $actualDistributionDir = $_.Name } } } if (!$actualDistributionDir) { Write-Error "Could not find Maven distribution directory in extracted archive" } Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null try { Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null } catch { if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { Write-Error "fail to move MAVEN_HOME" } } finally { try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } } Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" ================================================ FILE: nbactions.xml ================================================ run jar process-classes org.codehaus.mojo:exec-maven-plugin:1.2.1:exec -Djna.nosys=true -classpath %classpath ${packageClassName} java debug jar process-classes org.codehaus.mojo:exec-maven-plugin:1.2.1:exec -Xdebug -Xrunjdwp:transport=dt_socket,server=n,address=${jpda.address} -Djna.nosys=true -classpath %classpath ${packageClassName} java true profile jar process-classes org.codehaus.mojo:exec-maven-plugin:1.2.1:exec -Djna.nosys=true -classpath %classpath ${packageClassName} java run.single.main * process-classes org.codehaus.mojo:exec-maven-plugin:1.2.1:exec -Djna.nosys=true -classpath %classpath ${packageClassName} java ${classPathScope} test * test -Djna.nosys=true test.single * test-compile surefire:test -Djna.nosys=true ${packageClassName} ================================================ FILE: pom.xml ================================================ 4.0.0 org.freedesktop.gstreamer gst1-java-core 1.5.0-SNAPSHOT jar GStreamer 1.x Java Core Unofficial Java binding for the GStreamer framework https://github.com/gstreamer-java/gst1-java-core gstreamer-java http://www.github.com/gstreamer-java LGPL-3.0-only http://www.gnu.org/licenses/lgpl.html repo https://github.com/gstreamer-java/gst1-java-core scm:git:https://github.com/gstreamer-java/gst1-java-core.git scm:git:https://github.com/gstreamer-java/gst1-java-core.git sonatype-central https://central.sonatype.com/repository/maven-snapshots sonatype-central https://repo.maven.apache.org/maven2 neilcsmith-net Neil C Smith Codelerity Ltd. neil@codelerity.com Lead maintainer Developer https://www.codelerity.com wmeissner Wayne Meissner Founder of GStreamer 0.10 bindings 8 0.8.5 UTF-8 junit junit 4.13.2 test net.java.dev.jna jna 5.18.1 src src **/*.java test test **/*.java eu.maveniverse.maven.njord extension3 ${njord.version} org.apache.maven.plugins maven-surefire-plugin 3.5.4 1 none false -XX:+IgnoreUnrecognizedVMOptions --enable-native-access=ALL-UNNAMED -Djna.nosys=true ${maven.test.jvmargs} **/Test*.java org.apache.maven.plugins maven-compiler-plugin 3.14.1 8 org.apache.maven.plugins maven-jar-plugin 3.4.2 org.freedesktop.gstreamer windows-gstreamer-path windows gstreamer.path org.apache.maven.plugins maven-surefire-plugin ${gstreamer.path};${java.library.path} release org.apache.maven.plugins maven-source-plugin 3.3.1 attach-sources jar-no-fork org.apache.maven.plugins maven-javadoc-plugin 3.12.0 none org.freedesktop.gstreamer.lowlevel 8 attach-javadocs jar org.apache.maven.plugins maven-gpg-plugin 3.2.8 sign-artifacts verify sign ================================================ FILE: src/org/freedesktop/gstreamer/Bin.java ================================================ /* * Copyright (c) 2025 Neil C Smith * Copyright (c) 2016 Christophe Lafolet * Copyright (c) 2009 Levente Farkas * Copyright (C) 2007 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2004 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import static org.freedesktop.gstreamer.lowlevel.GstBinAPI.GSTBIN_API; import java.util.EnumSet; import java.util.List; import org.freedesktop.gstreamer.glib.NativeFlags; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback; import org.freedesktop.gstreamer.lowlevel.GstIteratorPtr; import org.freedesktop.gstreamer.lowlevel.GstObjectPtr; /** * Base class and element that can contain other elements. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstBin.html *

* Bin is an element that can contain other {@link Element}s, allowing them to * be managed as a group. *

* Pads from the child elements can be ghosted to the bin, see {@link GhostPad}. * This makes the bin look like any other elements and enables creation of * higher-level abstraction elements. *

* A new {@link Bin} is created with {@link Bin#Bin(String)}. Use a * {@link Pipeline} instead if you want to create a toplevel bin because a * normal bin doesn't have a bus or handle clock distribution of its own. *

* After the bin has been created you will typically add elements to it with * {@link Bin#add(Element)}. Elements can be removed with * {@link Bin#remove(Element)} *

* An element can be retrieved from a bin with * {@link Bin#getElementByName(String)}. *

* A list of elements contained in a bin can be retrieved with * {@link Bin#getElements} * * The {@link ELEMENT_ADDED} signal is fired whenever a new element is added to * the bin. Likewise the {@link ELEMENT_REMOVED} signal is fired whenever an * element is removed from the bin. * */ public class Bin extends Element { public static final String GST_NAME = "bin"; public static final String GTYPE_NAME = "GstBin"; protected Bin(Initializer init) { super(init); } Bin(Handle handle, boolean needRef) { super(handle, needRef); } /** * Creates a new Bin with a unique name. */ public Bin() { this(Natives.initializer(GSTBIN_API.ptr_gst_bin_new(null), false, true)); } /** * Creates a new Bin with the given name. * * @param name The Name to assign to the new Bin */ public Bin(String name) { this(Natives.initializer(GSTBIN_API.ptr_gst_bin_new(name), false, true)); } /** * Adds an Element to this Bin. *

* Sets the element's parent, and thus takes ownership of the element. An * element can only be added to one bin. *

* If the element's pads are linked to other pads, the pads will be unlinked * before the element is added to the bin. * * @param element The {@link Element} to add to this Bin. * @return true if the element was successfully added, false if the Bin will * not accept the element. */ public boolean add(Element element) { return GSTBIN_API.gst_bin_add(this, element); } /** * Adds an array of Element objects to this Bin * * @param elements The array of {@link Element} to add to this Bin * @see Bin#add(Element) */ public void addMany(Element... elements) { GSTBIN_API.gst_bin_add_many(this, elements); } /** * Removes a Element from this Bin *

* Removes the element from the bin, unparenting it as well. * * If the element's pads are linked to other pads, the pads will be unlinked * before the element is removed from the bin. * * @param element The {@link Element} to remove * @return true if the element was successfully removed */ public boolean remove(Element element) { return GSTBIN_API.gst_bin_remove(this, element); } /** * Removes an array of {@link Element} objects from this Bin * * @param elements The list {@link Element} to remove */ public void removeMany(Element... elements) { GSTBIN_API.gst_bin_remove_many(this, elements); } private List elementList(GstIteratorPtr iter) { return GstIterator.asList(iter, Element.class); } /** * Retrieve a list of the {@link Element}s contained in the Bin. * * @return The List of {@link Element}s. */ public List getElements() { return elementList(GSTBIN_API.gst_bin_iterate_elements(this)); } /** * Gets an a list of the elements in this bin in topologically sorted order. * This means that the elements are returned from the most downstream * elements (sinks) to the sources. * * @return The List of {@link Element}s. */ public List getElementsSorted() { return elementList(GSTBIN_API.gst_bin_iterate_sorted(this)); } /** * Retrieve a list of the {@link Element}s contained in the Bin and its Bin * children. * * This differs from {@link #getElements()} as it will also return * {@link Element}s that are in any Bin elements contained in this Bin, also * recursing down those Bins. * * @return The List of {@link Element}s. */ public List getElementsRecursive() { return elementList(GSTBIN_API.gst_bin_iterate_recurse(this)); } /** * Retrieve a list of the sink {@link Element}s contained in the Bin. * * @return The List of sink {@link Element}s. */ public List getSinks() { return elementList(GSTBIN_API.gst_bin_iterate_sinks(this)); } /** * Retrieve a list of the source {@link Element}s contained in the Bin. * * @return The List of source {@link Element}s. */ public List getSources() { return elementList(GSTBIN_API.gst_bin_iterate_sources(this)); } /** * Gets the {@link Element} with the given name from the bin. This function * recurses into child bins. * * @param name The name of the {@link Element} to find. * @return The {@link Element} if found, else null. */ public Element getElementByName(String name) { return GSTBIN_API.gst_bin_get_by_name(this, name); } /** * Gets the element with the given name from this bin. If the element is not * found, a recursion is performed on the parent bin. * * @param name The name of the {@link Element} to find. * @return The {@link Element} if found, else null. */ public Element getElementByNameRecurseUp(String name) { return GSTBIN_API.gst_bin_get_by_name_recurse_up(this, name); } // /** // * Looks for an element inside the bin that implements the given interface. // * If such an element is found, it returns the element. // * // * @param iface The class of the {@link Element} to search for. // * @return The {@link Element} that implements the interface. // */ // public T getElementByInterface(Class iface) { // return iface.cast(GSTBIN_API.gst_bin_get_by_interface(this, GstTypes.typeFor(iface))); // } /** * To aid debugging applications one can use this method to write out the * whole network of gstreamer elements that form the pipeline into a dot * file. This file can be processed with graphviz to get an image. e.g. dot * -Tpng -oimage.png graph_lowlevel.dot *

* The function is only active if gstreamer is configured with * "--gst-enable-gst-debug" and the environment variable * GST_DEBUG_DUMP_DOT_DIR is set to a basepath (e.g. /tmp). * * @param details to show in the graph * @param fileName output base filename (e.g. "myplayer") */ public void debugToDotFile(EnumSet details, String fileName) { GSTBIN_API.gst_debug_bin_to_dot_file( this, NativeFlags.toInt(details), fileName); } /** * To aid debugging applications one can use this method to write out the * whole network of gstreamer elements that form the pipeline into a dot * file. This file can be processed with graphviz to get an image. e.g. dot * -Tpng -oimage.png graph_lowlevel.dot *

* The function is only active if gstreamer is configured with * "--gst-enable-gst-debug" and the environment variable * GST_DEBUG_DUMP_DOT_DIR is set to a basepath (e.g. /tmp). *

* Unlike {@link #debugToDotFile(java.util.EnumSet, java.lang.String)} this * method adds the current timestamp to the filename, so that it can be * used to take multiple snapshots. * * @param details to show in the graph * @param fileName output base filename (e.g. "myplayer") */ public void debugToDotFileWithTS(EnumSet details, String fileName) { GSTBIN_API.gst_debug_bin_to_dot_file_with_ts( this, NativeFlags.toInt(details), fileName); } /** * Signal emitted when an {@link Element} is added to this Bin * * @see #connect(ELEMENT_ADDED) * @see #disconnect(ELEMENT_ADDED) */ public static interface ELEMENT_ADDED { /** * Called when an {@link Element} is added to a {@link Bin} * * @param bin the Bin the element was added to. * @param element the {@link Element} that was added. */ public void elementAdded(Bin bin, Element element); } /** * Add a listener for the element-added signal on this Bin * * @param listener The listener to be called when an {@link Element} is * added. */ public void connect(final ELEMENT_ADDED listener) { connect(ELEMENT_ADDED.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(Bin bin, Element elem) { listener.elementAdded(bin, elem); } }); } /** * Disconnect the listener for the element-added signal * * @param listener The listener that was registered to receive the signal. */ public void disconnect(ELEMENT_ADDED listener) { disconnect(ELEMENT_ADDED.class, listener); } /** * Signal emitted when an {@link Element} is removed from this Bin * * @see #connect(ELEMENT_REMOVED) * @see #disconnect(ELEMENT_REMOVED) */ public static interface ELEMENT_REMOVED { /** * Called when an {@link Element} is removed from a {@link Bin} * * @param bin the Bin the element was removed from. * @param element the {@link Element} that was removed. */ public void elementRemoved(Bin bin, Element element); } /** * Add a listener for the element-removed signal on this Bin * * @param listener The listener to be called when an {@link Element} is * removed. */ public void connect(final ELEMENT_REMOVED listener) { connect(ELEMENT_REMOVED.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(Bin bin, Element elem) { listener.elementRemoved(bin, elem); } }); } /** * Disconnect the listener for the element-removed signal * * @param listener The listener that was registered to receive the signal. */ public void disconnect(ELEMENT_REMOVED listener) { disconnect(ELEMENT_REMOVED.class, listener); } /** * Signal emitted when an {@link Element} is added to sub-bin of this * {@link Bin} * * @see #connect(DEEP_ELEMENT_ADDED) * @see #disconnect(DEEP_ELEMENT_ADDED) */ @Gst.Since(minor = 10) public static interface DEEP_ELEMENT_ADDED { /** * Called when an {@link Element} is added to a {@link Bin} * * Since GStreamer 1.10 * * @param bin the Bin * @param sub_bin the Bin the element was added to. * @param element the {@link Element} that was added. */ public void elementAdded(Bin bin, Bin sub_bin, Element element); } /** * Add a listener for the deep-element-added signal on this Bin * * @param listener The listener to be called when an {@link Element} is * added. */ @Gst.Since(minor = 10) public void connect(final DEEP_ELEMENT_ADDED listener) { Gst.checkVersion(1, 10); connect(DEEP_ELEMENT_ADDED.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(Bin bin, Bin sub_bin, Element elem) { listener.elementAdded(bin, sub_bin, elem); } }); } /** * Disconnect the listener for the deep-element-added signal * * @param listener The listener that was registered to receive the signal. */ @Gst.Since(minor = 10) public void disconnect(DEEP_ELEMENT_ADDED listener) { disconnect(DEEP_ELEMENT_ADDED.class, listener); } /** * Signal emitted when an {@link Element} is removed from sub-bin of this * {@link Bin} * * @see #connect(ELEMENT_REMOVED) * @see #disconnect(ELEMENT_REMOVED) */ @Gst.Since(minor = 10) public static interface DEEP_ELEMENT_REMOVED { /** * Called when an {@link Element} is removed from a {@link Bin} * * Since GStreamer 1.10 * * @param bin the Bin * @param sub_bin the Bin the element was removed from. * @param element the {@link Element} that was removed. */ public void elementRemoved(Bin bin, Bin sub_bin, Element element); } /** * Add a listener for the deep-element-removed signal on this * Bin * * @param listener The listener to be called when an {@link Element} is * removed. */ @Gst.Since(minor = 10) public void connect(final DEEP_ELEMENT_REMOVED listener) { Gst.checkVersion(1, 10); connect(DEEP_ELEMENT_REMOVED.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(Bin bin, Bin sub_bin, Element elem) { listener.elementRemoved(bin, sub_bin, elem); } }); } /** * Disconnect the listener for the deep-element-removed signal * * @param listener The listener that was registered to receive the signal. */ @Gst.Since(minor = 10) public void disconnect(DEEP_ELEMENT_REMOVED listener) { disconnect(DEEP_ELEMENT_REMOVED.class, listener); } /** * Signal emitted when an {@link Element} has latency * * @see #connect(DO_LATENCY) * @see #disconnect(DO_LATENCY) */ public static interface DO_LATENCY { /** * Called when an {@link Element} is removed from a {@link Bin} * * @param bin the Bin the element was removed from. */ public void doLatency(Bin bin); } /** * Add a listener for the do-latency signal on this Bin * * @param listener The listener to be called when an {@link Element} is * removed. */ public void connect(final DO_LATENCY listener) { connect(DO_LATENCY.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(Bin bin) { listener.doLatency(bin); } }); } /** * Disconnect the listener for the do-latency signal * * @param listener The listener that was registered to receive the signal. */ public void disconnect(DO_LATENCY listener) { disconnect(DO_LATENCY.class, listener); } /** * Available details for pipeline graphs produced by * {@link #debugToDotFile(java.util.EnumSet, java.lang.String)} */ public static enum DebugGraphDetails implements NativeFlags { /** * Show caps-name on edges. */ SHOW_MEDIA_TYPE(1 << 0), /** * Show caps-details on edges. */ SHOW_CAPS_DETAILS(1 << 1), /** * Show modified parameters on elements. */ SHOW_NON_DEFAULT_PARAMS(1 << 2), /** * Show element states. */ SHOW_STATES(1 << 3); /** * A convenience EnumSet with all values. */ public final static EnumSet SHOW_ALL = EnumSet.allOf(DebugGraphDetails.class); private final int value; private DebugGraphDetails(int value) { this.value = value; } @Override public int intValue() { return value; } } static class Handle extends Element.Handle { public Handle(GstObjectPtr ptr, boolean ownsHandle) { super(ptr, ownsHandle); } } } ================================================ FILE: src/org/freedesktop/gstreamer/Buffer.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2019 Christophe Lafolet * Copyright (C) 2014 Tom Greenwood * Copyright (C) 2007 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import static org.freedesktop.gstreamer.lowlevel.GstBufferAPI.GSTBUFFER_API; import java.nio.ByteBuffer; import org.freedesktop.gstreamer.lowlevel.GstBufferAPI; import org.freedesktop.gstreamer.lowlevel.GstBufferAPI.BufferStruct; import org.freedesktop.gstreamer.lowlevel.GstBufferAPI.MapInfoStruct; import com.sun.jna.Pointer; import com.sun.jna.ptr.PointerByReference; import java.util.EnumSet; import java.util.Iterator; import java.util.NoSuchElementException; import org.freedesktop.gstreamer.glib.NativeFlags; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GType; import org.freedesktop.gstreamer.lowlevel.GstMetaPtr; /** * Buffers are the basic unit of data transfer in GStreamer. They contain the * timing and offset along with other arbitrary metadata that is associated with * the GstMemory blocks that the buffer contains. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstBuffer.html */ public class Buffer extends MiniObject { public static final String GTYPE_NAME = "GstBuffer"; private final MapInfoStruct mapInfo; private final BufferStruct struct; /** * Creates a newly allocated buffer without any data. */ public Buffer() { this(Natives.initializer(GSTBUFFER_API.ptr_gst_buffer_new())); } /** * Creates a newly allocated buffer with data of the given size. The buffer * memory is not cleared. If the requested amount of memory cannot be * allocated, an exception will be thrown. *

* Note that when size == 0, the buffer data pointer will be NULL. * * @param size */ public Buffer(int size) { this(Natives.initializer(allocBuffer(size))); } Buffer(Initializer init) { super(init); mapInfo = new MapInfoStruct(); struct = new BufferStruct(getRawPointer()); } private static Pointer allocBuffer(int size) { Pointer ptr = GSTBUFFER_API.ptr_gst_buffer_new_allocate(null, size, null); if (ptr == null) { throw new OutOfMemoryError("Could not allocate Buffer of size " + size); } return ptr; } /** * Gets a {@link java.nio.ByteBuffer} that can access the native memory * associated with this Buffer, with the option of ensuring the memory is * writable. *

* When requesting a writable buffer, if the buffer is writable but the * underlying memory isn't, a writable copy will automatically be created * and returned. The readonly copy of the buffer memory will then also be * replaced with this writable copy. *

* The Buffer should be unmapped with {@link #unmap()} after usage. * * @param writable * @return A {@link java.nio.ByteBuffer} that can access this Buffer's data. */ public ByteBuffer map(boolean writable) { final boolean ok = GSTBUFFER_API.gst_buffer_map(this, mapInfo, writable ? GstBufferAPI.GST_MAP_WRITE : GstBufferAPI.GST_MAP_READ); if (ok && mapInfo.data != null) { return mapInfo.data.getByteBuffer(0, mapInfo.size.intValue()); } return null; } /** * Release the memory previously mapped with {@link #map(boolean)} */ public void unmap() { GSTBUFFER_API.gst_buffer_unmap(this, mapInfo); } /** * Get the amount of memory blocks that this buffer has. This amount is never * larger than what {@code gst_buffer_get_max_memory()} returns. * * @return the number of memory blocks this buffer is made of. */ public int getMemoryCount() { return GSTBUFFER_API.gst_buffer_n_memory(this); } /** * Gets the timestamps of this buffer. The buffer DTS refers to the * timestamp when the buffer should be decoded and is usually monotonically * increasing. * * @return a long representing the timestamp or {@link ClockTime#NONE} * when the timestamp is not known or relevant. */ public long getDecodeTimestamp() { return (long) this.struct.readField("dts"); } /** * Set the decode timestamp of the Buffer * * @param val a long representing the timestamp or * {@link ClockTime#NONE} when the timestamp is not known or relevant. */ public void setDecodeTimestamp(long val) { this.struct.writeField("dts", val); } /** * Gets the timestamps of this buffer. The buffer PTS refers to the * timestamp when the buffer content should be presented to the user and is * not always monotonically increasing. * * @return a long representing the timestamp or {@link ClockTime#NONE} * when the timestamp is not known or relevant. */ public long getPresentationTimestamp() { return (long) this.struct.readField("pts"); } /** * Set the presentation timestamp of the Buffer * * @param val a long representing the timestamp or * {@link ClockTime#NONE} when the timestamp is not known or relevant. */ public void setPresentationTimestamp(long val) { this.struct.writeField("pts", val); } /** * Gets the duration of this buffer. * * @return a ClockTime representing the timestamp or {@link ClockTime#NONE} * when the timestamp is not known or relevant. */ public long getDuration() { return (long) this.struct.readField("duration"); } /** * Set the duration of this buffer. * * @param val a long representing the duration or * {@link ClockTime#NONE} when the timestamp is not known or relevant. */ public void setDuration(long val) { this.struct.writeField("duration", val); } /** * Get the offset (media-specific) of this buffer * * @return a media specific offset for the buffer data. For video frames, * this is the frame number of this buffer. For audio samples, this is the * offset of the first sample in this buffer. For file data or compressed * data this is the byte offset of the first byte in this buffer. */ public long getOffset() { return (Long) this.struct.readField("offset"); } /** * Set the offset (media-specific) of this buffer * * @param val a media specific offset for the buffer data. For video frames, * this is the frame number of this buffer. For audio samples, this is the * offset of the first sample in this buffer. For file data or compressed * data this is the byte offset of the first byte in this buffer. */ public void setOffset(long val) { this.struct.writeField("offset", val); } /** * Get the offset (media-specific) of this buffer * * @return a media specific offset for the buffer data. For video frames, * this is the frame number of this buffer. For audio samples, this is the * offset of the first sample in this buffer. For file data or compressed * data this is the byte offset of the first byte in this buffer. */ public long getOffsetEnd() { return (Long) this.struct.readField("offset_end"); } /** * Set the offset (media-specific) of this buffer * * @param val a media specific offset for the buffer data. For video frames, * this is the frame number of this buffer. For audio samples, this is the * offset of the first sample in this buffer. For file data or compressed * data this is the byte offset of the first byte in this buffer. */ public void setOffsetEnd(long val) { this.struct.writeField("offset_end", val); } /** * Get the GstBufferFlags describing this buffer. *

* Since GStreamer 1.10 * * @return an EnumSet of {@link BufferFlags} */ @Gst.Since(minor = 10) public EnumSet getFlags() { Gst.checkVersion(1, 10); int nativeInt = GstBufferAPI.GSTBUFFER_API.gst_buffer_get_flags(this); return NativeFlags.fromInt(BufferFlags.class, nativeInt); } /** * Get the metadata for api on buffer. When there is no such metadata, NULL * is returned. * * @param implementation type of metadata * @param api api type of metadata * @return meta or null */ public T getMeta(Meta.API api) { GType apiType = api.getAPIGType(); if (apiType == GType.INVALID) { return null; } GstMetaPtr ptr = GSTBUFFER_API.gst_buffer_get_meta(this, apiType); // can not create metadata class from null pointer if (ptr == null) { return null; } return Natives.objectFor(ptr, api.getImplClass(), false, false); } /** * Iterate all Meta on buffer. * * @return iterator of meta */ public Iterator iterateMeta() { return new MetaIterator(this); } /** * Check if buffer contains metadata for api. *

* Since GStreamer 1.14 * * @param implementation type of metadata * @param api type of metadata * @return return true only if buffer contains selected type of metadata */ @Gst.Since(minor = 14) public boolean hasMeta(Meta.API api) { return getMetaCount(api) > 0; } /** * Check number of metadata for api. There can be more than one metadata in * case of multiple video/audio layer. *

* Since GStreamer 1.14 * * @param implementation type of metadata * @param api type of metadata * @return count of metadata of provided api type */ @Gst.Since(minor = 14) public int getMetaCount(Meta.API api) { Gst.checkVersion(1, 14); GType apiType = api.getAPIGType(); if (apiType == GType.INVALID) { return 0; } return GSTBUFFER_API.gst_buffer_get_n_meta(this, apiType); } /** * Set some of the GstBufferFlags describing this buffer. This is a union * operation and does not clear flags that are not mentioned. *

* Since GStreamer 1.10 * * @param flags an EnumSet of {@link BufferFlags} to be set on the buffer. * @return true if flags were successfully set on this buffer */ @Gst.Since(minor = 10) public boolean setFlags(EnumSet flags) { Gst.checkVersion(1, 10); return GstBufferAPI.GSTBUFFER_API.gst_buffer_set_flags(this, NativeFlags.toInt(flags)); } /** * unset the GstBufferFlags describing this buffer. This is a difference * operation and does not clear flags that are not mentioned. *

* Since GStreamer 1.10 * * @param flags an EnumSet of {@link BufferFlags} to be cleared on the buffer. * @return true if flags were successfully cleared on this buffer * */ @Gst.Since(minor = 10) public boolean unsetFlags(EnumSet flags) { Gst.checkVersion(1, 10); return GstBufferAPI.GSTBUFFER_API.gst_buffer_unset_flags(this, NativeFlags.toInt(flags)); } private static class MetaIterator implements Iterator { private final PointerByReference state; private final Buffer buffer; private Meta next; MetaIterator(final Buffer buffer) { state = new PointerByReference(); this.buffer = buffer; } @Override public boolean hasNext() { if (next == null) { next = getNext(); } return next != null; } @Override public Meta next() { if (!hasNext() || next == null) { throw new NoSuchElementException(); } Meta m = next; next = null; return m; } private Meta getNext() { return Natives.objectFor( GSTBUFFER_API.gst_buffer_iterate_meta(this.buffer, this.state), Meta.class, false, false ); } } } ================================================ FILE: src/org/freedesktop/gstreamer/BufferFlags.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (C) 2007 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.NativeFlags; /** * A set of buffer flags used to describe properties of a {@link Buffer}. */ public enum BufferFlags implements NativeFlags { /** * the {@link Buffer} is live data and should be discarded in the PAUSED state. */ LIVE(MiniObjectFlags.LAST.intValue() << 0), /** * the {@link Buffer} contains data that should be dropped * because it will be clipped against the segment * boundaries or because it does not contain data * that should be shown to the user. */ DECODE_ONLY(MiniObjectFlags.LAST.intValue() << 1), /** * The {@link Buffer} marks a discontinuity in the stream. * This typically occurs after a seek or a dropped buffer from a live or * network source. */ DISCONT(MiniObjectFlags.LAST.intValue() << 2), /** * The {@link Buffer} timestamps might have a discontinuity and this buffer is a good point to resynchronize. */ RESYNC(MiniObjectFlags.LAST.intValue() << 3), /** * the {@link Buffer} data is corrupted. */ CORRUPTED(MiniObjectFlags.LAST.intValue() << 4), /** * the buffer contains a media specific marker. for video this is typically the end of a frame boundary, for audio this is usually the start of a talkspurt. */ MARKER(MiniObjectFlags.LAST.intValue() << 5), /** * he buffer contains header information that is needed to decode the following data. */ HEADER(MiniObjectFlags.LAST.intValue() << 6), /** * The {@link Buffer} has been created to fill a gap in the * stream and contains media neutral data (elements can switch to optimized code * path that ignores the buffer content). */ GAP(MiniObjectFlags.LAST.intValue() << 7), /** * the {@link Buffer} can be dropped without breaking the stream, for example to reduce bandwidth. */ DROPPABLE(MiniObjectFlags.LAST.intValue() << 8), /** This unit cannot be decoded independently. */ DELTA_UNIT(MiniObjectFlags.LAST.intValue() << 9), /** * this flag is set when memory of the {@link Buffer} is added/removed */ TAG_MEMORY(MiniObjectFlags.LAST.intValue() << 10), /** * Elements which write to disk or permanent storage should ensure the data is synced after writing the contents of this {@link Buffer}. (Since 1.6) */ SYNC_AFTER(MiniObjectFlags.LAST.intValue() << 11), /** * This buffer is important and should not be dropped. This can be used to * mark important buffers, e.g. to flag RTP packets carrying keyframes or * codec setup data for RTP Forward Error Correction purposes, or to prevent * still video frames from being dropped by elements due to QoS. (Since * 1.14) */ @Gst.Since(minor = 14) NON_DROPPABLE(MiniObjectFlags.LAST.intValue() << 12), /* padding */ LAST(MiniObjectFlags.LAST.intValue() << 16); private final int value; private BufferFlags(int value) { this.value = value; } /** * Get the integer value of the enum. * @return The integer value for this enum. */ public final int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/BufferPool.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2016 Christophe Lafolet * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.lowlevel.GstBufferPoolAPI; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.glib.Natives; /** * A BufferPool is an object that can be used to pre-allocate and recycle * buffers of the same size and with the same properties. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstBufferPool.html */ public class BufferPool extends GstObject { public static final String GTYPE_NAME = "GstBufferPool"; /** * Creates a new instance of BufferPool */ public BufferPool() { this(Natives.initializer(GstBufferPoolAPI.GSTBUFFERPOOL_API.ptr_gst_buffer_pool_new())); } /** * This constructor is for internal use only. * @param init initialization data. */ BufferPool(final Initializer init) { super(init); } /** * Configure the BufferPool with the given parameters. * * @param caps the {@link Caps} for the buffers * @param size the size of each buffer, not including prefix and padding * @param min_buffers the minimum amount of buffers to allocate * @param max_buffers the maximum amount of buffers to allocate or 0 for unlimited */ public void setParams(Caps caps, int size, int min_buffers, int max_buffers) { Structure config = GstBufferPoolAPI.GSTBUFFERPOOL_API.gst_buffer_pool_get_config(this); GstBufferPoolAPI.GSTBUFFERPOOL_API.gst_buffer_pool_config_set_params(config, caps, size, min_buffers, max_buffers); } /** * Query the {@link Caps} configured on the BufferPool. * * @return Caps configured on the BufferPool */ public Caps getCaps() { Structure config = GstBufferPoolAPI.GSTBUFFERPOOL_API.gst_buffer_pool_get_config(this); Pointer[] ptr = new Pointer[1]; GstBufferPoolAPI.GSTBUFFERPOOL_API.gst_buffer_pool_config_get_params(config, ptr, null, null, null); return new Caps(Natives.initializer(ptr[0], false, true)); } } ================================================ FILE: src/org/freedesktop/gstreamer/Bus.java ================================================ /* * Copyright (c) 2025 Neil C Smith * Copyright (C) 2014 Tom Greenwood * Copyright (C) 2007 Wayne Meissner * Copyright (C) 2004 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import java.util.List; import java.util.Locale; import java.util.concurrent.CopyOnWriteArrayList; import java.util.logging.Level; import java.util.logging.Logger; import com.sun.jna.Callback; import com.sun.jna.CallbackThreadInitializer; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.LongByReference; import com.sun.jna.ptr.PointerByReference; import org.freedesktop.gstreamer.glib.GObject; import org.freedesktop.gstreamer.glib.NativeEnum; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstAPI.GErrorStruct; import org.freedesktop.gstreamer.lowlevel.GstBusAPI; import org.freedesktop.gstreamer.lowlevel.GstBusAPI.BusCallback; import org.freedesktop.gstreamer.lowlevel.GstBusPtr; import org.freedesktop.gstreamer.lowlevel.GstMessagePtr; import org.freedesktop.gstreamer.message.Message; import org.freedesktop.gstreamer.message.MessageType; import static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API; import static org.freedesktop.gstreamer.lowlevel.GstBusAPI.GSTBUS_API; import static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API; import static org.freedesktop.gstreamer.lowlevel.GstMiniObjectAPI.GSTMINIOBJECT_API; /** * The {@link Bus} is an object responsible for delivering {@link Message}s in a * first-in first-out way from the streaming threads to the application. *

* See upstream documentation at * https://gstreamer.freedesktop.org/documentation/gstreamer/gstbus.html *

* Since the application typically only wants to deal with delivery of these * messages from one thread, the Bus will marshal the messages between different * threads. This is important since the actual streaming of media is done in * another thread than the application. *

* It is also possible to get messages from the bus without any thread * marshalling with the {@link #setSyncHandler} method. This makes it possible * to react to a message in the same thread that posted the message on the bus. * This should only be used if the application is able to deal with messages * from different threads. *

* Every {@link Pipeline} has one bus. *

* Note that a Pipeline will set its bus into flushing state when changing from * READY to NULL state. */ public class Bus extends GstObject { public static final String GTYPE_NAME = "GstBus"; private static final Logger LOG = Logger.getLogger(Bus.class.getName()); private static final SyncCallback SYNC_CALLBACK = new SyncCallback(); private volatile BusSyncHandler syncHandler = null; private final Object lock = new Object(); private final List> messageProxies = new CopyOnWriteArrayList<>(); private boolean watchAdded = false; /** * This constructor is used internally by gstreamer-java * * @param init internal initialization data */ Bus(Initializer init) { super(init); GSTBUS_API.gst_bus_set_sync_handler(this, null, null, null); GSTBUS_API.gst_bus_set_sync_handler(this, SYNC_CALLBACK, null, null); } /** * Instructs the bus to flush out any queued messages. * * If flushing, flush out any messages queued in the bus. Will flush future * messages until {@link #setFlushing} is called with false. * * @param flushing true if flushing is desired. */ public void setFlushing(boolean flushing) { GSTBUS_API.gst_bus_set_flushing(this, flushing ? 1 : 0); } /** * Add a listener for end-of-stream messages. * * @param listener The listener to be called when end-of-stream is * encountered. */ public void connect(final EOS listener) { connect(EOS.class, listener, new BusCallback() { public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) { listener.endOfStream(Natives.objectFor(msg.getSource(), GstObject.class, true, true)); return true; } }); } /** * Disconnect the listener for end-of-stream messages. * * @param listener The listener that was registered to receive the message. */ public void disconnect(EOS listener) { disconnect(EOS.class, listener); } /** * Add a listener for error messages. * * @param listener The listener to be called when an error in the stream is * encountered. */ public void connect(final ERROR listener) { connect(ERROR.class, listener, new BusCallback() { public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) { PointerByReference err = new PointerByReference(); GSTMESSAGE_API.gst_message_parse_error(msg, err, null); GErrorStruct error = new GErrorStruct(err.getValue()); GstObject source = Natives.objectFor(msg.getSource(), GstObject.class, true, true); listener.errorMessage(source, error.getCode(), error.getMessage()); GLIB_API.g_error_free(err.getValue()); return true; } }); } /** * Disconnect the listener for error messages. * * @param listener The listener that was registered to receive the message. */ public void disconnect(ERROR listener) { disconnect(ERROR.class, listener); } /** * Add a listener for warning messages. * * @param listener The listener to be called when an {@link Element} emits a * warning. */ public void connect(final WARNING listener) { connect(WARNING.class, listener, new BusCallback() { public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) { PointerByReference err = new PointerByReference(); GSTMESSAGE_API.gst_message_parse_warning(msg, err, null); GErrorStruct error = new GErrorStruct(err.getValue()); GstObject source = Natives.objectFor(msg.getSource(), GstObject.class, true, true); listener.warningMessage(source, error.getCode(), error.getMessage()); GLIB_API.g_error_free(err.getValue()); return true; } }); } /** * Disconnect the listener for warning messages. * * @param listener The listener that was registered to receive the message. */ public void disconnect(WARNING listener) { disconnect(WARNING.class, listener); } /** * Add a listener for informational messages. * * @param listener The listener to be called when an {@link Element} emits a * an informational message. */ public void connect(final INFO listener) { connect(INFO.class, listener, new BusCallback() { public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) { PointerByReference err = new PointerByReference(); GSTMESSAGE_API.gst_message_parse_info(msg, err, null); GErrorStruct error = new GErrorStruct(err.getValue()); GstObject source = Natives.objectFor(msg.getSource(), GstObject.class, true, true); listener.infoMessage(source, error.getCode(), error.getMessage()); GLIB_API.g_error_free(err.getValue()); return true; } }); } /** * Disconnect the listener for informational messages. * * @param listener The listener that was registered to receive the message. */ public void disconnect(INFO listener) { disconnect(INFO.class, listener); } /** * Add a listener for {@link State} changes in the Pipeline. * * @param listener The listener to be called when the Pipeline changes * state. */ public void connect(final STATE_CHANGED listener) { connect(STATE_CHANGED.class, listener, new BusCallback() { public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) { IntByReference oldPtr = new IntByReference(); IntByReference currentPtr = new IntByReference(); IntByReference pendingPtr = new IntByReference(); GSTMESSAGE_API.gst_message_parse_state_changed(msg, oldPtr, currentPtr, pendingPtr); State old = NativeEnum.fromInt(State.class, oldPtr.getValue()); State current = NativeEnum.fromInt(State.class, currentPtr.getValue()); State pending = NativeEnum.fromInt(State.class, pendingPtr.getValue()); GstObject source = Natives.objectFor(msg.getSource(), GstObject.class, true, true); listener.stateChanged(source, old, current, pending); return true; } }); } /** * Disconnect the listener for {@link State} change messages. * * @param listener The listener that was registered to receive the message. */ public void disconnect(STATE_CHANGED listener) { disconnect(STATE_CHANGED.class, listener); } /** * Add a listener for new media tags. * * @param listener The listener to be called when new media tags are found. */ public void connect(final TAG listener) { connect(TAG.class, listener, new BusCallback() { public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) { PointerByReference list = new PointerByReference(); GSTMESSAGE_API.gst_message_parse_tag(msg, list); TagList tl = new TagList(Natives.initializer(list.getValue())); GstObject source = Natives.objectFor(msg.getSource(), GstObject.class, true, true); listener.tagsFound(source, tl); return true; } }); } /** * Disconnect the listener for tag messages. * * @param listener The listener that was registered to receive the message. */ public void disconnect(TAG listener) { disconnect(TAG.class, listener); } /** * Add a listener for {@link BUFFERING} messages in the Pipeline. * * @param listener The listener to be called when the Pipeline buffers data. */ public void connect(final BUFFERING listener) { connect(BUFFERING.class, listener, new BusCallback() { public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) { IntByReference percent = new IntByReference(); GSTMESSAGE_API.gst_message_parse_buffering(msg, percent); GstObject source = Natives.objectFor(msg.getSource(), GstObject.class, true, true); listener.bufferingData(source, percent.getValue()); return true; } }); } /** * Disconnect the listener for buffering messages. * * @param listener The listener that was registered to receive the message. */ public void disconnect(BUFFERING listener) { disconnect(BUFFERING.class, listener); } /** * Add a listener for duration changes. * * @param listener The listener to be called when the duration changes. */ public void connect(final DURATION_CHANGED listener) { connect(DURATION_CHANGED.class, listener, new BusCallback() { public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) { GstObject source = Natives.objectFor(msg.getSource(), GstObject.class, true, true); listener.durationChanged(source); return true; } }); } /** * Disconnect the listener for duration change messages. * * @param listener The listener that was registered to receive the message. */ public void disconnect(DURATION_CHANGED listener) { disconnect(DURATION_CHANGED.class, listener); } /** * Add a listener for {@link SEGMENT_START} messages in the Pipeline. * * @param listener The listener to be called when the Pipeline has started a * segment. */ public void connect(final SEGMENT_START listener) { connect(SEGMENT_START.class, listener, new BusCallback() { public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) { IntByReference formatPtr = new IntByReference(); LongByReference positionPtr = new LongByReference(); GSTMESSAGE_API.gst_message_parse_segment_start(msg, formatPtr, positionPtr); Format format = NativeEnum.fromInt(Format.class, formatPtr.getValue()); GstObject source = Natives.objectFor(msg.getSource(), GstObject.class, true, true); listener.segmentStart(source, format, positionPtr.getValue()); return true; } }); } /** * Disconnect the listener for segment-start messages. * * @param listener The listener that was registered to receive the message. */ public void disconnect(SEGMENT_START listener) { disconnect(SEGMENT_START.class, listener); } /** * Add a listener for {@link SEGMENT_DONE} messages in the Pipeline. * * @param listener The listener to be called when the Pipeline has finished * a segment. */ public void connect(final SEGMENT_DONE listener) { connect(SEGMENT_DONE.class, listener, new BusCallback() { public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) { IntByReference formatPtr = new IntByReference(); LongByReference positionPtr = new LongByReference(); GSTMESSAGE_API.gst_message_parse_segment_done(msg, formatPtr, positionPtr); Format format = NativeEnum.fromInt(Format.class, formatPtr.getValue()); GstObject source = Natives.objectFor(msg.getSource(), GstObject.class, true, true); listener.segmentDone(source, format, positionPtr.getValue()); return true; } }); } /** * Disconnect the listener for segment-done messages. * * @param listener The listener that was registered to receive the message. */ public void disconnect(SEGMENT_DONE listener) { disconnect(SEGMENT_DONE.class, listener); } /** * Add a listener for {@link ASYNC_DONE} messages in the Pipeline. * * @param listener The listener to be called when the an element has * finished an async state change. */ public void connect(final ASYNC_DONE listener) { connect(ASYNC_DONE.class, listener, new BusCallback() { public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) { GstObject source = Natives.objectFor(msg.getSource(), GstObject.class, true, true); listener.asyncDone(source); return true; } }); } /** * Disconnect the listener for async-done messages. * * @param listener The listener that was registered to receive the message. */ public void disconnect(ASYNC_DONE listener) { disconnect(ASYNC_DONE.class, listener); } /** * Add a listener for all messages posted on the Bus. * * @param listener The listener to be called when a {@link Message} is * posted. */ public void connect(final MESSAGE listener) { connect(MESSAGE.class, listener, new BusCallback() { public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) { listener.busMessage(Bus.this, Natives.objectFor(msg, Message.class, true, true)); return true; } }); } /** * Add a listener for messages of type {@code signal} posted on the Bus. * * @param signal the signal to connect to. * @param listener The listener to be called when a {@link Message} is * posted. */ public void connect(String signal, final MESSAGE listener) { // // Deal with being called as e.g. "message::eos" // if (signal.contains("::")) { signal = signal.substring(signal.lastIndexOf("::") + 2); } connect(signal, MESSAGE.class, listener, new BusCallback() { public boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer user_data) { listener.busMessage(Bus.this, Natives.objectFor(msg, Message.class, true, true)); return true; } }); } /** * Disconnect the listener for segment-done messages. * * @param listener The listener that was registered to receive the message. */ public void disconnect(MESSAGE listener) { disconnect(MESSAGE.class, listener); } /** * Posts a {@link Message} on this Bus. * * @param message the message to post. * @return true if the message could be posted, false if * the bus is flushing. */ public boolean post(Message message) { return GSTBUS_API.gst_bus_post(this, message); } /** * Sets the synchronous handler (message listener) on the bus. The handler * will be called every time a new message is posted on the bus. Note that * the handler will be called in the same thread context as the posting * object. Applications should generally handle messages asynchronously * using the other message listeners. *

* Only one handler may be attached to the bus at any one time. An attached * sync handler forces creation of {@link Message} objects for all messages * on the bus, so the handler should be removed if no longer required. *

* A single native sync handler is used at all times, with synchronous and * asynchronous dispatch handled on the Java side, so the bindings do not * inherit issues in clearing or replacing the sync handler with versions of * GStreamer prior to 1.16.3. * * @param handler bus sync handler, or null to remove */ public void setSyncHandler(BusSyncHandler handler) { syncHandler = handler; } /** * Clear the synchronous handler. *

* This is a convenience method equivalent to {@code setSyncHandler(null)} */ public void clearSyncHandler() { setSyncHandler(null); } /** * Get the current synchronous handler. * * @return current sync handler, or null */ public BusSyncHandler getSyncHandler() { return syncHandler; } /** * Connects to a signal. * * The signal name is deduced from the listenerClass name. * * @param listenerClass the class of the listener. * @param listener the listener to associate with the {@code callback} * @param callback The callback to call when the signal is emitted. */ private void connect(Class listenerClass, T listener, BusCallback callback) { String className = listenerClass.getSimpleName(); MessageType type; if ("MESSAGE".equals(className)) { type = MessageType.ANY; } else { type = MessageType.valueOf(listenerClass.getSimpleName()); } addMessageProxy(type, listenerClass, listener, callback); } /** * Connects a callback to a signal. *

* This differs to {@link GObject#connect} in that it hooks up Bus signals * to the sync callback, not the generic GObject signal mechanism. * * @param listener type * @param signal the name of the signal to connect to. * @param listenerClass the class of the {@code listener} * @param listener the listener to associate with the {@code callback} * @param callback the callback to call when the signal is emitted. */ @Override public void connect(String signal, Class listenerClass, T listener, final Callback callback) { if (listenerClass.getEnclosingClass() != Bus.class) { super.connect(signal, listenerClass, listener, callback); } else { MessageType type; if ("message".equals(signal)) { type = MessageType.ANY; } else { type = MessageType.valueOf(signal.toUpperCase(Locale.ROOT).replace('-', '_')); } addMessageProxy(type, listenerClass, listener, (BusCallback) callback); } } private synchronized void addMessageProxy(MessageType type, Class listenerClass, T listener, BusCallback callback) { messageProxies.add(new MessageProxy(type, listenerClass, listener, callback)); addWatch(); } @Override public void disconnect(Class listenerClass, T listener) { if (listenerClass.getEnclosingClass() != Bus.class) { super.disconnect(listenerClass, listener); } else { removeMessageProxy(listenerClass, listener); } } private synchronized void removeMessageProxy(Class listenerClass, T listener) { messageProxies.removeIf(p -> p.listener == listener); if (messageProxies.isEmpty()) { removeWatch(); } } /** * Dispatches a message to all interested listeners. *

* We do this here from a sync callback, because the default gstbus dispatch * uses the default main context to signal that there are messages waiting * on the bus. Since that is used by the GTK L&F under swing, we never get * those notifications, and the messages just queue up. * */ private void dispatchMessage(GstBusPtr busPtr, GstMessagePtr msgPtr) { messageProxies.forEach(p -> { try { p.busMessage(busPtr, msgPtr); } catch (Throwable t) { LOG.log(Level.SEVERE, "Exception thrown by bus message handler", t); } }); GSTMINIOBJECT_API.gst_mini_object_unref(msgPtr); } @Override public void dispose() { removeWatch(); super.dispose(); } /** * Adds the bus signal watch. This will reference the bus until the signal * watch is removed and so will stop the Bus being GC'd and disposed. */ private void addWatch() { synchronized (lock) { if (!watchAdded) { LOG.fine("Add watch"); GSTBUS_API.gst_bus_add_signal_watch(this); watchAdded = true; } } } /** * Removes the bus signal watch (which will remove the bus reference held by * the signal watch). */ private void removeWatch() { synchronized (lock) { if (watchAdded) { LOG.fine("Remove watch"); GSTBUS_API.gst_bus_remove_signal_watch(this); watchAdded = false; } } } /** * Signal emitted when end-of-stream is reached in a pipeline. * * The application will only receive this message in the PLAYING state and * every time it sets a pipeline to PLAYING that is in the EOS state. The * application can perform a flushing seek in the pipeline, which will undo * the EOS state again. * * @see #connect(EOS) * @see #disconnect(EOS) */ public static interface EOS { /** * Called when a {@link Pipeline} element posts a end-of-stream message. * * @param source the element which posted the message. */ public void endOfStream(GstObject source); } /** * Signal emitted when an error occurs. *

* When the application receives an error message it should stop playback of * the pipeline and not assume that more data will be played. * * @see #connect(ERROR) * @see #disconnect(ERROR) */ public static interface ERROR { /** * Called when a {@link Pipeline} element posts an error message. * * @param source the element which posted the message. * @param code a numeric code representing the error. * @param message a string representation of the error. */ public void errorMessage(GstObject source, int code, String message); } /** * Signal emitted when a warning message is delivered. * * @see #connect(WARNING) * @see #disconnect(WARNING) */ public static interface WARNING { /** * Called when a {@link Pipeline} element posts an warning message. * * @param source the element which posted the message. * @param code a numeric code representing the warning. * @param message a string representation of the warning. */ public void warningMessage(GstObject source, int code, String message); } /** * Signal emitted when an informational message is delivered. * * @see #connect(INFO) * @see #disconnect(INFO) */ public static interface INFO { /** * Called when a {@link Pipeline} element posts an informational * message. * * @param source the element which posted the message. * @param code a numeric code representing the informational message. * @param message a string representation of the informational message. */ public void infoMessage(GstObject source, int code, String message); } /** * Signal emitted when a new tag is identified on the stream. * * @see #connect(TAG) * @see #disconnect(TAG) */ public static interface TAG { /** * Called when a {@link Pipeline} element finds media meta-data. * * @param source the element which posted the message. * @param tagList a list of media meta-data. */ public void tagsFound(GstObject source, TagList tagList); } /** * Signal emitted when a state change happens. * * @see #connect(STATE_CHANGED) * @see #disconnect(STATE_CHANGED) */ public static interface STATE_CHANGED { /** * Called when a {@link Pipeline} element executes a {@link State} * change. * * @param source the element which posted the message. * @param old the old state that the element is changing from. * @param current the new (current) state the element is changing to. * @param pending the pending (target) state. */ public void stateChanged(GstObject source, State old, State current, State pending); } /** * Signal emitted when the pipeline is buffering data. * * @see #connect(BUFFERING) * @see #disconnect(BUFFERING) */ public static interface BUFFERING { /** * Called when a {@link Pipeline} element needs to buffer data before it * can continue processing. *

* {@code percent} is a value between 0 and 100. A value of 100 means * that the buffering completed. *

* When {@code percent} is less than 100 the application should PAUSE a * PLAYING pipeline. When {@code percent} is 100, the application can * set the pipeline (back) to PLAYING. *

* The application must be prepared to receive BUFFERING messages in the * PREROLLING state and may only set the pipeline to PLAYING after * receiving a message with {@code percent} set to 100, which can happen * after the pipeline completed prerolling. * * @param source the element which posted the message. * @param percent the percentage of buffering that has completed. */ public void bufferingData(GstObject source, int percent); } /** * Signal sent when a new duration message is posted by an element that know * the duration of a stream in a specific format. *

* This message is received by bins and is used to calculate the total * duration of a pipeline. *

* Elements may post a duration message with a duration of * {@link ClockTime#NONE} to indicate that the duration has changed and the * cached duration should be discarded. The new duration can then be * retrieved via a query. The application can get the new duration with a * duration query. * * @see #connect(DURATION) * @see #disconnect(DURATION) */ public static interface DURATION_CHANGED { /** * Called when a new duration message is posted on the Bus. * * @param source the element which posted the message. */ public void durationChanged(GstObject source); } /** * This message is posted by elements that start playback of a segment as a * result of a segment seek. *

* This message is not received by the application but is used for * maintenance reasons in container elements. */ public static interface SEGMENT_START { public void segmentStart(GstObject source, Format format, long position); } /** * Signal emitted when the pipeline has completed playback of a segment. *

* This message is posted by elements that finish playback of a segment as a * result of a segment seek. This message is received by the application * after all elements that posted a {@link SEGMENT_START} have posted * segment-done. * * @see #connect(SEGMENT_DONE) * @see #disconnect(SEGMENT_DONE) */ public static interface SEGMENT_DONE { /** * Called when a segment-done message has been posted. * * @param source the element which posted the message. * @param format the format of the position being done. * @param position the position of the segment being done. */ public void segmentDone(GstObject source, Format format, long position); } /** * Signal emitted by elements when they complete an ASYNC state change. *

* Applications will only receive this message from the top level pipeline. *

* * @see #connect(ASYNC_DONE) * @see #disconnect(ASYNC_DONE) */ public static interface ASYNC_DONE { /** * Called when a segment-done message has been posted. * * @param source the element which posted the message. */ public void asyncDone(GstObject source); } /** * Catch all signals emitted on the Bus. *

* The signal handler will be called asynchronously from the thread that * posted the message on the Bus. * * @see #connect(MESSAGE) * @see #disconnect(MESSAGE) */ public static interface MESSAGE { /** * Called when a {@link Element} posts a {@link Message} on the Bus. * * @param bus the Bus the message was posted on. * @param message the message that was posted. */ public void busMessage(Bus bus, Message message); } private static class MessageProxy { private final MessageType type; private final Class listenerClass; private final Object listener; private final BusCallback callback; MessageProxy(MessageType type, Class listenerClass, T listener, BusCallback callback) { this.type = type; this.listenerClass = listenerClass; this.listener = listener; this.callback = callback; } void busMessage(final GstBusPtr bus, final GstMessagePtr msg) { if (type == MessageType.ANY || type.intValue() == msg.getMessageType()) { callback.callback(bus, msg, null); } } } private static class SyncCallback implements GstBusAPI.BusSyncHandler { { Native.setCallbackThreadInitializer(this, new CallbackThreadInitializer(true, Boolean.getBoolean("glib.detachCallbackThreads"), "GstBus")); } @Override public BusSyncReply callback(final GstBusPtr busPtr, final GstMessagePtr msgPtr, Pointer userData) { Bus bus = Natives.objectFor(busPtr, Bus.class, true, true); // volatile - use local reference BusSyncHandler syncHandler = bus.syncHandler; if (syncHandler != null) { Message msg = Natives.objectFor(msgPtr, Message.class, true, true); BusSyncReply reply = syncHandler.syncMessage(msg); if (reply != BusSyncReply.DROP) { Gst.getExecutor().execute(() -> bus.dispatchMessage(busPtr, msgPtr)); } else { // not calling dispatch message so unref here GSTMINIOBJECT_API.gst_mini_object_unref(msgPtr); } } else { Gst.getExecutor().execute(() -> bus.dispatchMessage(busPtr, msgPtr)); } return BusSyncReply.DROP; } } } ================================================ FILE: src/org/freedesktop/gstreamer/BusSyncHandler.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.message.Message; /** * A BusSyncHandler will be invoked synchronously, when a new message has been * injected into a {@link Bus}. This function is mostly used internally. Only * one sync handler can be attached to a given bus. * * @see Bus#setSyncHandler(org.freedesktop.gstreamer.BusSyncHandler) */ public interface BusSyncHandler { public BusSyncReply syncMessage(Message message); } ================================================ FILE: src/org/freedesktop/gstreamer/BusSyncReply.java ================================================ /* * Copyright (c) 2025 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.NativeEnum; import org.freedesktop.gstreamer.message.Message; /** * The result values for a GstBusSyncHandler. */ public enum BusSyncReply implements NativeEnum { /** Drop the {@link Message} */ DROP(0), /** Pass the {@link Message} to the async queue */ PASS(1), /** Pass {@link Message} to async queue, continue if message is handled */ ASYNC(2); private final int value; BusSyncReply(int value) { this.value = value; } /** * Gets the integer value of the enum. * @return The integer value for this enum. */ @Override public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/Caps.java ================================================ /* * Copyright (c) 2025 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (C) 2007 Wayne Meissner * Copyright (C) <2003> David A. Schleef * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstCapsAPI.GSTCAPS_API; /** * Structure describing sets of media formats *

* Caps (capabilities) are lightweight objects describing media types. They are * composed of an array of {@link Structure}. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstCaps.html *

* Caps are exposed on {@link PadTemplate} to describe all possible types a * given pad can handle. They are also stored in the {@link Registry} along with * a description of the {@link Element}. *

* Caps are exposed on the element pads using the {@link Pad#getAllowedCaps() } * method. This method describes the possible types that the pad can handle or * produce at runtime. *

* Caps are also attached to buffers to describe the content of the data pointed * to by the buffer with {@link Sample#setCaps}. Caps attached to a * {@link Buffer} allow for format negotiation upstream and downstream. *

* A Caps can be constructed with the following code fragment: *

* * Caps caps = Caps.fromString("video/x-raw-rgb, bpp=32, depth=24, width=640, height=480"); * *

* A Caps is fixed when it has no properties with ranges or lists. Use * {@link #isFixed} to test for fixed caps. Only fixed caps can be set on a * {@link Pad} or {@link Buffer}. *

* Various methods exist to work with the media types such as subtracting or * intersecting. * * @see Structure */ public class Caps extends MiniObject { public static final String GTYPE_NAME = "GstCaps"; /** * Creates a new Caps that is empty. That is, the returned Caps contains no * media formats. * * @see #emptyCaps */ public Caps() { this(Natives.initializer(GSTCAPS_API.ptr_gst_caps_new_empty())); } /** * Construct a new Caps from a string representation. * * @param caps The string representation of the caps. * @see #fromString */ public Caps(String caps) { this(Natives.initializer(GSTCAPS_API.ptr_gst_caps_from_string(caps))); } /** * Create a caps that is a copy of another caps. * * @param caps The caps to copy. * @see #copy */ public Caps(Caps caps) { this(Natives.initializer(GSTCAPS_API.ptr_gst_caps_copy(caps))); } Caps(Initializer init) { super(init); } /** * Append the structures contained in caps to this caps object. The * structures in caps are not copied -- they are transferred to this caps. *

* If either caps is ANY, the resulting caps will be ANY. * * @param caps The Caps to append */ public void append(Caps caps) { GSTCAPS_API.gst_caps_append(this, caps); } /** * Append structure to this caps. The structure is not copied; this caps * takes ownership, so do not use struct after calling this method. * * @param struct The structure to append. */ public void append(Structure struct) { GSTCAPS_API.gst_caps_append_structure(this, struct); } /** * Create a new Caps as a copy of the this caps. * * The new Caps will be a copy of this caps, with all the internal * structures copied as well. * * @return The new Caps. */ public Caps copy() { return GSTCAPS_API.gst_caps_copy(this); } @Override public boolean equals(Object other) { if (other == null || !(other instanceof Caps)) { return false; } return other == this || isEqual((Caps) other); } /** * Get a {@link Structure} contained in this caps. * * Finds the structure in @caps that has the index @index, and returns it. * * @param index The index of the structure to get. * @return The Structure corresponding to index. */ public Structure getStructure(int index) { /* * WARNING: This function takes a const GstCaps *, but returns a * non-const GstStructure *. This is for programming convenience -- * the caller should be aware that structures inside a constant * #GstCaps should not be modified. */ // The above means we return a Structure proxy which does not own the pointer. // gst_caps_get_structure is not marked as CallerOwnsReturn, so it should work return GSTCAPS_API.gst_caps_get_structure(this, index); } /** * Creates a new {@link Caps} that contains all the formats that are common * to both this Caps and the other Caps. * * @param other The {@link Caps} to intersect with this one. * * @return The new {@link Caps} */ public Caps intersect(Caps other) { return GSTCAPS_API.gst_caps_intersect(this, other); } /** * Check if this caps is always compatible with another caps. *

* A given Caps structure is always compatible with another if every media * format that is in the first is also contained in the second. That is, * this caps1 is a subset of other. * * @param other The caps to test against. * @return true if other is always compatible with this caps. */ public boolean isAlwaysCompatible(Caps other) { return GSTCAPS_API.gst_caps_is_always_compatible(this, other); } /** * Determine if this caps represents any media format. * * @return true if this caps represents any format. */ public boolean isAny() { return GSTCAPS_API.gst_caps_is_any(this); } /** * Determine if this caps represents no media formats. * * @return true if this caps represents no formats. */ public boolean isEmpty() { return GSTCAPS_API.gst_caps_is_empty(this); } /** * Checks if the given caps represent the same set of caps. *

* This function does not work reliably if optional properties for caps are * included on one caps and omitted on the other. * * @param other The caps to compare this caps to. * @return true if other caps equals this one. */ public boolean isEqual(Caps other) { return GSTCAPS_API.gst_caps_is_equal(this, other); } /** * Tests if two Caps are equal. This function only works on fixed Caps. * * @param other The other caps to test against. * @return true if the other caps is equal to this one. */ public boolean isEqualFixed(Caps other) { return GSTCAPS_API.gst_caps_is_equal_fixed(this, other); } /** * Determine if this caps is fixed. *

* Fixed Caps describe exactly one format, that is, they have exactly one * structure, and each field in the structure describes a fixed type. * Examples of non-fixed types are GST_TYPE_INT_RANGE and GST_TYPE_LIST. * * @return true if this caps is fixed */ public boolean isFixed() { return GSTCAPS_API.gst_caps_is_fixed(this); } /** * Checks if all caps represented by this caps are also represented by * superset. *

* This function does not work reliably if optional properties for caps are * included on one caps and omitted on the other. * * @param superset The potentially greater Caps * @return true if this caps is a subset of superset */ public boolean isSubset(Caps superset) { return GSTCAPS_API.gst_caps_is_subset(this, superset); } /** * * Returns a writable copy of this caps. *

* This method will invalidate the native side of this caps object, so it * should not be used after calling this method, and only the returned Caps * object should be used. *

* * @return A writable version of this caps object. */ // @TODO should this take a ref ? public Caps makeWritable() { return GSTCAPS_API.gst_caps_make_writable(this); } /** * Normalize the Caps. * * Creates a new {@link Caps} that represents the same set of formats as * this Caps, but contains no lists. Each list is expanded into separate * {@link Structure}s * * @return The new {@link Caps} * @see Structure */ public Caps normalize() { // this.ref(); // gst_caps_normalize copies "this" and drops one reference Natives.ref(this); return GSTCAPS_API.gst_caps_normalize(this); } /** * Remove a structure from the caps. Removes the structure with the given * index from the list of structures contained in this caps. * * @param index Index of the structure to remove. */ public void removeStructure(int index) { GSTCAPS_API.gst_caps_remove_structure(this, index); } public void setInteger(String field, Integer value) { GSTCAPS_API.gst_caps_set_simple(this, field, value, null); } /** * Modifies this caps inplace into a representation that represents the same * set of formats, but in a simpler form. Component structures that are * identical are merged. Component structures that have values that can be * merged are also merged. * * @return The new {@link Caps} */ public Caps simplify() { // this.ref(); // gst_caps_simplify copies "this" and drops one reference Natives.ref(this); return GSTCAPS_API.gst_caps_simplify(this); } /** * Get the number of structures contained in this caps. * * @return the number of structures that this caps contains */ public int size() { return GSTCAPS_API.gst_caps_get_size(this); } /** * Subtracts the subtrahend Caps from this Caps. * * This function does not work reliably if optional properties for * caps are included on one caps and omitted on the other. * * @param subtrahend The {@link Caps} to subtract. * @return The resulting caps. */ public Caps subtract(Caps subtrahend) { return GSTCAPS_API.gst_caps_subtract(this, subtrahend); } @Override public String toString() { return GSTCAPS_API.gst_caps_to_string(this); } /** * Destructively discard all but the first structure from this caps. * * Useful when fixating. This caps must be writable. * * @return truncated copy of the Caps */ public Caps truncate() { // this.ref(); Natives.ref(this); return GSTCAPS_API.gst_caps_truncate(this); } /** * Creates a new Caps that indicates that it is compatible with any media * format. * * @return The new Caps. */ public static Caps anyCaps() { return new Caps(Natives.initializer(GSTCAPS_API.ptr_gst_caps_new_any())); } /** * Creates a new Caps that is empty. That is, the returned Caps contains no * media formats. * * @return The new Caps. */ public static Caps emptyCaps() { return new Caps(Natives.initializer(GSTCAPS_API.ptr_gst_caps_new_empty())); } /** * Construct a new Caps from a string representation. Example: *

* * Caps caps = Caps.fromString("video/x-raw, format=RGB, bpp=32, depth=24, width=640, height=480"); * * * @param caps The string representation of the caps. * @return The new Caps. */ public static Caps fromString(String caps) { return new Caps(Natives.initializer(GSTCAPS_API.ptr_gst_caps_from_string(caps))); } /** * Merge two {@link Caps} together. *

* Appends the structures contained in caps2 to caps1 if they are not yet * expressed by caps1 . The structures in caps2 are not copied -- they are * transferred to a writable copy of caps1 , and then caps2 is freed. If * either caps is ANY, the resulting caps will be ANY. *

* * @param caps1 the {@link Caps} that will take the new entries. * @param caps2 the {@link Caps} to merge in * @return merged Caps */ public static Caps merge(Caps caps1, Caps caps2) { return GSTCAPS_API.gst_caps_merge(caps1, caps2); } } ================================================ FILE: src/org/freedesktop/gstreamer/Clock.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2004 Wim Taymans * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import static org.freedesktop.gstreamer.lowlevel.GstClockAPI.GSTCLOCK_API; /** * Abstract class for global clocks. *

* GStreamer uses a global clock to synchronize the plugins in a pipeline. * Different clock implementations are possible by implementing this abstract * base class. *

* The {@link Clock} returns a monotonically increasing time with the method * gst_clock_get_time(). Its accuracy and base time depend on the specific * clock implementation but time is always expressed in nanoseconds. Since the * baseline of the clock is undefined, the clock time returned is not * meaningful in itself, what matters are the deltas between two clock times. * The time returned by a clock is called the absolute time. *

* The pipeline uses the clock to calculate the stream time. Usually all * renderers synchronize to the global clock using the buffer timestamps, the * newsegment events and the element's base time, see #GstPipeline. *

* A clock implementation can support periodic and single shot clock * notifications both synchronous and asynchronous. *

* One first needs to create a {@link ClockID} for the periodic or single shot * notification using {@link #newSingleShotID} or {@link #newPeriodicID}. *

* To perform a blocking wait for the specific time of the {@link ClockID} use the * gst_clock_id_wait(). To receive a callback when the specific time is reached * in the clock use gst_clock_id_wait_async(). Both these calls can be * interrupted with the gst_clock_id_unschedule() call. If the blocking wait is * unscheduled a return value of GST_CLOCK_UNSCHEDULED is returned. *

* Periodic callbacks scheduled async will be repeatedly called automatically * until it is unscheduled. To schedule a sync periodic callback, * gst_clock_id_wait() should be called repeatedly. *

* The async callbacks can happen from any thread, either provided by the core * or from a streaming thread. The application should be prepared for this. *

* A {@link ClockID} that has been unscheduled cannot be used again for any wait * operation, a new ClockID should be created. *

* It is possible to perform a blocking wait on the same ClockID from * multiple threads. However, registering the same ClockID for multiple * async notifications is not possible, the callback will only be called for * the thread registering the entry last. *

* These clock operations do not operate on the stream time, so the callbacks * will also occur when not in {@link State#PLAYING} state as if the clock just keeps on * running. Some clocks however do not progress when the element that provided * the clock is not {@link State#PLAYING}. *

* When a clock has the GST_CLOCK_FLAG_CAN_SET_MASTER flag set, it can be * slaved to another #GstClock with the gst_clock_set_master(). The clock will * then automatically be synchronized to this master clock by repeatedly * sampling the master clock and the slave clock and recalibrating the slave * clock with {@link #setCalibration}. This feature is mostly useful for * plugins that have an internal clock but must operate with another clock * selected by the {@link Pipeline}. They can track the offset and rate difference * of their internal clock relative to the master clock by using the * gst_clock_get_calibration() function. *

* The master/slave synchronisation can be tuned with the "timeout", "window-size" * and "window-threshold" properties. The "timeout" property defines the interval * to sample the master clock and run the calibration functions. * "window-size" defines the number of samples to use when calibrating and * "window-threshold" defines the minimum number of samples before the * calibration is performed. */ public class Clock extends GstObject { public static final String GTYPE_NAME = "GstClock"; @Deprecated // should be package private public Clock(Initializer init) { super(init); } /** * Sets the accuracy of the clock. *

* Some clocks have the possibility to operate with different accuracy at * the expense of more resource usage. There is normally no need to change * the default resolution of a clock. The resolution of a clock can only be * changed if the clock has the GST_CLOCK_FLAG_CAN_SET_RESOLUTION flag set. * * @param resolution the new resolution of the clock. * @return the new resolution of the clock. */ public long setResolution(long resolution) { return GSTCLOCK_API.gst_clock_set_resolution(this, resolution); } /** * Gets the accuracy of the clock. The accuracy of the clock is the granularity * of the values returned by {@link #getTime}. * * @return the resolution of the clock in nanoseconds. */ public long getResolution() { return GSTCLOCK_API.gst_clock_get_resolution(this); } /** * Gets the current time of the given clock. The time is always * monotonically increasing and adjusted according to the current * offset and rate. * * Returns: the time of the clock. Or GST_CLOCK_TIME_NONE when * giving wrong input. * @return the time of the clock. Or {@link ClockTime#NONE} when * given incorrect input. */ public long getTime() { return GSTCLOCK_API.gst_clock_get_time(this); } /** * Gets the current internal time of this clock. The time is returned * unadjusted for the offset and the rate. * * Thread safe. * * @return the internal time of the clock. Or {@link ClockTime#NONE} when given wrong input. */ public long getInternalTime() { return GSTCLOCK_API.gst_clock_get_internal_time(this); } /** * Gets the master clock that this clock is slaved to or null when the clock is * not slaved to any master clock. * * @return A master Clock or null when this clock is not slaved to a master * clock. */ public Clock getMaster() { return GSTCLOCK_API.gst_clock_get_master(this); } /** * Set master as the master clock for this clock. This clock will be automatically * calibrated so that {@link #getTime} reports the same time as the * master clock. * * A clock provider that slaves its clock to a master can get the current * calibration values with {@link #getCalibration}. * * master can be null in which case clock will not be slaved anymore. It will * however keep reporting its time adjusted with the last configured rate * and time offsets. * * @param master a master Clock * @return true if the clock is capable of being slaved to a master clock. * Trying to set a master on a clock without the CAN_SET_MASTER flag will make * this function return false. */ public boolean setMaster(Clock master) { return GSTCLOCK_API.gst_clock_set_master(this, master); } /** * Gets the internal rate and reference time of clock. See {@link #setCalibration} for more information. *

* internal, external, rate_num, and rate_denom can be left NULL if the caller is not interested in the values. * * Thread safe. * @param internal a reference internal time * @param external a reference external time * @param rateNumerator the numerator of the rate of the clock relative to its internal time * @param rateDenominator the denominator of the rate of the clock */ @Deprecated public void getCalibration(long internal, long external, long rateNumerator, long rateDenominator) { GSTCLOCK_API.gst_clock_set_calibration(this, internal, external, rateNumerator, rateDenominator); } /** * Gets the internal rate and reference time of clock. See * {@link #setCalibration} for more information. * * @return calibration */ public Calibration getCalibration() { long[] internalPtr = new long[1]; long[] externalPtr = new long[1]; long[] rateNumPtr = new long[1]; long[] rateDenomPtr = new long[1]; GSTCLOCK_API.gst_clock_get_calibration(this, internalPtr, externalPtr, rateNumPtr, rateDenomPtr); return new Calibration(internalPtr[0], externalPtr[0], rateNumPtr[0], rateDenomPtr[0]); } /** * Adjusts the rate and time of this clock. A rate of 1/1 is the normal speed of * the clock. Values bigger than 1/1 make the clock go faster. *

* internal and external are calibration parameters that arrange that * {@link #getTime} should have been external at internal time internal. * This internal time should not be in the future; that is, it should be less * than the value of {@link #getInternalTime} when this function is called. *

* Subsequent calls to gst_clock_get_time() will return clock times computed as * follows: *

* * time = (internal_time - internal) * rateNumerator/ rateDenominator + external * *

* This formula is implemented in gst_clock_adjust_unlocked(). Of course, it * tries to do the integer arithmetic as precisely as possible. *

* Note that {@link #getTime} always returns increasing values so when you * move the clock backwards, getTime() will report the previous value * until the clock catches up. * * Thread safe. * @param internal a reference internal time * @param external a reference external time * @param rateNumerator the numerator of the rate of the clock relative to its internal time * @param rateDenominator the denominator of the rate of the clock */ public void setCalibration(long internal, long external, long rateNumerator, long rateDenominator) { GSTCLOCK_API.gst_clock_set_calibration(this, internal, external, rateNumerator, rateDenominator); } /** * Gets a {@link ClockID} from this clock to trigger a single shot * notification at the requested time. *

* Thread safe. * * @param time The requested time * @return A {@link ClockID} that can be used to request the time notification. */ public ClockID newSingleShotID(long time) { return GSTCLOCK_API.gst_clock_new_single_shot_id(this, time); } /** * Gets an ID from this clock to trigger a periodic notification. * The periodeic notifications will be start at time start_time and * will then be fired with the given interval. *

* Thread safe. * * @param startTime The requested start time. * @param interval The requested interval. * @return A {@link ClockID} that can be used to request the time notification. */ public ClockID newPeriodicID(long startTime, long interval) { return GSTCLOCK_API.gst_clock_new_periodic_id(this, startTime, interval); } /** * Data storage for clock calibration. */ public static final class Calibration { private final long internal; private final long external; private final long rateNum; private final long rateDenom; private Calibration(long internal, long external, long rateNum, long rateDenom) { this.internal = internal; this.external = external; this.rateNum = rateNum; this.rateDenom = rateDenom; } /** * The internal time. * * @return internal time */ public long internal() { return internal; } /** * The external time. * * @return external time */ public long external() { return external; } /** * The rate numerator. * * @return rate numerator */ public long rateNum() { return rateNum; } /** * The rate denominator. * * @return rate denominator */ public long rateDenom() { return rateDenom; } @Override public int hashCode() { int hash = 7; hash = 59 * hash + (int) (this.internal ^ (this.internal >>> 32)); hash = 59 * hash + (int) (this.external ^ (this.external >>> 32)); hash = 59 * hash + (int) (this.rateNum ^ (this.rateNum >>> 32)); hash = 59 * hash + (int) (this.rateDenom ^ (this.rateDenom >>> 32)); return hash; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final Calibration other = (Calibration) obj; if (this.internal != other.internal) { return false; } if (this.external != other.external) { return false; } if (this.rateNum != other.rateNum) { return false; } if (this.rateDenom != other.rateDenom) { return false; } return true; } @Override public String toString() { return "Calibration{" + "internal=" + internal + ", external=" + external + ", rateNum=" + rateNum + ", rateDenom=" + rateDenom + '}'; } } } ================================================ FILE: src/org/freedesktop/gstreamer/ClockID.java ================================================ /* * Copyright (c) 2025 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.RefCountedObject; import org.freedesktop.gstreamer.lowlevel.GPointer; import static org.freedesktop.gstreamer.lowlevel.GstClockAPI.GSTCLOCK_API; /** * A datatype to hold the handle to an outstanding sync or async clock callback. */ public class ClockID extends RefCountedObject implements Comparable { ClockID(Initializer init) { super(new Handle(init.ptr, init.ownsHandle), init.needRef); } /** * Cancel an outstanding request. This can either be an outstanding async * notification or a pending sync notification. After this call, @id cannot * be used anymore to receive sync or async notifications, you need to * create a new #GstClockID. */ public void unschedule() { GSTCLOCK_API.gst_clock_id_unschedule(this); } /** * Gets the time of the clock ID *

* Thread safe. * * @return The time of this clock id. */ public long getTime() { return GSTCLOCK_API.gst_clock_id_get_time(this); } /** * Compares this ClockID to another. * * @param other The other ClockID to compare to * @return negative value if * {@code a < b; zero if a = b; positive value if a > b} */ @Override public int compareTo(ClockID other) { return GSTCLOCK_API.gst_clock_id_compare_func(this, other); } private static final class Handle extends RefCountedObject.Handle { public Handle(GPointer ptr, boolean ownsHandle) { super(ptr, ownsHandle); } @Override protected void disposeNativeHandle(GPointer ptr) { GSTCLOCK_API.gst_clock_id_unref(ptr); } @Override protected void ref() { GSTCLOCK_API.gst_clock_id_ref(getPointer()); } @Override protected void unref() { GSTCLOCK_API.gst_clock_id_unref(getPointer()); } } } ================================================ FILE: src/org/freedesktop/gstreamer/ClockReturn.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue; /** * The return value of a clock operation. */ public enum ClockReturn { /** The operation succeeded. */ OK, /** The operation was scheduled too late. */ EARLY, /** The clockID was unscheduled */ UNSCHEDULED, /** The ClockID is busy */ BUSY, /** A bad time was provided to a function. */ BADTIME, /** An error occured */ ERROR, /** Operation is not supported */ @DefaultEnumValue UNSUPPORTED, /** The ClockID is done waiting */ DONE } ================================================ FILE: src/org/freedesktop/gstreamer/ClockTime.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import java.util.concurrent.TimeUnit; /** * Utility methods for working with clock time (ns) in GStreamer. */ public final class ClockTime { public final static long NONE = -1; public final static long ZERO = 0; private ClockTime() {} /** * Convert time in microseconds to GStreamer clocktime (nanoseconds) * * @param microseconds the microsecond value to represent. * @return time in nanoseconds */ public static long fromMicros(long microseconds) { return TimeUnit.MICROSECONDS.toNanos(microseconds); } /** * Convert GStreamer clocktime (nanoseconds) to microseconds. * * @param clocktime nanosecond time * @return time in microseconds */ public static long toMicros(long clocktime) { return TimeUnit.NANOSECONDS.toMicros(clocktime); } /** * Convert time in milliseconds to GStreamer clocktime (nanoseconds) * * @param milliseconds the millisecond value to represent. * @return time in nanoseconds */ public static long fromMillis(long milliseconds) { return TimeUnit.MILLISECONDS.toNanos(milliseconds); } /** * Convert GStreamer clocktime (nanoseconds) to milliseconds. * * @param clocktime nanosecond time * @return time in milliseconds */ public static long toMillis(long clocktime) { return TimeUnit.NANOSECONDS.toMillis(clocktime); } /** * Convert time in milliseconds to GStreamer clocktime (nanoseconds) * * @param seconds the seconds value to represent. * @return time in nanoseconds */ public static long fromSeconds(long seconds) { return TimeUnit.SECONDS.toNanos(seconds); } /** * Convert GStreamer clocktime (nanoseconds) to seconds. * * @param clocktime nanosecond time * @return time in milliseconds */ public static long toSeconds(long clocktime) { return TimeUnit.NANOSECONDS.toSeconds(clocktime); } /** * Get the hours component of the total time. * * @param clocktime GStreamer time in nanoseconds * @return The hours component of the total time. */ public static long getHoursComponent(long clocktime) { return (toSeconds(clocktime) / 3600) % 24; } /** * Get the minutes component of the total time. * * @param clocktime GStreamer time in nanoseconds * @return The minutes component of the total time. */ public static long getMinutesComponent(long clocktime) { return (toSeconds(clocktime) / 60) % 60; } /** * Get the seconds component of the total time. * * @param clocktime GStreamer time in nanoseconds * @return The seconds component of the total time. */ public static long getSecondsComponent(long clocktime) { return toSeconds(clocktime) % 60; } /** * Determines if this ClockTime represents a valid time value. * * @param clocktime GStreamer time in nanoseconds * @return true if valid, else false */ public static boolean isValid(long clocktime) { return clocktime != NONE; } /** * Returns a {@code String} representation of this {@code ClockTime}. * * @param clocktime GStreamer time in nanoseconds * @return a string representation of this {@code ClockTime} */ public static String toString(long clocktime) { return String.format("%02d:%02d:%02d", getHoursComponent(clocktime), getMinutesComponent(clocktime), getSecondsComponent(clocktime)); } } ================================================ FILE: src/org/freedesktop/gstreamer/Context.java ================================================ /* * Copyright (c) 2025 Neil C Smith * Copyright (c) 2019 Christophe Lafolet * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.lowlevel.GstContextAPI; import org.freedesktop.gstreamer.lowlevel.GstContextPtr; /** * Lightweight objects to represent element contexts. *

* See upstream documentation at https://gstreamer.freedesktop.org/documentation/gstreamer/gstcontext.html *

* Context is a container object used to store contexts like a device context, a * display server connection and similar concepts that should be shared between * multiple elements. *

* Applications can set a context on a complete pipeline by using * {@link Element#setContext(Context)}, which will then be propagated to all * child elements. Elements can handle these in * {@link Element#setContext(Context)} and merge them with the context * information they already have. *

* When an element needs a context it will do the following actions in this * order until one step succeeds: *

    *
  1. Check if the element already has a context
  2. *
  3. Query downstream with GST_QUERY_CONTEXT for the context
  4. *
  5. Query upstream* with GST_QUERY_CONTEXT for the context
  6. *
  7. Post a GST_MESSAGE_NEED_CONTEXT message on the bus with the required * context types and afterwards check if a usable context was set now
  8. *
  9. Create a context by itself and post a GST_MESSAGE_HAVE_CONTEXT message on * the bus.
  10. *
*

* Bins will catch GST_MESSAGE_NEED_CONTEXT messages and will set any previously * known context on the element that asks for it if possible. Otherwise the * application should provide one if it can. *

* Contexts can be persistent. A persistent context is kept in elements when * they reach {@link State#NULL}, non-persistent ones will be removed. Also, a * non-persistent context won't override a previous persistent context set to an * element. */ public class Context extends MiniObject { public static final String GTYPE_NAME = "GstContext"; private final Handle handle; public Context(String contextType) { this(contextType, true); } /** * Create a new context. */ public Context(String context_type, boolean persistent) { this(new Handle(GstContextAPI.GSTCONTEXT_API.gst_context_new(context_type, persistent), true), false); } Context(Handle handle, boolean needRef) { super(handle, needRef); this.handle = handle; } Context(Initializer init) { this(new Handle(init.ptr.as(GstContextPtr.class, GstContextPtr::new), init.ownsHandle), init.needRef); } /** * Access the structure of the context. * * @return The structure of this context. The structure is still owned by this * context, which means that you should not modify it and not dispose of * it. */ public Structure getStructure() { return GstContextAPI.GSTCONTEXT_API.gst_context_get_structure(handle.getPointer()); } /** * Get a writable version of the structure. * * @return The structure of this context. The structure is still owned by the * context, which means that you should not dispose of it. */ public Structure getWritableStructure() { return GstContextAPI.GSTCONTEXT_API.gst_context_writable_structure(handle.getPointer()); } /** * Get the type of this context. * * @return The type of this context. */ public String getContextType() { return GstContextAPI.GSTCONTEXT_API.gst_context_get_context_type(handle.getPointer()); } protected static class Handle extends MiniObject.Handle { public Handle(GstContextPtr ptr, boolean ownsHandle) { super(ptr, ownsHandle); } @Override protected GstContextPtr getPointer() { return (GstContextPtr) super.getPointer(); } } } ================================================ FILE: src/org/freedesktop/gstreamer/ControlBinding.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.lowlevel.GValueAPI; import org.freedesktop.gstreamer.lowlevel.GstControlBindingPtr; import static org.freedesktop.gstreamer.lowlevel.GstControlBindingAPI.GSTCONTROLBINDING_API; /** * Attachment for control source sources. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstControlBinding.html *

*/ public class ControlBinding extends GstObject { public static final String GTYPE_NAME = "GstControlBinding"; private final Handle handle; protected ControlBinding(Handle handle, boolean needRef) { super(handle, needRef); this.handle = handle; } ControlBinding(Initializer init) { this(new Handle( init.ptr.as(GstControlBindingPtr.class, GstControlBindingPtr::new), init.ownsHandle), init.needRef); } /** * Gets the value for the given controlled property at the requested time. * * @param timestamp the time the control-change should be read from * @return the value of the property at the given time, or NULL if the * property isn't controlled */ public Object getValue(long timestamp) { GValueAPI.GValue gValue = GSTCONTROLBINDING_API.gst_control_binding_get_value( handle.getPointer(), timestamp); return gValue == null ? null : gValue.getValue(); } /** * Gets a number of values for the given controlled property starting at * the requested time. *

* This function is useful if one wants to e.g. draw a graph of the control * curve or apply a control curve sample by sample. * * @param timestamp the time that should be processed * @param interval the time spacing between subsequent values * @param values array to fill with control values * @return false if the given array could not be filled */ public boolean getValueArray(long timestamp, long interval, Object[] values) { GValueAPI.GValue[] gValues = new GValueAPI.GValue[values.length]; boolean ok = GSTCONTROLBINDING_API.gst_control_binding_get_g_value_array( handle.getPointer(), timestamp, interval, gValues.length, gValues); if (ok) { for (int i = 0; i < values.length; i++) { values[i] = gValues[i].getValue(); } } return ok; } /** * This function is used to disable a control binding for some time, i.e. * GstObject.syncValues() will do nothing. * * @param disabled whether to disable the controller or not */ public void setDisabled(boolean disabled) { GSTCONTROLBINDING_API.gst_control_binding_set_disabled(handle.getPointer(), disabled); } /** * Check if the control binding is disabled. * * @return TRUE if the binding is inactive */ public boolean isDisabled() { return GSTCONTROLBINDING_API.gst_control_binding_is_disabled(handle.getPointer()); } protected static class Handle extends GstObject.Handle { public Handle(GstControlBindingPtr ptr, boolean ownsHandle) { super(ptr, ownsHandle); } @Override protected GstControlBindingPtr getPointer() { return (GstControlBindingPtr) super.getPointer(); } } } ================================================ FILE: src/org/freedesktop/gstreamer/ControlSource.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.lowlevel.GstControlSourcePtr; import static org.freedesktop.gstreamer.lowlevel.GstControlSourceAPI.GSTCONTROLSOURCE_API; /** * Base class for control source sources. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstControlSource.html *

*/ public class ControlSource extends GstObject { public static final String GTYPE_NAME = "GstControlSource"; private final Handle handle; protected ControlSource(Handle handle, boolean needRef) { super(handle, needRef); this.handle = handle; } ControlSource(Initializer init) { this(new Handle( init.ptr.as(GstControlSourcePtr.class, GstControlSourcePtr::new), init.ownsHandle), init.needRef); } /** * Gets the value for this ControlSource at a given timestamp. * * @param timestamp the time for which the value should be returned * @return value * @throws IllegalStateException if the value could not be calculated */ public double getValue(long timestamp) { double[] out = new double[1]; boolean ok = GSTCONTROLSOURCE_API.gst_control_source_get_value(handle.getPointer(), timestamp, out); if (ok) { return out[0]; } else { throw new IllegalStateException(); } } /** * Gets an array of values for for this ControlSource. Values that are * undefined contain NANs. * * @param timestamp the first timestamp * @param interval the time steps * @param values array to put control-values in * @return true if the values were successfully calculated */ public boolean getValueArray(long timestamp, long interval, double[] values) { return GSTCONTROLSOURCE_API.gst_control_source_get_value_array( handle.getPointer(), timestamp, interval, values.length, values); } /** * A simple structure for saving a timestamp and a value. *

* Equivalent to GstTimedValue. *

* https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstControlSource.html#GstTimedValue * */ public static final class TimedValue { public final long timestamp; public final double value; /** * Create a TimedValue wrapping the timestamp (see {@link ClockTime}) * and corresponding value. * * @param timestamp the timestamp (GstClockTime) of the value change * @param value the corresponding value */ public TimedValue(long timestamp, double value) { this.timestamp = timestamp; this.value = value; } @Override public int hashCode() { int hash = 7; hash = 37 * hash + (int) (this.timestamp ^ (this.timestamp >>> 32)); hash = 37 * hash + (int) (Double.doubleToLongBits(this.value) ^ (Double.doubleToLongBits(this.value) >>> 32)); return hash; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } final TimedValue other = (TimedValue) obj; if (this.timestamp != other.timestamp) { return false; } if (Double.doubleToLongBits(this.value) != Double.doubleToLongBits(other.value)) { return false; } return true; } @Override public String toString() { return "TimedValue{" + "timestamp=" + timestamp + ", value=" + value + '}'; } } protected static class Handle extends GstObject.Handle { public Handle(GstControlSourcePtr ptr, boolean ownsHandle) { super(ptr, ownsHandle); } @Override protected GstControlSourcePtr getPointer() { return (GstControlSourcePtr) super.getPointer(); } } } ================================================ FILE: src/org/freedesktop/gstreamer/DateTime.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2016 Christophe Lafolet * Copyright (c) 2010 Levente Farkas * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import static org.freedesktop.gstreamer.lowlevel.GstDateTimeAPI.GSTDATETIME_API; import org.freedesktop.gstreamer.glib.NativeObject; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.lowlevel.GPointer; /** */ public class DateTime extends NativeObject { public static final String GTYPE_NAME = "GstDateTime"; public static DateTime createInstanceLocalEpoch(long secs) { return new DateTime(GSTDATETIME_API.gst_date_time_new_from_unix_epoch_local_time(secs), false, true); } DateTime(Initializer init) { this(new Handle(init.ptr, init.ownsHandle)); } DateTime(Pointer ptr, boolean needRef, boolean ownsHandle) { this(new Handle(new GPointer(ptr), ownsHandle)); } DateTime(Handle handle) { super(handle); } public int getYear() { return GSTDATETIME_API.gst_date_time_get_year(getRawPointer()); } public int getMonth() { return GSTDATETIME_API.gst_date_time_get_month(getRawPointer()); } public int getDay() { return GSTDATETIME_API.gst_date_time_get_day(getRawPointer()); } public int getHour() { return GSTDATETIME_API.gst_date_time_get_hour(getRawPointer()); } public int getMinute() { return GSTDATETIME_API.gst_date_time_get_minute(getRawPointer()); } public int getSecond() { return GSTDATETIME_API.gst_date_time_get_second(getRawPointer()); } public int getMicrosecond() { return GSTDATETIME_API.gst_date_time_get_microsecond(getRawPointer()); } @Override public String toString() { return "" + getYear() + "-" + getMonth() + "-" + getDay() + " " + getHour() + ":" + getMinute() + ":" + getSecond() + "." + getMicrosecond(); } private static final class Handle extends NativeObject.Handle { public Handle(GPointer ptr, boolean ownsHandle) { super(ptr, ownsHandle); } @Override protected void disposeNativeHandle(GPointer ptr) { GSTDATETIME_API.gst_date_time_unref(ptr.getPointer()); } } } ================================================ FILE: src/org/freedesktop/gstreamer/Element.java ================================================ /* * Copyright (c) 2025 Neil C Smith * Copyright (c) 2019 Christophe Lafolet * Copyright (c) 2009 Levente Farkas * Copyright (C) 2007 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2004 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import java.util.List; import java.util.Set; import java.util.concurrent.TimeUnit; import org.freedesktop.gstreamer.event.Event; import org.freedesktop.gstreamer.event.SeekEvent; import org.freedesktop.gstreamer.event.SeekFlags; import org.freedesktop.gstreamer.event.SeekType; import org.freedesktop.gstreamer.glib.NativeFlags; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback; import org.freedesktop.gstreamer.lowlevel.GstContextPtr; import org.freedesktop.gstreamer.lowlevel.GstIteratorPtr; import org.freedesktop.gstreamer.lowlevel.GstObjectPtr; import org.freedesktop.gstreamer.message.Message; import org.freedesktop.gstreamer.query.Query; import static org.freedesktop.gstreamer.lowlevel.GstElementAPI.GSTELEMENT_API; import static org.freedesktop.gstreamer.lowlevel.GObjectAPI.GOBJECT_API; /** * Abstract base class for all pipeline elements. *

* See upstream documentation at * https://gstreamer.freedesktop.org/documentation/gstreamer/gstelement.html *

* Element is the abstract base class needed to construct an element that can be * used in a GStreamer pipeline. Please refer to the plugin writers guide for * more information on creating Element subclasses. *

* The name of a Element can be retrieved with {@link #getName} and set with * {@link #setName}. *

* All elements have pads (of the type {@link Pad}). These pads link to pads on * other elements. {@link Buffer}s flow between these linked pads. An Element * has a list of {@link Pad} structures for all their input (or sink) and output * (or source) pads. Core and plug-in writers can add and remove pads with * {@link #addPad} and {@link #removePad}. *

* Elements can be linked through their pads. If the link is straightforward, * use the {@link #link} convenience function to link two elements, or * {@link #linkMany} for more elements in a row. *

* For finer control, use {@link #linkPads} and {@link #linkPadsFiltered} to * specify the pads to link on each element by name. *

* Each element has a state (see {@link State}). You can get and set the state * of an element with {@link #getState} and {@link #setState}. * */ public class Element extends GstObject { public static final String GTYPE_NAME = "GstElement"; /** * Creates a new instance of Element. This constructor is used internally. * * @param init internal initialization data. */ protected Element(Initializer init) { super(init); } Element(Handle handle, boolean needRef) { super(handle, needRef); } /** * Creates an instance of the required element type, but does not wrap it in * a proxy. * * @param factoryName The name of the factory to use to produce the Element * @param elementName The name to assign to the created Element * @return a raw element. */ protected static Initializer makeRawElement(String factoryName, String elementName) { return Natives.initializer(ElementFactory.makeRawElement(factoryName, elementName)); } /** * Links this element to another element. The link must be from source to * destination; the other direction will not be tried. *

* The function looks for existing pads that aren't linked yet. It will * request new pads if necessary. Such pads need to be released manually * when unlinking. If multiple links are possible, only one is established. *

* Make sure you have added your elements to a bin or pipeline with * {@link Bin#add} or {@link Bin#addMany} before trying to link them. *

* See {@link #linkPadsFiltered} if you need more control about which pads * are selected for linking. * * @param dest The element containing the destination pad. * @return true if the elements could be linked, false otherwise. */ public boolean link(Element dest) { return GSTELEMENT_API.gst_element_link(this, dest); } /** * Links this element to another element using the given caps as filtercaps. * The link must be from source to destination; the other direction will not * be tried. *

* The function looks for existing pads that aren't linked yet. It will * request new pads if necessary. Such pads need to be released manually * when unlinking. If multiple links are possible, only one is established. *

* Make sure you have added your elements to a bin or pipeline with * {@link Bin#add} or {@link Bin#addMany} before trying to link them. *

* See {@link #linkPadsFiltered} if you need more control about which pads * are selected for linking. * * @param dest The element containing the destination pad. * @param filter The {@link Caps} to filter the link, or Null for no filter. * @return true if the elements could be linked, false otherwise. */ public boolean linkFiltered(Element dest, Caps filter) { return GSTELEMENT_API.gst_element_link_filtered(this, dest, filter); } /** * Unlinks all source pads of this source element with all sink pads of the * sink element to which they are linked. *

* If the link has been made using {@link #link}, it could have created an * requestpad, which has to be released using * gst_element_release_request_pad(). * * @param dest The sink Element to unlink. */ public void unlink(Element dest) { GSTELEMENT_API.gst_element_unlink(this, dest); } /** * Tests if the Element is currently playing. * * @return true if the Element is currently playing */ public boolean isPlaying() { return getState() == State.PLAYING; } /** * Tells the Element to start playing the media stream. Equivalent to * calling {@link #setState(org.freedesktop.gstreamer.State)} with * {@link State#PLAYING}. * * @return the status of the element's state change. */ public StateChangeReturn play() { return setState(State.PLAYING); } /** * Tells the Element to set ready the media stream. Equivalent to calling * {@link #setState(org.freedesktop.gstreamer.State)} with * {@link State#READY}. * * @return the status of the element's state change. */ public StateChangeReturn ready() { return setState(State.READY); } /** * Tells the Element to pause playing the media stream. Equivalent to * calling {@link #setState(org.freedesktop.gstreamer.State)} with * {@link State#PAUSED}. * * @return the status of the element's state change. */ public StateChangeReturn pause() { return setState(State.PAUSED); } /** * Tells the Element to stop playing the media stream. Equivalent to calling * {@link #setState(org.freedesktop.gstreamer.State)} with * {@link State#NULL}. * * @return the status of the element's state change. */ public StateChangeReturn stop() { return setState(State.NULL); } /** * Sets the state of the element. *

* This method will try to set the requested state by going through all the * intermediary states. *

* This function can return {@link StateChangeReturn#ASYNC}, in which case * the element will perform the remainder of the state change asynchronously * in another thread. *

* An application can use {@link #getState} to wait for the completion of * the state change or it can wait for a state change message on the bus. * * @param state the element's new {@link State}. * @return the status of the element's state change. */ public StateChangeReturn setState(State state) { return GSTELEMENT_API.gst_element_set_state(this, state); } /** * Locks the state of an element, so state changes of the parent don't * affect this element anymore. * * @param locked_state true to lock the element's {@link State}. * @return true if the state was changed, false if bad parameters were given * or the elements state-locking needed no change. */ public boolean setLockedState(boolean locked_state) { return GSTELEMENT_API.gst_element_set_locked_state(this, locked_state); } /** * Gets the state of the element. *

* This method will wait until any async state change has completed. * * @return The {@link State} the Element is currently in. */ public State getState() { return getState(-1); } /** * Gets the state of the element. *

* For elements that performed an ASYNC state change, as reported by * {@link #setState(org.freedesktop.gstreamer.State)}, this function will * block up to the specified timeout value for the state change to complete. * * @param timeout the amount of time to wait. * @param units the units of the timeout. * @return The {@link State} the Element is currently in. * */ public State getState(long timeout, TimeUnit units) { State[] state = new State[1]; GSTELEMENT_API.gst_element_get_state(this, state, null, units.toNanos(timeout)); return state[0]; } /** * Gets the state of the element. *

* For elements that performed an ASYNC state change, as reported by * {@link #setState(org.freedesktop.gstreamer.State)}, this function will * block up to the specified timeout value for the state change to complete. * * @param timeout The amount of time in nanoseconds to wait. * @return The {@link State} the Element is currently in. * */ public State getState(long timeout) { State[] state = new State[1]; GSTELEMENT_API.gst_element_get_state(this, state, null, timeout); return state[0]; } /** * Gets the state of the element. *

* For elements that performed an ASYNC state change, as reported by * {@link #setState(org.freedesktop.gstreamer.State)}, this function will * block up to the specified timeout value for the state change to complete. * * @param timeout The amount of time in nanoseconds to wait. * @param states an array to store the states in. Must be of sufficient size * to hold two elements. */ public void getState(long timeout, State[] states) { State[] state = new State[1]; State[] pending = new State[1]; GSTELEMENT_API.gst_element_get_state(this, state, pending, timeout); states[0] = state[0]; states[1] = pending[0]; } /** * Tries to change the state of the element to the same as its parent. If * this function returns false, the state of element is undefined. * * @return true, if the element's state could be synced to the parent's * state. MT safe. */ public boolean syncStateWithParent() { return GSTELEMENT_API.gst_element_sync_state_with_parent(this); } /** * Sets the {@link Caps} on this Element. * * @param caps the new Caps to set. */ public void setCaps(Caps caps) { GOBJECT_API.g_object_set(this, "caps", caps); } /** * Retrieves a pad from the element by name. This version only retrieves * already-existing (i.e. 'static') pads. * * @param padname The name of the {@link Pad} to get. * @return The requested {@link Pad} if found, otherwise null. */ public Pad getStaticPad(String padname) { return GSTELEMENT_API.gst_element_get_static_pad(this, padname); } /** * Retrieves a list of the element's pads. * * @return the List of {@link Pad}s. */ public List getPads() { return padList(GSTELEMENT_API.gst_element_iterate_pads(this)); } /** * Retrieves a list of the element's source pads. * * @return the List of {@link Pad}s. */ public List getSrcPads() { return padList(GSTELEMENT_API.gst_element_iterate_src_pads(this)); } /** * Retrieves a list of the element's sink pads. * * @return the List of {@link Pad}s. */ public List getSinkPads() { return padList(GSTELEMENT_API.gst_element_iterate_sink_pads(this)); } private List padList(GstIteratorPtr iter) { return GstIterator.asList(iter, Pad.class); } /** * Adds a {@link Pad} (link point) to the Element. The Pad's parent will be * set to this element. *

* Pads are not automatically activated so elements should perform the * needed steps to activate the pad in case this pad is added in the PAUSED * or PLAYING state. See {@link Pad#setActive} for more information about * activating pads. *

* This function will emit the {@link PAD_ADDED} signal on the element. * * @param pad The {@link Pad} to add. * @return true if the pad could be added. This function can fail when a pad * with the same name already existed or the pad already had another parent. */ public boolean addPad(Pad pad) { return GSTELEMENT_API.gst_element_add_pad(this, pad); } /** * Retrieves a pad from the element by name. This version only retrieves * request pads. The pad must be released with {@link #releaseRequestPad}. * * @param name the name of the request {@link Pad} to retrieve. * @return the requested Pad if found, otherwise null. Release * using {@link #releaseRequestPad} after usage. */ public Pad getRequestPad(String name) { return GSTELEMENT_API.gst_element_get_request_pad(this, name); } /** * Frees the previously requested pad obtained via {@link #getRequestPad}. * * @param pad the pad to release. */ public void releaseRequestPad(Pad pad) { GSTELEMENT_API.gst_element_release_request_pad(this, pad); } /** * Remove a {@link Pad} from the element. *

* This method is used by plugin developers and should not be used by * applications. Pads that were dynamically requested from elements with * {@link #getRequestPad} should be released with the * {@link #releaseRequestPad} function instead. *

* Pads are not automatically deactivated so elements should perform the * needed steps to deactivate the pad in case this pad is removed in the * PAUSED or PLAYING state. See {@link Pad#setActive} for more information * about deactivating pads. *

* This function will emit the {@link PAD_REMOVED} signal on the element. * * @param pad The {@link Pad} to remove. * @return true if the pad could be removed. Can return false if the pad * does not belong to the provided element. */ public boolean removePad(Pad pad) { return GSTELEMENT_API.gst_element_remove_pad(this, pad); } /** * Retrieves the factory that was used to create this element. * * @return the {@link ElementFactory} used for creating this element. */ public ElementFactory getFactory() { return GSTELEMENT_API.gst_element_get_factory(this); } /** * Get the bus of the element. Note that only a {@link Pipeline} will * provide a bus for the application. * * @return the element's {@link Bus} */ public Bus getBus() { return GSTELEMENT_API.gst_element_get_bus(this); } /** * Sends an event to an element. *

* If the element doesn't implement an event handler, the event will be * pushed on a random linked sink pad for upstream events or a random linked * source pad for downstream events. * * @param ev The {@link Event} to send. * @return true if the event was handled. */ public boolean sendEvent(Event ev) { return GSTELEMENT_API.gst_element_send_event(this, ev); } /** * Signal emitted when an {@link Pad} is added to this element. * * @see #connect(PAD_ADDED) * @see #disconnect(PAD_ADDED) */ public static interface PAD_ADDED { /** * Called when a new {@link Pad} is added to an Element. * * @param element the element the pad was added to. * @param pad the pad which was added. */ public void padAdded(Element element, Pad pad); } /** * Signal emitted when an {@link Pad} is removed from this element. * * @see #connect(PAD_REMOVED) * @see #disconnect(PAD_REMOVED) */ public static interface PAD_REMOVED { /** * Called when a new {@link Pad} is removed from an Element. * * @param element the element the pad was removed from. * @param pad the pad which was removed. */ public void padRemoved(Element element, Pad pad); } /** * Signal emitted when this element ceases to generated dynamic pads. * * @see #connect(NO_MORE_PADS) * @see #disconnect(NO_MORE_PADS) */ public static interface NO_MORE_PADS { /** * Called when an element ceases to generated dynamic pads. * * @param element the element which posted this message. */ public void noMorePads(Element element); } /** * Add a listener for the pad-added signal * * @param listener Listener to be called when a {@link Pad} is added to the * element. */ public void connect(final PAD_ADDED listener) { connect(PAD_ADDED.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(Element elem, Pad pad) { listener.padAdded(elem, pad); } }); } /** * Remove a listener for the pad-added signal * * @param listener The listener that was previously added. */ public void disconnect(PAD_ADDED listener) { disconnect(PAD_ADDED.class, listener); } /** * Add a listener for the pad-added signal * * @param listener Listener to be called when a {@link Pad} is removed from * the element. */ public void connect(final PAD_REMOVED listener) { connect(PAD_REMOVED.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(Element elem, Pad pad) { listener.padRemoved(elem, pad); } }); } /** * Remove a listener for the pad-removed signal * * @param listener The listener that was previously added. */ public void disconnect(PAD_REMOVED listener) { disconnect(PAD_REMOVED.class, listener); } /** * Add a listener for the no-more-pads signal * * @param listener Listener to be called when the element has finished * generating dynamic pads. */ public void connect(final NO_MORE_PADS listener) { connect(NO_MORE_PADS.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(Element elem) { listener.noMorePads(elem); } }); } /** * Remove a listener for the no-more-pads signal * * @param listener The listener that was previously added. */ public void disconnect(NO_MORE_PADS listener) { disconnect(NO_MORE_PADS.class, listener); } /** * Link together a list of elements. *

* Make sure you have added your elements to a bin or pipeline with * {@link Bin#add} or {@link Bin#addMany} before trying to link them. * * @param elements The list of elements to link together. * @return true if all elements successfully linked. */ public static boolean linkMany(Element... elements) { return GSTELEMENT_API.gst_element_link_many(elements); } /** * Unlink a list of elements. * * @param elements The list of elements to link together * */ public static void unlinkMany(Element... elements) { GSTELEMENT_API.gst_element_unlink_many(elements); } /** * Link together source and destination pads of two elements. * * A side effect is that if one of the pads has no parent, it becomes a * child of the parent of the other element. If they have different parents, * the link fails. * * @param src The element containing the source {@link Pad}. * @param srcPadName The name of the source {@link Pad}. Can be null for any * pad. * @param dest The element containing the destination {@link Pad}. * @param destPadName The name of the destination {@link Pad}. Can be null * for any pad. * * @return true if the pads were successfully linked. */ public static boolean linkPads(Element src, String srcPadName, Element dest, String destPadName) { return GSTELEMENT_API.gst_element_link_pads(src, srcPadName, dest, destPadName); } /** * Link together source and destination pads of two elements. A side effect * is that if one of the pads has no parent, it becomes a child of the * parent of the other element. If they have different parents, the link * fails. If caps is not null, makes sure that the caps of the link is a * subset of caps. * * @param src The element containing the source {@link Pad}. * @param srcPadName The name of the source {@link Pad}. Can be null for any * pad. * @param dest The element containing the destination {@link Pad}. * @param destPadName The name of the destination {@link Pad}. Can be null * for any pad. * @param caps The {@link Caps} to use to filter the link. * * @return true if the pads were successfully linked. */ public static boolean linkPadsFiltered(Element src, String srcPadName, Element dest, String destPadName, Caps caps) { return GSTELEMENT_API.gst_element_link_pads_filtered(src, srcPadName, dest, destPadName, caps); } /** * Unlink source and destination pads of two elements. * * @param src The element containing the source {@link Pad}. * @param srcPadName The name of the source {@link Pad}. * @param dest The element containing the destination {@link Pad}. * @param destPadName The name of the destination {@link Pad}. * */ public static void unlinkPads(Element src, String srcPadName, Element dest, String destPadName) { GSTELEMENT_API.gst_element_unlink_pads(src, srcPadName, dest, destPadName); } /** * Posts a {@link Message} on the element's {@link Bus}. * * @param message the Message to post. * @return true if the message was posted, false if the * element does not have a {@link Bus}. */ public boolean postMessage(Message message) { return GSTELEMENT_API.gst_element_post_message(this, message); } /** * Gets the currently configured clock of the element. * * @return the clock of the element. */ public Clock getClock() { return GSTELEMENT_API.gst_element_get_clock(this); } /** * Returns the base time of the element. The base time is the absolute time * of the clock when this element was last put to PLAYING. Subtracting the * base time from the clock time gives the stream time of the element. * * @return the base time of the element */ public long getBaseTime() { return GSTELEMENT_API.gst_element_get_base_time(this); } /** * Set the base time of an element. * * @param time the base time to set * @see #getBaseTime() */ public void setBaseTime(long time) { GSTELEMENT_API.gst_element_set_base_time(this, time); } /** * Returns the start time of this element. * * The start time is the running time of the clock when this element was * last put to {@link State#PAUSED}. Usually the start_time is managed by a * toplevel element such as {@link Pipeline}. * * MT safe. * * @return the start time of this element. */ public long getStartTime() { return GSTELEMENT_API.gst_element_get_start_time(this); } /** * Set the start time of an element. The start time of the element is the * running time of the element when it last went to the {@link State#PAUSED} * state. In {@link State#READY} or after a flushing seek, it is set to 0. * * Toplevel elements like GstPipeline will manage the start_time and * base_time on its children. Setting the start_time to * {@link ClockTime#NONE} on such a toplevel element will disable the * distribution of the base_time to the children and can be useful if the * application manages the base_time itself, for example if you want to * synchronize capture from multiple pipelines, and you can also ensure that * the pipelines have the same clock. * * MT safe. * * @param time the start time to set * @see #getStartTime() */ public void setStartTime(long time) { GSTELEMENT_API.gst_element_set_start_time(this, time); } /** * Performs a query on the element. * * For elements that don't implement a query handler, this function forwards * the query to a random srcpad or to the peer of a random linked sinkpad of * this element. * * Please note that some queries might need a running pipeline to work. * * @param query the Query to perform * @return true if the query could be performed */ public boolean query(Query query) { return GSTELEMENT_API.gst_element_query(this, query); } /** * Sets the context of the element. * * @param context the Context to set. */ public void setContext(Context context) { GstContextPtr gstContextPtr = Natives.getPointer(context).as(GstContextPtr.class, GstContextPtr::new); GSTELEMENT_API.gst_element_set_context(this, gstContextPtr); } /** * Gets the context with the context_type set on the element or NULL. * * @param context_type * @return a context or NULL */ public Context getContext(String context_type) { GstContextPtr gstContextPtr = GSTELEMENT_API.gst_element_get_context(this, context_type); return gstContextPtr != null ? Natives.callerOwnsReturn(gstContextPtr, Context.class) : null; } /** * Queries an element (usually top-level pipeline or playbin element) for * the total stream duration in nanoseconds. This query will only work once * the pipeline is prerolled (i.e. reached PAUSED or PLAYING state). The * application will receive an ASYNC_DONE message on the pipeline bus when * that is the case. *

* If the duration changes for some reason, you will get a DURATION_CHANGED * message on the pipeline bus, in which case you should re-query the * duration using this function. * * @param format the {@code Format} to return the duration in * @return the total duration of the current media stream, or -1 if the * query failed */ public long queryDuration(Format format) { long[] dur = {0}; return GSTELEMENT_API.gst_element_query_duration(this, format, dur) ? dur[0] : -1L; } /** * Queries an element (usually top-level pipeline or playbin element) for * the stream position in nanoseconds. This will be a value between 0 and * the stream duration (if the stream duration is known). This query will * usually only work once the pipeline is prerolled (i.e. reached PAUSED or * PLAYING state). The application will receive an ASYNC_DONE message on the * pipeline bus when that is the case. * * @param format The {@link Format} to return the position in * @return the current position or -1 if the query failed. */ public long queryPosition(Format format) { long[] pos = {0}; return GSTELEMENT_API.gst_element_query_position(this, format, pos) ? pos[0] : -1L; } /** * Sends a seek event to an element. See {@link SeekEvent} for the details * of the parameters. The seek event is sent to the element using the native * equivalent of {@link #sendEvent(org.freedesktop.gstreamer.event.Event)}. * * @param rate the new playback rate * @param format the format of the seek values * @param seekFlags the seek flags * @param startType the type and flags for the new start position * @param start the value of the new start position * @param stopType the type and flags for the new stop position * @param stop the value of the new stop position * @return true if seek operation succeeded. Flushing seeks will trigger a * preroll, which will emit an ASYNC_DONE message */ public boolean seek(double rate, Format format, Set seekFlags, SeekType startType, long start, SeekType stopType, long stop) { return GSTELEMENT_API.gst_element_seek(this, rate, format, NativeFlags.toInt(seekFlags), startType, start, stopType, stop); } /** * Simple API to perform a seek on the given element, meaning it just seeks * to the given position relative to the start of the stream. For more * complex operations like segment seeks (e.g. for looping) or changing the * playback rate or seeking relative to the last configured playback segment * you should use * {@link #seek(double, org.freedesktop.gstreamer.Format, java.util.Set, org.freedesktop.gstreamer.event.SeekType, long, org.freedesktop.gstreamer.event.SeekType, long)}. *

* In a completely prerolled PAUSED or PLAYING pipeline, seeking is always * guaranteed to return TRUE on a seekable media type or FALSE when the * media type is certainly not seekable (such as a live stream). *

* Some elements allow for seeking in the READY state, in this case they * will store the seek event and execute it when they are put to PAUSED. If * the element supports seek in READY, it will always return TRUE when it * receives the event in the READY state. * * @param format a {@link Format} to seek in, such as {@link Format#TIME} * @param seekFlags seek options; playback applications will usually want to * use {@link SeekFlags#FLUSH} and {@link SeekFlags#KEY_UNIT} here * @param seekPosition position to seek to (relative to the start); if you * are doing a seek in format TIME this value is in nanoseconds * @return true if seek operation succeeded. Flushing seeks will trigger a * preroll, which will emit an ASYNC_DONE message */ public boolean seekSimple(Format format, Set seekFlags, long seekPosition) { return GSTELEMENT_API.gst_element_seek_simple(this, format, NativeFlags.toInt(seekFlags), seekPosition); } static class Handle extends GstObject.Handle { public Handle(GstObjectPtr ptr, boolean ownsHandle) { super(ptr, ownsHandle); } } } ================================================ FILE: src/org/freedesktop/gstreamer/ElementFactory.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import static org.freedesktop.gstreamer.lowlevel.GstElementFactoryAPI.GSTELEMENTFACTORY_API; import static org.freedesktop.gstreamer.lowlevel.GstPadTemplateAPI.GSTPADTEMPLATE_API; import static org.freedesktop.gstreamer.lowlevel.GstPluginAPI.GSTPLUGIN_API; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GList; import org.freedesktop.gstreamer.lowlevel.GstPadTemplateAPI.GstStaticPadTemplate; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.glib.Natives; /** * ElementFactory is used to create instances of elements. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstElementFactory.html *

* Use the {@link #find} and {@link #create} methods to create element instances * or use {@link #make} as a convenient shortcut. * */ public class ElementFactory extends PluginFeature { public static final String GTYPE_NAME = "GstElementFactory"; private static final Level DEBUG = Level.FINE; private static final Logger LOG = Logger.getLogger(ElementFactory.class.getName()); /** * Creates a new instance of ElementFactory * * @param init internal initialization data. */ ElementFactory(Initializer init) { super(init); if (LOG.isLoggable(Level.FINER)) { LOG.entering("ElementFactory", "", new Object[]{init}); } } /** * Creates a new element from the factory. * * @param name the name to assign to the created Element * @return A new {@link Element} */ public Element create(String name) { if (LOG.isLoggable(Level.FINER)) { LOG.entering("ElementFactory", "create", name); } Pointer elem = GSTELEMENTFACTORY_API.ptr_gst_element_factory_create(this, name); LOG.log(DEBUG, "gst_element_factory_create returned: " + elem); if (elem == null) { throw new IllegalArgumentException("Cannot create GstElement"); } return elementFor(elem, getName()); } /** * Returns the name of the person who wrote the factory. * * @return The name of the author */ public String getAuthor() { if (LOG.isLoggable(Level.FINER)) { LOG.entering("ElementFactory", "getAuthor"); } return GSTELEMENTFACTORY_API.gst_element_factory_get_metadata(this, "author"); } /** * Returns a description of the factory. * * @return A brief description of the factory. */ public String getDescription() { if (LOG.isLoggable(Level.FINER)) { LOG.entering("ElementFactory", "getDescription"); } return GSTELEMENTFACTORY_API.gst_element_factory_get_metadata(this, "description"); } /** * Returns a string describing the type of factory. This is an unordered * list separated with slashes ('/'). * * @return The description of the type of factory. */ public String getKlass() { if (LOG.isLoggable(Level.FINER)) { LOG.entering("ElementFactory", "getKlass"); } return GSTELEMENTFACTORY_API.gst_element_factory_get_metadata(this, "klass"); } /** * Returns the long, English name for the factory. * * @return The long, English name for the factory. */ public String getLongName() { if (LOG.isLoggable(Level.FINER)) { LOG.entering("ElementFactory", "getLongName"); } return GSTELEMENTFACTORY_API.gst_element_factory_get_metadata(this, "long-name"); } /** * Gets the list of {@link StaticPadTemplate} for this factory. * * @return The list of {@link StaticPadTemplate} */ public List getStaticPadTemplates() { if (LOG.isLoggable(Level.FINER)) { LOG.entering("ElementFactory", "getStaticPadTemplates"); } GList glist = GSTELEMENTFACTORY_API.gst_element_factory_get_static_pad_templates(this); LOG.log(DEBUG, "GSTELEMENTFACTORY_API.gst_element_factory_get_static_pad_templates returned: " + glist); List templates = new ArrayList(); GList next = glist; while (next != null) { if (next.data != null) { GstStaticPadTemplate temp = new GstStaticPadTemplate(next.data); templates.add(new StaticPadTemplate(temp.getName(), temp.getPadDirection(), temp.getPadPresence(), GSTPADTEMPLATE_API.gst_static_pad_template_get_caps(temp))); } next = next.next(); } return templates; } /** * Retrieve an instance of a factory that can produce {@link Element}s * * @param name The type of {@link Element} to produce. * @return An ElementFactory that will produce {@link Element}s of the * desired type. */ public static ElementFactory find(String name) { if (LOG.isLoggable(Level.FINER)) { LOG.entering("ElementFactory", "find", name); } ElementFactory factory = GSTELEMENTFACTORY_API.gst_element_factory_find(name); if (factory == null) { throw new IllegalArgumentException("No such Gstreamer factory: " + name); } return factory; } // /** // * Filter out all the elementfactories in list that can handle caps in the // * given direction. // * // * If subsetonly is true, then only the elements whose pads templates are a // * complete superset of caps will be returned. Else any element whose pad // * templates caps can intersect with caps will be returned. // * // * @param list a {@link List} of {@link ElementFactory} to filter // * @param caps a {@link Caps} // * @param direction a {@link PadDirection} to filter on // * @param subsetonly whether to filter on caps subsets or not. // * @return a {@link List} of {@link ElementFactory} elements that match the // * given requisits. // */ // public static List listFilter(List list, Caps caps, // PadDirection direction, boolean subsetonly) { // GList glist = null; // List filterList = new ArrayList(); // // for (ElementFactory fact : list) { // fact.ref(); // glist = GLIB_API.g_list_append(glist, fact.handle()); // } // // GList gFilterList = GSTELEMENTFACTORY_API.gst_element_factory_list_filter(glist, caps, direction, subsetonly); // // GList next = gFilterList; // while (next != null) { // if (next.data != null) { // ElementFactory fact = new ElementFactory(initializer(next.data, true, true)); // filterList.add(fact); // } // next = next.next(); // } // // GSTPLUGIN_API.gst_plugin_list_free(glist); // GSTPLUGIN_API.gst_plugin_list_free(gFilterList); // // return filterList; // } /** * Get a list of factories that match the given type. Only elements with a * rank greater or equal to minrank will be returned. The list of factories * is returned by decreasing rank. * * @param type a {@link ListType} * @param minrank Minimum rank * @return a List of ElementFactory elements. */ public static List listGetElements(ListType type, Rank minrank) { GList glist = GSTELEMENTFACTORY_API.gst_element_factory_list_get_elements(type.getValue(), minrank.intValue()); List list = new ArrayList(); GList next = glist; while (next != null) { if (next.data != null) { ElementFactory fact = new ElementFactory(Natives.initializer(next.data, true, true)); list.add(fact); } next = next.next(); } GSTPLUGIN_API.gst_plugin_list_free(glist); return list; } /** * Get a list of factories that match the given parameter. * * It is a combination of listGetElement and listFilter passing all the * results of the first call to the second. * * This method improves performance because there is no need to map to java * list the elements returned by the first call. * * @param type a {@link ListType} * @param minrank Minimum rank * @param caps a {@link Caps} * @param direction a {@link PadDirection} to filter on * @param subsetonly whether to filter on caps subsets or not. * @return a {@link List} of {@link ElementFactory} elements that match the * given requisits. */ public static List listGetElementsFilter(ListType type, Rank minrank, Caps caps, PadDirection direction, boolean subsetonly) { List filterList = new ArrayList(); GList glist = GSTELEMENTFACTORY_API.gst_element_factory_list_get_elements(type.getValue(), minrank.intValue()); GList gFilterList = GSTELEMENTFACTORY_API.gst_element_factory_list_filter(glist, caps, direction, subsetonly); GList next = gFilterList; while (next != null) { if (next.data != null) { ElementFactory fact = new ElementFactory(Natives.initializer(next.data, true, true)); filterList.add(fact); } next = next.next(); } GSTPLUGIN_API.gst_plugin_list_free(glist); GSTPLUGIN_API.gst_plugin_list_free(gFilterList); return filterList; } /** * Creates a new Element from the specified factory. * * @param factoryName The name of the factory to use to produce the Element * @param name The name to assign to the created Element * @return A new GstElemElement */ public static Element make(String factoryName, String name) { if (LOG.isLoggable(Level.FINER)) { LOG.entering("ElementFactory", "make", new Object[]{factoryName, name}); } return elementFor(makeRawElement(factoryName, name), factoryName); } static Pointer makeRawElement(String factoryName, String name) { if (LOG.isLoggable(Level.FINER)) { LOG.entering("ElementFactory", "makeRawElement", new Object[]{factoryName, name}); } Pointer elem = GSTELEMENTFACTORY_API.ptr_gst_element_factory_make(factoryName, name); LOG.log(DEBUG, "Return from gst_element_factory_make=" + elem); if (elem == null) { throw new IllegalArgumentException("No such Gstreamer factory: " + factoryName); } return elem; } private static Element elementFor(Pointer ptr, String factoryName) { return Natives.objectFor(ptr, Element.class, false, true); } /** * The type of ElementFactory to filter. */ public enum ListType { /** Decoder elements */ DECODER((long) 1 << 0), /** Encoder elements */ ENCODER((long) 1 << 1), /** Sink elements */ SINK((long) 1 << 2), /** Source elements */ SRC((long) 1 << 3), /** Muxer elements */ MUXER((long) 1 << 4), /** Demuxer elements */ DEMUXER((long) 1 << 5), /** Parser elements */ PARSER((long) 1 << 6), /** Payloader elements */ PAYLOADER((long) 1 << 7), /** Depayloader elements */ DEPAYLOADER((long) 1 << 8), /** Formatter elements */ FORMATTER((long) 1 << 9), /** Decryptor elements */ DECRYPTOR((long) 1 << 10), /** Encryptor elements */ ENCRYPTOR((long) 1 << 11), // /** Private, do not use */ // MAX_ELEMENTS((long) 1 << 48), /** Any elements */ ANY((((long) 1) << 49) - 1), /** Any of the defined media element types */ MEDIA_ANY(~((long) 0) << 48), /** Elements handling video media types */ MEDIA_VIDEO((long) 1 << 49), /** Elements handling audio media types */ MEDIA_AUDIO((long) 1 << 50), /** Elements handling image media types */ MEDIA_IMAGE((long) 1 << 51), /** Elements handling subtitle media types */ MEDIA_SUBTITLE((long) 1 << 52), /** Elements handling metadata media types */ MEDIA_METADATA((long) 1 << 53), /** All encoders handling video or image media types */ VIDEO_ENCODER(ENCODER.getValue() | MEDIA_VIDEO.getValue() | MEDIA_IMAGE.getValue()), /** All encoders handling audio media types */ AUDIO_ENCODER(ENCODER.getValue() | MEDIA_AUDIO.getValue()), /** All sinks handling audio, video or image media types */ AUDIOVIDEO_SINKS(SINK.getValue() | MEDIA_AUDIO.getValue() | MEDIA_VIDEO.getValue() | MEDIA_IMAGE.getValue()), /** All elements used to 'decode' streams (decoders, demuxers, parsers, depayloaders) */ DECODABLE(DECODER.getValue() | DEMUXER.getValue() | DEPAYLOADER.getValue() | PARSER.getValue()); private final long value; private ListType(long value) { this.value = value; } public long getValue() { return value; } } } ================================================ FILE: src/org/freedesktop/gstreamer/FlowReturn.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2007 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.NativeEnum; import org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue; /** * The result of passing data to a pad. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPad.html#GstFlowReturn *

*/ public enum FlowReturn implements NativeEnum { /** Data passing was ok. */ // @TODO need to map custom success and custom error OK and ERROR? @DefaultEnumValue OK(0), /** {@link Pad} is not linked. */ NOT_LINKED(-1), /** {@link Pad} is in wrong state. */ FLUSHING(-2), /** Did not expect anything, like after EOS. */ EOS(-3), /** {@link Pad} is in not negotiated. */ NOT_NEGOTIATED(-4), /** * Some (fatal) error occured. Element generating this error should post * an error message with more details. */ ERROR(-5), /** This operation is not supported. */ NOT_SUPPORTED(-6); private final int value; FlowReturn(int value) { this.value = value; } /** * Gets the integer value of the enum. * @return The integer value for this enum. */ @Override public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/Format.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.NativeEnum; import org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue; /** * Standard predefined formats. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstFormat.html#GstFormat *

*/ // @TODO this won't handle custom registered formats - do we need to? public enum Format implements NativeEnum { /** Undefined format */ @DefaultEnumValue UNDEFINED(0), /** * The default format of the pad/element. This can be samples for raw audio, * frames/fields for raw video (some, but not all, elements support this; * use {@link #TIME } if you don't have a good reason to query for * samples/frames) */ DEFAULT(1), /** Bytes */ BYTES(2), /** Time in nanoseconds */ TIME(3), /** {@link Buffer}s (few, if any, elements implement this as of May 2009) */ BUFFERS(4), /** Percentage of stream (few, if any, elements implement this as of May 2009) */ PERCENT(5); private final int value; Format(int value) { this.value = value; } @Override public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/Fraction.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007,2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; /** * Represents a fraction value. */ public class Fraction { public final int numerator; public final int denominator; /** * Creates a new {@code Fraction}. * * @param numerator the numerator value. * @param denominator the denominator value. */ public Fraction(int numerator, int denominator) { this.numerator = numerator; this.denominator = denominator; } /** * Gets the numerator of the {@code Fraction} * * @return the numerator as an integer. */ public int getNumerator() { return numerator; } /** * Gets the denominator of the {@code Fraction} * * @return the denominator as an integer. */ public int getDenominator() { return denominator; } /** * Returns the fraction as a floating point value (numerator divided by the denominator). * @return fraction as a double, or Double.NaN if the denominator is 0 */ public double toDouble() { return denominator != 0 ? ((double) numerator / denominator) : Double.NaN; } } ================================================ FILE: src/org/freedesktop/gstreamer/GhostPad.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (C) 2007 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Andy Wingo * 2006 Edward Hervey * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstGhostPadAPI.GSTGHOSTPAD_API; /** * Pseudo link pads. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstGhostPad.html *

* GhostPads are useful when organizing pipelines with {@link Bin} like * elements. The idea here is to create hierarchical element graphs. The bin * element contains a sub-graph. Now one would like to treat the bin-element * like any other {@link Element}. This is where GhostPads come into play. A * GhostPad acts as a proxy for another pad. Thus the bin can have sink and * source ghost-pads that are associated with sink and source pads of the child * elements. *

* If the target pad is known at creation time, {@link #GhostPad(String, Pad)} * is the function to use to get a ghost-pad. Otherwise one can use * {@link #GhostPad(String, PadDirection)} to create the ghost-pad and use * {@link #setTarget} to establish the association later on. *

* Note that GhostPads add overhead to the data processing of a pipeline. * * @see Pad */ public class GhostPad extends Pad { public static final String GTYPE_NAME = "GstGhostPad"; /** * Creates a new instance of GhostPad */ GhostPad(Initializer init) { super(init); } /** * Create a new ghostpad with target as the target. The direction will be * taken from the target pad. The target pad must be unlinked. * * @param name The name of the new pad, or null to assign a default name. * @param target The {@link Pad} to ghost. */ public GhostPad(String name, Pad target) { this(Natives.initializer(GSTGHOSTPAD_API.ptr_gst_ghost_pad_new(name, target))); } /** * Create a new ghostpad with target as the target. The direction will be * taken from the target pad. The template used on the ghostpad will be * template. * * @param name The name of the new pad, or null to assign a default name. * @param target The {@link Pad} to ghost. * @param template The {@link PadTemplate} to use on the ghostpad. */ public GhostPad(String name, Pad target, PadTemplate template) { this(Natives.initializer(GSTGHOSTPAD_API.ptr_gst_ghost_pad_new_from_template(name, target, template))); } /** * Create a new ghostpad without a target with the given direction. A target * can be set on the ghostpad later with the {@link #setTarget} method. *

* The created ghostpad will not have a padtemplate. * * @param name The name of the new pad, or null to assign a default name. * @param direction The direction of the ghostpad. */ public GhostPad(String name, PadDirection direction) { this(Natives.initializer(GSTGHOSTPAD_API.ptr_gst_ghost_pad_new_no_target(name, direction.ordinal()))); } /** * Create a new ghostpad based on template, without setting a target. The * direction will be taken from the template. * * @param name The name of the new pad, or null to assign a default name. * @param template The {@link PadTemplate} to use on the ghostpad. */ public GhostPad(String name, PadTemplate template) { this(Natives.initializer(GSTGHOSTPAD_API.ptr_gst_ghost_pad_new_no_target_from_template(name, template))); } /** * Get the target pad of this ghostpad. * * @return the target {@link Pad}, can be null if the ghostpad has no target * set */ public Pad getTarget() { return GSTGHOSTPAD_API.gst_ghost_pad_get_target(this); } /** * Set the new target of the ghostpad. Any existing target is unlinked and * links to the new target are established. * * @param pad The new pad target. * @return true if the new target could be set. This function can return * false when the internal pads could not be linked. */ public boolean setTarget(Pad pad) { return GSTGHOSTPAD_API.gst_ghost_pad_set_target(this, pad); } } ================================================ FILE: src/org/freedesktop/gstreamer/Gst.java ================================================ /* * Copyright (c) 2025 Neil C Smith * Copyright (c) 2018 Antonio Morales * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.query.Query; import org.freedesktop.gstreamer.message.Message; import org.freedesktop.gstreamer.event.Event; import org.freedesktop.gstreamer.glib.GError; import static org.freedesktop.gstreamer.lowlevel.GstAPI.GST_API; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.logging.Logger; import org.freedesktop.gstreamer.glib.MainContextExecutorService; import org.freedesktop.gstreamer.lowlevel.GstAPI.GErrorStruct; import org.freedesktop.gstreamer.lowlevel.GstTypes; import org.freedesktop.gstreamer.glib.NativeObject; import com.sun.jna.Memory; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ServiceLoader; import java.util.logging.Level; import java.util.stream.Stream; import org.freedesktop.gstreamer.controller.Controllers; import org.freedesktop.gstreamer.elements.Elements; import org.freedesktop.gstreamer.glib.GLib; import org.freedesktop.gstreamer.glib.GMainContext; import org.freedesktop.gstreamer.video.Video; import static org.freedesktop.gstreamer.lowlevel.GstParseAPI.GSTPARSE_API; import static org.freedesktop.gstreamer.glib.Natives.registration; import static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API; import org.freedesktop.gstreamer.webrtc.WebRTC; /** * Media library supporting arbitrary formats and filter graphs. */ public final class Gst { private final static Logger LOG = Logger.getLogger(Gst.class.getName()); private final static AtomicInteger INIT_COUNT = new AtomicInteger(0); private final static boolean CHECK_VERSIONS = !Boolean.getBoolean("gstreamer.suppressVersionChecks"); private final static boolean DISABLE_EXTERNAL = Boolean.getBoolean("gstreamer.disableExternalTypes"); private static ScheduledExecutorService executorService; private static volatile CountDownLatch quit = new CountDownLatch(1); private static GMainContext mainContext; private static boolean useDefaultContext = false; private static List shutdownTasks = Collections.synchronizedList(new ArrayList()); // set minorVersion to a value guaranteed to be >= anything else unless set in init() private static int minorVersion = Integer.MAX_VALUE; private static class NativeArgs { public IntByReference argcRef; public PointerByReference argvRef; Memory[] argsCopy; Memory argvMemory; public NativeArgs(String progname, String[] args) { // // Allocate some native memory to pass the args down to the native layer // argsCopy = new Memory[args.length + 2]; argvMemory = new Memory(argsCopy.length * Native.POINTER_SIZE); // // Insert the program name as argv[0] // Memory arg = new Memory(progname.getBytes().length + 4); arg.setString(0, progname); argsCopy[0] = arg; for (int i = 0; i < args.length; i++) { arg = new Memory(args[i].getBytes().length + 1); arg.setString(0, args[i]); argsCopy[i + 1] = arg; } argvMemory.write(0, argsCopy, 0, argsCopy.length); argvRef = new PointerByReference(argvMemory); argcRef = new IntByReference(args.length + 1); } String[] toStringArray() { // // Unpack the native arguments back into a String array // List args = new ArrayList(); Pointer argv = argvRef.getValue(); for (int i = 1; i < argcRef.getValue(); i++) { Pointer arg = argv.getPointer(i * Native.POINTER_SIZE); if (arg != null) { args.add(arg.getString(0)); } } return args.toArray(new String[args.size()]); } } private Gst() { } /** * Gets the version of gstreamer currently available. This function can be * used prior to calling {@link #init(org.freedesktop.gstreamer.Version) } * * @return the version of gstreamer */ public static Version getVersion() { long[] major = {0}, minor = {0}, micro = {0}, nano = {0}; GST_API.gst_version(major, minor, micro, nano); return new Version((int) major[0], (int) minor[0], (int) micro[0], (int) nano[0]); } /** * Gets the the version of gstreamer currently in use, as a String. * * @return a string representation of the version. */ public static String getVersionString() { return GST_API.gst_version_string(); } /** * Some functions in the GStreamer core might install a custom SIGSEGV * handler to better catch and report errors to the application. Currently * this feature is enabled by default when loading plugins. *

* Applications might want to disable this behaviour with the * {@link #setSegTrap(boolean) } function. This is typically done if the * application wants to install its own handler without GStreamer * interfering. * * @return Segmentation Trap status. */ public static boolean isSegTrapEnabled() { return GST_API.gst_segtrap_is_enabled(); } /** * Applications might want to disable/enable the SIGSEGV handling of the * GStreamer core. See {@link #isSegTrapEnabled() } for more information. * * @param enabled */ public static void setSegTrap(boolean enabled) { GST_API.gst_segtrap_set_enabled(enabled); } /** * Test whether the GStreamer library already initialized. * * @return true if the GStreamer library already initialized. */ public static synchronized final boolean isInitialized() { return INIT_COUNT.get() > 0; } /** * Gets the common {@link ScheduledExecutorService} used to execute * background tasks and schedule timeouts. * * @return an executor that can be used for background tasks. */ public static ScheduledExecutorService getExecutor() { return executorService; } /** * Signals the thread that called {@link #init} to return. */ public static void quit() { quit.countDown(); } /** * Create a new pipeline based on command line syntax. * * Please note that you might get a return value that is not NULL even * though the error is set. In this case there was a recoverable parsing * error and you can try to play the pipeline. * * @param pipelineDescription the command line describing the pipeline * @param errors a list that any errors will be added to * @return a new element on success. If more than one top-level element is * specified by the pipeline_description , all elements are put into a * Pipeline, which then is returned. * @throws GstException if the pipeline / element could not be created */ public static Element parseLaunch(String pipelineDescription, List errors) { Pointer[] err = {null}; Element pipeline = GSTPARSE_API.gst_parse_launch(pipelineDescription, err); if (pipeline == null) { throw new GstException(extractError(err[0])); } // check for error if (err[0] != null) { if (errors != null) { errors.add(extractError(err[0])); } else { LOG.log(Level.WARNING, extractError(err[0]).getMessage()); } } return pipeline; } /** * Create a new pipeline based on command line syntax. * * Please note that you might get a return value that is not NULL even * though the error is set. In this case there was a recoverable parsing * error and you can try to play the pipeline. * * @param pipelineDescription the command line describing the pipeline * @return a new element on success. If more than one top-level element is * specified by the pipeline_description , all elements are put into a * Pipeline, which then is returned. * @throws GstException if the pipeline / element could not be created */ public static Element parseLaunch(String pipelineDescription) { return parseLaunch(pipelineDescription, null); } /** * Create a new element based on command line syntax. * * error will contain an error message if an erroneous pipeline is * specified. An error does not mean that the pipeline could not be * constructed. * * @param pipelineDescription An array of strings containing the command * line describing the pipeline. * @param errors a list that any errors will be added to * @return a new element on success. * @throws GstException if the pipeline / element could not be created */ public static Element parseLaunch(String[] pipelineDescription, List errors) { Pointer[] err = {null}; Element pipeline = GSTPARSE_API.gst_parse_launchv(pipelineDescription, err); if (pipeline == null) { throw new GstException(extractError(err[0])); } // check for error if (err[0] != null) { if (errors != null) { errors.add(extractError(err[0])); } else { LOG.log(Level.WARNING, extractError(err[0]).getMessage()); } } return pipeline; } /** * Create a new element based on command line syntax. * * error will contain an error message if an erroneous pipeline is * specified. An error does not mean that the pipeline could not be * constructed. * * @param pipelineDescription An array of strings containing the command * line describing the pipeline. * @return a new element on success. * @throws GstException if the pipeline / element could not be created */ public static Element parseLaunch(String[] pipelineDescription) { return parseLaunch(pipelineDescription, null); } /** * Creates a bin from a text bin description. * * This function allows creation of a bin based on the syntax used in the * gst-launch utillity. * * @param binDescription the command line describing the bin * @param ghostUnlinkedPads whether to create ghost pads for the bin from * any unlinked pads * @param errors list that any errors will be added to * @return The new Bin. * @throws GstException if the bin could not be created */ public static Bin parseBinFromDescription(String binDescription, boolean ghostUnlinkedPads, List errors) { Pointer[] err = {null}; Bin bin = GSTPARSE_API.gst_parse_bin_from_description(binDescription, ghostUnlinkedPads, err); if (bin == null) { throw new GstException(extractError(err[0])); } // check for error if (err[0] != null) { if (errors != null) { errors.add(extractError(err[0])); } else { LOG.log(Level.WARNING, extractError(err[0]).getMessage()); } } return bin; } /** * Creates a bin from a text bin description. * * This function allows creation of a bin based on the syntax used in the * gst-launch utillity. * * @param binDescription the command line describing the bin * @param ghostUnlinkedPads whether to create ghost pads for the bin from * any unlinked pads * @return The new Bin. * @throws GstException if the bin could not be created */ public static Bin parseBinFromDescription(String binDescription, boolean ghostUnlinkedPads) { return parseBinFromDescription(binDescription, ghostUnlinkedPads, null); } private static GError extractError(Pointer errorPtr) { GErrorStruct struct = new GErrorStruct(errorPtr); struct.read(); GError err = new GError(struct.getCode(), struct.getMessage()); GLIB_API.g_error_free(errorPtr); return err; } /** * Waits for the gstreamer system to shutdown via a call to {@link #quit}. *

* For most gui programs, this is of little use. However, it can be a * convenient way of keeping the main thread alive whilst gstreamer * processing on other threads continues. */ public static void main() { try { CountDownLatch latch = quit; if (latch != null) { latch.await(); } } catch (InterruptedException ex) { } finally { quit = new CountDownLatch(1); } } /** * Schedules a task for execution on the gstreamer background * {@link java.util.concurrent.Executor}. * * @param task the task to execute. */ public static void invokeLater(final Runnable task) { getExecutor().execute(task); } /** * Gets the current main context used (if any). * * @return a main context. */ // @TODO leaking lowlevel public static GMainContext getMainContext() { return mainContext; } /** * Initializes the GStreamer library. *

* This is a shortcut if no arguments are to be passed to gstreamer. *

* This is equivalent to calling * {@link #init(org.freedesktop.gstreamer.Version) } with * {@link Version#BASELINE}, currently GStreamer 1.8. If you require * features from a later version of GStreamer you should specify the * required version. * * @throws org.freedesktop.gstreamer.GstException */ public static final void init() throws GstException { init(Version.BASELINE, "gst1-java-core"); } /** * Initializes the GStreamer library. *

* This is a shortcut if no arguments are to be passed to gstreamer. * * @param requiredVersion * @throws org.freedesktop.gstreamer.GstException */ public static final void init(Version requiredVersion) throws GstException { init(requiredVersion, "gst1-java-core"); } /** * Initializes the GStreamer library. *

* This sets up internal path lists, registers built-in elements, and loads * standard plugins. *

* This is equivalent to calling * {@link #init(org.freedesktop.gstreamer.Version, java.lang.String, java.lang.String...) } * with {@link Version#BASELINE}, currently GStreamer 1.8. If you * require features from a later version of GStreamer you should specify the * required version. * * @param progname the java program name. * @param args the java argument list. * @return the list of arguments with any gstreamer specific options * stripped out. * @throws org.freedesktop.gstreamer.GstException */ public static synchronized final String[] init(String progname, String... args) throws GstException { return init(Version.BASELINE, progname, args); } /** * Initializes the GStreamer library. *

* This sets up internal path lists, registers built-in elements, and loads * standard plugins. * * @param requestedVersion the minimum requested GStreamer version. * @param progname the java program name. * @param args the java argument list. * @return the list of arguments with any gstreamer specific options * stripped out. * @throws org.freedesktop.gstreamer.GstException */ public static synchronized final String[] init(Version requestedVersion, String progname, String... args) throws GstException { if (CHECK_VERSIONS) { Version availableVersion = getVersion(); if (requestedVersion.getMajor() != 1 || availableVersion.getMajor() != 1) { throw new GstException("gst1-java-core only supports GStreamer 1.x"); } if (requestedVersion.getMinor() < 8) { requestedVersion = new Version(1, 8); } if (!availableVersion.checkSatisfies(requestedVersion)) { throw new GstException(String.format( "The requested version of GStreamer is not available\nRequested : %s\nAvailable : %s\n", requestedVersion, availableVersion)); } } // // Only do real init the first time through // if (INIT_COUNT.getAndIncrement() > 0) { if (CHECK_VERSIONS) { if (requestedVersion.getMinor() > minorVersion) { minorVersion = (int) requestedVersion.getMinor(); } } return args; } NativeArgs argv = new NativeArgs(progname, args); Pointer[] error = {null}; if (!GST_API.gst_init_check(argv.argcRef, argv.argvRef, error)) { INIT_COUNT.decrementAndGet(); throw new GstException(extractError(error[0])); } LOG.fine("after gst_init, argc=" + argv.argcRef.getValue()); Version runningVersion = getVersion(); if (runningVersion.getMajor() != 1) { LOG.warning("gst1-java-core only supports GStreamer 1.x"); } if (useDefaultContext) { mainContext = GMainContext.getDefaultContext(); executorService = new MainContextExecutorService(mainContext); } else { mainContext = new GMainContext(); executorService = Executors.newSingleThreadScheduledExecutor(threadFactory); } quit = new CountDownLatch(1); loadAllClasses(); if (CHECK_VERSIONS) { minorVersion = requestedVersion.getMinor(); } return argv.toStringArray(); } /** * Clean up any resources created by GStreamer in * {@link #init(org.freedesktop.gstreamer.Version)}. * * It is normally not needed to call this function in a normal * application as the resources will automatically be freed when the program * terminates. This function is therefore mostly used by testsuites and * other memory profiling tools. * * After this call GStreamer (including this method) should not be used * anymore. */ public static synchronized final void deinit() { // // Only perform real shutdown if called as many times as Gst.init() is // if (INIT_COUNT.decrementAndGet() > 0) { return; } // Perform any cleanup tasks for (Object task : shutdownTasks.toArray()) { ((Runnable) task).run(); } // Stop any more tasks/timers from being scheduled executorService.shutdown(); // Wake up the run thread. quit(); // Wait for tasks to complete. try { if (!executorService.awaitTermination(100, TimeUnit.MILLISECONDS)) { // Force-kill everything executorService.shutdownNow(); } } catch (InterruptedException ex) { } mainContext = null; System.gc(); // Make sure any dangling objects are unreffed before calling deinit(). GST_API.gst_deinit(); } /** * Adds a task to be called when {@link Gst#deinit} is called. *

* This is used internally, and is not recommended for other uses. * * @param task the task to execute. */ static void addStaticShutdownTask(Runnable task) { shutdownTasks.add(task); } /** * Instructs gstreamer-java to use the default main context. *

* This may be useful if integration with the GTK main loop is desirable, as * all {@link Bus} signals and timers will be executed in the context of the * GTK main loop. *

* For the majority of programs though, it is better to wrap the individual * listeners in a proxy which executes the listener in the appropriate * context. * * @param useDefault if true, use the default glib main context. */ public static void setUseDefaultContext(boolean useDefault) { useDefaultContext = useDefault; } /** * Checks that the version of GStreamer requested in init() satisfies the * given version or throws an exception. * * @param major major version, only 1 is supported * @param minor minor version required * @throws GstException if the requested version support was not requested */ public static void checkVersion(int major, int minor) { if (CHECK_VERSIONS && (major != 1 || minor > minorVersion)) { throw new GstException("Not supported by requested GStreamer version"); } } /** * Tests that the version of GStreamer requested in init() satisfies the * given version. * * @param major major version, only 1 is supported * @param minor minor version required * @return boolean whether the version requirement can be satisfied */ public static boolean testVersion(int major, int minor) { if (CHECK_VERSIONS && (major != 1 || minor > minorVersion)) { return false; } return true; } // Make the gstreamer executor threads daemon, so they don't stop the main // program from exiting private static final ThreadFactory threadFactory = new ThreadFactory() { private final AtomicInteger counter = new AtomicInteger(0); @Override public Thread newThread(Runnable task) { final String name = "gstreamer service thread " + counter.incrementAndGet(); Thread t = new Thread(task, name); t.setDaemon(true); t.setPriority(Thread.NORM_PRIORITY); return t; } }; private static synchronized void loadAllClasses() { Stream.of(new GLib.Types(), new Types(), new Event.Types(), new Message.Types(), new Query.Types(), new Controllers(), new Elements(), new WebRTC.Types(), new Video.Types()) .flatMap(NativeObject.TypeProvider::types) .forEachOrdered(GstTypes::register); if (!DISABLE_EXTERNAL) { try { ServiceLoader extProviders = ServiceLoader.load(NativeObject.TypeProvider.class); extProviders.iterator().forEachRemaining(prov -> prov.types().forEachOrdered(GstTypes::register)); } catch (Throwable t) { LOG.log(Level.SEVERE, "Error during external types registration", t); } } } public static class Types implements NativeObject.TypeProvider { @Override public Stream> types() { return Stream.of( registration(Bin.class, Bin.GTYPE_NAME, Bin::new), registration(Buffer.class, Buffer.GTYPE_NAME, Buffer::new), registration(BufferPool.class, BufferPool.GTYPE_NAME, BufferPool::new), registration(Bus.class, Bus.GTYPE_NAME, Bus::new), registration(Caps.class, Caps.GTYPE_NAME, Caps::new), registration(Clock.class, Clock.GTYPE_NAME, Clock::new), registration(Context.class, Context.GTYPE_NAME, Context::new), registration(DateTime.class, DateTime.GTYPE_NAME, DateTime::new), registration(Element.class, Element.GTYPE_NAME, Element::new), registration(ElementFactory.class, ElementFactory.GTYPE_NAME, ElementFactory::new), registration(GhostPad.class, GhostPad.GTYPE_NAME, GhostPad::new), registration(Pad.class, Pad.GTYPE_NAME, Pad::new), registration(PadTemplate.class, PadTemplate.GTYPE_NAME, PadTemplate::new), registration(Pipeline.class, Pipeline.GTYPE_NAME, Pipeline::new), registration(Plugin.class, Plugin.GTYPE_NAME, Plugin::new), registration(PluginFeature.class, PluginFeature.GTYPE_NAME, PluginFeature::new), registration(Promise.class, Promise.GTYPE_NAME, Promise::new), registration(Registry.class, Registry.GTYPE_NAME, Registry::new), registration(SDPMessage.class, SDPMessage.GTYPE_NAME, SDPMessage::new), registration(Sample.class, Sample.GTYPE_NAME, Sample::new), registration(Structure.class, Structure.GTYPE_NAME, Structure::new), registration(TagList.class, TagList.GTYPE_NAME, TagList::new) ); } } /** * Annotation on classes, methods or fields to show the required GStreamer * version. This should particularly be used where the version required is * higher than the current baseline supported version (GStreamer 1.8) */ @Retention(RetentionPolicy.RUNTIME) @Documented public static @interface Since { public int major() default 1; public int minor(); } } ================================================ FILE: src/org/freedesktop/gstreamer/GstException.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * Copyright (C) 2004 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.GError; import org.freedesktop.gstreamer.glib.GLibException; /** * Thrown when a GStreamer error occurs. */ public class GstException extends GLibException { private static final long serialVersionUID = -7413580400835548033L; /** * Creates a new instance of GstException without detail message. */ public GstException() { } /** * Constructs an instance of GstException with the specified detail message. * * @param msg the detail message. */ public GstException(String msg) { super(msg); } public GstException(GError error) { super(error); } } ================================================ FILE: src/org/freedesktop/gstreamer/GstIterator.java ================================================ /* * Copyright (c) 2021 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import java.util.ArrayList; import java.util.List; import org.freedesktop.gstreamer.glib.NativeObject; import org.freedesktop.gstreamer.lowlevel.GstIteratorPtr; import org.freedesktop.gstreamer.lowlevel.GstTypes; import org.freedesktop.gstreamer.lowlevel.GType; import org.freedesktop.gstreamer.lowlevel.GValueAPI; import static org.freedesktop.gstreamer.lowlevel.GstIteratorAPI.GSTITERATOR_API; /** * Utility class for working with gstiterator. */ class GstIterator { static List asList(GstIteratorPtr iter, Class type) { final GType gtype = GstTypes.typeFor(type); final GValueAPI.GValue gValue = new GValueAPI.GValue(gtype); List list = new ArrayList<>(); while (GSTITERATOR_API.gst_iterator_next(iter, gValue) == 1) { list.add((T) gValue.getValue()); } gValue.reset(); GSTITERATOR_API.gst_iterator_free(iter); return list; } } ================================================ FILE: src/org/freedesktop/gstreamer/GstObject.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import com.sun.jna.Pointer; import java.util.logging.Logger; import org.freedesktop.gstreamer.glib.GObject; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GObjectAPI; import org.freedesktop.gstreamer.lowlevel.GType; import org.freedesktop.gstreamer.lowlevel.GstControlBindingPtr; import org.freedesktop.gstreamer.lowlevel.GstObjectPtr; import org.freedesktop.gstreamer.lowlevel.GValueAPI.GValue; import static org.freedesktop.gstreamer.lowlevel.GObjectAPI.GOBJECT_API; import static org.freedesktop.gstreamer.lowlevel.GValueAPI.GVALUE_API; import static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API; import static org.freedesktop.gstreamer.lowlevel.GstObjectAPI.GSTOBJECT_API; import static org.freedesktop.gstreamer.lowlevel.GstValueAPI.GSTVALUE_API; /** * Base class for the GStreamer object hierarchy *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstObject.html *

* GstObject provides a root for the object hierarchy tree filed in by the * GStreamer library. It is currently a thin wrapper on top of {@link GObject}. * It is an abstract class that is not very usable on its own. * */ public class GstObject extends GObject { private static Logger LOG = Logger.getLogger(GstObject.class.getName()); private final Handle handle; /** * Wraps an underlying C GstObject with a Java proxy * * @param init Initialization data */ protected GstObject(Initializer init) { this(new Handle(init.ptr.as(GstObjectPtr.class, GstObjectPtr::new), init.ownsHandle), init.needRef); } protected GstObject(Handle handle, boolean needRef) { super(handle, needRef); this.handle = handle; } /** * Set the value of a GstObject property from a String representation. *

* The data value is deserialized using gst_value_deserialize. * * @param property the property to set * @param data the value as a valid String representation * @throws IllegalArgumentException if the data cannot be deserialized to * the required type. */ public void setAsString(String property, String data) { GObjectAPI.GParamSpec propertySpec = findProperty(property); if (propertySpec == null) { throw new IllegalArgumentException("Unknown property: " + property); } final GType propType = propertySpec.value_type; GValue propValue = new GValue(); GVALUE_API.g_value_init(propValue, propType); boolean success = GSTVALUE_API.gst_value_deserialize(propValue, data); if (success) { GOBJECT_API.g_param_value_validate(propertySpec, propValue); GOBJECT_API.g_object_set_property(this, property, propValue); } GVALUE_API.g_value_unset(propValue); // Release any memory if (!success) { throw new IllegalArgumentException( "Unable to deserialize data to required type: " + propType.getTypeName()); } } /** * Get the value of a GstObject property as a serialized String * representation of its value. *

* The data value is serialized using gst_value_serialize. * * @param property the property to get * @return serialized String value of property */ public String getAsString(String property) { GObjectAPI.GParamSpec propertySpec = findProperty(property); if (propertySpec == null) { throw new IllegalArgumentException("Unknown property: " + property); } final GType propType = propertySpec.value_type; GValue propValue = new GValue(); GVALUE_API.g_value_init(propValue, propType); GOBJECT_API.g_object_get_property(this, property, propValue); Pointer ptr = GSTVALUE_API.gst_value_serialize(propValue); String ret = ptr.getString(0); GLIB_API.g_free(ptr); return ret; } private GObjectAPI.GParamSpec findProperty(String propertyName) { Pointer ptr = GOBJECT_API.g_object_class_find_property( getRawPointer().getPointer(0), propertyName); if (ptr == null) { return null; } return new GObjectAPI.GParamSpec(ptr); } /** * Sets the name of this object, or gives this object a guaranteed unique * name (if name is null). * * Returns: TRUE if the name could be set. Since Objects that have a parent * cannot be renamed, this function returns FALSE in those cases. * * MT safe. * * @param name new name of object * @return true if the name was set. Since Objects that have a parent cannot * be renamed, this function returns false in those cases. */ public boolean setName(String name) { LOG.entering("GstObject", "setName", name); return GSTOBJECT_API.gst_object_set_name(this, name); } /** * Returns a copy of the name of this object. * * For a nameless object, this returns null. * * @return the name of this object. */ public String getName() { LOG.entering("GstObject", "getName"); return GSTOBJECT_API.gst_object_get_name(this); } /** * Returns this object's parent, if there is one. * * @return parent or null */ public GstObject getParent() { return GSTOBJECT_API.gst_object_get_parent(this); } /** * Returns a suggestion for timestamps where buffers should be split to get * best controller results. * * @return the suggested timestamp or {@link ClockTime#NONE} if no * control-rate was set. */ public long suggestNextSync() { return GSTOBJECT_API.gst_object_suggest_next_sync(handle.getPointer()); } /** * Sets the properties of the object, according to the {@link ControlSource} * that (maybe) handle them and for the given timestamp. *

* If this function fails, it is most likely the application developers * fault. Most probably the control sources are not setup correctly. * * @param timestamp the time that should be processed * @return true if the controller values have been applied to the object * properties */ public boolean syncValues(long timestamp) { return GSTOBJECT_API.gst_object_sync_values(handle.getPointer(), timestamp); } /** * Check if this object has active controlled properties. * * @return TRUE if the object has active controlled properties */ public boolean hasActiveControlBindings() { return GSTOBJECT_API.gst_object_has_active_control_bindings(handle.getPointer()); } /** * This function is used to disable all controlled properties of the object * for some time, i.e. {@link #syncValues(long) } will do nothing. * * @param disabled whether to disable the controllers or not */ public void setControlBindingsDisabled(boolean disabled) { GSTOBJECT_API.gst_object_set_control_bindings_disabled(handle.getPointer(), disabled); } /** * This function is used to disable the control bindings on a property for * some time, i.e. {@link #syncValues(long) } will do nothing for the * property. * * @param propertyName property to disable * @param disabled whether to disable the controller or not */ public void setControlBindingDisabled(String propertyName, boolean disabled) { GSTOBJECT_API.gst_object_set_control_binding_disabled(handle.getPointer(), propertyName, disabled); } /** * Attach a {@link ControlBinding } to this object. If there was already a * binding for this property it will be replaced. * * @param binding the ControlBinding that should be used * @throws IllegalStateException if the binding has not been setup for this * object */ public void addControlBinding(ControlBinding binding) { GstControlBindingPtr bindingPtr = Natives.getPointer(binding) .as(GstControlBindingPtr.class, GstControlBindingPtr::new); boolean ok = GSTOBJECT_API.gst_object_add_control_binding(handle.getPointer(), bindingPtr); if (!ok) { throw new IllegalStateException(); } } /** * Gets the corresponding {@link ControlBinding} for the property. * * @param propertyName name of the property * @return control binding for the property or NULL if the property is not * controlled */ public ControlBinding getControlBinding(String propertyName) { GstControlBindingPtr ptr = GSTOBJECT_API.gst_object_get_control_binding( handle.getPointer(), propertyName); return ptr == null ? null : Natives.callerOwnsReturn(ptr, ControlBinding.class); } /** * Removes the corresponding {@link ControlBinding }. * * @param binding the binding to remove * @return true if the binding could be removed */ public boolean removeControlBinding(ControlBinding binding) { GstControlBindingPtr bindingPtr = Natives.getPointer(binding) .as(GstControlBindingPtr.class, GstControlBindingPtr::new); return GSTOBJECT_API.gst_object_remove_control_binding(handle.getPointer(), bindingPtr); } @Override public String toString() { return String.format("%s: [%s]", getClass().getSimpleName(), getName()); } // protected static Initializer initializer(Pointer ptr) { // return initializer(ptr, true, true); // } // // protected static Initializer initializer(Pointer ptr, boolean needRef) { // return initializer(ptr, needRef, true); // } protected static class Handle extends GObject.Handle { public Handle(GstObjectPtr ptr, boolean ownsHandle) { super(ptr, ownsHandle); } @Override protected void ref() { GSTOBJECT_API.gst_object_ref(getPointer()); } @Override protected void sink() { GSTOBJECT_API.gst_object_ref_sink(getPointer()); } @Override protected void unref() { GSTOBJECT_API.gst_object_unref(getPointer()); } @Override protected GstObjectPtr getPointer() { return (GstObjectPtr) super.getPointer(); } } } ================================================ FILE: src/org/freedesktop/gstreamer/Meta.java ================================================ /* * Copyright (c) 2020 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import java.util.Objects; import org.freedesktop.gstreamer.glib.NativeObject; import org.freedesktop.gstreamer.lowlevel.GPointer; import org.freedesktop.gstreamer.lowlevel.GType; import org.freedesktop.gstreamer.lowlevel.GstMetaPtr; /** * Base for all metadata types added to a Buffer. *

* See upstream documentation at * https://gstreamer.freedesktop.org/documentation/gstreamer/gstmeta.html *

*/ public class Meta extends NativeObject { /** * Create Meta from Initializer. * * @param init initializer. */ protected Meta(Initializer init) { this(new Handle(init.ptr.as(GstMetaPtr.class, GstMetaPtr::new), init.ownsHandle)); } /** * Create Meta from Handle. * * @param handle native object handle. */ protected Meta(Handle handle) { super(handle); } @Override public String toString() { GstMetaPtr pointer = (GstMetaPtr)this.getPointer(); return "[meta : gType=" + pointer.getGType() + "]"; } /** * NativeObject.Handle implementation. */ protected static class Handle extends NativeObject.Handle { /** * Create Handle. * * @param ptr pointer to underlying native GstMeta. * @param ownsHandle */ public Handle(GstMetaPtr ptr, boolean ownsHandle) { super(ptr, ownsHandle); } @Override protected void disposeNativeHandle(GPointer ptr) { } } /** * API for Meta subclass. Used for querying from Buffer. *

* The relevant API will usually be available as a public static final field * on the implementation class. *

* The API type reflects two distinct types (api and implementation) used in * the underlying GStreamer GstMetaInfo. *

* See upstream documentation at * https://gstreamer.freedesktop.org/documentation/gstreamer/gstmeta.html#GstMetaInfo *

* * @param implementation type */ public static final class API { private final Class implClass; private final String apiTypeName; private GType apiType; /** * Create an API for the given implementation type. * * @param impl class implementing the API, must be registered to the * underlying implementation GType * @param api name of the underlying API GType */ public API(Class impl, String api) { this.implClass = Objects.requireNonNull(impl); this.apiTypeName = Objects.requireNonNull(api); apiType = GType.INVALID; } Class getImplClass() { return implClass; } GType getAPIGType() { GType type = apiType; if (type == GType.INVALID) { type = GType.valueOf(apiTypeName); apiType = type; } return type; } } } ================================================ FILE: src/org/freedesktop/gstreamer/MetaFlags.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2020 Petr Lastovka * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.NativeFlags; /** * See upstream documentation at * https://gstreamer.freedesktop.org/documentation/gstreamer/gstmeta.html#GstMetaFlags */ /*public*/ enum MetaFlags implements NativeFlags { // /** // * no flags // */ // GST_META_FLAG_NONE(0), /** * metadata should not be modified */ GST_META_FLAG_READONLY(1 << 0), /** * metadata is managed by a bufferpool */ GST_META_FLAG_POOLED(1 << 1), /** * metadata should not be removed */ GST_META_FLAG_LOCKED(1 << 2), // /** // * additional flags can be added starting from this flag. // */ // GST_META_FLAG_LAST(1 << 16) // ; private final int value; MetaFlags(int value) { this.value = value; } /** * Gets the integer value of the enum. * * @return The integer value for this enum. */ @Override public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/MiniObject.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2016 Christophe Lafolet * Copyright (c) 2014 Tom Greenwood * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.lowlevel.GstMiniObjectAPI.MiniObjectStruct; import org.freedesktop.gstreamer.glib.RefCountedObject; import org.freedesktop.gstreamer.lowlevel.GPointer; import static org.freedesktop.gstreamer.lowlevel.GstMiniObjectAPI.GSTMINIOBJECT_API; import org.freedesktop.gstreamer.lowlevel.GstMiniObjectPtr; /** * Lightweight base class for the GStreamer object hierarchy *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstMiniObject.html *

* MiniObject is a simple structure that can be used to implement refcounted * types. */ public abstract class MiniObject extends RefCountedObject { /** * Creates a new instance of MiniObject */ protected MiniObject(Initializer init) { this(new Handle(init.ptr.as(GstMiniObjectPtr.class, GstMiniObjectPtr::new), init.ownsHandle), init.needRef); } protected MiniObject(Handle handle, boolean needRef) { super(handle, needRef); } /** * If mini_object has the LOCKABLE flag set, check if the current EXCLUSIVE * lock on object is the only one, this means that changes to the object * will not be visible to any other object. * *

*

If the LOCKABLE flag is not set, check if the refcount of mini_object * is exactly 1, meaning that no other reference exists to the object and * that the object is therefore writable. * *

*

Modification of a mini-object should only be done after verifying * that it is writable. * * @return true if the object is writable. */ public boolean isWritable() { return GSTMINIOBJECT_API.gst_mini_object_is_writable(this); } /** * Makes a writable instance of this MiniObject. *

* The result is cast to subclass. * * @return a writable version (possibly a duplicate) of this MiniObject. */ protected T makeWritable() { MiniObject result = GSTMINIOBJECT_API.gst_mini_object_make_writable(this); if (result == null) { throw new NullPointerException("Could not make " + this.getClass().getSimpleName() + " writable"); } return (T) result; } /** * Create a new MiniObject as a copy of the this instance. * * @return the new MiniObject. */ public T copy() { MiniObject result = GSTMINIOBJECT_API.gst_mini_object_copy(this); if (result == null) { throw new NullPointerException("Could not make a copy of " + this.getClass().getSimpleName()); } return (T) result; } public int getRefCount() { final MiniObjectStruct struct = new MiniObjectStruct(getRawPointer()); return (Integer) struct.readField("refcount"); } protected static class Handle extends RefCountedObject.Handle { public Handle(GstMiniObjectPtr ptr, boolean ownsHandle) { super(ptr, ownsHandle); } @Override protected void disposeNativeHandle(GPointer ptr) { GSTMINIOBJECT_API.gst_mini_object_unref( ptr.as(GstMiniObjectPtr.class, GstMiniObjectPtr::new)); } @Override protected void ref() { GSTMINIOBJECT_API.gst_mini_object_ref(getPointer()); } @Override protected void unref() { GSTMINIOBJECT_API.gst_mini_object_unref(getPointer()); } @Override protected GstMiniObjectPtr getPointer() { return (GstMiniObjectPtr) super.getPointer(); } } } ================================================ FILE: src/org/freedesktop/gstreamer/MiniObjectFlags.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.NativeFlags; /** * Flags for {@link MiniObject } */ public enum MiniObjectFlags implements NativeFlags { /** * the object can be locked and unlocked with gst_mini_object_lock() and * gst_mini_object_unlock() * */ LOCKABLE(1 << 0), /** * the object is permanently locked in READONLY mode. Only read locks can be * performed on the object. */ LOCK_READONLY(1 << 1), /** * the object is expected to stay alive even after gst_deinit() has been * called and so should be ignored by leak detection tools. (Since 1.10) */ MAY_BE_LEAKED(1 << 2), /** * The last valid MiniObject flag */ LAST(1 << 4); private final int value; private MiniObjectFlags(int value) { this.value = value; } public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/Pad.java ================================================ /* * Copyright (C) 2020 Neil C Smith * Copyright (C) 2018 Antonio Morales * Copyright (C) 2014 Tom Greenwood * Copyright (C) 2009 Tamas Korodi * Copyright (C) 2007 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import com.sun.jna.NativeLong; import org.freedesktop.gstreamer.event.Event; import com.sun.jna.Pointer; import java.util.HashSet; import java.util.Set; import org.freedesktop.gstreamer.glib.NativeFlags; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback; import org.freedesktop.gstreamer.lowlevel.GstPadProbeInfo; import org.freedesktop.gstreamer.lowlevel.GstPadAPI; import static org.freedesktop.gstreamer.lowlevel.GstPadAPI.GSTPAD_API; import org.freedesktop.gstreamer.lowlevel.GstPadPtr; /** * Object contained by elements that allows links to other elements. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPad.html *

* An {@link Element} is linked to other elements via "pads", which are extremely * light-weight generic link points. After two pads are retrieved from an * element with {@link Element#getPad}, the pads can be link with {@link #link}. * (For quick links, you can also use {@link Element#link}, which will make the * obvious link for you if it's straightforward.) *

* Pads are typically created from a {@link PadTemplate} with * {@link #Pad(PadTemplate, String)}. *

* Pads have {@link Caps} attached to it to describe the media type they are * capable of dealing with. {@link #queryCaps} and {@link #setCaps} are used to * manipulate the caps of the pads. Pads created from a pad template cannot set * capabilities that are incompatible with the pad template capabilities. *

* Pads without pad templates can be created with gst_pad_new(), which takes a * direction and a name as an argument. If the name is NULL, then a guaranteed * unique name will be assigned to it. *

* {@link #getParentElement} will retrieve the Element that owns the pad. *

* An Element creating a pad will typically use the various * gst_pad_set_*_function() calls to register callbacks for various events on * the pads. *

* GstElements will use gst_pad_push() and gst_pad_pull_range() to push out or * pull in a buffer. *

* To send an Event on a pad, use {@link #sendEvent} and {@link #pushEvent}. * * @see PadTemplate * @see Element * @see Event */ public class Pad extends GstObject { public static final String GTYPE_NAME = "GstPad"; private static final int EVENT_HAS_INFO_MASK = GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_UPSTREAM; private final Handle handle; /** * Creates a new instance of Pad */ Pad(Initializer init) { this(new Handle(init.ptr.as(GstPadPtr.class, GstPadPtr::new), init.ownsHandle), init.needRef); } private Pad(Handle handle, boolean needRef) { super(handle, needRef); this.handle = handle; } /** * Creates a new pad with the given name in the given direction. If name is * null, a guaranteed unique name (across all pads) will be assigned. * * @param name The name of the new pad. * @param direction The direction of the new pad. */ public Pad(String name, PadDirection direction) { this(Natives.initializer(GSTPAD_API.ptr_gst_pad_new(name, direction), false)); } /** * Creates a new pad with the given name from the given template. * * If name is null, a guaranteed unique name (across all pads) will be * assigned. * * @param template The pad template to use. * @param name The name of the new pad. */ public Pad(PadTemplate template, String name) { this(Natives.initializer(GSTPAD_API.ptr_gst_pad_new_from_template(template, name), false)); } /** * Gets the capabilities this pad can produce or consume. Note that this * method doesn't necessarily return the caps set by sending a * gst_event_new_caps() - use {@link #getCurrentCaps() } for that instead. * queryCaps returns all possible caps a pad can operate with, * using the pad's CAPS query function, If the query fails, this function * will return filter, if not NULL, otherwise ANY. *

* When called on sinkpads filter contains the caps that upstream could * produce in the order preferred by upstream. When called on srcpads filter * contains the caps accepted by downstream in the preferred order. filter * might be NULL but if it is not NULL the returned caps will be a subset of * filter . *

* Note that this function does not return writable Caps. * * @param filter suggested Caps or null * @return a newly allocated copy of the {@link Caps} of this pad. */ public Caps queryCaps(Caps filter) { return GSTPAD_API.gst_pad_query_caps(this, filter); } /** * Gets the capabilities of the allowed media types that can flow through * this pad and its peer. *

* The allowed capabilities is calculated as the intersection of the results * of calling {@link #queryCaps} on this pad and its peer. *

* MT safe. * * @return The allowed {@link Caps} of the pad link, or null if this pad has * no peer. */ public Caps getAllowedCaps() { return GSTPAD_API.gst_pad_get_allowed_caps(this); } /** * Gets the capabilities currently configured on pad with the last * GST_EVENT_CAPS event. * * @return the negotiated #GstCaps or null if this pad has * no current caps * */ public Caps getCurrentCaps() { return GSTPAD_API.gst_pad_get_current_caps(this); } /** * Get the peer of this pad. * * MT safe. * * @return The peer Pad of this Pad. */ public Pad getPeer() { return GSTPAD_API.gst_pad_get_peer(this); } /** * Get the capabilities of the peer connected to this pad. *

* When called on srcpads filter contains the caps that upstream could * produce in the order preferred by upstream. When called on sinkpads * filter contains the caps accepted by downstream in the preferred order. * filter might be NULL but if it is not NULL the returned caps will be a * subset of filter . * * @param filter Caps to filter by, or null * @return the {@link Caps} of the peer pad, or null if there is no peer * pad. */ public Caps peerQueryCaps(Caps filter) { return GSTPAD_API.gst_pad_peer_query_caps(this, filter); } /** * Check if the pad accepts the given caps. * * @param caps a {@link Caps} to check on the pad. * @return true if the pad can accept the caps. */ public boolean queryAcceptCaps(Caps caps) { return GSTPAD_API.gst_pad_query_accept_caps(this, caps); } /** * Check if the peer of this pad accepts the caps. If this pad has no peer, * this method returns true. * * @param caps {@link Caps} to check on the pad * @return true if the peer pad can accept the caps or this pad no peer. */ public boolean peerQueryAcceptCaps(Caps caps) { return GSTPAD_API.gst_pad_peer_query_accept_caps(this, caps); } /** * Links this source pad and a sink pad. * * MT Safe. * * @param sink the sink Pad to link. * @throws PadLinkException if pads cannot be linked. */ public void link(Pad sink) throws PadLinkException { PadLinkReturn result = GSTPAD_API.gst_pad_link(this, sink); if (result != PadLinkReturn.OK) { throw new PadLinkException(result); } } /** * * Unlinks the source pad from the sink pad. Will emit the "unlinked" signal * on both pads. * * MT safe. * * @param pad the sink Pad to unlink. * @return true if the pads were unlinked. This function returns false if * the pads were not linked together. */ public boolean unlink(Pad pad) { return GSTPAD_API.gst_pad_unlink(this, pad); } /** * Check if this pad is linked to another pad or not. * * @return true if the pad is linked, else false. */ public boolean isLinked() { return GSTPAD_API.gst_pad_is_linked(this); } /** * Get the direction of the pad. The direction of the pad is decided at * construction time so this function does not take the LOCK. * * @return The {@link PadDirection} of the pad. */ public PadDirection getDirection() { return GSTPAD_API.gst_pad_get_direction(this); } /** * Get the parent of this pad, cast to an {@link Element}. If this pad has no * parent or its parent is not an element, returns null. * * @return The parent of the pad. */ public Element getParentElement() { return GSTPAD_API.gst_pad_get_parent_element(this); } /** * Activates or deactivates the given pad. Normally called from within core * state change functions. *

* If active is true, makes sure the pad is active. If it is already active, * either in push or pull mode, just return. Otherwise dispatches to the * pad's activate function to perform the actual activation. *

* If not @active, checks the pad's current mode and calls * gst_pad_activate_push() or gst_pad_activate_pull(), as appropriate, with * a FALSE argument. * * @param active whether or not the pad should be active. * @return true if the operation was successful. */ public boolean setActive(boolean active) { return GSTPAD_API.gst_pad_set_active(this, active); } /** * Checks if the pad is blocked or not. This function returns the last * requested state of the pad. It is not certain that the pad is actually * blocking at this point (see {@link #isBlocking}). * * @return true if the pad is blocked. */ public boolean isBlocked() { return GSTPAD_API.gst_pad_is_blocked(this); } /** * Run a runnable under a blocked state * * @param callback The code to run when pad is blocked */ public void block(final Runnable callback) { addEventProbe(new EVENT_PROBE() { public PadProbeReturn eventReceived(Pad pad, Event event) { callback.run(); pad.removeCallback(EVENT_PROBE.class, this); return PadProbeReturn.REMOVE; } }, GstPadAPI.GST_PAD_PROBE_TYPE_IDLE); } /** * Checks if the pad is blocking or not. This is a guaranteed state of * whether the pad is actually blocking on a {@link Buffer} or an * {@link Event}. * * @return true if the pad is blocking. */ public boolean isBlocking() { return GSTPAD_API.gst_pad_is_blocking(this); } /** * Add a listener for the linked signal on this {@link Pad} * * @param listener The listener to be called when a peer {@link Pad} is * linked. */ public void connect(final LINKED listener) { connect(LINKED.class, listener, new GstCallback() { @SuppressWarnings("unused") public boolean callback(Pad pad, Pad peer) { listener.linked(pad, peer); return true; } }); } /** * Remove a listener for the linked signal on this {@link Pad} * * @param listener The listener previously added for this signal. */ public void disconnect(LINKED listener) { disconnect(LINKED.class, listener); } /** * Add a listener for the unlinked signal on this {@link Pad} * * @param listener The listener to be called when when a peer {@link Pad} is * unlinked. */ public void connect(final UNLINKED listener) { connect(UNLINKED.class, listener, new GstCallback() { @SuppressWarnings("unused") public boolean callback(Pad pad, Pad peer) { listener.unlinked(pad, peer); return true; } }); } /** * Remove a listener for the unlinked signal on this * {@link Pad} * * @param listener The listener previously added for this signal. */ public void disconnect(UNLINKED listener) { disconnect(UNLINKED.class, listener); } /** * Be notified of different states of pads. The provided callback is called * for every state that matches mask. *

* Probes are called in groups: First {@link PadProbeType#BLOCK} probes are * called, then others, then finally {@link PadProbeType#IDLE}. The only * exception here are IDLE probes that are called immediately if the pad is * already idle while calling addProbe(). In each of the groups, probes are * called in the order in which they were added. * * @param mask set of mask flags for probe - common options are fields of * {@link PadProbeType} * @param callback callback that will be called with notifications of the * pad state */ public void addProbe(final Set mask, PROBE callback) { addProbe(NativeFlags.toInt(mask), callback); } /** * Be notified of different states of pads. The provided callback is called * for every state that matches mask. *

* Probes are called in groups: First {@link PadProbeType#BLOCK} probes are * called, then others, then finally {@link PadProbeType#IDLE}. The only * exception here are IDLE probes that are called immediately if the pad is * already idle while calling addProbe(). In each of the groups, probes are * called in the order in which they were added. * * @param mask mask flag for probe * @param callback callback that will be called with notifications of the * pad state */ public void addProbe(PadProbeType mask, PROBE callback) { addProbe(mask.intValue(), callback); } synchronized void addProbe(int mask, PROBE callback) { final GstPadAPI.PadProbeCallback probe = new GstPadAPI.PadProbeCallback() { @Override public PadProbeReturn callback(Pad pad, GstPadProbeInfo probeInfo, Pointer user_data) { PadProbeInfo info = new PadProbeInfo(probeInfo); PadProbeReturn ret = callback.probeCallback(pad, info); info.invalidate(); if (ret == PadProbeReturn.REMOVE) { // don't want handle to try and remove in GCallback::disconnect // @TODO move to Map of probes over callback handle.probes.remove(probeInfo.id); removeCallback(PROBE.class, callback); } return ret; } }; NativeLong id = handle.addProbe(mask, probe); if (id.longValue() == 0) { // the Probe was an IDLE-Probe and it was already handled synchronously in handle.addProbe, // so no Callback needs to be registered return; } GCallback cb = new GCallback(id, probe) { @Override protected void disconnect() { handle.removeProbe(id); } }; addCallback(PROBE.class, callback, cb); } /** * Remove the provided probe callback from the Pad. * * @param callback callback to remove */ public synchronized void removeProbe(PROBE callback) { removeCallback(PROBE.class, callback); } public void addEventProbe(final EVENT_PROBE listener) { final int mask = GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_BOTH | GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_FLUSH; addEventProbe(listener, mask); } synchronized void addEventProbe(final EVENT_PROBE listener, final int mask) { final GstPadAPI.PadProbeCallback probe = new GstPadAPI.PadProbeCallback() { public PadProbeReturn callback(Pad pad, GstPadProbeInfo probeInfo, Pointer user_data) { if ((probeInfo.padProbeType & mask) != 0) { Event event = null; if ((probeInfo.padProbeType & EVENT_HAS_INFO_MASK) != 0) { event = GSTPAD_API.gst_pad_probe_info_get_event(probeInfo); } PadProbeReturn ret = listener.eventReceived(pad, event); if (ret == PadProbeReturn.REMOVE) { // don't want handle to try and remove in GCallback::disconnect handle.probes.remove(probeInfo.id); removeCallback(EVENT_PROBE.class, listener); } return ret; } return PadProbeReturn.OK; } }; NativeLong id = handle.addProbe(mask, probe); if (id.longValue() == 0) { // the Probe was an IDLE-Probe and it was already handled synchronously in handle.addProbe, // so no Callback needs to be registered return; } GCallback cb = new GCallback(id, probe) { @Override protected void disconnect() { handle.removeProbe(id); } }; addCallback(EVENT_PROBE.class, listener, cb); } public void removeEventProbe(EVENT_PROBE listener) { removeCallback(EVENT_PROBE.class, listener); } public synchronized void addDataProbe(final DATA_PROBE listener) { final GstPadAPI.PadProbeCallback probe = new GstPadAPI.PadProbeCallback() { public PadProbeReturn callback(Pad pad, GstPadProbeInfo probeInfo, Pointer user_data) { if ((probeInfo.padProbeType & GstPadAPI.GST_PAD_PROBE_TYPE_BUFFER) != 0) { Buffer buffer = GSTPAD_API.gst_pad_probe_info_get_buffer(probeInfo); PadProbeReturn ret = listener.dataReceived(pad, buffer); if (ret == PadProbeReturn.REMOVE) { // don't want handle to try and remove in GCallback::disconnect handle.probes.remove(probeInfo.id); removeCallback(DATA_PROBE.class, listener); } return ret; } return PadProbeReturn.OK; } }; GCallback cb = new GCallback(handle.addProbe(GstPadAPI.GST_PAD_PROBE_TYPE_BUFFER, probe), probe) { @Override protected void disconnect() { handle.removeProbe(id); } }; addCallback(DATA_PROBE.class, listener, cb); } public void removeDataProbe(DATA_PROBE listener) { removeCallback(DATA_PROBE.class, listener); } /** * Sends the event to this pad. *

* This function can be used by applications to send events in the pipeline. * *

* If this pad is a source pad, event should be an upstream event. * If this pad is a sink pad, event should be a downstream event. *

* For example, you would not send a {@link EventType#EOS} on a src pad; EOS * events only propagate downstream. * *

* Furthermore, some downstream events have to be serialized with data flow, * like EOS, while some can travel out-of-band, like * {@link EventType#FLUSH_START}. If the event needs to be serialized with * data flow, this function will take the pad's stream lock while calling * its event function. * * @param event the event to send. * @return true if the event was handled. */ public boolean sendEvent(Event event) { return GSTPAD_API.gst_pad_send_event(this, event); } /** * Sends the event to the peer of this pad. * *

* This function is mainly used by elements to send events to their peer * elements. * * @param event the event to send * @return true if the event was handled */ public boolean pushEvent(Event event) { return GSTPAD_API.gst_pad_push_event(this, event); } /** * Chain a buffer to pad. *

* The function returns {@link FlowReturn#FLUSHING} if the * pad was flushing. *

* If the caps on buffer are different from the current caps on pad, this * function will call any function installed on pad (see * gst_pad_set_setcaps_function()). If the new caps are not acceptable for * pad, this function returns * {@link FlowReturn#NOT_NEGOTIATED}. *

* The function proceeds calling the chain function installed on pad and the * return value of that function is returned to the caller. * {@link FlowReturn#NOT_SUPPORTED} is returned if pad has no * chain function. *

* In all cases, success or failure, the caller loses its reference to * buffer after calling this function. * * @param buffer the Buffer, returns {@link FlowReturn#ERROR} * if NULL. * @return a org.gstreamer.FlowReturn */ public FlowReturn chain(Buffer buffer) { return GSTPAD_API.gst_pad_chain(this, buffer); } /** * When pad is flushing this function returns * {@link FlowReturn#FLUSHING} immediately. *

* Calls the getRange function of pad, see GstPadGetRangeFunction for a * description of a getRange function. If pad has no getRange function * installed (see gst_pad_set_getrange_function()) this function returns * {@link FlowReturn#NOT_SUPPORTED}. *

* This is a lowlevel function. Usualy {@link Pad#pullRange} is used. * * @param offset The start offset of the buffer * @param size The length of the buffer * @param buffer the Buffer, returns {@link FlowReturn#ERROR} if NULL. * @return a FlowReturn from the peer pad. When this function returns OK, * buffer will contain a valid Buffer. */ public FlowReturn getRange(long offset, int size, Buffer[] buffer) { return GSTPAD_API.gst_pad_get_range(this, offset, size, buffer); } /** * Pulls a buffer from the peer pad. *

* This function will first trigger the pad block signal if it was * installed. *

* When pad is not linked {@link FlowReturn#NOT_LINKED} is returned else * this function returns the result of {@link Pad#getRange} on the peer pad. * See {@link Pad#getRange} for a list of return values and for the * semantics of the arguments of this function. *

* buffer's caps must either be unset or the same as what is already * configured on pad. Renegotiation within a running pull-mode pipeline is * not supported. * * @param offset The start offset of the buffer * @param size The length of the buffer * @param buffer the Buffer, returns {@link FlowReturn#ERROR} if NULL. * @return a FlowReturn from the peer pad. When this function returns OK, * buffer will contain a valid Buffer. MT safe. */ public FlowReturn pullRange(long offset, int size, Buffer[] buffer) { return GSTPAD_API.gst_pad_pull_range(this, offset, size, buffer); } /** * Pushes a buffer to the peer of pad . This function will call installed * block probes before triggering any installed data probes. *

* The function proceeds calling gst_pad_chain() on the peer pad and returns * the value from that function. If pad has no peer, {@link FlowReturn#NOT_LINKED} * will be returned. *

* In all cases, success or failure, the caller loses its reference to * buffer after calling this function. * * @param buffer the GstBuffer to push returns GST_FLOW_ERROR if not. * [transfer full] * @return a GstFlowReturn from the peer pad. * * MT safe. */ public FlowReturn push(final Buffer buffer) { return GSTPAD_API.gst_pad_push(this, buffer); } /** * Gets the template for pad. * * @return the GstPadTemplate from which this pad was instantiated, or NULL * if this pad has no template. */ public PadTemplate getTemplate() { return GSTPAD_API.gst_pad_get_pad_template(this); } /** * Check if the pad has caps set on it with a GST_EVENT_CAPS events * * @return true if the pad has caps set */ public boolean hasCurrentCaps() { return GSTPAD_API.gst_pad_has_current_caps(this); } /** * Signal emitted when new this {@link Pad} is linked to another {@link Pad} * * @see #connect(LINKED) * @see #disconnect(LINKED) */ public static interface LINKED { /** * Called when a {@link Pad} is linked to another Pad. * * @param pad the pad that emitted the signal. * @param peer the peer pad that has been connected. */ public void linked(Pad pad, Pad peer); } /** * Signal emitted when new this {@link Pad} is disconnected from a peer * {@link Pad} * * @see #connect(UNLINKED) * @see #disconnect(UNLINKED) */ public static interface UNLINKED { /** * Called when a {@link Pad} is unlinked from another Pad. * * @param pad the pad that emitted the signal. * @param peer the peer pad that has been connected. */ public void unlinked(Pad pad, Pad peer); } /** * Callback used by * {@link #addProbe(java.util.EnumSet, org.freedesktop.gstreamer.Pad.PROBE)} */ public static interface PROBE { /** * Callback used by * {@link #addProbe(java.util.EnumSet, org.freedesktop.gstreamer.Pad.PROBE)}. * Gets called to notify about the current blocking type. *

* The PadProbeInfo and any Buffer, Event or Query referenced from * it, is only valid for the duration of the callback. * * @param pad Pad that is blocked * @param info PadProbeInfo with access to underlying data * @return PadProbeReturn value */ public PadProbeReturn probeCallback(Pad pad, PadProbeInfo info); } /** * Probe for listening when an event passes through this Pad. * * @see #addEventProbe(EVENT_PROBE) * @see #removeEventProbe(EVENT_PROBE) */ public static interface EVENT_PROBE { public PadProbeReturn eventReceived(Pad pad, Event event); } /** * Probe for listening when new data is available on the Pad. * * @see #addDataProbe(DATA_PROBE) * @see #removeDataProbe(DATA_PROBE) */ public static interface DATA_PROBE { public PadProbeReturn dataReceived(Pad pad, Buffer buffer); } private static class Handle extends GstObject.Handle { private final Set probes; private Handle(GstPadPtr ptr, boolean ownsHandle) { super(ptr, ownsHandle); probes = new HashSet<>(); } @Override protected GstPadPtr getPointer() { return (GstPadPtr) super.getPointer(); } private synchronized NativeLong addProbe(int mask, GstPadAPI.PadProbeCallback probe) { NativeLong id = GSTPAD_API.gst_pad_add_probe(getPointer(), mask, probe, null, null); if (id.longValue() != 0) { probes.add(id); } return id; } private synchronized void removeProbe(NativeLong id) { if (probes.remove(id)) { GSTPAD_API.gst_pad_remove_probe(getPointer(), id); } } private synchronized void clearProbes() { probes.forEach(id -> GSTPAD_API.gst_pad_remove_probe(getPointer(), id)); probes.clear(); } @Override public void invalidate() { clearProbes(); super.invalidate(); } @Override public void dispose() { clearProbes(); super.dispose(); } } } ================================================ FILE: src/org/freedesktop/gstreamer/PadDirection.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.NativeEnum; /** * The direction of a {@link Pad}. */ public enum PadDirection implements NativeEnum { /** The direction is unknown. */ UNKNOWN(0), /** The {@link Pad} is a source pad. */ SRC(1), /** The {@link Pad} is a sink pad. */ SINK(2); private final int value; private PadDirection(int value) { this.value = value; } @Override public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/PadLinkException.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; /** * The exception thrown when a pad link operation returns a non-OK result */ public class PadLinkException extends GstException { private final PadLinkReturn linkResult; PadLinkException(PadLinkReturn result) { this("failed to link pads (" + result + ")", result); } PadLinkException(String message, PadLinkReturn result) { super(message); linkResult = result; } /** * Get the PadLinkReturn result that caused this exception. * @return PadLinkReturn */ public PadLinkReturn getLinkResult() { return linkResult; } } ================================================ FILE: src/org/freedesktop/gstreamer/PadLinkReturn.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.NativeEnum; import org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue; /** * Result values from {@link Pad#link(Pad)} and friends. */ public enum PadLinkReturn implements NativeEnum { /** Link succeeded. */ OK(0), /** Pads have no common grandparent. */ WRONG_HIERARCHY(-1), /** Pad was already linked. */ WAS_LINKED(-2), /** Pads have wrong direction. */ WRONG_DIRECTION(-3), /** Pads do not have common format. */ NOFORMAT(-4), /** Pads cannot cooperate in scheduling. */ NOSCHED(-5), /** Refused for some reason. */ @DefaultEnumValue REFUSED(-6); private final int value; PadLinkReturn(int value) { this.value = value; } /** * Gets the integer value of the enum. * @return The integer value for this enum. */ @Override public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/PadMode.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue; /** * The status of a {@link Pad}. After activating a pad, which usually happens when * the parent element goes from {@link State#READY} to {@link State#PAUSED}, the * PadMode defines if the {@link Pad} operates in push or pull mode. */ public enum PadMode { /** * Pad will not handle dataflow */ @DefaultEnumValue NONE, /** * Pad handles dataflow in downstream push mode */ PUSH, /** * Pad handles dataflow in upstream pull mode */ PULL; } ================================================ FILE: src/org/freedesktop/gstreamer/PadPresence.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; /** * Indicates when a {@link Pad} will become available, for use in {@link PadTemplate} */ public enum PadPresence { /** * The Pad is always available. */ ALWAYS, /** * The pad will become available depending on the media stream. */ SOMETIMES, /** * The pad is only available on request with {@link Element#getRequestPad(java.lang.String) } */ REQUEST; } ================================================ FILE: src/org/freedesktop/gstreamer/PadProbeInfo.java ================================================ /* * Copyright (C) 2020 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import java.util.Set; import org.freedesktop.gstreamer.event.Event; import org.freedesktop.gstreamer.glib.NativeFlags; import org.freedesktop.gstreamer.lowlevel.GstPadProbeInfo; import org.freedesktop.gstreamer.query.Query; import static org.freedesktop.gstreamer.lowlevel.GstPadAPI.GSTPAD_API; /** * Probe info passed in to Pad.PROBE callback. */ public final class PadProbeInfo { private GstPadProbeInfo info; PadProbeInfo(GstPadProbeInfo info) { this.info = info; } /** * Get the set of flags for the current probe type. * * @return probe type */ public Set getType() { return NativeFlags.fromInt(PadProbeType.class, info.padProbeType); } /** * Get the Buffer from the probe, or null. * * @return buffer or null */ public Buffer getBuffer() { return GSTPAD_API.gst_pad_probe_info_get_buffer(info); } /** * Get the Event from the probe, or null. * * @return event or null */ public Event getEvent() { return GSTPAD_API.gst_pad_probe_info_get_event(info); } /** * Get the query from the probe, or null. * * @return query or null */ public Query getQuery() { return GSTPAD_API.gst_pad_probe_info_get_query(info); } void invalidate() { info = null; } } ================================================ FILE: src/org/freedesktop/gstreamer/PadProbeReturn.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; /** * Different return values for Pad probe callbacks */ public enum PadProbeReturn { /** * Drop data in data probes. For push mode this means that the data item is * not sent downstream. For pull mode, it means that the data item is not * passed upstream. In both cases, no other probes are called for this item * and %GST_FLOW_OK or %TRUE is returned to the caller. */ DROP, /** * Normal probe return value. This leaves the probe in place, and defers * decisions about dropping or passing data to other probes, if any. If * there are no other probes, the default behaviour for the probe type * applies ('block' for blocking probes, and 'pass' for non-blocking * probes). */ OK, /** * Remove the probe */ REMOVE, /** * Pass the data item in the block probe and block on the next item. */ PASS, /** * Data has been handled in the probe and will not be forwarded further. For * events and buffers this is the same behaviour as %GST_PAD_PROBE_DROP * (except that in this case you need to unref the buffer or event * yourself). For queries it will also return %TRUE to the caller. The probe * can also modify the #GstFlowReturn value by using the * #GST_PAD_PROBE_INFO_FLOW_RETURN() accessor. Note that the resulting query * must contain valid entries. Since: 1.6 */ HANDLED; } ================================================ FILE: src/org/freedesktop/gstreamer/PadProbeType.java ================================================ /* * Copyright (c) 2020 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import java.util.Collections; import java.util.Set; import org.freedesktop.gstreamer.glib.NativeFlags; import org.freedesktop.gstreamer.lowlevel.GstPadAPI; /** * The different probing types that can occur. When either one of {@link #IDLE} * or {@link #BLOCK} is used, the probe will be a blocking probe. *

* For convenience, the various flag combinations are provided as immutable * Sets. *

* See upstream documentation at * https://gstreamer.freedesktop.org/documentation/gstreamer/gstpad.html#GstPadProbeType */ public enum PadProbeType implements NativeFlags { /* flags to control blocking */ /** * Probe idle pads and block while the callback is called. */ IDLE(GstPadAPI.GST_PAD_PROBE_TYPE_IDLE), /** * Probe and block pads. */ BLOCK(GstPadAPI.GST_PAD_PROBE_TYPE_BLOCK), /* flags to select datatypes */ /** * Probe buffers. */ BUFFER(GstPadAPI.GST_PAD_PROBE_TYPE_BUFFER), /** * Probe buffer lists. */ BUFFER_LIST(GstPadAPI.GST_PAD_PROBE_TYPE_BUFFER_LIST), /** * Probe downstream events. */ EVENT_DOWNSTREAM(GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM), /** * Probe upstream events. */ EVENT_UPSTREAM(GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_UPSTREAM), /** * Probe flush events. This probe has to be explicitly enabled and is not * included in the DOWNSTREAM or UPSTREAM probe types. */ EVENT_FLUSH(GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_FLUSH), /** * Probe downstream queries. */ QUERY_DOWNSTREAM(GstPadAPI.GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM), /** * Probe upstream queries. */ QUERY_UPSTREAM(GstPadAPI.GST_PAD_PROBE_TYPE_QUERY_UPSTREAM), /* flags to select scheduling mode */ /** * Probe push. */ PUSH(GstPadAPI.GST_PAD_PROBE_TYPE_PUSH), /** * Probe pull. */ PULL(GstPadAPI.GST_PAD_PROBE_TYPE_PULL); /** * Probe and block at the next opportunity, at data flow or when idle. */ public static final Set BLOCKING = Collections.unmodifiableSet(NativeFlags.fromInt(PadProbeType.class, GstPadAPI.GST_PAD_PROBE_TYPE_BLOCKING)); /** * Probe downstream data (buffers, buffer lists and events). */ public static final Set DATA_DOWNSTREAM = Collections.unmodifiableSet(NativeFlags.fromInt(PadProbeType.class, GstPadAPI.GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM)); /** * Probe upstream data (events). */ public static final Set DATA_UPSTREAM = Collections.unmodifiableSet(NativeFlags.fromInt(PadProbeType.class, GstPadAPI.GST_PAD_PROBE_TYPE_DATA_UPSTREAM)); /** * Probe upstream and downstream data (buffers, buffer lists and events). */ public static final Set DATA_BOTH = Collections.unmodifiableSet(NativeFlags.fromInt(PadProbeType.class, GstPadAPI.GST_PAD_PROBE_TYPE_DATA_BOTH)); /** * Probe and block downstream data (buffers, buffer lists and events). */ public static final Set BLOCK_DOWNSTREAM = Collections.unmodifiableSet(NativeFlags.fromInt(PadProbeType.class, GstPadAPI.GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM)); /** * Probe and block upstream data (events). */ public static final Set BLOCK_UPSTREAM = Collections.unmodifiableSet(NativeFlags.fromInt(PadProbeType.class, GstPadAPI.GST_PAD_PROBE_TYPE_BLOCK_UPSTREAM)); /** * Probe upstream and downstream events. */ public static final Set EVENT_BOTH = Collections.unmodifiableSet(NativeFlags.fromInt(PadProbeType.class, GstPadAPI.GST_PAD_PROBE_TYPE_EVENT_BOTH)); /** * Probe upstream and downstream queries. */ public static final Set QUERY_BOTH = Collections.unmodifiableSet(NativeFlags.fromInt(PadProbeType.class, GstPadAPI.GST_PAD_PROBE_TYPE_QUERY_BOTH)); /** * Probe upstream events and queries and downstream buffers, buffer lists, * events and queries. */ public static final Set ALL_BOTH = Collections.unmodifiableSet(NativeFlags.fromInt(PadProbeType.class, GstPadAPI.GST_PAD_PROBE_TYPE_ALL_BOTH)); /** * Probe push and pull. */ public static final Set SCHEDULING = Collections.unmodifiableSet(NativeFlags.fromInt(PadProbeType.class, GstPadAPI.GST_PAD_PROBE_TYPE_SCHEDULING)); private final int value; private PadProbeType(int value) { this.value = value; } @Override public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/PadTemplate.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (C) 2007, 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstPadTemplateAPI.GSTPADTEMPLATE_API; /** * Padtemplates describe the possible media types a {@link Pad} or an * {@link ElementFactory} can handle. This allows for both inspection of handled * types before loading the element plugin as well as identifying pads on * elements that are not yet created (request or sometimes pads). *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPadTemplate.html *

* Pad and PadTemplates have {@code Caps} attached to it to describe the media * type they are capable of dealing with. {@link #getCaps} is used to get the * caps of a PadTemplate. It is not possible to modify the caps of a PadTemplate * after creation. */ public class PadTemplate extends GstObject { public static final String GTYPE_NAME = "GstPadTemplate"; /** * Creates a new proxy for PadTemplate. *

* This is only for internal use. * * @param init internal initialization data. */ PadTemplate(Initializer init) { super(init); } /** * Creates a new pad template with a name according to the given template, * with the given arguments and {@link PadPresence#ALWAYS } * * @param nameTemplate the name template. * @param direction the direction of the template. * @param caps a {@code Caps} set for the template. */ public PadTemplate(String nameTemplate, PadDirection direction, Caps caps) { this(Natives.initializer(GSTPADTEMPLATE_API.ptr_gst_pad_template_new(nameTemplate, direction, PadPresence.ALWAYS, caps))); } /** * Creates a new pad template with a name according to the given template * and with the given arguments. * * @param nameTemplate the name template. * @param direction the direction of the template. * @param presence the presence of the pad, which controls the lifetime. * @param caps a {@code Caps} set for the template. */ public PadTemplate(String nameTemplate, PadDirection direction, PadPresence presence, Caps caps) { this(Natives.initializer(GSTPADTEMPLATE_API.ptr_gst_pad_template_new(nameTemplate, direction, presence, caps))); } /** * Gets the {@link Caps} set on this {@code PadTemplate} * * @return the media type on this template. */ public Caps getCaps() { return GSTPADTEMPLATE_API.gst_pad_template_get_caps(this); } /** * Gets the name of this template * * @return the name of this template */ public String getTemplateName() { return get("name-template").toString(); } /** * Gets the direction of this template * * @return {@link PadDirection} */ public PadDirection getDirection() { Object d = get("direction"); if (d instanceof Number) { return PadDirection.values()[((Number) d).intValue()]; } return null; } /** * Gets presence of this template * * @return {@link PadPresence} */ public PadPresence getPresence() { Object p = get("presence"); if (p instanceof Number) { return PadPresence.values()[((Number) p).intValue()]; } return null; } } ================================================ FILE: src/org/freedesktop/gstreamer/Pipeline.java ================================================ /* * Copyright (c) 2021 Neil C Smith * Copyright (c) 2008 Wayne Meissner * Copyright (C) 2000 Erik Walthinsen * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import com.sun.jna.Pointer; import java.util.EnumSet; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import java.util.logging.Logger; import org.freedesktop.gstreamer.event.SeekFlags; import org.freedesktop.gstreamer.event.SeekType; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstObjectPtr; import org.freedesktop.gstreamer.query.Query; import static org.freedesktop.gstreamer.lowlevel.GstElementAPI.GSTELEMENT_API; import static org.freedesktop.gstreamer.lowlevel.GstPipelineAPI.GSTPIPELINE_API; import static org.freedesktop.gstreamer.lowlevel.GstQueryAPI.GSTQUERY_API; /** * A {@code Pipeline} is a special {@link Bin} used as the top level container * for the filter graph. The Pipeline will manage the selection and distribution * of a global {@link Clock} as well as provide a {@link Bus} to the * application. It will also implement a default behaviour for managing seek * events (see {@link #seek seek}). *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPipeline.html *

* Elements are added and removed from the pipeline using the {@code Bin} * methods like {@link Bin#add add} and {@link Bin#remove remove}. *

* Before changing the state of the Pipeline (see {@link Element}) a {@link Bus} * can be retrieved with {@link #getBus getBus}. This bus can then be used to * receive {@link Message}s from the elements in the pipeline. *

* By default, a Pipeline will automatically flush the pending Bus messages when * going to the NULL state to ensure that no circular references exist when no * messages are read from the Bus. This behaviour can be changed with * {@link #setAutoFlushBus setAutoFlushBus} *

* When the Pipeline performs the PAUSED to PLAYING state change it will select * a clock for the elements. The clock selection algorithm will by default * select a clock provided by an element that is most upstream (closest to the * source). For live pipelines (ones that return * {@link StateChangeReturn#NO_PREROLL} from the * {@link Element#setState setState} call) this will select the clock provided * by the live source. For normal pipelines this will select a clock provided by * the sinks (most likely the audio sink). If no element provides a clock, a * default SystemClock is used. * *

* The clock selection can be controlled with the gst_pipeline_use_clock() * method, which will enforce a given clock on the pipeline. With * gst_pipeline_auto_clock() the default clock selection algorithm can be * restored. * *

* A Pipeline maintains a stream time for the elements. The stream time is * defined as the difference between the current clock time and the base time. * When the pipeline goes to READY or a flushing seek is performed on it, the * stream time is reset to 0. When the pipeline is set from PLAYING to PAUSED, * the current clock time is sampled and used to configure the base time for the * elements when the pipeline is set to PLAYING again. This default behaviour * can be changed with the gst_pipeline_set_new_stream_time() method. * * When sending a flushing seek event to a GstPipeline (see {@link #seek seek}), * it will make sure that the pipeline is properly PAUSED and resumed as well as * set the new stream time to 0 when the seek succeeded. */ public class Pipeline extends Bin { public static final String GST_NAME = "pipeline"; public static final String GTYPE_NAME = "GstPipeline"; private static Logger LOG = Logger.getLogger(Pipeline.class.getName()); private final Handle handle; protected Pipeline(Initializer init) { this(new Handle(init.ptr.as(GstObjectPtr.class, GstObjectPtr::new), init.ownsHandle), init.needRef); } Pipeline(Handle handle, boolean needRef) { super(handle, needRef); this.handle = handle; handle.busRef.set(GSTPIPELINE_API.gst_pipeline_get_bus(this)); } /** * Creates a new instance of Pipeline with a unique name. */ public Pipeline() { this(Natives.initializer(GSTPIPELINE_API.ptr_gst_pipeline_new(null), false)); } /** * Creates a new instance of Pipeline with the given name. * * @param name The name used to identify this pipeline. */ public Pipeline(String name) { this(initializer(name)); } private static Initializer initializer(String name) { Pointer new_pipeline = GSTPIPELINE_API.ptr_gst_pipeline_new(name); return Natives.initializer(new_pipeline, false); } /** * Usually, when a pipeline goes from READY to NULL state, it automatically * flushes all pending messages on the bus, which is done for refcounting * purposes, to break circular references. *

* This means that applications that update state using (async) bus messages * (e.g. do certain things when a pipeline goes from PAUSED to READY) might * not get to see messages when the pipeline is shut down, because they * might be flushed before they can be dispatched in the main thread. This * behaviour can be disabled using this function. *

* It is important that all messages on the bus are handled when the * automatic flushing is disabled else memory leaks will be introduced. *

* MT safe. * * @param flush whether or not to automatically flush the bus when the * pipeline goes from READY to NULL state */ public void setAutoFlushBus(boolean flush) { GSTPIPELINE_API.gst_pipeline_set_auto_flush_bus(this, flush); } /** * Checks if the pipeline will automatically flush messages when going to * the NULL state. *

* MT safe. * * @return true if the pipeline automatically flushes messages. */ public boolean getAutoFlushBus() { return GSTPIPELINE_API.gst_pipeline_get_auto_flush_bus(this); } /** * Set the clock for pipeline. The clock will be distributed to all the * elements managed by the pipeline. *

* MT safe * * @param clock The {@link Clock} to use * @return true if the clock could be set on the pipeline, false if some * element did not accept the clock. * */ public boolean setClock(Clock clock) { return GSTPIPELINE_API.gst_pipeline_set_clock(this, clock); } /** * Return the current {@link Clock} used by the pipeline. * * @return The {@link Clock} currently in use. */ @Override public Clock getClock() { return GSTPIPELINE_API.gst_pipeline_get_clock(this); } /** * Force the Pipeline to use the a specific clock. The pipeline will always * use the given clock even if new clock providers are added to this * pipeline. *

* MT safe * * @param clock The {@link Clock} to use. If clock is null, all clocking is * disabled, and the pipeline will run as fast as possible. * */ public void useClock(Clock clock) { GSTPIPELINE_API.gst_pipeline_use_clock(this, clock); } /** * Gets the {@link Bus} this pipeline uses for messages. * * @return The {@link Bus} that this pipeline uses. */ @Override public Bus getBus() { return handle.busRef.get(); } /** * Sets the position in the media stream to time in nanoseconds. *

* Prefer use of * {@link Element#seekSimple(org.freedesktop.gstreamer.Format, java.util.Set, long)}. * * @param time The time to change the position to. * @return true if seek is successful */ // @TODO move seek and query methods on to element? public boolean seek(long time) { return seek(time, TimeUnit.NANOSECONDS); } /** * Sets the current position in the media stream. *

* Prefer use of * {@link Element#seekSimple(org.freedesktop.gstreamer.Format, java.util.Set, long)}. * * @param time the time to change the position to. * @param unit the {@code TimeUnit} the time is expressed in. * @return true if seek is successful */ public boolean seek(long time, TimeUnit unit) { return seek(1.0, Format.TIME, EnumSet.of(SeekFlags.FLUSH, SeekFlags.KEY_UNIT), SeekType.SET, TimeUnit.NANOSECONDS.convert(time, unit), SeekType.NONE, -1); } /** * Seeks to a new position in the media stream. * *

* The start and stop values are expressed in format. *

* A rate of 1.0 means normal playback rate, 2.0 means double speed. * Negative values means backwards playback. A value of 0.0 for the rate is * not allowed and should be accomplished instead by PAUSING the pipeline. *

* A pipeline has a default playback segment configured with a start * position of 0, a stop position of -1 and a rate of 1.0. The currently * configured playback segment can be queried with #GST_QUERY_SEGMENT. *

* startType and stopType specify how to adjust the currently configured * start and stop fields in segment. Adjustments can be made relative or * absolute to the last configured values. A type of {@link SeekType#NONE} * means that the position should not be updated. *

* When the rate is positive and start has been updated, playback will start * from the newly configured start position. *

* For negative rates, playback will start from the newly configured stop * position (if any). If the stop position if updated, it must be different * from -1 for negative rates. *

* It is not possible to seek relative to the current playback position, to * do this, PAUSE the pipeline, query the current playback position with * {@link org.gstreamer.Pipeline#queryPosition queryPosition} and update the * playback segment current position with a {@link SeekType#SET} to the * desired position. * * @param rate the new playback rate * @param format the format of the seek values * @param seekFlags the seek flags * @param startType the type and flags for the new start position * @param start the value of the new start position * @param stopType the type and flags for the new stop position * @param stop the value of the new stop position * @return true if seek is successful */ // for compatibility public boolean seek(double rate, Format format, EnumSet seekFlags, SeekType startType, long start, SeekType stopType, long stop) { return super.seek(rate, format, seekFlags, startType, start, stopType, stop); } @Override public boolean seek(double rate, Format format, Set seekFlags, SeekType startType, long start, SeekType stopType, long stop) { return super.seek(rate, format, seekFlags, startType, start, stopType, stop); } /** * Gets the current position in the media stream. * * @param unit the {@code TimeUnit} to return the position in terms of. * @return a time value representing the current position in units of unit. */ public long queryPosition(TimeUnit unit) { return unit.convert(queryPosition(Format.TIME), TimeUnit.NANOSECONDS); } @Override public long queryPosition(Format format) { return super.queryPosition(format); } /** * Gets the time duration of the current media stream. * * @param unit the {@code TimeUnit} to return the position in. * @return The total duration of the current media stream. */ public long queryDuration(TimeUnit unit) { return unit.convert(queryDuration(Format.TIME), TimeUnit.NANOSECONDS); } @Override public long queryDuration(Format format) { return super.queryDuration(format); } /** * Gets the {@link Segment} for the current media stream in terms of time. * * @return The information regarding the current {@code Segment}. */ public Segment querySegment() { return querySegment(Format.TIME); } /** * Gets the {@link Segment} for the current media stream in terms of the * specified {@link Format}. * * @param format the {@code Format} to return the segment in. * @return The information regarding the current {@code Segment}. */ public Segment querySegment(Format format) { Query qry = GSTQUERY_API.gst_query_new_segment(format); GSTELEMENT_API.gst_element_query(this, qry); double[] rate = {0.0D}; Format[] fmt = {Format.UNDEFINED}; long[] start_value = {0}; long[] stop_value = {0}; GSTQUERY_API.gst_query_parse_segment(qry, rate, fmt, start_value, stop_value); return new Segment(rate[0], fmt[0], start_value[0], stop_value[0]); } static class Handle extends Bin.Handle { private final AtomicReference busRef; public Handle(GstObjectPtr ptr, boolean ownsHandle) { super(ptr, ownsHandle); this.busRef = new AtomicReference<>(); } @Override public void invalidate() { disposeBus(); super.invalidate(); } @Override public void dispose() { disposeBus(); super.dispose(); } private void disposeBus() { Bus bus = busRef.getAndSet(null); if (bus != null) { bus.dispose(); } } } } ================================================ FILE: src/org/freedesktop/gstreamer/Plugin.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (C) 2007 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import static org.freedesktop.gstreamer.lowlevel.GstPluginAPI.GSTPLUGIN_API; /** * Container for features loaded from a shared object module *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPlugin.html *

* GStreamer is extensible, so {@link Element} instances can be loaded at * runtime. A plugin system can provide one or more of the basic GStreamer * {@link PluginFeature} subclasses. *

* A plugin should export a symbol gst_plugin_desc that is a struct * of type GstPluginDesc. the plugin loader will check the version of the core * library the plugin was linked against and will create a new Plugin. It will * then call the #GstPluginInitFunc function that was provided in the * gst_plugin_desc. *

* Once you have a handle to a #GstPlugin (e.g. from the #GstRegistryPool), you * can add any object that subclasses #GstPluginFeature. *

* Use gst_plugin_find_feature() and gst_plugin_get_feature_list() to find * features in a plugin. *

* Usually plugins are always automatically loaded so you don't need to call * {@link #loadByName} explicitly to bring it into memory. There are options to * statically link plugins to an app or even use GStreamer without a plugin * repository in which case {@link #loadByName} can be needed to bring the * plugin into memory. *

* @see PluginFeature * @see ElementFactory */ public class Plugin extends GstObject { public static final String GTYPE_NAME = "GstPlugin"; /** * Creates a new instance of GstElement * * @param init internal initialization data. */ Plugin(Initializer init) { super(init); } /** * Load the named plugin. * * @param pluginName * @return A new Plugin reference if the plugin was loaded, else null. */ public static Plugin loadByName(String pluginName) { return GSTPLUGIN_API.gst_plugin_load_by_name(pluginName); } /** * Get the short name of the plugin. * * @return the name of the plugin. */ @Override public String getName() { return GSTPLUGIN_API.gst_plugin_get_name(this); } /** * Get the long descriptive name of the plugin. * * @return The long name of the plugin. */ public String getDescription() { return GSTPLUGIN_API.gst_plugin_get_description(this); } /** * Get the filename of the plugin. * * @return The filename of the plugin. */ public String getFilename() { return GSTPLUGIN_API.gst_plugin_get_filename(this); } /** * Get the version of the plugin. * * @return The version of the plugin. */ public String getVersion() { return GSTPLUGIN_API.gst_plugin_get_version(this); } /** * Get the license of the plugin. * * @return The license of the plugin. */ public String getLicense() { return GSTPLUGIN_API.gst_plugin_get_license(this); } /** * Get the source module the plugin belongs to. * * @return The source of the plugin. */ public String getSource() { return GSTPLUGIN_API.gst_plugin_get_source(this); } /** * Get the package the plugin belongs to. * * @return The package of the plugin. */ public String getPackage() { return GSTPLUGIN_API.gst_plugin_get_package(this); } /** * Get the URL where the plugin comes from. * * @return The origin of the plugin. */ public String getOrigin() { return GSTPLUGIN_API.gst_plugin_get_origin(this); } /** * Get the release date (and possibly time) in form of a string, if * available. * * For normal GStreamer plugin releases this will usually just be a date in * the form of "YYYY-MM-DD", while pre-releases and builds from git may * contain a time component after the date as well, in which case the string * will be formatted like "YYYY-MM-DDTHH:MMZ" (e.g. * "2012-04-30T09:30Z").Test */ public String getReleaseDateString() { return GSTPLUGIN_API.gst_plugin_get_release_date_string(this); } /** * Queries if the plugin is loaded into memory. * * @return true if it is loaded, false otherwise. */ public boolean isLoaded() { return GSTPLUGIN_API.gst_plugin_is_loaded(this); } // /** // * Ensures this plugin is loaded. // * // * @return a potentially new Plugin reference. // */ // public Plugin load() { // return GSTPLUGIN_API.gst_plugin_load(this); // } } ================================================ FILE: src/org/freedesktop/gstreamer/PluginFeature.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2007 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.NativeEnum; import static org.freedesktop.gstreamer.lowlevel.GstObjectAPI.GSTOBJECT_API; import static org.freedesktop.gstreamer.lowlevel.GstPluginFeatureAPI.GSTPLUGINFEATURE_API; /** * Base class for contents of a {@link Plugin} *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPluginFeature.html *

* This is a base class for anything that can be added to a Plugin. * * @see Plugin */ public class PluginFeature extends GstObject { public static final String GTYPE_NAME = "GstPluginFeature"; /** * Element priority ranks. Defines the order in which the autoplugger (or * similar rank-picking mechanisms, such as e.g. * gst_element_make_from_uri()) will choose this element over an alternative * one with the same function. * * These constants serve as a rough guidance for defining the rank of a * GstPluginFeature. Any value is valid, including values bigger than * GST_RANK_PRIMARY . */ public enum Rank implements NativeEnum { /** * Will be chosen last or not at all. */ NONE(0), /** * Unlikely to be chosen. */ MARGINAL(64), /** * Likely to be chosen. */ SECONDARY(128), /** * Will be chosen first. */ PRIMARY(256); private final int value; private Rank(int value) { this.value = value; } @Override public int intValue() { return value; } } /** * Creates a new instance of PluginFeature */ PluginFeature(Initializer init) { super(init); } @Override public String toString() { return getName(); } /** * Gets the name of a plugin feature. * * @return The name. */ @Override public String getName() { return GSTOBJECT_API.gst_object_get_name(this); } /** * Sets the name of the plugin feature, getting rid of the old name if there * was one. * * @param name The name to set. */ @Override public boolean setName(String name) { GSTOBJECT_API.gst_object_set_name(this, name); return true; } /** * Set the rank for the plugin feature. Specifies a rank for a plugin * feature, so that autoplugging uses the most appropriate feature. * * @param rank The rank value - higher number means more priority rank */ public void setRank(int rank) { GSTPLUGINFEATURE_API.gst_plugin_feature_set_rank(this, rank); } /** * Set the rank for the plugin feature. Specifies a rank for a plugin * feature, so that autoplugging uses the most appropriate feature. * * @param rank The rank value */ public void setRank(Rank rank) { setRank(rank.intValue()); } /** * Gets the rank of a plugin feature. * * @return The rank of the feature. */ public int getRank() { return GSTPLUGINFEATURE_API.gst_plugin_feature_get_rank(this); } /** * Checks whether the given plugin feature is at least the required version. * * @param major Minimum required major version * @param minor Minimum required minor version * @param micro Minimum required micro version * @return true if the plugin feature has at least the required version, * otherwise false. */ public boolean checkVersion(int major, int minor, int micro) { return GSTPLUGINFEATURE_API.gst_plugin_feature_check_version(this, minor, minor, micro); } /** * Get the name of the plugin that provides this feature. * * @return the name of the plugin that provides this feature, or NULL if the * feature is not associated with a plugin. */ public String getPluginName() { return GSTPLUGINFEATURE_API.gst_plugin_feature_get_plugin_name(this); } /** * Get the plugin that provides this feature. * * @return the plugin that provides this feature, or NULL. */ public Plugin getPlugin() { return GSTPLUGINFEATURE_API.gst_plugin_feature_get_plugin(this); } } ================================================ FILE: src/org/freedesktop/gstreamer/Promise.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2018 Vinicius Tona * Copyright (c) 2018 Antonio Morales * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer; import static org.freedesktop.gstreamer.lowlevel.GstPromiseAPI.GSTPROMISE_API; import org.freedesktop.gstreamer.glib.NativeObject; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.glib.Natives; /** * A miniobject for future/promise-like functionality *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstPromise.html *

*/ @Gst.Since(minor = 14) public class Promise extends MiniObject { public static final String GTYPE_NAME = "GstPromise"; private GstCallback changeFunction; /** * Creates a new instance of Promise. This constructor is used internally. * * @param init internal initialization data. */ Promise(final Initializer init) { super(init); } /** * Creates a new instance of promise */ public Promise() { this(Natives.initializer(GSTPROMISE_API.ptr_gst_promise_new())); Gst.checkVersion(1, 14); // @TODO ideally this check would be before native call! } /** * Creates a new instance of promise with a callback attached. * * @param listener Listener to be called whenever the state of a * {@link Promise} is changed */ public Promise(final PROMISE_CHANGE listener) { this(new GstCallback() { public void callback(Promise promise, Pointer userData) { listener.onChange(promise); } }); } private Promise(GstCallback callback) { this(Natives.initializer(GSTPROMISE_API .ptr_gst_promise_new_with_change_func(callback, null, null))); this.changeFunction = callback; } /** * Wait for the promise to move out of the PENDING {@link PromiseResult} * state. If the promise is not in PENDING then it will immediately return. * * @return the {@link PromiseResult} of the promise. */ public PromiseResult waitResult() { return GSTPROMISE_API.gst_promise_wait(this); } /** * Set a reply on the promise. * * Will wake up any waiters on the promise with the REPLIED * {@link PromiseResult} state. If the promise has already been interrupted * than the replied will not be visible to any waiters * * @param structure the {@link Structure} to reply the promise with, caller * should not use this structure afterward as it is invalidated through * {@link NativeObject#invalidate()} */ public void reply(final Structure structure) { GSTPROMISE_API.gst_promise_reply(this, structure); } /** * Interrupt waiting for the result of the promise. * * Any waiters on the promise will receive the INTERRUPTED * {@link PromiseResult} state. */ public void interrupt() { GSTPROMISE_API.gst_promise_interrupt(this); } /** * Expire a promise. * * Any waiters on the promise will received the EXPIRED * {@link PromiseResult} state. */ public void expire() { GSTPROMISE_API.gst_promise_expire(this); } /** * Retrieve the reply set on the promise. * * The state of the promise must be in the REPLIED {@link PromiseResult} * state. The return structure is owned by the promise and thus cannot be * modified. * * @return the {@link Structure} set on the promise reply. */ public Structure getReply() { return Structure.objectFor(GSTPROMISE_API.ptr_gst_promise_get_reply(this), false, false); } /** * Called whenever the state of the promise is changed from PENDING to any * other {@link PromiseResult} */ public static interface PROMISE_CHANGE { /** * Called whenever the state of the promise is changed from PENDING to * any other {@link PromiseResult} * * @param promise the original promise that had the callback attached to */ public void onChange(Promise promise); } } ================================================ FILE: src/org/freedesktop/gstreamer/PromiseResult.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2018 Antonio Morales * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue; /** * The result of a {@link Promise} * Available since GStreamer 1.14 */ @Gst.Since(minor = 14) public enum PromiseResult { /** Initial state. Waiting for transition to any other state. */ @DefaultEnumValue PENDING, /** Interrupted by the consumer as it doesn't want the value anymore. */ INTERRUPTED, /** A producer marked a reply. */ REPLIED, /** The promise expired (the carrying object lost all refs) and the promise * will never be fulfilled. */ EXPIRED } ================================================ FILE: src/org/freedesktop/gstreamer/Range.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (C) 2009 Tamas Korodi * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.lowlevel.GValueAPI; import static org.freedesktop.gstreamer.lowlevel.GstValueAPI.GSTVALUE_API; /** * Represents a range of float, double, int, fraction types stored in a GValue * @author kotyo * */ public class Range { // there are multiple native types //public static final String GTYPE_NAME = "GstDoubleRange"; private GValueAPI.GValue value; Range(GValueAPI.GValue value) { this.value = value; } /** * Gets the minimum fraction of the range * @return minimum fraction of the range */ public Fraction getMinFraction() { GValueAPI.GValue frMin = GSTVALUE_API.gst_value_get_fraction_range_min(value); int num = GSTVALUE_API.gst_value_get_fraction_numerator(frMin); int denom = GSTVALUE_API.gst_value_get_fraction_denominator(frMin); return new Fraction(num, denom); } /** * Gets the maximum fraction of the range * @return maximum fraction of the range */ public Fraction getMaxFraction() { GValueAPI.GValue frMax = GSTVALUE_API.gst_value_get_fraction_range_max(value); int num = GSTVALUE_API.gst_value_get_fraction_numerator(frMax); int denom = GSTVALUE_API.gst_value_get_fraction_denominator(frMax); return new Fraction(num, denom); } /** * Gets the minimum double of the range * @return minimum double of the range */ public double getMinDouble() { return GSTVALUE_API.gst_value_get_double_range_min(value); } /** * Gets the maximum double of the range * @return maximum double of the range */ public double getMaxDouble() { return GSTVALUE_API.gst_value_get_double_range_max(value); } /** * Gets the minimum integer of the range * @return minimum integer of the range */ public int getMinInt() { return GSTVALUE_API.gst_value_get_int_range_min(value); } /** * Gets the maximum integer of the range * @return maximum integer of the range */ public int getMaxInt() { return GSTVALUE_API.gst_value_get_int_range_max(value); } } ================================================ FILE: src/org/freedesktop/gstreamer/Registry.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 David A. Schleef * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GList; import static org.freedesktop.gstreamer.lowlevel.GstPluginAPI.GSTPLUGIN_API; import static org.freedesktop.gstreamer.lowlevel.GstRegistryAPI.GSTREGISTRY_API; import static org.freedesktop.gstreamer.lowlevel.GstPluginFeatureAPI.GSTPLUGINFEATURE_API; /** * Abstract base class for management of {@link Plugin} objects. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstRegistry.html *

* One registry holds the metadata of a set of plugins. * All registries build the RegistryPool. *

* Design: *

* The Registry object is a list of plugins and some methods for dealing * with them. Plugins are matched 1-1 with a file on disk, and may or may * not be loaded at a given time. There may be multiple Registry objects, * but the "default registry" is the only object that has any meaning to the * core. *

* The registry.xml file is actually a cache of plugin information. This is * unlike versions prior to 0.10, where the registry file was the primary source * of plugin information, and was created by the gst-register command. *

* The primary source, at all times, of plugin information is each plugin file * itself. Thus, if an application wants information about a particular plugin, * or wants to search for a feature that satisfies given criteria, the primary * means of doing so is to load every plugin and look at the resulting * information that is gathered in the default registry. Clearly, this is a time * consuming process, so we cache information in the registry.xml file. *

* On startup, plugins are searched for in the plugin search path. This path can * be set directly using the GST_PLUGIN_PATH environment variable. The registry * file is loaded from ~/.gstreamer-$GST_MAJORMINOR/registry-$ARCH.xml or the * file listed in the GST_REGISTRY environment variable. The only reason to change the * registry location is for testing. *

* For each plugin that is found in the plugin search path, there could be 3 * possibilities for cached information: *

    *
  1. * the cache may not contain information about a given file. *
  2. *
  3. * the cache may have stale information. *
  4. *
  5. * the cache may have current information. *
  6. *
*

* In the first two cases, the plugin is loaded and the cache updated. In * addition to these cases, the cache may have entries for plugins that are not * relevant to the current process. These are marked as not available to the * current process. If the cache is updated for whatever reason, it is marked * dirty. *

* A dirty cache is written out at the end of initialization. Each entry is * checked to make sure the information is minimally valid. If not, the entry is * simply dropped. *

* Implementation notes: *

* The "cache" and "default registry" are different concepts and can represent * different sets of plugins. For various reasons, at init time, the cache is * stored in the default registry, and plugins not relevant to the current * process are marked with the %GST_PLUGIN_FLAG_CACHED bit. These plugins are * removed at the end of intitialization. */ public class Registry extends GstObject { public static final String GTYPE_NAME = "GstRegistry"; /** Creates a new instance of Registry */ Registry(Initializer init) { super(init); } /** * Find a plugin in the registry. * * @param name The plugin name to find. * @return The plugin with the given name or null if the plugin was not found. */ public Plugin findPlugin(String name) { return GSTREGISTRY_API.gst_registry_find_plugin(this, name); } /** * Add the plugin to the registry. The plugin-added signal will be emitted. * * @param plugin the {@link Plugin} to add * @return true on success. */ public boolean addPlugin(Plugin plugin) { return GSTREGISTRY_API.gst_registry_add_plugin(this, plugin); } /** * Remove a plugin from the registry. * * @param plugin The plugin to remove. */ public void removePlugin(Plugin plugin) { GSTREGISTRY_API.gst_registry_remove_plugin(this, plugin); } // /** // * Find the {@link PluginFeature} with the given name and type in the registry. // * // * @param name The name of the plugin feature to find. // * @param type The type of the plugin feature to find. // * @return The pluginfeature with the given name and type or null // * if the plugin was not found. // */ // public PluginFeature findPluginFeature(String name, GType type) { // return GSTREGISTRY_API.gst_registry_find_feature(this, name, type); // } /** * Find a {@link PluginFeature} by name in the registry. * * @param name The name of the plugin feature to find. * @return The {@link PluginFeature} or null if not found. */ public PluginFeature lookupFeature(String name) { return GSTREGISTRY_API.gst_registry_lookup_feature(this, name); } /** * Get a list of all plugins registered in the registry. * * @return a List of {@link Plugin} */ public List getPluginList() { GList glist = GSTREGISTRY_API.gst_registry_get_plugin_list(this); List list = objectList(glist, Plugin.class); GSTPLUGIN_API.gst_plugin_list_free(glist); return list; } /** * Get a subset of the Plugins in the registry, filtered by filter. * * @param filter the filter to use * @return A List of {@link Plugin} objects that match the filter. */ public List getPluginList(final PluginFilter filter) { return getPluginList().stream().filter(filter::accept).collect(Collectors.toList()); } // /** // * Retrieves a list of {@link PluginFeature} of the {@link Plugin} type. // * // * @param type The plugin type. // * @return a List of {@link PluginFeature} for the plugin type. // */ // public List getPluginFeatureListByType(GType type) { // GList glist = GSTREGISTRY_API.gst_registry_get_feature_list(this, type); // List list = objectList(glist, PluginFeature.class); // GSTPLUGINFEATURE_API.gst_plugin_feature_list_free(glist); // return list; // } /** * Retrieves a list of {@link PluginFeature} of the named {@link Plugin}. * * @param name The plugin name. * @return a List of {@link PluginFeature} for the named plugin. */ public List getPluginFeatureListByPlugin(String name) { GList glist = GSTREGISTRY_API.gst_registry_get_feature_list_by_plugin(this, name); List list = objectList(glist, PluginFeature.class); GSTPLUGINFEATURE_API.gst_plugin_feature_list_free(glist); return list; } /** * Add the given path to the registry. The syntax of the * path is specific to the registry. If the path has already been * added, do nothing. * * @param path The path to add to the registry. * @return true if the registry changed. */ public boolean scanPath(String path) { return GSTREGISTRY_API.gst_registry_scan_path(this, path); } /** * Build a {@link java.util.List} of {@link GstObject} from the native GList. * @param glist The native list to get the objects from. * @param objectClass The proxy class to wrap the list elements in. * @return The converted list. */ private List objectList(GList glist, Class objectClass) { List list = new ArrayList(); GList next = glist; while (next != null) { if (next.data != null) { list.add(Natives.objectFor(next.data, objectClass, true, true)); } next = next.next(); } return list; } public static interface PluginFilter { public boolean accept(Plugin plugin); } // public static interface PluginFeatureFilter { // public boolean accept(PluginFeature feature); // } // /** * Retrieves the default registry. * * @return The default Registry. */ public static Registry get() { // Need to handle the return value here, as it is a persistent object // i.e. the java proxy should not dispose of the underlying object when finalized return Natives.objectFor(GSTREGISTRY_API.gst_registry_get(), Registry.class, false, false); } } ================================================ FILE: src/org/freedesktop/gstreamer/SDPMessage.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2018 Antonio Morales * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer; import java.nio.charset.StandardCharsets; import static org.freedesktop.gstreamer.lowlevel.GstSDPMessageAPI.GSTSDPMESSAGE_API; import org.freedesktop.gstreamer.glib.NativeObject; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.lowlevel.GPointer; /** * Wrapping type and helper methods for dealing with SDP messages. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-libs/html/gst-plugins-base-libs-GstSDPMessage.html */ public class SDPMessage extends NativeObject { public static final String GTYPE_NAME = "GstSDPMessage"; /** * Internally used constructor. Do not use. * * @param init internal initialization data */ SDPMessage(Initializer init) { this(new Handle(init.ptr, init.ownsHandle)); } SDPMessage(Handle handle) { super(handle); } /** * Creates a new instance of SDPMessage */ public SDPMessage() { this(initHandle()); } /** * A SDP formatted string representation of SDPMessage. * * Used for offer/answer exchanges for real time communicationse * * @return the SDP string representation of SDPMessage. */ public String toString() { return GSTSDPMESSAGE_API.gst_sdp_message_as_text(this); } /** * Takes a SDP string and parses it and fills in all fields for SDPMessage. * * Look at https://tools.ietf.org/html/rfc4566 for more information on SDP * * @param sdpString the sdp string */ public void parseBuffer(String sdpString) { byte[] data = sdpString.getBytes(StandardCharsets.US_ASCII); int length = sdpString.length(); GSTSDPMESSAGE_API.gst_sdp_message_parse_buffer(data, length, this); } // /** // * Creates a copy of this SDPMessage. // * // * @return a copy of SDPMessage. // */ // SDPMessage copy(boolean shouldInvalidateOriginal) { // Pointer[] ptr = new Pointer[1]; // GSTSDPMESSAGE_API.gst_sdp_message_copy(this, ptr); // if (shouldInvalidateOriginal) { // this.invalidate(); // } // return new SDPMessage(initializer(ptr[0])); // } private static Handle initHandle() { Pointer[] ptr = new Pointer[1]; GSTSDPMESSAGE_API.gst_sdp_message_new(ptr); return new Handle(new GPointer(ptr[0]), true); } private static final class Handle extends NativeObject.Handle { public Handle(GPointer ptr, boolean ownsHandle) { super(ptr, ownsHandle); } @Override protected void disposeNativeHandle(GPointer ptr) { GSTSDPMESSAGE_API.gst_sdp_message_free(ptr.getPointer()); } } } ================================================ FILE: src/org/freedesktop/gstreamer/SDPResult.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2018 Antonio Morales * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.NativeEnum; import org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue; /** * Return values for SDP functions *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-libs/html/gst-plugins-base-libs-GstSDPMessage.html#GstSDPResult * * @see SDPMessage */ public enum SDPResult implements NativeEnum { /** A successful return value*/ OK(0), /** A function to SDPMessage was given invalid parameters */ @DefaultEnumValue EINVAL(-1); private final int value; SDPResult(int value) { this.value = value; } /** * Gets the integer value of the enum * @return the integer value for this enum. */ @Override public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/Sample.java ================================================ /* * Copyright (c) 2020 Christophe Lafolet * Copyright (c) 2019 Neil C Smith * Copyright (c) 2014 Tom Greenwood * Copyright (c) 2007, 2008 Wayne Meissner * Copyright (C) 2004 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import static org.freedesktop.gstreamer.lowlevel.GstSampleAPI.GSTSAMPLE_API; /** * A Sample is a small object containing data, a type, timing and extra * arbitrary information. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstSample.html * */ public class Sample extends MiniObject { public static final String GTYPE_NAME = "GstSample"; Sample(Initializer init) { super(init); } /** * Get the {@link Caps} associated with sample, or NULL when there is no caps. * The caps remains valid as long as sample is valid. * If you need to hold on to the caps for longer than that, take a ref to the caps * * @return caps of sample or NULL when there is no caps. */ public Caps getCaps() { return GSTSAMPLE_API.gst_sample_get_caps(this); } /** * Set the {@link Caps} associated with sample. * This sample must be writable. * * Since GStreamer 1.16 * * @param caps */ @Gst.Since(minor = 16) public void setCaps(Caps caps) { Gst.checkVersion(1, 16); GSTSAMPLE_API.gst_sample_set_caps(this, caps); } /** * Get the {@link Buffer} associated with sample, or NULL when there is no * buffer. * The buffer remains valid as long as sample is valid. * If you need to hold on to it for longer than that, take a ref to the buffer. * * @return buffer of sample or NULL when there is no buffer. */ public Buffer getBuffer() { return GSTSAMPLE_API.gst_sample_get_buffer(this); } /** * Set the {@link Buffer} associated with sample. * This sample must be writable. * * Since GStreamer 1.16 * * @param buffer */ @Gst.Since(minor = 16) public void setBuffer(Buffer buffer) { Gst.checkVersion(1, 16); GSTSAMPLE_API.gst_sample_set_buffer(this, buffer); } } ================================================ FILE: src/org/freedesktop/gstreamer/Segment.java ================================================ /* * Copyright (c) 2010 David Hoyt * Copyright (c) 2010 David Hoyt * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; /** * A representation of the values used in querying the pipeline using * gst_query_new_segment() and subsequently gst_query_parse_segment(). */ public final class Segment { //-------------------------------------------------------------------------- // Instance variables // private final double rate; private final Format format; private final long startValue; private final long stopValue; /** * Creates a new instance of {@link Segment}. * * @param rate the rate of the segment. * @param format the {@link Format} of the segment values. * @param startValue the start value. * @param stopValue the stop value. */ Segment(double rate, Format format, long startValue, long stopValue) { this.rate = rate; this.format = format; this.stopValue = stopValue; this.startValue = startValue; } /** * Gets the rate of the segment. * * @return The rate of the segment. */ public double getRate() { return rate; } /** * Gets the {@link Format} of the segment values. * * @return The {@link Format} of the segment values. */ public Format getFormat() { return format; } /** * Gets the start value. * * @return The start value. */ public long getStartValue() { return startValue; } /** * Gets the stop value. * * @return The stop value. */ public long getStopValue() { return stopValue; } } ================================================ FILE: src/org/freedesktop/gstreamer/SegmentFlags.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.event.SeekFlags; import org.freedesktop.gstreamer.glib.NativeFlags; /** * GstSegmentFlags */ enum SegmentFlags implements NativeFlags { // /** // * no flags // */ // public static final int NONE = SeekFlags.NONE; /** * reset the pipeline running_time to the segment running_time */ RESET(SeekFlags.FLUSH), /** * perform skip playback */ TRICKMODE(SeekFlags.TRICKMODE), /** * send SEGMENT_DONE instead of EOS */ SEGMENT(SeekFlags.SEGMENT), /** * Decode only keyframes, where possible */ TRICKMODE_KEY_UNITS(SeekFlags.TRICKMODE_KEY_UNITS), /** * Do not decode any audio, where possible (Since 1.6) */ TRICKMODE_NO_AUDIO(SeekFlags.TRICKMODE_NO_AUDIO); private final SeekFlags seekFlags; private SegmentFlags(SeekFlags seekFlags) { this.seekFlags = seekFlags; } @Override public int intValue() { return seekFlags.intValue(); } } ================================================ FILE: src/org/freedesktop/gstreamer/State.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.NativeEnum; //import org.freedesktop.gstreamer.lowlevel.EnumMapper; /** * The possible states an element can be in. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstElement.html#GstState *

*/ public enum State implements NativeEnum { /** * No pending state. */ VOID_PENDING(0), /** * The initial state of an {@link Element}. */ NULL(1), /** * The {@link Element} is ready to go to PAUSED. */ READY(2), /** * The {@link Element} is PAUSED */ PAUSED(3), /** * The {@link Element} is PLAYING */ PLAYING(4); private final int value; private State(int value) { this.value = value; } /** * Gets the integer value of the enum. * * @return The integer value for this enum. */ @Override public int intValue() { return value; } // /** // * Returns the enum constant of this type with the specified integer value. // * // * @param state integer value. // * @return Enum constant. // * @throws java.lang.IllegalArgumentException if the enum type has no // * constant with the specified value. // */ // public static final State valueOf(int state) { // return EnumMapper.getInstance().valueOf(state, State.class); // } } ================================================ FILE: src/org/freedesktop/gstreamer/StateChangeReturn.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.NativeEnum; /** * The possible return values from a state change function. *

* Only {@link StateChangeReturn#FAILURE} is a real failure. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstElement.html#GstStateChangeReturn *

*/ public enum StateChangeReturn implements NativeEnum { /** The state change failed. */ FAILURE(0), /** The state change succeeded. */ SUCCESS(1), /** The state change will happen asynchronously. */ ASYNC(2), /** * The state change succeeded but the {@link Element} cannot produce data in * {@link State#PAUSED}. This typically happens with live sources. */ NO_PREROLL(3); private final int value; private StateChangeReturn(int value) { this.value = value; } @Override public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/StaticPadTemplate.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; public class StaticPadTemplate { private final String templateName; private final PadDirection direction; private final PadPresence presence; private final Caps caps; StaticPadTemplate(String templateName, PadDirection direction, PadPresence presence, Caps caps) { this.templateName = templateName; this.direction = direction; this.presence = presence; this.caps = caps; } /** * Get the name of the template. * * @return The name of the template. */ public String getName() { return templateName; } /** * Get the direction (SINK, SRC) of the template. * * @return The {@link PadDirection} of the template. */ public PadDirection getDirection() { return direction; } /** * Get the presence (ALWAYS, SOMETIMES, REQUEST) of the template. * * @return The {@link PadPresence} of this template. */ public PadPresence getPresence() { return presence; } /** * Get the {@link Caps} of the template. * * @return The {@link Caps} for this template. */ public Caps getCaps() { return caps; } } ================================================ FILE: src/org/freedesktop/gstreamer/Structure.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (C) 2009 Tamas Korodi * Copyright (C) 2007 Wayne Meissner * Copyright (C) 2003 David A. Schleef * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import com.sun.jna.Pointer; import com.sun.jna.ptr.PointerByReference; import org.freedesktop.gstreamer.glib.GObject; import org.freedesktop.gstreamer.glib.NativeObject; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GPointer; import org.freedesktop.gstreamer.lowlevel.GType; import org.freedesktop.gstreamer.lowlevel.GValueAPI; import org.freedesktop.gstreamer.lowlevel.GValueAPI.GValue; import java.util.ArrayList; import java.util.Collections; import java.util.List; import static org.freedesktop.gstreamer.lowlevel.GstStructureAPI.GSTSTRUCTURE_API; import static org.freedesktop.gstreamer.lowlevel.GstValueAPI.GSTVALUE_API; /** * Generic structure containing fields of names and values. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstStructure.html *

* A Structure is a collection of key/value pairs. The keys are expressed as * GQuarks and the values can be of any GType. *

* In addition to the key/value pairs, a Structure also has a name. The name * starts with a letter and can be followed by letters, numbers and any of * "/-_.:". *

* Structure is used by various GStreamer subsystems to store information in a * flexible and extensible way. *

* A Structure can be created with new {@link #Structure(String)} or * {@link #Structure(String, String, Object...)}, which both take a name and an * optional set of key/value pairs along with the types of the values. *

* Field values can be changed with set{Integer,String}() etc functions. *

* Field values can be retrieved with get{Integer,String}() etc functions. *

* Fields can be removed with {@link #removeField} or {@link #removeFields} * * @see Caps * @see Event */ public class Structure extends NativeObject { public static final String GTYPE_NAME = "GstStructure"; /** * Creates a new, empty #GstStructure with the given name. * * @param name The name of new structure. */ public Structure(String name) { this(new Handle(new GPointer(GSTSTRUCTURE_API.ptr_gst_structure_new_empty(name)), true)); } /** * Creates a new Structure with the given name. Parses the list of variable * arguments and sets fields to the values listed. Variable arguments should * be passed as field name, field type, and value. * * @param name The name of new structure. * @param firstFieldName The name of first field to set * @param data Additional arguments. */ public Structure(String name, String firstFieldName, Object... data) { this(new Handle(new GPointer(GSTSTRUCTURE_API.ptr_gst_structure_new(name, firstFieldName, data)), true)); } /** * Creates a new instance of Structure */ Structure(Initializer init) { this(new Handle(init.ptr, init.ownsHandle)); } private Structure(Handle handle) { super(handle); } public Structure copy() { return GSTSTRUCTURE_API.gst_structure_copy(this); } public boolean fixateNearestInteger(String field, Integer value) { return GSTSTRUCTURE_API.gst_structure_fixate_field_nearest_int(this, field, value); } /** * Get the value of the named field as a boolean. Throws * {@link InvalidFieldException} if the Structure does not contain the named * field or the named field is not a boolean. * * @param fieldName name of field * @return boolean value of the named field */ public boolean getBoolean(String fieldName) { int[] val = {0}; if (!GSTSTRUCTURE_API.gst_structure_get_boolean(this, fieldName, val)) { throw new InvalidFieldException("boolean", fieldName); } return val[0] != 0; } /** * Get the value of the named field as a double. Throws * {@link InvalidFieldException} if the Structure does not contain the named * field or the named field is not a double. * * @param fieldName name of field * @return double value of the named field */ public double getDouble(String fieldName) { double[] val = {0d}; if (!GSTSTRUCTURE_API.gst_structure_get_double(this, fieldName, val)) { throw new InvalidFieldException("double", fieldName); } return val[0]; } /** * Extract the values of the named field as an array of doubles. If the * native GType of the field is a GValueArray then this method will return * an array of the contained values, assuming all contained values are of * G_TYPE_DOUBLE. Else if the field is of G_TYPE_DOUBLE a single value array * will be returned. *

* This method will create a new array each time. If you are repeatedly * calling this method consider using * {@link #getDoubles(java.lang.String, double[])}. *

* Throws {@link InvalidFieldException} if the field does not exist, or the * field values contained are not of type G_TYPE_DOUBLE. *

* This method only currently supports lists of values inside a GValueArray * - other native list types will be supported in future. * * @param fieldName name of field * @return List of values from the named field */ public double[] getDoubles(String fieldName) { return getDoubles(fieldName, null); } /** * Extract the values of the named field as an array of doubles. If the * native GType of the field is a GValueArray then this method will return * an array of the contained values, assuming all contained values are of * G_TYPE_DOUBLE. Else if the field is of G_TYPE_DOUBLE a single value array * will be returned. *

* An array may be passed into this method to contain the result. A new * array will be created if the array is null or not of the correct length. *

* Throws {@link InvalidFieldException} if the field does not exist, or the * field values contained are not of type G_TYPE_DOUBLE. *

* This method only currently supports lists of values inside a GValueArray * - other native list types will be supported in future. * * @param fieldName name of field * @param array an array to hold values, or null * @return List of values from the named field */ public double[] getDoubles(String fieldName, double[] array) { Object val = getValue(fieldName); if (val instanceof GValueAPI.GValueArray) { GValueAPI.GValueArray arr = (GValueAPI.GValueArray) val; int count = arr.getNValues(); double[] values = array == null || array.length != count ? new double[count] : array; for (int i = 0; i < count; i++) { GValue gval = arr.nth(i); if (gval.checkHolds(GType.DOUBLE)) { values[i] = GValueAPI.GVALUE_API.g_value_get_double(gval); } else { throw new InvalidFieldException("doubles", fieldName); } } return values; } else { if (Double.class.isInstance(val)) { double[] values = array == null || array.length != 1 ? new double[1] : array; values[0] = ((Double) val); return values; } else { throw new InvalidFieldException("double", fieldName); } } } /** * Get the number of fields in the {@link Structure}. * * @return the structure's filed number. */ public int getFields() { return GSTSTRUCTURE_API.gst_structure_n_fields(this); } /** * Gets FOURCC field int representation * * @param fieldName The name of the field. * @return FOURCC field as a 4 byte integer */ public int getFourcc(String fieldName) { int[] val = {0}; if (!GSTSTRUCTURE_API.gst_structure_get_fourcc(this, fieldName, val)) { throw new InvalidFieldException("FOURCC", fieldName); } return val[0]; } /** * Gets FOURCC field String representation * * @param fieldName The name of the field. * @return FOURCC field as a String */ public String getFourccString(String fieldName) { int f = getFourcc(fieldName); byte[] b = {(byte) ((f >> 0) & 0xff), (byte) ((f >> 8) & 0xff), (byte) ((f >> 16) & 0xff), (byte) ((f >> 24) & 0xff)}; return new String(b); } /** * Get the value of the named field as a Fraction. Throws * {@link InvalidFieldException} if the Structure does not contain the named * field or the named field is not a Fraction. * * @param fieldName name of field * @return boolean value of the named field */ public Fraction getFraction(String fieldName) { int[] numerator = {0}; int[] denominator = {0}; if (!GSTSTRUCTURE_API.gst_structure_get_fraction(this, fieldName, numerator, denominator)) { throw new InvalidFieldException("fraction", fieldName); } return new Fraction(numerator[0], denominator[0]); } /** * Get the value of the named field as an int. Throws * {@link InvalidFieldException} if the Structure does not contain the named * field or the named field is not an integer. * * @param fieldName name of field * @return int value of the named field */ public int getInteger(String fieldName) { int[] val = {0}; if (!GSTSTRUCTURE_API.gst_structure_get_int(this, fieldName, val)) { throw new InvalidFieldException("integer", fieldName); } return val[0]; } /** * Extract the values of the named field as an array of integers. If the * native GType of the field is a GValueArray then this method will return * an array of the contained values, assuming all contained values are of * G_TYPE_INT. Else if the field is of G_TYPE_INT a single value array will * be returned. *

* This method will create a new array each time. If you are repeatedly * calling this method consider using * {@link #getIntegers(java.lang.String, int[])}. *

* Throws {@link InvalidFieldException} if the field does not exist, or the * field values contained are not of type G_TYPE_INT. *

* This method only currently supports lists of values inside a GValueArray * - other native list types will be supported in future. * * @param fieldName name of field * @return List of values from the named field */ public int[] getIntegers(String fieldName) { return getIntegers(fieldName, null); } /** * Extract the values of the named field as an array of integers. If the * native GType of the field is a GValueArray then this method will return * an array of the contained values, assuming all contained values are of * G_TYPE_INT. Else if the field is of G_TYPE_INT a single value array will * be returned. *

* An array may be passed into this method to contain the result. A new * array will be created if the array is null or not of the correct length. *

* Throws {@link InvalidFieldException} if the field does not exist, or the * field values contained are not of type G_TYPE_INT. *

* This method only currently supports lists of values inside a GValueArray * - other native list types will be supported in future. * * @param fieldName name of field * @param array an array to hold values, or null * @return List of values from the named field */ public int[] getIntegers(String fieldName, int[] array) { Object val = getValue(fieldName); if (val instanceof GValueAPI.GValueArray) { GValueAPI.GValueArray arr = (GValueAPI.GValueArray) val; int count = arr.getNValues(); int[] values = array == null || array.length != count ? new int[count] : array; for (int i = 0; i < count; i++) { GValue gval = arr.nth(i); if (gval.checkHolds(GType.INT)) { values[i] = GValueAPI.GVALUE_API.g_value_get_int(gval); } else { throw new InvalidFieldException("integers", fieldName); } } return values; } else { if (Integer.class.isInstance(val)) { int[] values = array == null || array.length != 1 ? new int[1] : array; values[0] = ((Integer) val); return values; } else { throw new InvalidFieldException("integer", fieldName); } } } /** * Sets the name of the structure to the given name. * * The name must not be empty, must start with a letter and can be followed * by letters, numbers and any of "/-_.:". * * @param name The new name of the structure. */ public void setName(String name) { GSTSTRUCTURE_API.gst_structure_set_name(this, name); } /** * Get the name of @structure as a string. * * @return The name of the structure. */ public String getName() { return GSTSTRUCTURE_API.gst_structure_get_name(this); } /** * Get the @structure's ith field name as a string. * * @param i the requested filed number * @return The name of the structure. */ public String getName(int i) { return GSTSTRUCTURE_API.gst_structure_nth_field_name(this, i); } /** * Get the value of the named field as a Range. Throws * {@link InvalidFieldException} if the Structure does not contain the named * field. * * @param fieldName name of field * @return Range value of the named field */ public Range getRange(String fieldName) { GValue val = GSTSTRUCTURE_API.gst_structure_get_value(this, fieldName); if (val == null) { throw new InvalidFieldException("Range", fieldName); } return new Range(val); } /** * Get the value of the named field as a String. * * @param fieldName name of field * @return String value of the named field */ public String getString(String fieldName) { return GSTSTRUCTURE_API.gst_structure_get_string(this, fieldName); } /** * Get the value of the named field. Throws {@link InvalidFieldException} if * the Structure does not contain the named field. * * @param fieldName name of field * @return Object representation of the named field */ public Object getValue(String fieldName) { GValue val = GSTSTRUCTURE_API.gst_structure_get_value(this, fieldName); if (val == null) { throw new InvalidFieldException("Object", fieldName); } return val.getValue(); } /** * Extract the values of the named field as a List of the provided type. If * the native GType of the field is a GValueArray then this method will * return a list of the contained values, assuming all contained values can * be converted to the provided Java type T. Else if the field GType can be * directly converted to the provided Java type T, a singleton List will be * returned. *

* Throws {@link InvalidFieldException} if the field does not exist, or the * field values cannot be converted to type T. *

* This method currently supports lists of values inside a GValueArray or * GstValueList. * * @param * @param type type of values * @param fieldName name of field * @return List of values from the named field */ public List getValues(Class type, String fieldName) { GValue gValue = GSTSTRUCTURE_API.gst_structure_get_value(this, fieldName); if (gValue == null) { throw new InvalidFieldException(type.getSimpleName(), fieldName); } GType gType = gValue.getType(); if (gType.equals(GSTVALUE_API.gst_value_list_get_type())) { int size = GSTVALUE_API.gst_value_list_get_size(gValue); ArrayList values = new ArrayList<>(size); for (int i = 0; i values = new ArrayList(count); for (int i = 0; i < count; i++) { Object o = arr.getValue(i); if (type.isInstance(o)) { values.add(type.cast(o)); } else { throw new InvalidFieldException(type.getSimpleName(), fieldName); } } return values; } else { if (type.isInstance(val)) { return Collections.singletonList(type.cast(val)); } else { throw new InvalidFieldException(type.getSimpleName(), fieldName); } } } /** * Check if the {@link Structure} contains a double field named fieldName. * * @param fieldName The name of the field to check. * @return true if the structure contains a double field named fieldName */ public boolean hasDoubleField(String fieldName) { return hasField(fieldName, GType.DOUBLE); } /** * Check if the {@link Structure} contains a field named fieldName. * * @param fieldName The name of the field to check. * @return true if the structure contains a field with the given name. */ public boolean hasField(String fieldName) { return GSTSTRUCTURE_API.gst_structure_has_field(this, fieldName); } /** * Check if the {@link Structure} contains a field named fieldName. * * @param fieldName The name of the field to check. * @param fieldType The type of the field. * @return true if the structure contains a field named fieldName and of * type fieldType */ boolean hasField(String fieldName, GType fieldType) { return GSTSTRUCTURE_API.gst_structure_has_field_typed(this, fieldName, fieldType); } /** * Check if the {@link Structure} contains a field named fieldName. * * @param fieldName The name of the field to check. * @param fieldType The type of the field. * @return true if the structure contains a field named fieldName and of * type fieldType */ public boolean hasField(String fieldName, Class fieldType) { return GSTSTRUCTURE_API.gst_structure_has_field_typed(this, fieldName, GType.valueOf(fieldType)); } /** * Check if the {@link Structure} contains an integer field named fieldName. * * @param fieldName The name of the field to check. * @return true if the structure contains an integer field named fieldName */ public boolean hasIntField(String fieldName) { return hasField(fieldName, GType.INT); } /** * Checks if the structure has the given name. * * @param name structure name to check for * @return true if @name matches the name of the structure. */ public boolean hasName(String name) { return GSTSTRUCTURE_API.gst_structure_has_name(this, name); } /** * Checks that two structures are equal * * @param structure the structure to check if it's equal to this structure * @return true if both structures are equal */ public boolean isEqual(Structure structure) { return GSTSTRUCTURE_API.gst_structure_is_equal(this, structure); } /** * Removes the field with the given name from the structure. If the field * with the given name does not exist, the structure is unchanged. * * @param fieldName The name of the field to remove. */ public void removeField(String fieldName) { GSTSTRUCTURE_API.gst_structure_remove_field(this, fieldName); } /** * Removes the fields with the given names. If a field does not exist, the * argument is ignored. * * @param fieldNames A list of field names to remove. */ public void removeFields(String... fieldNames) { GSTSTRUCTURE_API.gst_structure_remove_fields(this, fieldNames); } public void setDouble(String field, Double value) { GSTSTRUCTURE_API.gst_structure_set(this, field, GType.DOUBLE, value); } public void setDoubleRange(String field, Double min, Double max) { GSTSTRUCTURE_API.gst_structure_set(this, field, GSTVALUE_API.gst_double_range_get_type(), min, max); } public void setFraction(String field, Integer numerator, Integer denominator) { GSTSTRUCTURE_API.gst_structure_set(this, field, GSTVALUE_API.gst_fraction_get_type(), numerator, denominator); } /** * Sets an integer field in the structure. * * @param field the name of the field to set. * @param value the value to set for the field. */ public void setInteger(String field, Integer value) { GSTSTRUCTURE_API.gst_structure_set(this, field, GType.INT, value); } public void setIntegerRange(String field, Integer min, Integer max) { GSTSTRUCTURE_API.gst_structure_set(this, field, GSTVALUE_API.gst_int_range_get_type(), min, max); } /** * Set an object field in the structure. * * @param field the name of the field to set. * @param typeName a type into which the provided object could be coerced into. * @param object the value to set for the field (must not be {@code null}). */ public void setObject(String field, String typeName, GObject object) { GType type = GType.valueOf(typeName); if (!GType.INVALID.equals(type)) { if (object != null) { GType realType = GType.valueOf(object.getTypeName()); while (!realType.equals(GType.OBJECT) && !realType.equals(type)) { realType = realType.getParentType(); } if (!realType.equals(type)) { throw new IllegalArgumentException( "Provided instance of " + object.getTypeName() + " is not a " + typeName); } setValue(field, type, object); } else { throw new IllegalArgumentException("Null object provided"); } } else { throw new IllegalArgumentException("Unknown GType name: " + typeName); } } void setPointer(String field, Pointer value) { GSTSTRUCTURE_API.gst_structure_set(this, field, GType.POINTER, value); } void setValue(String field, GType type, Object value) { GSTSTRUCTURE_API.gst_structure_set(this, field, type, value); } @Override public String toString() { return GSTSTRUCTURE_API.gst_structure_to_string(this); } /** * Creates a Structure from a string representation. * * @param data A string representation of a Structure. * @return A new Structure or null when the string could not be parsed. */ public static Structure fromString(String data) { return new Structure( new Handle( new GPointer(GSTSTRUCTURE_API.ptr_gst_structure_from_string(data, new PointerByReference())) , true)); } static Structure objectFor(Pointer ptr, boolean needRef, boolean ownsHandle) { return Natives.objectFor(ptr, Structure.class, needRef, ownsHandle); } public class InvalidFieldException extends RuntimeException { private static final long serialVersionUID = 864118748304334069L; public InvalidFieldException(String type, String fieldName) { super(String.format("Structure does not contain %s field '%s'", type, fieldName)); } } private static final class Handle extends NativeObject.Handle { public Handle(GPointer ptr, boolean ownsHandle) { super(ptr, ownsHandle); } @Override protected void disposeNativeHandle(GPointer ptr) { GSTSTRUCTURE_API.gst_structure_free(ptr.getPointer()); } } } ================================================ FILE: src/org/freedesktop/gstreamer/Tag.java ================================================ /* * Copyright (C) 2007 Wayne Meissner * Copyright (C) 2003 Benjamin Otte * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; /** * GStreamer core tags */ enum Tag { /** * The artist name as it should be displayed, e.g. 'Jimi Hendrix' or * 'The Guitar Heroes' */ ARTIST("artist"), /** * The artist name as it should be sorted, e.g. 'Hendrix, Jimi' or * 'Guitar Heroes, The' */ ARTIST_SORTNAME("musicbrainz-sortname"), /** The title as it should be displayed, e.g. 'The Doll House' */ TITLE("title"), /** The title as it should be sorted, e.g. 'Doll House, The' */ TITLE_SORTNAME("title-sortname"), /** The album name as it should be displayed, e.g. 'The Jazz Guitar' */ ALBUM("album"), /** The album name as it should be sorted, e.g. 'Jazz Guitar, The' */ ALBUM_SORTNAME("album-sortname"), /** Person(s) who composed the recording */ COMPOSER("composer"), /** Genre of the media */ GENRE("genre"), COMMENT("comment"), EXTENDED_COMMENT("extended-comment"), /** Original location of file as a URI */ LOCATION("location"), /** Short text describing the content of the data */ DESCRIPTION("description"), /** Version of this data */ VERSION("version"), /** Organization */ ORGANIZATION("organization"), /** Copyright notice for the data */ COPYRIGHT("copyright"), /** URI to location where copyright details can be found */ COPYRIGHT_URI("copyright-uri"), /** Contact information */ CONTACT("contact"), /** License of data */ LICENSE("license"), /** URI to location where license details can be found */ LICENSE_URI("license-uri"), /** Person(s) performing */ PERFORMER("performer"), /** Codec the data is stored in */ CODEC("codec"), /** Codec the audio data is stored in */ AUDIO_CODEC("audio-codec"), /** Codec the video data is stored in */ VIDEO_CODEC("video-codec"), /** Encoder used to encode this stream */ ENCODER("encoder"), /** Version of the encoder used to encode this stream */ ENCODER_VERSION("encoder-version"), /** Language code (ISO-639-1) String */ LANGUAGE_CODE("language-code"), /** Track number inside a collection. */ TRACK_NUMBER("track-number"), /** Count of tracks inside collection this track belongs to. */ TRACK_COUNT("track-count"), /** Disc number inside a collection. */ ALBUM_VOLUME_NUMBER("album-disc-number"), /** Count of discs inside collection this disc belongs to. */ ALBUM_VOLUME_COUNT("album-disc-count"), /** Exact or average bitrate in bits per second */ BITRATE("bitrate"), /** Nominal bitrate in bits/s */ NOMINAL_BITRATE("nominal-bitrate"), /** Minimum bitrate in bits/s */ MINIMUM_BITRATE("minimum-bitrate"), /** Maximum bitrate in bits/s */ MAXIMUM_BITRATE("maximum-bitrate"), /** Track gain in db */ TRACK_GAIN("replaygain-track-gain"), /** Peak of the track */ TRACK_PEAK("replaygain-track-peak"), /** Album gain in db */ ALBUM_GAIN("replaygain-album-gain"), /** Peak of the album */ ALBUM_PEAK("replaygain-album-peak"), /** Reference level of track and album gain values */ REFERENCE_LEVEL("replaygain-reference-level"), /** Serial number of track */ SERIAL("serial"), /** date the data was created */ DATE("date"), /** Length in GStreamer time units (nanoseconds) */ DURATION("duration"), ISRC("isrc"), /** Image */ IMAGE("image"), /** Image that is meant for preview purposes */ PREVIEW_IMAGE("preview-image"), /** Number of beats per minute in audio */ BEATS_PER_MINUTE("beats-per-minute"); Tag(String id) { this.id = id; } public String getId() { return id; } private String id; } ================================================ FILE: src/org/freedesktop/gstreamer/TagFlag.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2007 Wayne Meissner * Copyright (C) 2003 Benjamin Otte * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.NativeEnum; import org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue; /** * Extra tag flags used when registering tags. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstTagList.html#GstTagFlag *

*/ public enum TagFlag implements NativeEnum { /** Undefined flag. */ @DefaultEnumValue UNDEFINED(0), /** Tag is meta data. */ META(1), /** Tag is encoded. */ ENCODED(2), /** Tag is decoded. */ DECODED(3), /** Number of tag flags. */ COUNT(4); private final int value; private TagFlag(int value) { this.value = value; } @Override public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/TagList.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2016 Christophe Lafolet * Copyright (c) 2014 Tom Greenwood * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API; import static org.freedesktop.gstreamer.lowlevel.GstTagAPI.GSTTAG_API; import static org.freedesktop.gstreamer.lowlevel.GstTagListAPI.GSTTAGLIST_API; import java.util.AbstractList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.freedesktop.gstreamer.glib.GDate; import org.freedesktop.gstreamer.lowlevel.GType; import org.freedesktop.gstreamer.lowlevel.GstTagListAPI; import com.sun.jna.Pointer; import com.sun.jna.ptr.PointerByReference; import org.freedesktop.gstreamer.glib.NativeObject; import org.freedesktop.gstreamer.glib.Natives; /** * List of tags and values used to describe media metadata. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstTagList.html *

*/ //@TODO consider handling Sample fields. public class TagList extends MiniObject { public static final String GTYPE_NAME = "GstTagList"; /** * Creates a new instance of TagList * * @param init internal initialization data. */ TagList(Initializer init) { super(init); } /** * Constructs a new empty tag list. */ public TagList() { super(initializer()); } private static Initializer initializer() { final Pointer ptr_new_tag_list = GSTTAGLIST_API.ptr_gst_tag_list_new_empty(); return Natives.initializer(ptr_new_tag_list); } /** * Gets the number of values of type {@code tag} stored in the list. * * @param tag the name of the tag to get the size of. * @return the number of values for {@code tag} in this list. */ public int getValueCount(String tag) { return GSTTAGLIST_API.gst_tag_list_get_tag_size(this, tag); } /** * Gets all data values for a tag contained in this list. * * @param tag the name of the tag to retrieve. * @return the data associated with {@code tag}. */ public List getValues(final String tag) { final int size = getValueCount(tag); return new AbstractList() { public int size() { return size; } @Override public Object get(int index) { return getValue(tag, index); } }; } // /** // * Gets all data values for a tag contained in this list. // * // * @param tag the name of the tag to retrieve. // * @return the data associated with {@code tag}. // */ // public List getValues(Tag tag) { // return getValues(tag.getId()); // } /** * Gets data for a tag from this list. * * @param tag the tag to retrieve. * @param index which element of the array of data for this tag to retrieve. * @return the data for the tag. */ public Object getValue(String tag, int index) { TagGetter get = MapHolder.getterMap.get(getTagType(tag)); return get != null ? get.get(this, tag, index) : ""; } // /** // * Gets data for a tag from this list. // * // * @param tag the tag to retrieve. // * @param index which element of the array of data for this tag to retrieve. // * @return the data for the tag. // */ // public Object getValue(Tag tag, int index) { // return getValue(tag.getId(), index); // } /** * Gets a string tag from this list. * * @param tag the tag to retrieve. * @param index which element of the array of data for this tag to retrieve. * @return the data for the tag. */ public String getString(String tag, int index) { return getValue(tag, index).toString(); } // /** // * Gets a string tag from this list. // * // * @param tag the tag to retrieve. // * @param index which element of the array of data for this tag to retrieve. // * @return the data for the tag. // */ // public String getString(Tag tag, int index) { // return getString(tag.getId(), index); // } /** * Gets a numeric tag from this list. * * @param tag the tag to retrieve. * @param index which element of the array of data for this tag to retrieve. * @return the data for the tag. */ public Number getNumber(String tag, int index) { Object data = getValue(tag, index); if (!(data instanceof Number)) { throw new IllegalArgumentException("Tag [" + tag + "] is not a number"); } return (Number) data; } // /** // * Gets a numeric tag from this list. // * // * @param tag the tag to retrieve. // * @param index which element of the array of data for this tag to retrieve. // * @return the data for the tag. // */ // public Number getNumber(Tag tag, int index) { // return getNumber(tag.getId(), index); // } /** * Gets a list of all the tags contained in this list. * * @return a list of tag names. */ public List getTagNames() { final List list = new LinkedList(); GSTTAGLIST_API.gst_tag_list_foreach(this, new GstTagListAPI.TagForeachFunc() { public void callback(Pointer ptr, String tag, Pointer user_data) { list.add(tag); } }, null); return list; } /** * Merges this tag list and {@code list2} into a new list. If {@code list2} * is null, a copy of this list is returned. * * @param list2 the other tag list to merge with this one. * @param mode the {@link TagMergeMode}. * @return a new tag list. */ public TagList merge(TagList list2, TagMergeMode mode) { return GSTTAGLIST_API.gst_tag_list_merge(this, list2, mode); } /** * Gets the low level type for the tag. * * @param tag the tag * @return the type of {@code tag} */ private static GType getTagType(String tag) { GType type = MapHolder.tagTypeMap.get(tag); if (type != null) { return type; } MapHolder.tagTypeMap.put(tag, type = GSTTAG_API.gst_tag_get_type(tag)); return type; } private static interface TagGetter { Object get(TagList tl, String tag, int index); } // // Put the maps in a holder class so they don't get initialized until used. // This helps avoid calling gstreamer methods before Gst.init(). // private static final class MapHolder { private static final Map getterMap = new HashMap() { { put(GType.INT, new TagGetter() { public Object get(TagList tl, String tag, int index) { int[] value = {0}; GSTTAGLIST_API.gst_tag_list_get_int_index(tl, tag, index, value); return value[0]; } }); put(GType.UINT, new TagGetter() { public Object get(TagList tl, String tag, int index) { int[] value = {0}; GSTTAGLIST_API.gst_tag_list_get_uint_index(tl, tag, index, value); return value[0]; } }); put(GType.INT64, new TagGetter() { public Object get(TagList tl, String tag, int index) { long[] value = {0}; GSTTAGLIST_API.gst_tag_list_get_int64_index(tl, tag, index, value); return value[0]; } }); put(GType.DOUBLE, new TagGetter() { public Object get(TagList tl, String tag, int index) { double[] value = {0d}; GSTTAGLIST_API.gst_tag_list_get_double_index(tl, tag, index, value); return value[0]; } }); put(GType.STRING, new TagGetter() { public Object get(TagList tl, String tag, int index) { Pointer[] value = {null}; GSTTAGLIST_API.gst_tag_list_get_string_index(tl, tag, index, value); if (value[0] == null) { return null; } String ret = value[0].getString(0); GLIB_API.g_free(value[0]); return ret; } }); put(GType.valueOf(GDate.GTYPE_NAME), new TagGetter() { public Object get(TagList tl, String tag, int index) { PointerByReference value = new PointerByReference(); GSTTAGLIST_API.gst_tag_list_get_date_index(tl, tag, index, value); if (value.getValue() == null) { return null; } return Natives.objectFor(value.getValue(), GDate.class, false, true); } }); put(GType.valueOf(DateTime.GTYPE_NAME), new TagGetter() { public Object get(TagList tl, String tag, int index) { PointerByReference value = new PointerByReference(); GSTTAGLIST_API.gst_tag_list_get_date_time_index(tl, tag, index, value); if (value.getValue() == null) { return null; } return new DateTime(value.getValue(), false, true); } }); } }; static private final Map tagTypeMap = new ConcurrentHashMap(); } } ================================================ FILE: src/org/freedesktop/gstreamer/TagMergeMode.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2007 Wayne Meissner * Copyright (C) 2003 Benjamin Otte * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.NativeEnum; import org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue; /** * The different tag merging modes are basically replace, overwrite and append, * but they can be seen from two directions. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstTagList.html#GstTagMergeMode *

* Given two taglists: A - the one that are supplied to * gst_tag_setter_merge_tags() or gst_tag_setter_add_tags() and B - the tags * already in the element, how are the tags merged? In the table below this is * shown for the cases that a tag exists in the list (A) or does not exists (!A) * and combination thereof. */ public enum TagMergeMode implements NativeEnum { /** Undefined merge mode. */ @DefaultEnumValue UNDEFINED(0), /** Replace all tags (clear list and append). */ REPLACE_ALL(1), /** Replace tags */ REPLACE(2), /** Append tags */ APPEND(3), /** Prepend tags */ PREPEND(4), /** Keep existing tags */ KEEP(5), /** Keep all existing tags */ KEEP_ALL(6); private final int value; private TagMergeMode(int value) { this.value = value; } @Override public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/Version.java ================================================ /* * Copyright (c) 2021 Neil C Smith * Copyright (c) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; /** * Describes a GStreamer version. *

* Also upstream documentation at * https://gstreamer.freedesktop.org/documentation/gstreamer/gst.html#gst_version *

*/ public class Version { /** * The baseline version of GStreamer supported by these Java bindings. * Currently GStreamer 1.8. */ public static final Version BASELINE = new Version(1, 8); private final int major, minor, micro, nano; /** * Constructor for creating a Version with micro and nano set to zero. For * requesting version in {@link Gst#init(org.freedesktop.gstreamer.Version)} * prefer using {@link #of(int, int)}. *

* The library only supports major version 1 * * @param major Major version of GStreamer * @param minor Minor version of GStreamer */ public Version(int major, int minor) { this(major, minor, 0, 0); } /** * Constructor for creating a Version reflecting all aspects of the native * GStreamer version. *

* The library only supports major version 1 * * @param major Major version of GStreamer * @param minor Minor version of GStreamer * @param micro Micro (patch) version of GStreamer * @param nano Nano The nano version of GStreamer : Actual releases have 0, * GIT versions have 1, prerelease versions have 2 */ public Version(int major, int minor, int micro, int nano) { this.major = major; this.minor = minor; this.micro = micro; this.nano = nano; } /** * Gets a string representation of the version. * * @return a string representing the version. */ @Override public String toString() { return String.format("%d.%d.%d%s", major, minor, micro, nano == 1 ? " (CVS)" : nano >= 2 ? " (Pre-release)" : ""); } /** * Gets the major version of GStreamer. * * @return the major version. */ public int getMajor() { return major; } /** * Gets the minor version of GStreamer. * * @return the minor version. */ public int getMinor() { return minor; } /** * Gets the micro version of GStreamer. * * @return the micro version. */ public int getMicro() { return micro; } /** * Gets the nano version of GStreamer. Actual releases have 0, GIT versions * have 1, prerelease versions have 2 * * @return the nano version. */ public int getNano() { return nano; } /** * Check whether this version is equal to or greater than the passed in * version. Roughly comparable to GST_CHECK_VERSION * * @param required version to check against * @return true if this version satisfies the required version */ public boolean checkSatisfies(Version required) { return (major == required.major && minor > required.minor) || (major == required.major && minor == required.minor && micro >= required.micro); } /** * Create a Version with specified major and minor version, and micro and * nano version set to zero. Useful for specifying a required version in * {@link Gst#init(org.freedesktop.gstreamer.Version)}. *

* The library only supports major version 1 *

* Unlike the constructor this method will throw an exception if the version * is not greater or equal to {@link #BASELINE}, or the major version isn't * 1. * * @param major major version, currently must be 1 * @param minor minor version, greater or equal to 8 * @return requested version * @throws IllegalArgumentException if the requested version is invalid */ public static Version of(int major, int minor) { if (major == BASELINE.getMajor() && minor >= BASELINE.getMinor()) { return new Version(major, minor); } throw new IllegalArgumentException("Invalid version"); } } ================================================ FILE: src/org/freedesktop/gstreamer/controller/ARGBControlBinding.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.controller; import org.freedesktop.gstreamer.ControlBinding; import org.freedesktop.gstreamer.ControlSource; import org.freedesktop.gstreamer.GstObject; import org.freedesktop.gstreamer.glib.GObject; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstARGBControlBindingPtr; import org.freedesktop.gstreamer.lowlevel.GstControlSourcePtr; import org.freedesktop.gstreamer.lowlevel.GstDirectControlBindingPtr; import static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API; import org.freedesktop.gstreamer.lowlevel.GstObjectPtr; /** * Attachment for control sources to ARGB properties *

* A value mapping object that attaches multiple control sources to int GObject * properties representing colors. A control value of 0.0 will turn the color * component off and a value of 1.0 will be the color level. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstARGBControlBinding.html *

*/ public class ARGBControlBinding extends ControlBinding { public static final String GTYPE_NAME = "GstARGBControlBinding"; ARGBControlBinding(Initializer init) { this(new Handle( init.ptr.as(GstARGBControlBindingPtr.class, GstARGBControlBindingPtr::new), init.ownsHandle), init.needRef); } private ARGBControlBinding(Handle handle, boolean needRef) { super(handle, needRef); } /** * Create a new control-binding that attaches the given * {@link ControlSource} to the {@link GObject} property. * * @param object the object of the property * @param propertyName the property-name to attach the control source * @param controlSourceA the control source for the alpha channel * @param controlSourceR the control source for the red channel * @param controlSourceG the control source for the green channel * @param controlSourceB the control source for the blue channel * @return new ARGBControlBinding */ public static ARGBControlBinding create(GstObject object, String propertyName, ControlSource controlSourceA, ControlSource controlSourceR, ControlSource controlSourceG, ControlSource controlSourceB) { GstARGBControlBindingPtr ptr = GSTCONTROLLER_API.gst_argb_control_binding_new( Natives.getPointer(object).as(GstObjectPtr.class, GstObjectPtr::new), propertyName, controlSourcePtr(controlSourceA), controlSourcePtr(controlSourceR), controlSourcePtr(controlSourceG), controlSourcePtr(controlSourceB)); return new ARGBControlBinding(new Handle(ptr, true), false); } private static GstControlSourcePtr controlSourcePtr(ControlSource cs) { return cs == null ? null : Natives.getPointer(cs).as(GstControlSourcePtr.class, GstControlSourcePtr::new); } } ================================================ FILE: src/org/freedesktop/gstreamer/controller/Controllers.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.controller; import java.util.stream.Stream; import org.freedesktop.gstreamer.glib.NativeObject; import static org.freedesktop.gstreamer.glib.Natives.registration; /** * Controllers registration */ public class Controllers implements NativeObject.TypeProvider { @Override public Stream> types() { return Stream.of( registration(ARGBControlBinding.class, ARGBControlBinding.GTYPE_NAME, ARGBControlBinding::new), registration(DirectControlBinding.class, DirectControlBinding.GTYPE_NAME, DirectControlBinding::new), registration(ProxyControlBinding.class, ProxyControlBinding.GTYPE_NAME, ProxyControlBinding::new), registration(InterpolationControlSource.class, InterpolationControlSource.GTYPE_NAME, InterpolationControlSource::new), registration(TriggerControlSource.class, TriggerControlSource.GTYPE_NAME, TriggerControlSource::new), registration(LFOControlSource.class, LFOControlSource.GTYPE_NAME, LFOControlSource::new), registration(TimedValueControlSource.class, TimedValueControlSource.GTYPE_NAME, TimedValueControlSource::new) ); } } ================================================ FILE: src/org/freedesktop/gstreamer/controller/DirectControlBinding.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.controller; import org.freedesktop.gstreamer.ControlBinding; import org.freedesktop.gstreamer.ControlSource; import org.freedesktop.gstreamer.GstObject; import org.freedesktop.gstreamer.glib.GObject; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstControlSourcePtr; import org.freedesktop.gstreamer.lowlevel.GstDirectControlBindingPtr; import static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API; import org.freedesktop.gstreamer.lowlevel.GstObjectPtr; /** * Direct attachment for control sources. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstDirectControlBinding.html *

*/ public class DirectControlBinding extends ControlBinding { public static final String GTYPE_NAME = "GstDirectControlBinding"; DirectControlBinding(Initializer init) { this(new Handle( init.ptr.as(GstDirectControlBindingPtr.class, GstDirectControlBindingPtr::new), init.ownsHandle), init.needRef); } private DirectControlBinding(Handle handle, boolean needRef) { super(handle, needRef); } /** * Create a new control-binding that attaches the {@link ControlSource } to * the {@link GObject} property. It will map the control source range [0.0 * ... 1.0] to the full target property range, and clip all values outside * this range. * * @param object the object of the property * @param propertyName the property-name to attach the control source * @param controlSource the control source * @return new DirectControlBinding */ public static DirectControlBinding create(GstObject object, String propertyName, ControlSource controlSource) { GstDirectControlBindingPtr ptr = GSTCONTROLLER_API.gst_direct_control_binding_new( Natives.getPointer(object).as(GstObjectPtr.class, GstObjectPtr::new), propertyName, Natives.getPointer(controlSource).as(GstControlSourcePtr.class, GstControlSourcePtr::new)); return new DirectControlBinding(new Handle(ptr, true), false); } /** * Create a new control-binding that attaches the {@link ControlSource } to * the {@link GObject} property. It will directly map the control source * values to the target property range without any transformations. * * @param object the object of the property * @param propertyName the property-name to attach the control source * @param controlSource the control source * @return new DirectControlBinding */ public static DirectControlBinding createAbsolute(GstObject object, String propertyName, ControlSource controlSource) { GstDirectControlBindingPtr ptr = GSTCONTROLLER_API.gst_direct_control_binding_new_absolute( Natives.getPointer(object).as(GstObjectPtr.class, GstObjectPtr::new), propertyName, Natives.getPointer(controlSource).as(GstControlSourcePtr.class, GstControlSourcePtr::new)); return new DirectControlBinding(new Handle(ptr, true), false); } } ================================================ FILE: src/org/freedesktop/gstreamer/controller/InterpolationControlSource.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.controller; import org.freedesktop.gstreamer.ControlSource; import org.freedesktop.gstreamer.glib.NativeEnum; import org.freedesktop.gstreamer.lowlevel.GstInterpolationControlSourcePtr; import static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API; /** * Interpolation control source. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstInterpolationControlSource.html *

* InterpolationControlSource is a {@link ControlSource}, that interpolates * values between user-given control points. It supports several interpolation * modes and property types. *

* To use InterpolationControlSource create a new instance, bind it to a * GParamSpec and set some control points by calling {@link TimedValueControlSource#set(long, double) * }. *

* All functions are MT-safe. */ public class InterpolationControlSource extends TimedValueControlSource { public static final String GTYPE_NAME = "GstInterpolationControlSource"; /** * Create a new, unbound InterpolationControlSource. */ public InterpolationControlSource() { this(new Handle(GSTCONTROLLER_API.gst_interpolation_control_source_new(), true), false); } InterpolationControlSource(Initializer init) { this(new Handle( init.ptr.as(GstInterpolationControlSourcePtr.class, GstInterpolationControlSourcePtr::new), init.ownsHandle), init.needRef); } private InterpolationControlSource(Handle handle, boolean needRef) { super(handle, needRef); } /** * Interpolation mode to use. * * @param mode * @return this */ public InterpolationControlSource setMode(InterpolationMode mode) { set("mode", mode.intValue()); return this; } /** * Current interpolation mode. * * @return mode */ public InterpolationMode getMode() { Object val = get("mode"); if (val instanceof Integer) { int nativeInt = (Integer) val; return NativeEnum.fromInt(InterpolationMode.class, nativeInt); } return InterpolationMode.NONE; } private static class Handle extends TimedValueControlSource.Handle { public Handle(GstInterpolationControlSourcePtr ptr, boolean ownsHandle) { super(ptr, ownsHandle); } } } ================================================ FILE: src/org/freedesktop/gstreamer/controller/InterpolationMode.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.controller; import org.freedesktop.gstreamer.glib.NativeEnum; /** * The various interpolation modes available for use with * {@link InterpolationControlSource}. */ // https://gitlab.freedesktop.org/gstreamer/gstreamer/blob/master/libs/gst/controller/gstinterpolationcontrolsource.h#L64 public enum InterpolationMode implements NativeEnum { /** * Steps-like interpolation, default. */ NONE(0), /** * Linear interpolation. */ LINEAR(1), /** * Cubic interpolation (natural), may overshoot the min or max values set by * the control point, but is more 'curvy'. */ CUBIC(2), /** * Monotonic cubic interpolation, will not produce any values outside of the * min-max range set by the control points. */ CUBIC_MONOTONIC(3); private final int value; private InterpolationMode(int value) { this.value = value; } @Override public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/controller/LFOControlSource.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.controller; import org.freedesktop.gstreamer.ControlSource; import org.freedesktop.gstreamer.glib.NativeEnum; import static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API; import org.freedesktop.gstreamer.lowlevel.GstLFOControlSourcePtr; /** * LFO control source. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstLFOControlSource.html *

* LFOControlSource is a {@link ControlSource}, that provides several periodic * waveforms as control values. *

* To use InterpolationControlSource create a new instance, bind it to a * GParamSpec and set the relevant properties. *

* All functions are MT-safe. */ public class LFOControlSource extends ControlSource { public static final String GTYPE_NAME = "GstLFOControlSource"; /** * Create a new, unbound LFOControlSource. */ public LFOControlSource() { this(new Handle(GSTCONTROLLER_API.gst_lfo_control_source_new(), true), false); } LFOControlSource(Initializer init) { this(new Handle( init.ptr.as(GstLFOControlSourcePtr.class, GstLFOControlSourcePtr::new), init.ownsHandle), init.needRef); } private LFOControlSource(Handle handle, boolean needRef) { super(handle, needRef); } /** * Specifies the amplitude for the waveform of this LFOControlSource. *

* Allowed values: [0,1] *

* Default value: 1 * * @param value amplitude between 0 and 1 * @return this */ public LFOControlSource setAmplitude(double value) { set("amplitude", value); return this; } /** * Get the amplitude of the waveform. * * @return amplitude */ public double getAmplitude() { Object val = get("amplitude"); if (val instanceof Double) { return (double) val; } return 1; } /** * Specifies the frequency that should be used for the waveform of this * LFOControlSource. It should be large enough so that the period is longer * than one nanosecond. *

* Allowed values: >= {@link Double#MIN_VALUE } *

* Default value: 1 * * @param value frequency >= {@link Double#MIN_VALUE } * @return this */ public LFOControlSource setFrequency(double value) { set("frequency", value); return this; } /** * Get the frequency of the waveform. * * @return amplitude */ public double getFrequency() { Object val = get("frequency"); if (val instanceof Double) { return (double) val; } return 1; } /** * Specifies the value offset for the waveform of this LFOControlSource. *

* Allowed values: [0,1] *

* Default value: 1 * * @param value offset between 0 and 1 * @return this */ public LFOControlSource setOffset(double value) { set("offset", value); return this; } /** * Get the value offset of the waveform. * * @return offset */ public double getOffset() { Object val = get("offset"); if (val instanceof Double) { return (double) val; } return 1; } /** * Specifies the timeshift to the right that should be used for the waveform * of this LFOControlSource in nanoseconds. *

* Default value: 0 * * @param value timeshift in nanoseconds * @return this */ public LFOControlSource setTimeshift(long value) { set("timeshift", value); return this; } /** * Get the timeshift of the waveform. * * @return timeshift */ public long getTimeshift() { Object val = get("timeshift"); if (val instanceof Long) { return (long) val; } return 1; } /** * Specifies the waveform that should be used for this LFOControlSource. *

* Default value: {@link LFOWaveform#SINE } * * @param value waveform * @return this */ public LFOControlSource setWaveform(LFOWaveform value) { set("waveform", value.intValue()); return this; } /** * Get the waveform. * * @return waveform */ public LFOWaveform getWaveform() { Object val = get("waveform"); if (val instanceof Integer) { int nativeInt = (Integer) val; return NativeEnum.fromInt(LFOWaveform.class, nativeInt); } return LFOWaveform.SINE; } private static class Handle extends ControlSource.Handle { public Handle(GstLFOControlSourcePtr ptr, boolean ownsHandle) { super(ptr, ownsHandle); } } } ================================================ FILE: src/org/freedesktop/gstreamer/controller/LFOWaveform.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.controller; import org.freedesktop.gstreamer.glib.NativeEnum; /** * The various waveform modes available for use with {@link LFOControlSource} */ // https://gitlab.freedesktop.org/gstreamer/gstreamer/blob/master/libs/gst/controller/gstlfocontrolsource.h#L60 public enum LFOWaveform implements NativeEnum { /** * Sine waveform. */ SINE(0), /** * Square waveform. */ SQUARE(1), /** * Saw waveform. */ SAW(2), /** * Reverse saw waveform. */ REVERSE_SAW(3), /** * Triangle waveform. */ TRIANGLE(4) ; private final int value; private LFOWaveform(int value) { this.value = value; } @Override public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/controller/ProxyControlBinding.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.controller; import org.freedesktop.gstreamer.ControlBinding; import org.freedesktop.gstreamer.Gst; import org.freedesktop.gstreamer.GstObject; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API; import org.freedesktop.gstreamer.lowlevel.GstObjectPtr; import org.freedesktop.gstreamer.lowlevel.GstProxyControlBindingPtr; /** * Attachment for forwarding control sources *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/gstreamer-libs-GstProxyControlBinding.html *

*/ @Gst.Since(minor = 12) public class ProxyControlBinding extends ControlBinding { public static final String GTYPE_NAME = "GstProxyControlBinding"; ProxyControlBinding(Initializer init) { this(new Handle( init.ptr.as(GstProxyControlBindingPtr.class, GstProxyControlBindingPtr::new), init.ownsHandle), init.needRef); } private ProxyControlBinding(Handle handle, boolean needRef) { super(handle, needRef); } /** * Create a ProxyControlBinding that forwards all access to data or * syncValues() requests from propertyName on object to the control * binding at refPropertyName on refObject . * * @param object the object of the property * @param propertyName the property-name to attach the control source * @param refObject a GstObject to forward all ControlBinding requests to * @param refPropertyName the property name in refObject to control * @return new ProxyControlBinding */ @Gst.Since(minor = 12) public static ProxyControlBinding create(GstObject object, String propertyName, GstObject refObject, String refPropertyName) { GstProxyControlBindingPtr ptr = GSTCONTROLLER_API.gst_proxy_control_binding_new( Natives.getPointer(object).as(GstObjectPtr.class, GstObjectPtr::new), propertyName, Natives.getPointer(refObject).as(GstObjectPtr.class, GstObjectPtr::new), refPropertyName); return new ProxyControlBinding(new Handle(ptr, true), false); } } ================================================ FILE: src/org/freedesktop/gstreamer/controller/TimedValueControlSource.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.controller; import java.util.ArrayList; import java.util.List; import org.freedesktop.gstreamer.ControlSource; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GList; import static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API; import org.freedesktop.gstreamer.lowlevel.GstTimedValueControlSourcePtr; /** * Timed value control source base class. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstTimedValueControlSource.html *

* Base class for {@link ControlSource} that use time-stamped values. *

* When overriding bind, chain up first to give this bind implementation a * chance to setup things. *

* All functions are MT-safe. */ public class TimedValueControlSource extends ControlSource { public static final String GTYPE_NAME = "GstTimedValueControlSource"; private final Handle handle; protected TimedValueControlSource(Handle handle, boolean needRef) { super(handle, needRef); this.handle = handle; } TimedValueControlSource(Initializer init) { this(new Handle( init.ptr.as(GstTimedValueControlSourcePtr.class, GstTimedValueControlSourcePtr::new), init.ownsHandle), init.needRef); } /** * Set the value of given controller-handled property at a certain time. * * @param timestamp the time the control-change is scheduled for * @param value the control value * @return false if the value could not be set */ public boolean set(long timestamp, double value) { return GSTCONTROLLER_API.gst_timed_value_control_source_set( handle.getPointer(), timestamp, value); } /** * Sets multiple timed values at once. * * @param timedValues a list of {@link TimedValue} * @return false if the values could not be set */ public boolean setFromList(List timedValues) { for (TimedValue timedvalue : timedValues) { boolean ok = set(timedvalue.timestamp, timedvalue.value); if (!ok) { return false; } } return true; } /** * Returns a copy of the list of {@link TimedValue} for the given property. * * @return a list of TimedValue */ public List getAll() { GList next = GSTCONTROLLER_API.gst_timed_value_control_source_get_all(handle.getPointer()); List list = new ArrayList<>(); while (next != null) { if (next.data != null) { list.add(new TimedValue(next.data.getLong(0), next.data.getDouble(Long.BYTES))); } next = next.next(); } return list; } /** * Used to remove the value of given controller-handled property at a * certain time. * * @param timestamp the time the control-change should be removed from * @return FALSE if the value couldn't be unset (i.e. not found) */ public boolean unset(long timestamp) { return GSTCONTROLLER_API.gst_timed_value_control_source_unset( handle.getPointer(), timestamp); } /** * Used to remove all time-stamped values of given controller-handled * property. */ public void unsetAll() { GSTCONTROLLER_API.gst_timed_value_control_source_unset_all(handle.getPointer()); } /** * Get the number of control points that are set. * * @return the number of control points that are set */ public int getCount() { return GSTCONTROLLER_API.gst_timed_value_control_source_get_count(handle.getPointer()); } /** * Reset the controlled value cache. */ public void invalidateCache() { GSTCONTROLLER_API.gst_timed_value_control_invalidate_cache(handle.getPointer()); } protected static class Handle extends ControlSource.Handle { public Handle(GstTimedValueControlSourcePtr ptr, boolean ownsHandle) { super(ptr, ownsHandle); } @Override protected GstTimedValueControlSourcePtr getPointer() { return (GstTimedValueControlSourcePtr) super.getPointer(); } } } ================================================ FILE: src/org/freedesktop/gstreamer/controller/TriggerControlSource.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.controller; import org.freedesktop.gstreamer.ControlSource; import org.freedesktop.gstreamer.glib.NativeEnum; import org.freedesktop.gstreamer.lowlevel.GstInterpolationControlSourcePtr; import static org.freedesktop.gstreamer.lowlevel.GstControllerAPI.GSTCONTROLLER_API; import org.freedesktop.gstreamer.lowlevel.GstTriggerControlSourcePtr; /** * Trigger control source. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstTriggerControlSource.html *

* TriggerControlSource is a {@link ControlSource}, that returns values from * user-given control points. It allows for a tolerance on time-stamps. *

* To use TriggerControlSource create a new instance, bind it to a GParamSpec * and set some control points by calling * {@link TimedValueControlSource#set(long, double)}. *

* All functions are MT-safe. */ public class TriggerControlSource extends TimedValueControlSource { public static final String GTYPE_NAME = "GstTriggerControlSource"; /** * Create a new, unbound InterpolationControlSource. */ public TriggerControlSource() { this(new Handle(GSTCONTROLLER_API.gst_trigger_control_source_new(), true), false); } TriggerControlSource(Initializer init) { this(new Handle( init.ptr.as(GstTriggerControlSourcePtr.class, GstTriggerControlSourcePtr::new), init.ownsHandle), init.needRef); } private TriggerControlSource(Handle handle, boolean needRef) { super(handle, needRef); } /** * Amount of nanoseconds a control time can be off to still trigger. *

* Allowed values: >= 0 *

* Default value: 0 * * @param tolerance in nanoseconds * @return this */ public TriggerControlSource setTolerance(long tolerance) { set("tolerance", tolerance); return this; } /** * Current tolerance in nanoseconds. * * @return tolerance in nanoseconds */ public long getTolerance() { Object val = get("tolerance"); if (val instanceof Long) { return (long) val; } return 0L; } private static class Handle extends TimedValueControlSource.Handle { public Handle(GstTriggerControlSourcePtr ptr, boolean ownsHandle) { super(ptr, ownsHandle); } } } ================================================ FILE: src/org/freedesktop/gstreamer/device/Device.java ================================================ /* * * Copyright (c) 2019 Neil C Smith * Copyright (c) 2015 Andres Colubri * Copyright (C) 2013 Olivier Crete * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.device; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.Element; import org.freedesktop.gstreamer.GstObject; import org.freedesktop.gstreamer.Structure; import static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API; import static org.freedesktop.gstreamer.lowlevel.GstDeviceAPI.GSTDEVICE_API; /** * Devices are objects representing a device, they contain relevant metadata * about the device, such as its class and the GstCaps representing the media * types it can produce or handle. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstDevice.html *

* Device objects are created by {@link DeviceProvider} objects, which can be * aggregated by {@link DeviceMonitor} objects. */ public class Device extends GstObject { public static final String GTYPE_NAME = "GstDevice"; Device(Initializer init) { super(init); } /** * Creates the element with all of the required parameters set to use this * device. * * @param name name of new element, or NULL to automatically create a unique * name * @return a new {@link Element} configured to use this device. */ public Element createElement(String name) { return GSTDEVICE_API.gst_device_create_element(this, name); } /** * Get the {@link Caps} that this device supports. * * @return The Caps supported by this device. */ public Caps getCaps() { return GSTDEVICE_API.gst_device_get_caps(this); } /** * Gets the "class" of a device. This is a "/" separated list of classes * that represent this device. They are a subset of the classes of the * {@link DeviceProvider} that produced this device. * * @return class the device class */ public String getDeviceClass() { Pointer ptr = GSTDEVICE_API.gst_device_get_device_class(this); String ret = ptr.getString(0); GLIB_API.g_free(ptr); return ret; } /** * Gets the user-friendly name of the device. * * @return name of the device */ public String getDisplayName() { Pointer ptr = GSTDEVICE_API.gst_device_get_display_name(this); String ret = ptr.getString(0); GLIB_API.g_free(ptr); return ret; } /** * Check if device matches all of the given classes. * * @param classes a "/"-separated list of device classes to match, only * match if all classes are matched * @return true if device matches */ public boolean hasClasses(String classes) { return GSTDEVICE_API.gst_device_has_classes(this, classes); } /** * Check if device matches all of the given classes. * * @param classes an array of classes to match, only match if all classes * are matched. * @return true if device matches */ public boolean hasClasses(String[] classes) { return GSTDEVICE_API.gst_device_has_classesv(this, classes); } /** * Tries to reconfigure an existing element to use the device. If this * function fails, then one must destroy the element and create a new one * using {@link #createElement(java.lang.String) } *

* Note: This should only be implemented for elements can change their * device in the PLAYING state. * * @param element the element to be configured * @return true if the element could be reconfigured to use this device */ public boolean reconfigureElement(Element element) { return GSTDEVICE_API.gst_device_reconfigure_element(this, element); } /** * Gets the extra properties of a device. * * @return The extra properties or NULL when there are none. */ public Structure getProperties() { return GSTDEVICE_API.gst_device_get_properties(this); } } ================================================ FILE: src/org/freedesktop/gstreamer/device/DeviceMonitor.java ================================================ /* * * Copyright (c) 2019 Neil C Smith * Copyright (c) 2015 Andres Colubri * Copyright (C) 2013 Olivier Crete * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.device; import java.util.ArrayList; import java.util.List; import org.freedesktop.gstreamer.Bus; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.GstObject; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GList; import static org.freedesktop.gstreamer.lowlevel.GstDeviceMonitorAPI.GSTDEVICEMONITOR_API; /** * A device monitor and prober *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstDeviceMonitor.html *

* Applications should create a DeviceMonitor when they want to probe, list and * monitor devices of a specific type. The DeviceMonitor will create the * appropriate {@link DeviceProvider} objects and manage them. It will then post * messages on its {@link Bus} for devices that have been added and removed. *

* The device monitor will monitor all devices matching the filters that the * application has set. */ public class DeviceMonitor extends GstObject { public static final String GTYPE_NAME = "GstDeviceMonitor"; public DeviceMonitor() { super(Natives.initializer(GSTDEVICEMONITOR_API.ptr_gst_device_monitor_new(), false, true)); } DeviceMonitor(Initializer init) { super(init); } /** * Get the {@link Bus} for this DeviceMonitor * * @return bus */ public Bus getBus() { return GSTDEVICEMONITOR_API.gst_device_monitor_get_bus(this); } /** * Adds a filter for which devices will be monitored, any device that * matches all these classes and the {@link Caps} will be returned. *

* If this function is called multiple times to add more filters, each will * be matched independently. That is, adding more filters will not further * restrict what devices are matched. *

* The GstCaps supported by the device as returned by gst_device_get_caps() * are not intersected with caps filters added using this function. *

* Filters must be added before the GstDeviceMonitor is started. * * @param classes device classes to use as filter or NULL for any class. * @param caps the GstCaps to filter or NULL for ANY. * @return id the id of the new filter or 0 if no provider matched the * filter's classes. */ public int addFilter(String classes, Caps caps) { return GSTDEVICEMONITOR_API.gst_device_monitor_add_filter(this, classes, caps); } /** * Remove a filter from the DeviceMonitor using the id that was returned * from {@link #addFilter(java.lang.String, org.freedesktop.gstreamer.Caps) * } * * @param filterId of filter to remove * @return true if the filter id was valid and the filter was removed */ public boolean removeFilter(int filterId) { return GSTDEVICEMONITOR_API.gst_device_monitor_remove_filter(this, filterId); } /** * Starts monitoring the devices, once this has succeeded, the * GST_MESSAGE_DEVICE_ADDED and GST_MESSAGE_DEVICE_REMOVED messages will be * emitted on the bus when the list of devices changes. * * @return true if the device monitoring could be started */ public boolean start() { return GSTDEVICEMONITOR_API.gst_device_monitor_start(this); } /** * Stop monitoring devices. */ public void stop() { GSTDEVICEMONITOR_API.gst_device_monitor_stop(this); } /** * Gets a list of devices from all of the relevant monitors. This may * actually probe the hardware if the monitor is not currently started. * * @return list of {@link Device} */ public List getDevices() { GList glist = GSTDEVICEMONITOR_API.gst_device_monitor_get_devices(this); List list = new ArrayList<>(); GList next = glist; while (next != null) { if (next.data != null) { Device dev = new Device(Natives.initializer(next.data, false, true)); list.add(dev); } next = next.next(); } return list; } } ================================================ FILE: src/org/freedesktop/gstreamer/device/DeviceProvider.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2015 Andres Colubri * Copyright (C) 2013 Olivier Crete * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.device; import java.util.ArrayList; import java.util.List; import org.freedesktop.gstreamer.Bus; import org.freedesktop.gstreamer.GstObject; import org.freedesktop.gstreamer.Plugin; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GType; import org.freedesktop.gstreamer.lowlevel.GlibAPI; import org.freedesktop.gstreamer.lowlevel.GstDeviceProviderAPI; import static org.freedesktop.gstreamer.lowlevel.GstDeviceProviderAPI.GSTDEVICEPROVIDER_API; /** * A device provider. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/gstreamer-GstDeviceProvider.html *

* A DeviceProvider subclass is provided by a plugin that handles devices if * there is a way to programatically list connected devices. It can also * optionally provide updates to the list of connected devices. *

* Each DeviceProvider subclass is a singleton, a plugin should normally provide * a single subclass for all devices. *

* Applications would normally use a {@link DeviceMonitor} to monitor devices * from all relevant providers. */ public class DeviceProvider extends GstObject { public static final String GTYPE_NAME = "GstDeviceProvider"; DeviceProvider(Initializer init) { super(init); } /** * Whether the provider can monitor. * * @return true if the provider can monitor */ public boolean canMonitor() { return GSTDEVICEPROVIDER_API.gst_device_provider_can_monitor(this); } // /** // * Set key with value as metadata in klass. // * // * @param klass class to set metadata for // * @param key the key to set // * @param value the value to set // */ // public void addMetadata(GstDeviceProviderAPI.GstDeviceProviderClass klass, String key, String value) { // GSTDEVICEPROVIDER_API.gst_device_provider_class_add_metadata(klass, key, value); // } // // /** // * Get metadata with key in klass. // * // * @param klass class to get metadata for // * @param key the key to get // * @return the metadata for key // */ // public String getMetadata(GstDeviceProviderAPI.GstDeviceProviderClass klass, String key) { // return GSTDEVICEPROVIDER_API.gst_device_provider_class_get_metadata(klass, key); // } // public void setMetadata(GstDeviceProviderAPI.GstDeviceProviderClass klass, // String longname, String classification, String description, String author) { // GSTDEVICEPROVIDER_API.gst_device_provider_class_set_metadata(klass, longname, classification, description, author); // } // public void add(Device device) { // GSTDEVICEPROVIDER_API.gst_device_provider_device_add(this, device); // } // // public void remove(Device device) { // GSTDEVICEPROVIDER_API.gst_device_provider_device_remove(this, device); // } /** * Get the {@link Bus} of this DeviceProvider * * @return bus */ public Bus getBus() { return GSTDEVICEPROVIDER_API.gst_device_provider_get_bus(this); } /** * Gets a list of {@link Device} that this provider understands. This may * actually probe the hardware if the provider is not currently started. * * @return device list */ public List getDevices() { GlibAPI.GList glist = GSTDEVICEPROVIDER_API.gst_device_provider_get_devices(this); List list = new ArrayList(); GlibAPI.GList next = glist; while (next != null) { if (next.data != null) { Device dev = new Device(Natives.initializer(next.data, true, true)); list.add(dev); } next = next.next(); } return list; } /** * Retrieves the factory that was used to create this device provider. * * @return the {@link DeviceProviderFactory} used for creating this device * provider. */ public DeviceProviderFactory getFactory() { return GSTDEVICEPROVIDER_API.gst_device_provider_get_factory(this); } // @TODO rethink this to not require GType // /** // * Create a new device providerfactory capable of instantiating objects of // * the type and add the factory to plugin. // * // * @param plugin {@link Plugin} to register the device provider with, or NULL for a static device provider. // * @param name name of device providers of this type // * @param rank rank of device provider (higher rank means more importance when autoplugging) // * @param type // * @return // */ // public boolean register(Plugin plugin, String name, int rank, GType type) { // return GSTDEVICEPROVIDER_API.gst_device_provider_register(plugin, name, rank, type); // } /** * Starts providering the devices. This will cause GST_MESSAGE_DEVICE_ADDED * and GST_MESSAGE_DEVICE_REMOVED messages to be posted on the provider's * bus when devices are added or removed from the system. *

* Since the DeviceProvider is a singleton, start may already have been * called by another user of the object, {@link #stop() } needs to be called * the same number of times. * * @return true if the device providering could be started. */ public boolean start() { return GSTDEVICEPROVIDER_API.gst_device_provider_start(this); } /** * Decreases the use-count by one. If the use count reaches zero, this * DeviceProvider will stop providering the devices. This needs to be called * the same number of times that {@link #start() } was called. */ public void stop() { GSTDEVICEPROVIDER_API.gst_device_provider_stop(this); } } ================================================ FILE: src/org/freedesktop/gstreamer/device/DeviceProviderFactory.java ================================================ /* * Copyright (c) 2025 Neil C Smith * Copyright (c) 2015 Andres Colubri * Copyright (C) 2013 Olivier Crete * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.device; import java.util.ArrayList; import java.util.List; import org.freedesktop.gstreamer.GstObject; import org.freedesktop.gstreamer.PluginFeature.Rank; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GList; import static org.freedesktop.gstreamer.lowlevel.GstDeviceProviderFactoryAPI.GSTDEVICEPROVIDERFACTORY_API; import org.freedesktop.gstreamer.lowlevel.GstPluginAPI; /** * A factory for {@link DeviceProvider} *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstDeviceProviderFactory.html *

* DeviceProviderFactory is used to create instances of device providers. A * DeviceProviderfactory can be added to a Plugin as it is also a PluginFeature. * * Use the {@link #find(java.lang.String)} and * {@link #get()} functions to create device provider * instances or use {@link #getByName(java.lang.String)} as a convenient * shortcut. */ public class DeviceProviderFactory extends GstObject { public static final String GTYPE_NAME = "GstDeviceProviderFactory"; DeviceProviderFactory(Initializer init) { super(init); } /** * Returns the {@link DeviceProvider} of the type defined by the given * device provider factory. * * @return DeviceProvider or NULL if the device provider couldn't be * created. */ public DeviceProvider get() { return GSTDEVICEPROVIDERFACTORY_API.gst_device_provider_factory_get(this); } /** * Get the metadata on factory with key. * * @param key * @return the metadata with key on factory or null when there was no * metadata with the given key . */ public String getMetadata(String key) { return GSTDEVICEPROVIDERFACTORY_API.gst_device_provider_factory_get_metadata(this, key); } // @TODO List ?? // public String[] getMetadataKeys() { // return GSTDEVICEPROVIDERFACTORY_API.gst_device_provider_factory_get_metadata_keys(this); // } /** * Check if factory matches all of the given classes * * @param classes a "/" separate list of classes to match, only match if all * classes are matched. * @return true if factory matches */ public boolean hasClasses(String classes) { return GSTDEVICEPROVIDERFACTORY_API.gst_device_provider_factory_has_classes(this, classes); } // public boolean hasClasses(String[] classes) { // return GSTDEVICEPROVIDERFACTORY_API.gst_device_provider_factory_has_classesv(this, classes); // } /** * Search for an device provider factory of the given name. * * @param name name of factory to find * @return DeviceProviderFactory if found, or null */ public static DeviceProviderFactory find(String name) { return GSTDEVICEPROVIDERFACTORY_API.gst_device_provider_factory_find(name); } /** * Returns the device provider of the type defined by the given device * provider factory. * * @param factoryName a named factory to instantiate * @return DeviceProvider or NULL if the device provider couldn't be * created. */ public static DeviceProvider getByName(String factoryName) { return GSTDEVICEPROVIDERFACTORY_API.gst_device_provider_factory_get_by_name(factoryName); } /** * Get a list of factories with a rank greater or equal to minrank . The * list of factories is returned by decreasing rank. * @param minRank minimum rank * @return a list of */ public static List getDeviceProviders(Rank minRank) { GList glist = GSTDEVICEPROVIDERFACTORY_API.gst_device_provider_factory_list_get_device_providers(minRank); List list = new ArrayList<>(); GList next = glist; while (next != null) { if (next.data != null) { DeviceProviderFactory factory = new DeviceProviderFactory(Natives.initializer(next.data, true, true)); list.add(factory); } next = next.next(); } GstPluginAPI.GSTPLUGIN_API.gst_plugin_list_free(glist); return list; } // public GType getDeviceProviderType() { // return GSTDEVICEPROVIDERFACTORY_API.gst_device_provider_factory_get_device_provider_type(this); // } } ================================================ FILE: src/org/freedesktop/gstreamer/elements/AppSink.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2016 Christophe Lafolet * Copyright (c) 2009 Levente Farkas * Copyright (c) 2009 Wayne Meissner * Copyright (c) 2008 Wayne Meissner * Copyright (C) 2007 David Schleef * (C) 2008 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.elements; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.Element; import org.freedesktop.gstreamer.FlowReturn; import org.freedesktop.gstreamer.Sample; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback; import static org.freedesktop.gstreamer.lowlevel.AppAPI.APP_API; /** * A sink {@link Element} that provides an easy way for applications to extract * samples from a pipeline. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-libs/html/gst-plugins-base-libs-appsink.html *

* Appsink is a sink plugin that supports many different methods for making the * application get a handle on the GStreamer data in a pipeline. Unlike most * GStreamer elements, Appsink provides external API functions. *

* The normal way of retrieving samples from appsink is by using the * {@link #pullSample()} and {@link #pullPreroll()} methods. These methods block * until a sample becomes available in the sink or when the sink is shut down or * reaches EOS. (TODO - not currently mapped in the Java bindings. * There are also timed variants of these methods, * gst_app_sink_try_pull_sample() and gst_app_sink_try_pull_preroll(), which * accept a timeout parameter to limit the amount of time to wait). *

* Appsink will internally use a queue to collect buffers from the streaming * thread. If the application is not pulling samples fast enough, this queue * will consume a lot of memory over time. The "max-buffers" property can be * used to limit the queue size. The "drop" property controls whether the * streaming thread blocks or if older buffers are dropped when the maximum * queue size is reached. Note that blocking the streaming thread can negatively * affect real-time performance and should be avoided. *

* If a blocking behaviour is not desirable, setting the "emit-signals" property * to TRUE will make appsink emit the "new-sample" and "new-preroll" signals * when a sample can be pulled without blocking. *

* The "caps" property on appsink can be used to control the formats that * appsink can receive. This property can contain non-fixed caps, the format of * the pulled samples can be obtained by getting the sample caps. *

* If one of the pull-preroll or pull-sample methods return NULL, the appsink is * stopped or in the EOS state. You can check for the EOS state with the "eos" * property or with the {@link #isEOS()} method. *

* The eos signal can also be used to be informed when the EOS state is reached * to avoid polling. */ public class AppSink extends BaseSink { public static final String GST_NAME = "appsink"; public static final String GTYPE_NAME = "GstAppSink"; AppSink(Initializer init) { super(init); } public AppSink(String name) { this(makeRawElement(GST_NAME, name)); } /** * Sets the {@link Caps} on the AppSink. *

* After calling this method, the sink will only accept Caps that match * caps. If caps is non-fixed, you must check the caps on * the buffers to get the actual used caps. * * @param caps the Caps to set. */ @Override public void setCaps(Caps caps) { APP_API.gst_app_sink_set_caps(this, caps); } /** * Gets the {@link Caps} configured on this AppSink * * @return the Caps accepted by this sink */ public Caps getCaps() { return APP_API.gst_app_sink_get_caps(this); } /** * Check if this AppSink is EOS, which is when no more samples can be pulled * because an EOS event was received. *

* This function also returns TRUE when the AppSink is not in the PAUSED or * PLAYING state. * * @return true if no more buffers can be pulled and this AppSink is EOS. */ public boolean isEOS() { return APP_API.gst_app_sink_is_eos(this); } /** * Get the last preroll {@link Sample}. This was the Sample that caused the * AppSink to preroll in the PAUSED state. *

* This function is typically used when dealing with a pipeline in the * PAUSED state. Calling this function after doing a seek will give the * sample right after the seek position. *

* Calling this function will clear the internal reference to the preroll * buffer. *

* Note that the preroll sample will also be returned as the first sample * when calling {@link #pullSample() } *

* If an EOS event was received before any buffers, this function returns * NULL. Use {@link #isEOS() } to check for the EOS condition. *

* This function blocks until a preroll sample or EOS is received or the * AppSink element is set to the READY/NULL state. * * @return a Sample, or null if the AppSink is stopped or EOS */ public Sample pullPreroll() { return APP_API.gst_app_sink_pull_preroll(this); } /** * This function blocks until a {@link Sample} or EOS becomes available or * the AppSink element is set to the READY/NULL state. *

* This function will only return samples when the AppSink is in the PLAYING * state. All rendered buffers will be put in a queue so that the * application can pull samples at its own rate. Note that when the * application does not pull samples fast enough, the queued buffers could * consume a lot of memory, especially when dealing with raw video frames. *

* If an EOS event was received before any buffers, this function returns * NULL. Use {@link #isEOS() } to check for the EOS condition. * * @return a Sample, or null if the AppSink is stopped or EOS */ public Sample pullSample() { return APP_API.gst_app_sink_pull_sample(this); } /** * Signal emitted when this {@link AppSink} got EOS. */ public static interface EOS { /** * EOS signal * * @param elem AppSink */ public void eos(AppSink elem); } /** * Adds a listener for the eos signal. * * @param listener */ public void connect(final EOS listener) { connect(EOS.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(AppSink elem) { listener.eos(elem); } }); } /** * Removes a listener for the eos signal * * @param listener The listener that was previously added. */ public void disconnect(EOS listener) { disconnect(EOS.class, listener); } /** * Signal emitted when this {@link AppSink} when a new Sample is ready. */ public static interface NEW_SAMPLE { /** * New Sample signal * * @param elem AppSink * @return FlowReturn */ public FlowReturn newSample(AppSink elem); } /** * Adds a listener for the new-sample signal. If a blocking * behaviour is not desirable, setting the "emit-signals" property to TRUE * will make appsink emit the "new-sample" and "new-preroll" signals when a * buffer can be pulled without blocking. * * @param listener */ public void connect(final NEW_SAMPLE listener) { connect(NEW_SAMPLE.class, listener, new GstCallback() { @SuppressWarnings("unused") public FlowReturn callback(AppSink elem) { return listener.newSample(elem); } }); } /** * Removes a listener for the new-sample signal * * @param listener a listener that was previously added. */ public void disconnect(NEW_SAMPLE listener) { disconnect(NEW_SAMPLE.class, listener); } /** * Signal emitted when this {@link AppSink} when a new buffer is ready. */ public static interface NEW_PREROLL { /** * New preroll signal * * @param elem AppSink * @return FlowReturn */ public FlowReturn newPreroll(AppSink elem); } /** * Adds a listener for the new-preroll signal. If a blocking * behaviour is not desirable, setting the "emit-signals" property to TRUE * will make appsink emit the "new-buffer" and "new-preroll" signals when a * buffer can be pulled without blocking. * * @param listener */ public void connect(final NEW_PREROLL listener) { connect(NEW_PREROLL.class, listener, new GstCallback() { @SuppressWarnings("unused") public FlowReturn callback(AppSink elem) { return listener.newPreroll(elem); } }); } /** * Removes a listener for the new-preroll signal * * @param listener The listener that was previously added. */ public void disconnect(NEW_PREROLL listener) { disconnect(NEW_PREROLL.class, listener); } } ================================================ FILE: src/org/freedesktop/gstreamer/elements/AppSrc.java ================================================ /* * Copyright (c) 2025 Neil C Smith * Copyright (c) 2009 Andres Colubri * Copyright (c) 2008 Wayne Meissner * Copyright (C) 2007 David Schleef * (C) 2008 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.elements; import org.freedesktop.gstreamer.Buffer; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.Element; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback; import static org.freedesktop.gstreamer.lowlevel.AppAPI.APP_API; import com.sun.jna.ptr.LongByReference; import org.freedesktop.gstreamer.FlowReturn; import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.glib.NativeEnum; /** * A source {@link Element} that provides an easy way for applications to insert * data into a GStreamer pipeline. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-libs/html/gst-plugins-base-libs-appsrc.html *

* Before operating appsrc, the {@link Caps} property must be set to fixed caps * describing the format of the data that will be pushed with appsrc. An * exception to this is when pushing buffers with unknown caps, in which case no * caps should be set. This is typically true of file-like sources that push raw * byte buffers. If you don't want to explicitly set the caps, you can use * gst_app_src_push_sample (not yet mapped). This method gets the caps * associated with the sample and sets them on the appsrc replacing any * previously set caps (if different from sample's caps). *

* The main way of handing data to the appsrc element is by calling the * {@link #pushBuffer(Buffer) } method or by emitting the push-buffer action * signal. This will put the buffer onto a queue from which appsrc will read * from in its streaming thread. It is important to note that data transport * will not happen from the thread that performed the push-buffer call. *

* The "max-bytes" property controls how much data can be queued in appsrc * before appsrc considers the queue full. A filled internal queue will always * signal the "enough-data" signal, which signals the application that it should * stop pushing data into appsrc. The "block" property will cause appsrc to * block the push-buffer method until free data becomes available again. *

* When the internal queue is running out of data, the "need-data" signal is * emitted, which signals the application that it should start pushing more data * into appsrc. *

* In addition to the "need-data" and "enough-data" signals, appsrc can emit the * "seek-data" signal when the "stream-mode" property is set to "seekable" or * "random-access". The signal argument will contain the new desired position in * the stream expressed in the unit set with the "format" property. After * receiving the seek-data signal, the application should push-buffers from the * new position. *

* These signals allow the application to operate the appsrc in two different * ways: *

* The push mode, in which the application repeatedly calls the * push-buffer/push-sample method with a new buffer/sample. Optionally, the * queue size in the appsrc can be controlled with the enough-data and need-data * signals by respectively stopping/starting the push-buffer/push-sample calls. * This is a typical mode of operation for the stream-type "stream" and * "seekable". Use this mode when implementing various network protocols or * hardware devices. *

* The pull mode, in which the need-data signal triggers the next push-buffer * call. This mode is typically used in the "random-access" stream-type. Use * this mode for file access or other randomly accessable sources. In this mode, * a buffer of exactly the amount of bytes given by the need-data signal should * be pushed into appsrc. *

* In all modes, the size property on appsrc should contain the total stream * size in bytes. Setting this property is mandatory in the random-access mode. * For the stream and seekable modes, setting this property is optional but * recommended. *

* When the application has finished pushing data into appsrc, it should call * {@link #endOfStream() } or emit the end-of-stream action signal. After this * call, no more buffers can be pushed into appsrc until a flushing seek occurs * or the state of the appsrc has gone through READY. */ public class AppSrc extends BaseSrc { public static final String GST_NAME = "appsrc"; public static final String GTYPE_NAME = "GstAppSrc"; AppSrc(Initializer init) { super(init); } public AppSrc(String name) { this(makeRawElement(GST_NAME, name)); } /** * Set the capabilities on the appsrc element. This function takes a copy of * the caps structure. After calling this method, the source will only * produce caps that match caps . caps must be fixed and the caps on the * buffers must match the caps or left NULL. */ @Override public void setCaps(Caps caps) { APP_API.gst_app_src_set_caps(this, caps); } /** * Get the configured Caps on the AppSrc. * * @return the caps */ public Caps getCaps() { return APP_API.gst_app_src_get_caps(this); } /** * Set the size of the stream in bytes. A value of -1 means that the size is * not known. * * @param size the size to set, or -1 if not known */ public void setSize(long size) { APP_API.gst_app_src_set_size(this, size); } /** * Get the size of the stream in bytes. A value of -1 means that the size is * not known. * * @return the size of the stream, or -1 if not specified */ public long getSize() { return APP_API.gst_app_src_get_size(this); } /** * Set the stream type on appsrc . For seekable streams, the "seek" signal * must be connected to. * * @param type stream type */ public void setStreamType(AppSrc.StreamType type) { APP_API.gst_app_src_set_stream_type(this, type); } /** * Get the stream type set on the appsrc. * * @return stream type */ public AppSrc.StreamType getStreamType() { return APP_API.gst_app_src_get_stream_type(this); } /** * Set the maximum amount of bytes that can be queued in appsrc . After the * maximum amount of bytes are queued, appsrc will emit the "enough-data" * signal. * * @param max number of bytes to queue */ public void setMaxBytes(long max) { APP_API.gst_app_src_set_max_bytes(this, max); } /** * Get the maximum number of bytes that can be queued. * * @return maximum number of bytes */ public long getMaxBytes() { return APP_API.gst_app_src_get_max_bytes(this); } /** * Configure the min and max latency in src . If min is set to -1, the * default latency calculations for pseudo-live sources will be used. * * @param min the minimum latency * @param max the maximum latency */ public void setLatency(long min, long max) { APP_API.gst_app_src_set_latency(this, min, max); } /** * Get the latency. The returned value is a long array of length two, with * min latency at index 0 and max latency at index 1. * * @return values as {@code long[]{min, max} } */ public long[] getLatency() { LongByReference minRef = new LongByReference(); LongByReference maxRef = new LongByReference(); APP_API.gst_app_src_get_latency(this, minRef, minRef); return new long[]{minRef.getValue(), maxRef.getValue()}; } /** * Adds a buffer to the queue of buffers that the appsrc element will push * to its source pad. This function takes ownership of the buffer. *

* When the block property is TRUE, this function can block until free space * becomes available in the queue. * * @param buffer a {@link Buffer} to push * @return GST_FLOW_OK when the buffer was successfully queued. * GST_FLOW_FLUSHING when appsrc is not PAUSED or PLAYING. GST_FLOW_EOS when * EOS occurred. */ public FlowReturn pushBuffer(Buffer buffer) { return APP_API.gst_app_src_push_buffer(this, buffer); } /** * Indicates to the appsrc element that the last buffer queued in the * element is the last buffer of the stream. * * @return GST_FLOW_OK when the EOS was successfuly queued. GST_FLOW_FLUSHING when * appsrc is not PAUSED or PLAYING. */ public FlowReturn endOfStream() { return APP_API.gst_app_src_end_of_stream(this); } /** * Signal that the source has enough data. It is recommended that the * application stops calling push-buffer until the need-data signal is * emitted again to avoid excessive buffer queueing. */ public static interface ENOUGH_DATA { /** * Enough data signal * * @param elem the appsrc element that emitted the signal */ public void enoughData(AppSrc elem); } /** * Adds a listener for the enough-data signal * * @param listener Listener to be called this when appsrc fills its queue. */ public void connect(final ENOUGH_DATA listener) { connect(ENOUGH_DATA.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(AppSrc elem) { listener.enoughData(elem); } }); } /** * Removes a listener for the enough-data signal * * @param listener The listener that was previously added. */ public void disconnect(ENOUGH_DATA listener) { disconnect(ENOUGH_DATA.class, listener); } /** * Signal that the source needs more data. In the callback or from another * thread you should call push-buffer or end-of-stream. *

* length is just a hint and when it is set to -1, any number of bytes can * be pushed into appsrc . *

* You can call push-buffer multiple times until the enough-data signal is * fired. */ public static interface NEED_DATA { /** * Need data signal * * @param elem the appsrc element that emitted the signal * @param size the amount of bytes needed, or -1. This is just a hint. */ public void needData(AppSrc elem, int size); } /** * Adds a listener for the need-data signal * * @param listener Listener to be called when appsrc needs data. */ public void connect(final NEED_DATA listener) { connect(NEED_DATA.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(AppSrc elem, int size) { listener.needData(elem, size); } }); } /** * Removes a listener for the need-data signal * * @param listener The listener that was previously added. */ public void disconnect(NEED_DATA listener) { disconnect(NEED_DATA.class, listener); } /** * Seek to the given offset, expressed in terms of the {@link Format} set on * the AppSrc. The next push-buffer should produce buffers from the new * offset . This callback is only called for seekable stream types. */ public static interface SEEK_DATA { /** * Seek data signal. * * @param elem the appsrc element that emitted the signal * @param position the offset to seek to, expressed in the * {@link Format} set on the AppSrc * @return true if the seek succeeded */ public boolean seekData(AppSrc elem, long position); } /** * Adds a listener for the seek-data signal * * @param listener listener to be called when a seek is requested */ public void connect(final SEEK_DATA listener) { connect(SEEK_DATA.class, listener, new GstCallback() { @SuppressWarnings("unused") public boolean callback(AppSrc elem, long position) { return listener.seekData(elem, position); } }); } /** * Removes a listener for the seek-data signal * * @param listener The listener that was previously added. */ public void disconnect(SEEK_DATA listener) { disconnect(SEEK_DATA.class, listener); } /** * The stream type. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-libs/html/gst-plugins-base-libs-appsrc.html#GstAppStreamType *

*/ public enum StreamType implements NativeEnum { /** * No seeking is supported in the stream, such as a live stream. */ STREAM(0), /** * The stream is seekable but seeking might not be very fast, such as * data from a webserver. */ SEEKABLE(1), /** * The stream is seekable and seeking is fast, such as in a local file. */ RANDOM_ACCESS(2); private final int value; private StreamType(int value) { this.value = value; } @Override public int intValue() { return value; } } } ================================================ FILE: src/org/freedesktop/gstreamer/elements/BaseSink.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.elements; import org.freedesktop.gstreamer.Element; /** * A base class for sink elements. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstBaseSink.html *

*/ public class BaseSink extends Element { public static final String GTYPE_NAME = "GstBaseSink"; protected BaseSink(Initializer init) { super(init); } // @TODO review - all properties are available by set / get mechanism // some other methods require the preroll lock, but we don't have a way to // access. Methods for subclasses should probably be protected. // public FlowReturn doPreroll(MiniObject obj) { // return BASESINK_API.gst_base_sink_do_preroll(this, obj); // } // // public FlowReturn waitPreroll() { // return BASESINK_API.gst_base_sink_wait_preroll(this); // } // // public void setSync(boolean sync) { // BASESINK_API.gst_base_sink_set_sync(this, sync); // } // // public boolean isSync() { // return BASESINK_API.gst_base_sink_get_sync(this); // } // // public void setMaximumLateness(long lateness, TimeUnit units) { // BASESINK_API.gst_base_sink_set_max_lateness(this, units.toNanos(lateness)); // } // // public long getMaximumLateness(TimeUnit units) { // return units.convert(BASESINK_API.gst_base_sink_get_max_lateness(this), TimeUnit.NANOSECONDS); // } // // public void setQOSEnabled(boolean qos) { // BASESINK_API.gst_base_sink_set_qos_enabled(this, qos); // } // // public boolean isQOSEnabled() { // return BASESINK_API.gst_base_sink_is_qos_enabled(this); // } // // public void enableAsync(boolean enabled) { // BASESINK_API.gst_base_sink_set_async_enabled(this, enabled); // } // // public boolean isAsync() { // return BASESINK_API.gst_base_sink_is_async_enabled(this); // } // // public void setTsOffset(long offset) { // BASESINK_API.gst_base_sink_set_ts_offset(this, offset); // } // // public long getTsOffset() { // return BASESINK_API.gst_base_sink_get_ts_offset(this); // } // // public Buffer getLastBuffer() { // return BASESINK_API.gst_base_sink_get_last_buffer(this); // } // // public void enableLastBuffer(boolean enable) { // BASESINK_API.gst_base_sink_set_last_buffer_enabled(this, enable); // } // // public boolean isLastBufferEnabled() { // return BASESINK_API.gst_base_sink_is_last_buffer_enabled(this); // } // // public boolean queryLatency(boolean live, boolean upstream_live, ClockTime min_latency, ClockTime max_latency) { // return BASESINK_API.gst_base_sink_query_latency(this, live, upstream_live, min_latency, max_latency); // } // // public ClockTime getLatency() { // return BASESINK_API.gst_base_sink_get_latency(this); // } // // public void setRenderDelay(ClockTime delay) { // BASESINK_API.gst_base_sink_set_render_delay(this, delay); // } // // public ClockTime getRenderDelay() { // return BASESINK_API.gst_base_sink_get_render_delay(this); // } // // public void setBlocksize(int blocksize) { // BASESINK_API.gst_base_sink_set_blocksize(this, blocksize); // } // // public int getBlocksize() { // return BASESINK_API.gst_base_sink_get_blocksize(this); // } // // public ClockReturn waitClock(ClockTime time, /* GstClockTimeDiff */ Pointer jitter) { // return BASESINK_API.gst_base_sink_wait_clock(this, time, jitter); // } // // public FlowReturn waitEOS(ClockTime time, /* GstClockTimeDiff */ Pointer jitter) { // return BASESINK_API.gst_base_sink_wait_eos(this, time, jitter); // } // @TODO work out strategy for overriding methods // // /** // * Signal emitted when this {@link BaseSink} received a {@link ProposeAllocation} query. // * // * @see #setProposeAllocationHandler(ProposeAllocationHandler) // */ // public static interface ProposeAllocationHandler { // public boolean proposeAllocation(BaseSink sink, AllocationQuery query); // } // // /** // * Set a handler for the {@link ProposeAllocation} query on this sink // * // * @param handler The handler to be called when a {@link ProposeAllocation} is received. // */ // public void setProposeAllocationHandler(final ProposeAllocationHandler handler) { // GstBaseSinkStruct struct = new GstBaseSinkStruct(handle()); // struct.readField("element"); // GstBaseSinkClass basesinkClass = new GstBaseSinkClass(struct.element.object.object.g_type_instance.g_class.getPointer()); // basesinkClass.propose_allocation = new ProposeAllocation() { // @Override // public boolean callback(BaseSink sink, AllocationQuery query) { // return handler.proposeAllocation(sink, query); // } // }; // basesinkClass.writeField("propose_allocation"); // } } ================================================ FILE: src/org/freedesktop/gstreamer/elements/BaseSrc.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.elements; import org.freedesktop.gstreamer.Element; /** * A base class for source elements. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstBaseSrc.html *

*/ public class BaseSrc extends Element { public static final String GTYPE_NAME = "GstBaseSrc"; protected BaseSrc(Initializer init) { super(init); } // @TODO review - all properties are available by set / get mechanism // some other methods require the stream lock, but we don't have a way to // access. Methods for subclasses should probably be protected. // public FlowReturn waitPlaying() { // return gst().gst_base_src_wait_playing(this); // } // public void setLive(boolean live) { // gst().gst_base_src_set_live(this, live); // } // public boolean isLive() { // return gst().gst_base_src_is_live(this); // } // public void setFormat(Format format) { // gst().gst_base_src_set_format(this, format); // } // public boolean queryLatency(boolean[] live, ClockTime[] min_latency, ClockTime[] max_latency) { // return gst().gst_base_src_query_latency(this, live, min_latency, max_latency); // } // public void setBlocksize(long blocksize) { // gst().gst_base_src_set_blocksize(this, blocksize); // } // public long getBlocksize() { // return gst().gst_base_src_get_blocksize(this); // } // public void setTimestamp(boolean timestamp) { // gst().gst_base_src_set_do_timestamp(this, timestamp); // } // public boolean getTimestamp() { // return gst().gst_base_src_get_do_timestamp(this); // } // public boolean newSeamlessSegment(long start, long stop, long position) { // return gst().gst_base_src_new_seamless_segment(this, start, stop, position); // } // } ================================================ FILE: src/org/freedesktop/gstreamer/elements/BaseTransform.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2009 Levente Farkas * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.elements; import org.freedesktop.gstreamer.Element; /** * A base class for simple transform filters. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer-libs/html/GstBaseTransform.html *

*/ public class BaseTransform extends Element { public static final String GTYPE_NAME = "GstBaseTransform"; protected BaseTransform(Initializer init) { super(init); } } ================================================ FILE: src/org/freedesktop/gstreamer/elements/DecodeBin.java ================================================ /* * Copyright (c) 2025 Neil C Smith * Copyright (c) 2016 Christophe Lafolet * Copyright (c) 2010 DHoyt * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.elements; import java.util.ArrayList; import java.util.List; import java.util.Optional; import org.freedesktop.gstreamer.Bin; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.Element; import org.freedesktop.gstreamer.ElementFactory; import org.freedesktop.gstreamer.Pad; import org.freedesktop.gstreamer.glib.NativeEnum; import org.freedesktop.gstreamer.query.Query; import org.freedesktop.gstreamer.lowlevel.GValueAPI.GValueArray; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback; import org.freedesktop.gstreamer.lowlevel.GType; import org.freedesktop.gstreamer.lowlevel.GValueAPI; /** * A {@link Bin} that auto-magically constructs a decoding pipeline using * available decoders and demuxers via auto-plugging. *

* {@link URIDecodeBin} uses DecodeBin internally and is often more convenient * to use, as it creates a suitable source element as well. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-plugins/html/gst-plugins-base-plugins-decodebin.html *

*/ public class DecodeBin extends Bin { public static final String GST_NAME = "decodebin"; public static final String GTYPE_NAME = "GstDecodeBin"; /** * Creates a new DecodeBin. * * @param name The name used to identify this DecodeBin. */ public DecodeBin(String name) { super(makeRawElement(GST_NAME, name)); } DecodeBin(Initializer init) { super(init); } /** * Signal is emitted when a pad for which there is no further possible * decoding is added to the {@link DecodeBin}. */ public static interface UNKNOWN_TYPE { /** * @param element The element which has the new Pad. * @param pad the new Pad. * @param caps the caps of the pad that cannot be resolved. */ public void unknownType(DecodeBin element, Pad pad, Caps caps); } /** * Adds a listener for the unknown-type signal * * @param listener Listener to be called */ public void connect(final UNKNOWN_TYPE listener) { connect(UNKNOWN_TYPE.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(DecodeBin elem, Pad pad, Caps caps) { listener.unknownType(elem, pad, caps); } }); } /** * Removes a listener for the unknown-type signal * * @param listener The listener that was previously added. */ public void disconnect(UNKNOWN_TYPE listener) { disconnect(UNKNOWN_TYPE.class, listener); } /** * Signal is emitted when a pad for which there is no further possible * decoding is added to the {@link DecodeBin}. */ public static interface AUTOPLUG_CONTINUE { /** * Autoplug continue signal. * * @param element The element which has the new Pad. * @param pad the new Pad. * @param caps the caps of the pad that cannot be resolved. * @return TRUE if you wish decodebin to look for elements that can * handle the given caps . If FALSE, those caps will be considered as * final and the pad will be exposed as such (see 'pad-added' signal of * {@link Element}). */ public boolean autoplugContinue(DecodeBin element, Pad pad, Caps caps); } /** * Adds a listener for the autoplug-continue signal * * @param listener Listener to be called */ public void connect(final AUTOPLUG_CONTINUE listener) { connect(AUTOPLUG_CONTINUE.class, listener, new GstCallback() { @SuppressWarnings("unused") public boolean callback(DecodeBin elem, Pad pad, Caps caps) { return listener.autoplugContinue(elem, pad, caps); } }); } /** * Removes a listener for the autoplug-continue signal * * @param listener The listener that was previously added. */ public void disconnect(AUTOPLUG_CONTINUE listener) { disconnect(AUTOPLUG_CONTINUE.class, listener); } /** * This function is emitted when an array of possible factories for caps on * pad is needed. {@link DecodeBin} will by default return an array with all * compatible factories, sorted by rank. *

* If this function returns {@link Optional#empty()}, pad will be exposed as * a final caps. *

* If this function returns an empty list, the pad will be considered as * having an unhandled type media type. */ public static interface AUTOPLUG_FACTORIES { /** * @param element The element which has the new Pad. * @param pad the new Pad. * @param caps the caps of the pad that cannot be resolved. * @return */ public Optional> autoplugFactories(DecodeBin element, Pad pad, Caps caps); } /** * Adds a listener for the autoplug-factories signal * * @param listener Listener to be called */ public void connect(final AUTOPLUG_FACTORIES listener) { connect(AUTOPLUG_FACTORIES.class, listener, new GstCallback() { @SuppressWarnings("unused") public GValueArray callback(DecodeBin elem, Pad pad, Caps caps) { Optional> factories = listener.autoplugFactories(elem, pad, caps); return factories.map(list -> { GValueArray array = new GValueArray(list.size(), false); list.forEach(factory -> array.append(new GValueAPI.GValue(GType.OBJECT, factory))); return array; }).orElse(null); } }); } /** * Removes a listener for the autoplug-factories signal * * @param listener The listener that was previously added. */ public void disconnect(AUTOPLUG_FACTORIES listener) { disconnect(AUTOPLUG_FACTORIES.class, listener); } /** * Once {@link DecodeBin} has found the possible ElementFactory objects to * try for caps on pad, this signal is emitted. The purpose of the signal is * for the application to perform additional sorting or filtering on the * element factory array. * * The callee should copy and modify factories. */ public static interface AUTOPLUG_SORT { /** * Autoplug sort * * @param element The element which has the new Pad * @param pad the new Pad * @param caps the caps of the pad that cannot be resolved * @param factories A List of possible {@link ElementFactory} to use * @return resorted list or {@link Optional#empty()} */ public Optional> autoplugSort( DecodeBin element, Pad pad, Caps caps, List factories); } /** * Adds a listener for the autoplug-sort signal * * @param listener Listener to be called */ public void connect(final AUTOPLUG_SORT listener) { connect(AUTOPLUG_SORT.class, listener, new GstCallback() { @SuppressWarnings("unused") public GValueArray callback(DecodeBin elem, Pad pad, Caps caps, GValueArray factories) { int size = factories.getNValues(); List list = new ArrayList<>(size); for (int i = 0; i < size; i++) { Object factory = factories.getValue(i); if (factory instanceof ElementFactory) { list.add((ElementFactory) factory); } } Optional> response = listener.autoplugSort(elem, pad, caps, list); return response.map(l -> { GValueArray array = new GValueArray(l.size(), false); list.forEach(factory -> array.append(new GValueAPI.GValue(GType.OBJECT, factory))); return array; }).orElse(null); } }); } /** * Removes a listener for the autoplug-sort signal * * @param listener The listener that was previously added. */ public void disconnect(AUTOPLUG_SORT listener) { disconnect(AUTOPLUG_SORT.class, listener); } public enum AutoplugSelectResult implements NativeEnum { TRY(0), EXPOSE(1), SKIP(2); AutoplugSelectResult(final int value) { this.value = value; } /** * Gets the integer value of the enum. * * @return The integer value for this enum. */ @Override public int intValue() { return value; } private final int value; } /** * Once {@link DecodeBin} has found the possible ElementFactory objects to * try for caps on pad, this signal is emitted. The purpose of the signal is * for the application to perform additional filtering on the element * factory array. *

* The signal handler should return a {@link AutoplugSelectResult} value * indicating what decodebin should do next. *

* A value of {@link AutoplugSelectResult#TRY} will try to autoplug an * element from factory. *

* A value of {@link AutoplugSelectResult#EXPOSE} will expose pad without * plugging any element to it. *

* A value of {@link AutoplugSelectResult#SKIP} will skip factory and move * to the next factory. */ public static interface AUTOPLUG_SELECT { /** * @param element The decodebin * @param pad the new Pad * @param caps the caps of the pad * @param factory the {@link ElementFactory} to use * @return an {@link AutoplugSelectResult} that indicates the required * operation. the default handler will always return * {@link AutoplugSelectResult#TRY} */ public AutoplugSelectResult autoplugSelect(final DecodeBin element, final Pad pad, final Caps caps, final ElementFactory factory); } /** * Adds a listener for the autoplug-select signal * * @param listener Listener to be called */ public void connect(final AUTOPLUG_SELECT listener) { connect(AUTOPLUG_SELECT.class, listener, new GstCallback() { @SuppressWarnings("unused") public AutoplugSelectResult callback(final DecodeBin elem, final Pad pad, final Caps caps, final ElementFactory factory) { return listener.autoplugSelect(elem, pad, caps, factory); } }); } /** * Removes a listener for the autoplug-select signal * * @param listener The listener that was previously added. */ public void disconnect(final AUTOPLUG_SELECT listener) { disconnect(AUTOPLUG_SELECT.class, listener); } /** * This signal is emitted whenever an autoplugged element that is not linked * downstream yet and not exposed does a query. It can be used to tell the * element about the downstream supported caps for example.. */ public static interface AUTOPLUG_QUERY { /** * @param element the decodebin. * @param pad the pad. * @param child the child element doing the query * @param query the query. */ public boolean autoplugQuery(DecodeBin element, Pad pad, Element child, Query query); } /** * Adds a listener for the autoplug-query signal * * @param listener Listener to be called */ public void connect(final AUTOPLUG_QUERY listener) { connect(AUTOPLUG_QUERY.class, listener, new GstCallback() { @SuppressWarnings("unused") public boolean callback(DecodeBin elem, Pad pad, Element child, Query query) { return listener.autoplugQuery(elem, pad, child, query); } }); } /** * Removes a listener for the autoplug-query signal * * @param listener The listener that was previously added. */ public void disconnect(AUTOPLUG_QUERY listener) { disconnect(AUTOPLUG_QUERY.class, listener); } /** * This signal is emitted once {@link DecodeBin} has finished decoding all * the data. */ public static interface DRAINED { /** * @param element The element */ public void drained(DecodeBin element); } /** * Adds a listener for the drained signal * * @param listener Listener to be called */ public void connect(final DRAINED listener) { connect(DRAINED.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(DecodeBin elem) { listener.drained(elem); } }); } /** * Removes a listener for the drained signal * * @param listener The listener that was previously added. */ public void disconnect(DRAINED listener) { disconnect(DRAINED.class, listener); } } ================================================ FILE: src/org/freedesktop/gstreamer/elements/Elements.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.elements; import java.util.stream.Stream; import org.freedesktop.gstreamer.glib.NativeObject; import static org.freedesktop.gstreamer.glib.Natives.registration; /** * * @author Neil C Smith - https://www.neilcsmith.net */ public class Elements implements NativeObject.TypeProvider { @Override public Stream> types() { return Stream.of( registration(AppSink.class, AppSink.GTYPE_NAME, AppSink::new), registration(AppSrc.class, AppSrc.GTYPE_NAME, AppSrc::new), registration(BaseSrc.class, BaseSrc.GTYPE_NAME, BaseSrc::new), registration(BaseSink.class, BaseSink.GTYPE_NAME, BaseSink::new), registration(BaseTransform.class, BaseTransform.GTYPE_NAME, BaseTransform::new), registration(DecodeBin.class, DecodeBin.GTYPE_NAME, DecodeBin::new), registration(PlayBin.class, PlayBin.GTYPE_NAME, PlayBin::new), registration(URIDecodeBin.class, URIDecodeBin.GTYPE_NAME, URIDecodeBin::new)); } } ================================================ FILE: src/org/freedesktop/gstreamer/elements/PlayBin.java ================================================ /* * Copyright (c) 2021 Neil C Smith * Copyright (c) 2014 Tom Greenwood * Copyright (c) 2009 Andres Colubri * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.elements; import java.io.File; import java.net.URI; import java.util.EnumSet; import java.util.Set; import org.freedesktop.gstreamer.Bus; import org.freedesktop.gstreamer.Element; import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.Gst; import org.freedesktop.gstreamer.Pad; import org.freedesktop.gstreamer.Pipeline; import org.freedesktop.gstreamer.TagList; import org.freedesktop.gstreamer.glib.NativeFlags; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback; /** *

* Playbin provides a stand-alone everything-in-one abstraction for an audio * and/or video player. *

* See upstream documentation at * https://gstreamer.freedesktop.org/documentation/playback/playbin.html *

*

* It can handle both audio and video files and features *

*
    *
  • * automatic file type recognition and based on that automatic selection and * usage of the right audio/video/subtitle demuxers/decoders *
  • *
  • * visualisations for audio files *
  • *
  • * subtitle support for video files. Subtitles can be store in external files. *
  • *
  • * stream selection between different video/audio/subtitles streams *
  • *
  • * meta info (tag) extraction *
  • *
  • * easy access to the last video frame *
  • *
  • * buffering when playing streams over a network *
  • *
  • * volume control with mute option *
  • *
*

* playbin is a {@link Pipeline}. It will notify the application of everything * that's happening (errors, end of stream, tags found, state changes, etc.) by * posting messages on its {@link Bus}. The application needs to watch the bus. *

* Playback can be initiated by setting the playbin to PLAYING state using * {@link #setState setState} or {@link #play play}. Note that the state change * will take place in the background in a separate thread, when the function * returns playback is probably not happening yet and any errors might not have * occured yet. Applications using playbin should ideally be written to deal * with things completely asynchroneous. *

* When playback has finished (an EOS message has been received on the bus) or * an error has occured (an ERROR message has been received on the bus) or the * user wants to play a different track, playbin should be set back to READY or * NULL state, then the input file/URI should be set to the new location and * then playbin be set to PLAYING state again. *

* Seeking can be done using {@link #seek seek} on the playbin element. Again, * the seek will not be executed instantaneously, but will be done in a * background thread. When the seek call returns the seek will most likely still * be in process. An application may wait for the seek to finish (or fail) using * {@link #getState(long)} with -1 as the timeout, but this will block the user * interface and is not recommended at all. *

* Applications may query the current position and duration of the stream via * {@link #queryPosition} and {@link #queryDuration} and setting the format * passed to {@link Format#TIME}. If the query was successful, the duration or * position will have been returned in units of nanoseconds. */ public class PlayBin extends Pipeline { public static final String GST_NAME = "playbin"; public static final String GTYPE_NAME = "GstPlayBin"; /** * Creates a new PlayBin. * * @param name The name used to identify this pipeline. */ public PlayBin(String name) { this(makeRawElement(GST_NAME, name)); } /** * Creates a new PlayBin. * * @param name The name used to identify this pipeline. * @param uri The URI of the media file to load. */ public PlayBin(String name, URI uri) { this(name); setURI(uri); } /** * Creates a new PlayBin proxy. * * @param init proxy initialization args * */ PlayBin(Initializer init) { super(init); } /** * Sets the media file to play. * * @param file The {@link java.io.File} to play. */ public void setInputFile(File file) { setURI(file.toURI()); } /** * Sets the media URI to play. * * @param uri The {@link java.net.URI} to play. */ public void setURI(URI uri) { set("uri", uri); } /** * Sets the audio output Element. *

* To disable audio output, call this method with a null argument. * * @param element The element to use for audio output. */ public void setAudioSink(Element element) { setElement("audio-sink", element); } /** * Sets the video output Element. *

* To disable video output, call this method with a null argument. * * @param element The element to use for video output. */ public void setVideoSink(Element element) { setElement("video-sink", element); } /** * Sets the text output Element. *

* To disable text output, call this method with a null argument. * * @param element The element to use for text output. */ public void setTextSink(Element element) { setElement("text-sink", element); } /** * Sets the visualization output Element. * * @param element The element to use for visualization. */ public void setVisualization(Element element) { setElement("vis-plugin", element); } /** * Sets an output {@link Element} on the PlayBin. * * @param key The name of the output to change. * @param element The Element to set as the output. */ private void setElement(String key, Element element) { set(key, element); } /** * Set the flags to control the behaviour of this PlayBin. *

* The default value is * soft-colorbalance+deinterlace+soft-volume+text+audio+video *

* See individual {@link PlayFlags} value descriptions for more information. * * @param flags set of {@link PlayFlags} */ public void setFlags(Set flags) { set("flags", NativeFlags.toInt(flags)); } /** * Get the current flags set on this PlayBin. The returned set will be * writable so that it can be altered and passed back to * {@link #setFlags(java.util.Set)}. * * @return set of current {@link PlayFlags} */ public Set getFlags() { Object flags = get("flags"); if (flags instanceof Number) { return NativeFlags.fromInt(PlayFlags.class, ((Number) flags).intValue()); } else { return EnumSet.noneOf(PlayFlags.class); } } /** * Sets the audio playback volume. * * @param volume value between 0.0 and 1.0 with 1.0 being full volume. */ public void setVolume(double volume) { set("volume", Math.max(Math.min(volume, 1d), 0d)); } /** * Gets the current volume. * * @return The current volume as a percentage between 0 and 100 of the max * volume. */ public double getVolume() { return ((Number) get("volume")).doubleValue(); } /** * Get the currently playing audio stream. By default the first audio stream * with data is played. Default value: -1 * * @return the currently playing audio stream index (index is zero based). */ public int getCurrentAudio() { return (Integer) get("current-audio"); } /** * Set the currently playing audio stream. By default the first audio stream * with data is played. * * @param n audio stream index to switch to (index is zero based). */ public void setCurrentAudio(int n) { set("current-audio", n); } /** * Get the total number of available audio streams. * * @return total number of available audio streams */ public int getNAudio() { return (Integer) get("n-audio"); } /** * Retrieve the stream-combiner sinkpad for a specific text stream. This pad * can be used for notifications of caps changes, stream-specific queries, * etc. * * @param audioStreamIndex a text stream number * @return a GstPad, or NULL when the stream number does not exist. */ public Pad getAudioPad(int audioStreamIndex) { return emit(Pad.class, "get-audio-pad", audioStreamIndex); } /** * Retrieve the tags of a specific audio stream number. This information can * be used to select a stream. * * @param audioStreamIndex an audio stream number * @return a GstTagList with tags or {@code null} when the stream number * does not exist. */ public TagList getAudioTags(int audioStreamIndex) { return emit(TagList.class, "get-audio-tags", audioStreamIndex); } /** * Get the currently playing text stream. By default the first text stream * with data is played. Default value: -1 * * @return the currently playing text stream index (index is zero based). */ public int getCurrentText() { return (Integer) get("current-text"); } /** * Set the currently playing text stream. By default the first text stream * with data is played. * * @param n text stream index to switch to (index is zero based). */ public void setCurrentText(int n) { set("current-text", n); } /** * Get the total number of available text streams. * * @return total number of available text streams */ public int getNText() { return (Integer) get("n-text"); } /** * Retrieve the stream-combiner sinkpad for a specific text stream. This pad * can be used for notifications of caps changes, stream-specific queries, * etc. * * @param textStreamIndex a text stream number * @return a GstPad, or {@code null} when the stream number does not exist. */ public Pad getTextPad(int textStreamIndex) { return emit(Pad.class, "get-text-pad", textStreamIndex); } /** * Retrieve the tags of a specific text stream number. This information can * be used to select a stream. * * @param textStreamIndex a text stream number * @return a GstTagList with tags or {@code null} when the stream number * does not exist. */ public TagList getTextTags(int textStreamIndex) { return emit(TagList.class, "get-text-tags", textStreamIndex); } /** * Adds a listener for the about-to-finish signal */ public void connect(final ABOUT_TO_FINISH listener) { connect(ABOUT_TO_FINISH.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(PlayBin elem) { listener.aboutToFinish(elem); } }); } /** * Removes a listener for the about-to-finish signal * * @param listener The listener that was previously added. */ public void disconnect(ABOUT_TO_FINISH listener) { disconnect(ABOUT_TO_FINISH.class, listener); } /** * Adds a listener for the video-changed signal */ public void connect(final VIDEO_CHANGED listener) { connect(VIDEO_CHANGED.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(PlayBin elem) { listener.videoChanged(elem); } }); } /** * Removes a listener for the video-changed signal * * @param listener The listener that was previously added. */ public void disconnect(VIDEO_CHANGED listener) { disconnect(VIDEO_CHANGED.class, listener); } /** * Adds a listener for the audio-changed signal */ public void connect(final AUDIO_CHANGED listener) { connect(AUDIO_CHANGED.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(PlayBin elem) { listener.audioChanged(elem); } }); } /** * Removes a listener for the audio-changed signal * * @param listener The listener that was previously added. */ public void disconnect(AUDIO_CHANGED listener) { disconnect(AUDIO_CHANGED.class, listener); } /** * Adds a listener for the audio-changed signal */ public void connect(final TEXT_CHANGED listener) { connect(TEXT_CHANGED.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(PlayBin elem) { listener.textChanged(elem); } }); } /** * Removes a listener for the text-changed signal * * @param listener The listener that was previously added. */ public void disconnect(TEXT_CHANGED listener) { disconnect(TEXT_CHANGED.class, listener); } /** * Adds a listener for the video-tags-changed signal */ public void connect(final VIDEO_TAGS_CHANGED listener) { connect(VIDEO_TAGS_CHANGED.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(PlayBin elem, int stream) { listener.videoTagsChanged(elem, stream); } }); } /** * Removes a listener for the video-tags-changed signal * * @param listener The listener that was previously added. */ public void disconnect(VIDEO_TAGS_CHANGED listener) { disconnect(VIDEO_TAGS_CHANGED.class, listener); } /** * Adds a listener for the audio-tags-changed signal */ public void connect(final AUDIO_TAGS_CHANGED listener) { connect(AUDIO_TAGS_CHANGED.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(PlayBin elem, int stream) { listener.audioTagsChanged(elem, stream); } }); } /** * Removes a listener for the audio-tags-changed signal * * @param listener The listener that was previously added. */ public void disconnect(AUDIO_TAGS_CHANGED listener) { disconnect(AUDIO_TAGS_CHANGED.class, listener); } /** * Adds a listener for the audio-tags-changed signal */ public void connect(final TEXT_TAGS_CHANGED listener) { connect(TEXT_TAGS_CHANGED.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(PlayBin elem, int stream) { listener.textTagsChanged(elem, stream); } }); } /** * Removes a listener for the text-tags-changed signal * * @param listener The listener that was previously added. */ public void disconnect(TEXT_TAGS_CHANGED listener) { disconnect(TEXT_TAGS_CHANGED.class, listener); } /** * Add a listener for the element-setup signal. * * @param listener listener to add */ @Gst.Since(minor = 10) public void connect(final ELEMENT_SETUP listener) { Gst.checkVersion(1, 10); connect(ELEMENT_SETUP.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(PlayBin playbin, Element element) { listener.elementSetup(playbin, element); } }); } /** * Remove listener for the element-setup signal. * * @param listener listener to remove */ @Gst.Since(minor = 10) public void disconnect(ELEMENT_SETUP listener) { disconnect(ELEMENT_SETUP.class, listener); } /** * Add a listener for the source-setup signal. * * @param listener listener to add */ public void connect(final SOURCE_SETUP listener) { connect(SOURCE_SETUP.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(PlayBin playbin, Element element) { listener.sourceSetup(playbin, element); } }); } /** * Remove listener for the source-setup signal. * * @param listener listener to remove */ public void disconnect(SOURCE_SETUP listener) { disconnect(SOURCE_SETUP.class, listener); } /** * Signal emitted when the current uri is about to finish. You can set the * uri and suburi to make sure that playback continues. */ public static interface ABOUT_TO_FINISH { /** */ public void aboutToFinish(PlayBin element); } /** * Signal is emitted whenever the number or order of the video streams has * changed. The application will most likely want to select a new video * stream. */ public static interface VIDEO_CHANGED { /** */ public void videoChanged(PlayBin element); } /** * Signal is emitted whenever the number or order of the audio streams has * changed. The application will most likely want to select a new audio * stream. */ public static interface AUDIO_CHANGED { /** */ public void audioChanged(PlayBin element); } /** * Signal is emitted whenever the number or order of the audio streams has * changed. The application will most likely want to select a new audio * stream. */ public static interface TEXT_CHANGED { /** */ public void textChanged(PlayBin element); } /** * Signal is emitted whenever the tags of a video stream have changed. The * application will most likely want to get the new tags. */ public static interface VIDEO_TAGS_CHANGED { /** * @param stream stream index with changed tags */ public void videoTagsChanged(PlayBin element, int stream); } /** * Signal is emitted whenever the tags of an audio stream have changed. The * application will most likely want to get the new tags. */ public static interface AUDIO_TAGS_CHANGED { /** * @param stream stream index with changed tags */ public void audioTagsChanged(PlayBin element, int stream); } /** * Signal is emitted whenever the tags of a text stream have changed. The * application will most likely want to get the new tags. */ public static interface TEXT_TAGS_CHANGED { /** * @param stream stream index with changed tags */ public void textTagsChanged(PlayBin element, int stream); } /** * This signal is emitted when a new element is added to playbin or any of * its sub-bins. This signal can be used to configure elements, e.g. to set * properties on decoders. This is functionally equivalent to connecting to * the deep-element-added signal, but more convenient. *

* This signal is usually emitted from the context of a GStreamer streaming * thread, so might be called at the same time as code running in the main * application thread. */ @Gst.Since(minor = 10) public static interface ELEMENT_SETUP { /** * Element setup signal callback. * * @param playbin signal source * @param element added element */ public void elementSetup(PlayBin playbin, Element element); } /** * This signal is emitted after the source element has been created, so it * can be configured by setting additional properties (e.g. set a proxy * server for an http source, or set the device and read speed for an audio * cd source). This is functionally equivalent to connecting to the * notify::source signal, but more convenient. *

* This signal is usually emitted from the context of a GStreamer streaming * thread. */ public static interface SOURCE_SETUP { /** * Source setup signal callback. * * @param playbin signal source * @param element source element added */ public void sourceSetup(PlayBin playbin, Element element); } } ================================================ FILE: src/org/freedesktop/gstreamer/elements/PlayFlags.java ================================================ /* * Copyright (c) 2021 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.elements; import org.freedesktop.gstreamer.glib.NativeFlags; /** * Extra flags to configure the behaviour of the {@link PlayBin} sinks. */ public enum PlayFlags implements NativeFlags { /** * Enable rendering of the video stream. */ VIDEO(1 << 0), /** * Enable rendering of the audio stream. */ AUDIO(1 << 1), /** * Enable rendering of subtitles. */ TEXT(1 << 2), /** * Enable rendering of visualisations when there is no video stream. */ VIS(1 << 3), /** * Use software volume. */ SOFT_VOLUME(1 << 4), /** * Only allow native audio formats, this omits configuration of audioconvert * and audioresample. */ NATIVE_AUDIO(1 << 5), /** * Only allow native video formats, this omits configuration of videoconvert * and videoscale. */ NATIVE_VIDEO(1 << 6), /** * Enable progressive download buffering for selected formats. */ DOWNLOAD(1 << 7), /** * Enable buffering of the demuxed or parsed data. */ BUFFERING(1 << 8), /** * Deinterlace raw video (if native not forced). */ DEINTERLACE(1 << 9), /** * Use a software filter for colour balance. */ SOFT_COLORBALANCE(1 << 10), /** * Force audio/video filters to be applied if set. */ FORCE_FILTERS(1 << 11), /** * Force to use only software-based decoders ignoring those with hardware * class. */ FORCE_SW_DECODERS(1 << 12); private final int value; private PlayFlags(int value) { this.value = value; } @Override public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/elements/URIDecodeBin.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2016 Christophe Lafolet * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.elements; import java.util.ArrayList; import java.util.List; import java.util.Optional; import org.freedesktop.gstreamer.Bin; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.Element; import org.freedesktop.gstreamer.ElementFactory; import org.freedesktop.gstreamer.Pad; import org.freedesktop.gstreamer.glib.NativeEnum; import org.freedesktop.gstreamer.query.Query; import org.freedesktop.gstreamer.lowlevel.GValueAPI.GValueArray; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback; import org.freedesktop.gstreamer.lowlevel.GType; import org.freedesktop.gstreamer.lowlevel.GValueAPI; /** * A {@link Bin} that decodes data from a URI into raw media. It selects a * source element that can handle the given “uri” scheme and connects it to a * decodebin. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gst-plugins-base-plugins/html/gst-plugins-base-plugins-uridecodebin.html *

*/ public class URIDecodeBin extends Bin { public static final String GST_NAME = "uridecodebin"; public static final String GTYPE_NAME = "GstURIDecodeBin"; public URIDecodeBin(final String name) { this(makeRawElement(GST_NAME, name)); } URIDecodeBin(final Initializer init) { super(init); } /** * Signal is emitted when a pad for which there is no further possible * decoding is added to the {@link URIDecodeBin}. */ public static interface UNKNOWN_TYPE { /** * @param element The element which has the new Pad. * @param pad the new Pad. * @param caps the caps of the pad that cannot be resolved. */ public void unknownType(URIDecodeBin element, Pad pad, Caps caps); } /** * Adds a listener for the unknown-type signal * * @param listener Listener to be called */ public void connect(final UNKNOWN_TYPE listener) { connect(UNKNOWN_TYPE.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(URIDecodeBin elem, Pad pad, Caps caps) { listener.unknownType(elem, pad, caps); } }); } /** * Removes a listener for the unknown-type signal * * @param listener The listener that was previously added. */ public void disconnect(UNKNOWN_TYPE listener) { disconnect(UNKNOWN_TYPE.class, listener); } /** * Signal is emitted when a pad for which there is no further possible * decoding is added to the {@link URIDecodeBin}. */ public static interface AUTOPLUG_CONTINUE { /** * Autoplug continue signal. * * @param element The element which has the new Pad. * @param pad the new Pad. * @param caps the caps of the pad that cannot be resolved. * @return TRUE if you wish decodebin to look for elements that can * handle the given caps . If FALSE, those caps will be considered as * final and the pad will be exposed as such (see 'pad-added' signal of * {@link Element}). */ public boolean autoplugContinue(URIDecodeBin element, Pad pad, Caps caps); } /** * Adds a listener for the autoplug-continue signal * * @param listener Listener to be called */ public void connect(final AUTOPLUG_CONTINUE listener) { connect(AUTOPLUG_CONTINUE.class, listener, new GstCallback() { @SuppressWarnings("unused") public boolean callback(URIDecodeBin elem, Pad pad, Caps caps) { return listener.autoplugContinue(elem, pad, caps); } }); } /** * Removes a listener for the autoplug-continue signal * * @param listener The listener that was previously added. */ public void disconnect(AUTOPLUG_CONTINUE listener) { disconnect(AUTOPLUG_CONTINUE.class, listener); } /** * This function is emitted when an array of possible factories for caps on * pad is needed. {@link URIDecodeBin} will by default return an array with all * compatible factories, sorted by rank. *

* If this function returns {@link Optional#EMPTY}, pad will be exposed as a * final caps. *

* If this function returns an empty list, the pad will be considered as * having an unhandled type media type. */ public static interface AUTOPLUG_FACTORIES { /** * @param element The element which has the new Pad. * @param pad the new Pad. * @param caps the caps of the pad that cannot be resolved. * @return */ public Optional> autoplugFactories(URIDecodeBin element, Pad pad, Caps caps); } /** * Adds a listener for the autoplug-factories signal * * @param listener Listener to be called */ public void connect(final AUTOPLUG_FACTORIES listener) { connect(AUTOPLUG_FACTORIES.class, listener, new GstCallback() { @SuppressWarnings("unused") public GValueArray callback(URIDecodeBin elem, Pad pad, Caps caps) { Optional> factories = listener.autoplugFactories(elem, pad, caps); return factories.map(list -> { GValueArray array = new GValueArray(list.size(), false); list.forEach(factory -> array.append(new GValueAPI.GValue(GType.OBJECT, factory))); return array; }).orElse(null); } }); } /** * Removes a listener for the autoplug-factories signal * * @param listener The listener that was previously added. */ public void disconnect(AUTOPLUG_FACTORIES listener) { disconnect(AUTOPLUG_FACTORIES.class, listener); } /** * Once {@link URIDecodeBin} has found the possible ElementFactory objects to * try for caps on pad, this signal is emitted. The purpose of the signal is * for the application to perform additional sorting or filtering on the * element factory array. * * The callee should copy and modify factories. */ public static interface AUTOPLUG_SORT { /** * Autoplug sort * * @param element The element which has the new Pad * @param pad the new Pad * @param caps the caps of the pad that cannot be resolved * @param factories A List of possible {@link ElementFactory} to use * @return resorted list or {@link Optional#EMPTY} */ public Optional> autoplugSort( URIDecodeBin element, Pad pad, Caps caps, List factories); } /** * Adds a listener for the autoplug-sort signal * * @param listener Listener to be called */ public void connect(final AUTOPLUG_SORT listener) { connect(AUTOPLUG_SORT.class, listener, new GstCallback() { @SuppressWarnings("unused") public GValueArray callback(URIDecodeBin elem, Pad pad, Caps caps, GValueArray factories) { int size = factories.getNValues(); List list = new ArrayList<>(size); for (int i = 0; i < size; i++) { Object factory = factories.getValue(i); if (factory instanceof ElementFactory) { list.add((ElementFactory) factory); } } Optional> response = listener.autoplugSort(elem, pad, caps, list); return response.map(l -> { GValueArray array = new GValueArray(l.size(), false); list.forEach(factory -> array.append(new GValueAPI.GValue(GType.OBJECT, factory))); return array; }).orElse(null); } }); } /** * Removes a listener for the autoplug-sort signal * * @param listener The listener that was previously added. */ public void disconnect(AUTOPLUG_SORT listener) { disconnect(AUTOPLUG_SORT.class, listener); } public enum AutoplugSelectResult implements NativeEnum { TRY(0), EXPOSE(1), SKIP(2); AutoplugSelectResult(final int value) { this.value = value; } /** * Gets the integer value of the enum. * * @return The integer value for this enum. */ @Override public int intValue() { return value; } private final int value; } /** * Once {@link URIDecodeBin} has found the possible ElementFactory objects to * try for caps on pad, this signal is emitted. The purpose of the signal is * for the application to perform additional filtering on the element * factory array. *

* The signal handler should return a {@link AutoplugSelectResult} value * indicating what decodebin should do next. *

* A value of {@link AutoplugSelectResult#TRY} will try to autoplug an * element from factory. *

* A value of {@link AutoplugSelectResult#EXPOSE} will expose pad without * plugging any element to it. *

* A value of {@link AutoplugSelectResult#SKIP} will skip factory and move * to the next factory. */ public static interface AUTOPLUG_SELECT { /** * @param element The decodebin * @param pad the new Pad * @param caps the caps of the pad * @param factory the {@link ElementFactory} to use * @return an {@link AutoplugSelectResult} that indicates the required * operation. the default handler will always return * {@link AutoplugSelectResult#TRY} */ public AutoplugSelectResult autoplugSelect(final URIDecodeBin element, final Pad pad, final Caps caps, final ElementFactory factory); } /** * Adds a listener for the autoplug-select signal * * @param listener Listener to be called */ public void connect(final AUTOPLUG_SELECT listener) { connect(AUTOPLUG_SELECT.class, listener, new GstCallback() { @SuppressWarnings("unused") public AutoplugSelectResult callback(final URIDecodeBin elem, final Pad pad, final Caps caps, final ElementFactory factory) { return listener.autoplugSelect(elem, pad, caps, factory); } }); } /** * Removes a listener for the autoplug-select signal * * @param listener The listener that was previously added. */ public void disconnect(final AUTOPLUG_SELECT listener) { disconnect(AUTOPLUG_SELECT.class, listener); } /** * This signal is emitted whenever an autoplugged element that is not linked * downstream yet and not exposed does a query. It can be used to tell the * element about the downstream supported caps for example.. */ public static interface AUTOPLUG_QUERY { /** * @param element the decodebin. * @param pad the pad. * @param child the child element doing the query * @param query the query. */ public boolean autoplugQuery(URIDecodeBin element, Pad pad, Element child, Query query); } /** * Adds a listener for the autoplug-query signal * * @param listener Listener to be called */ public void connect(final AUTOPLUG_QUERY listener) { connect(AUTOPLUG_QUERY.class, listener, new GstCallback() { @SuppressWarnings("unused") public boolean callback(URIDecodeBin elem, Pad pad, Element child, Query query) { return listener.autoplugQuery(elem, pad, child, query); } }); } /** * Removes a listener for the autoplug-query signal * * @param listener The listener that was previously added. */ public void disconnect(AUTOPLUG_QUERY listener) { disconnect(AUTOPLUG_QUERY.class, listener); } /** * This signal is emitted once {@link URIDecodeBin} has finished decoding all * the data. */ public static interface DRAINED { /** * @param element The element */ public void drained(URIDecodeBin element); } /** * Adds a listener for the drained signal * * @param listener Listener to be called */ public void connect(final DRAINED listener) { connect(DRAINED.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(URIDecodeBin elem) { listener.drained(elem); } }); } /** * Removes a listener for the drained signal * * @param listener The listener that was previously added. */ public void disconnect(DRAINED listener) { disconnect(DRAINED.class, listener); } /** * Signal is emitted after the source has been created, so it can be * configured by setting additionnal properties. */ public static interface SOURCE_SETUP { /** * * @param bin the container. * @param elem the created source */ public void sourceSetup(URIDecodeBin bin, Element elem); } /** * Adds a listener for the source-setup signal * * @param source-setup Listener to be called */ public void connect(final SOURCE_SETUP listener) { this.connect(SOURCE_SETUP.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(final URIDecodeBin bin, final Element elem) { listener.sourceSetup(bin, elem); } }); } /** * Removes a listener for the source-setup signal * * @param listener The listener that was previously added. */ public void disconnect(final SOURCE_SETUP listener) { this.disconnect(SOURCE_SETUP.class, listener); } } ================================================ FILE: src/org/freedesktop/gstreamer/event/BufferSizeEvent.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.event; import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API; /** * A buffersize event. The event is sent downstream and notifies elements that * they should provide a buffer of the specified dimensions. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-buffer-size *

* When the async flag is set, a thread boundary is preferred. */ public class BufferSizeEvent extends Event { /** * This constructor is for internal use only. * * @param init initialization data. */ BufferSizeEvent(Initializer init) { super(init); } /** * Creates a new buffersize event. *

* The event is sent downstream and notifies elements that they should * provide a buffer of the specified dimensions. *

* When the async flag is set, a thread boundary is preferred. * * @param format buffer format * @param minsize minimum buffer size * @param maxsize maximum buffer size * @param async thread behaviour */ public BufferSizeEvent(Format format, long minsize, long maxsize, boolean async) { super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_buffer_size(format, minsize, maxsize, async))); } /** * Gets the format of the buffersize event. * * @return the format. */ public Format getFormat() { Format[] format = new Format[1]; GSTEVENT_API.gst_event_parse_buffer_size(this, format, null, null, null); return format[0]; } /** * Gets the minimum buffer size. * * @return the minimum buffer size. */ public long getMinimumSize() { long[] size = {0}; GSTEVENT_API.gst_event_parse_buffer_size(this, null, size, null, null); return size[0]; } /** * Gets the maximum buffer size. * * @return the maximum buffer size. */ public long getMaximumSize() { long[] size = {0}; GSTEVENT_API.gst_event_parse_buffer_size(this, null, null, size, null); return size[0]; } /** * Gets the preferred thread behaviour. * * @return true if a thread boundary is preferred. */ public boolean isAsync() { boolean[] async = {false}; GSTEVENT_API.gst_event_parse_buffer_size(this, null, null, null, async); return async[0]; } } ================================================ FILE: src/org/freedesktop/gstreamer/event/CapsEvent.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2016 Christophe Lafolet * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.event; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API; /** * A CAPS event for {@link Caps}. The caps event can only travel downstream * synchronized with the buffer flow and contains the format of the buffers that * will follow after the event. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-caps *

*/ public class CapsEvent extends Event { /** * This constructor is for internal use only. * * @param init initialization data. */ CapsEvent(Initializer init) { super(init); } /** * Creates a new caps event. */ public CapsEvent(final Caps caps) { super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_caps(caps))); } } ================================================ FILE: src/org/freedesktop/gstreamer/event/EOSEvent.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.event; import org.freedesktop.gstreamer.Bus; import org.freedesktop.gstreamer.FlowReturn; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API; /** * End-Of-Stream event. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-eos *

* The eos event can only travel downstream synchronized with the buffer flow. * Elements that receive the EOS event on a pad can return * {@link FlowReturn#EOS} when data after the EOS event arrives. *

* The EOS event will travel down to the sink elements in the pipeline which * will then post the {@link Bus.EOS } message on the bus after they have * finished playing any buffered data. *

* When all sinks have posted an EOS message, an EOS message is forwarded to the * application. *

* The EOS event itself will not cause any state transitions of the pipeline. */ public class EOSEvent extends Event { /** * This constructor is for internal use only. * * @param init initialization data. */ EOSEvent(Initializer init) { super(init); } /** * Creates a new EOS event. */ public EOSEvent() { super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_eos())); } } ================================================ FILE: src/org/freedesktop/gstreamer/event/Event.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.event; import java.util.EnumMap; import java.util.Map; import java.util.function.Function; import java.util.stream.Stream; import org.freedesktop.gstreamer.MiniObject; import org.freedesktop.gstreamer.Structure; import org.freedesktop.gstreamer.glib.NativeObject; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstEventAPI; import org.freedesktop.gstreamer.lowlevel.ReferenceManager; import org.freedesktop.gstreamer.lowlevel.annotations.HasSubtype; import static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API; /** * Base type of all events. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html *

* Events are passed between elements in parallel to the data stream. Some * events are serialized with buffers, others are not. Some events only travel * downstream, others only upstream. Some events can travel both upstream and * downstream. *

* The events are used to signal special conditions in the datastream such as * EOS (end of stream) or the start of a new stream-segment. *

* Events are also used to flush the pipeline of any pending data. * * @see Pad#pushEvent * @see Pad#sendEvent * @see Element#sendEvent */ @HasSubtype public class Event extends MiniObject { public static final String GTYPE_NAME = "GstEvent"; private static final Map> TYPE_MAP = new EnumMap<>(EventType.class); static { TYPE_MAP.put(EventType.BUFFERSIZE, BufferSizeEvent::new); TYPE_MAP.put(EventType.EOS, EOSEvent::new); TYPE_MAP.put(EventType.CAPS, CapsEvent::new); TYPE_MAP.put(EventType.RECONFIGURE, ReconfigureEvent::new); TYPE_MAP.put(EventType.STREAM_START, StreamStartEvent::new); TYPE_MAP.put(EventType.LATENCY, LatencyEvent::new); TYPE_MAP.put(EventType.FLUSH_START, FlushStartEvent::new); TYPE_MAP.put(EventType.FLUSH_STOP, FlushStopEvent::new); TYPE_MAP.put(EventType.NAVIGATION, NavigationEvent::new); TYPE_MAP.put(EventType.SEGMENT, SegmentEvent::new); TYPE_MAP.put(EventType.SEEK, SeekEvent::new); TYPE_MAP.put(EventType.TAG, TagEvent::new); TYPE_MAP.put(EventType.QOS, QOSEvent::new); TYPE_MAP.put(EventType.STEP, StepEvent::new); } /** * This constructor is for internal use only. * * @param init initialization data. */ Event(Initializer init) { super(init); } /** * Gets the structure containing the data in this event. * * @return a structure. */ public Structure getStructure() { return ReferenceManager.addKeepAliveReference(GSTEVENT_API.gst_event_get_structure(this), this); } private static Event create(Initializer init) { GstEventAPI.EventStruct struct = new GstEventAPI.EventStruct(init.ptr.getPointer()); EventType type = (EventType) struct.readField("type"); return TYPE_MAP.getOrDefault(type, Event::new).apply(init); } public static class Types implements TypeProvider { @Override public Stream> types() { return Stream.of( Natives.registration(Event.class, GTYPE_NAME, Event::create) ); } } } ================================================ FILE: src/org/freedesktop/gstreamer/event/EventType.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.event; import org.freedesktop.gstreamer.Gst; import org.freedesktop.gstreamer.glib.NativeEnum; import org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue; /** * The standard event types that can be sent in a pipeline. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#GstEventType *

* The custom event types can be used for private messages between elements * that can't be expressed using normal GStreamer buffer passing semantics. *

* Custom events carry an arbitrary {@link Structure}. Specific custom events * are distinguished by the name of the structure. */ public enum EventType implements NativeEnum { /** Unknown event */ @DefaultEnumValue UNKNOWN(0, 0), /* bidirectional events */ /** * Start a flush operation. This event clears all data from the pipeline and * unblock all streaming threads. */ FLUSH_START(10, Flags.BOTH), /** * Stop a flush operation. This event resets the running-time of the * pipeline. */ FLUSH_STOP(20, Flags.BOTH | Flags.SERIALIZED), /* downstream serialized events */ /** * Event to mark the start of a new stream. Sent before any other serialized * event and only sent at the start of a new stream, not after flushing * seeks. */ STREAM_START(40, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY), /** * #GstCaps event. Notify the pad of a new media type. */ CAPS(50, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY), /** * A new media segment follows in the dataflow. The segment events contains * information for clipping buffers and converting buffer timestamps to * running-time and stream-time. */ SEGMENT(70, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY), /** * A new #GstStreamCollection is available (Since 1.10) */ @Gst.Since(minor = 10) STREAM_COLLECTION(75, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY | Flags.STICKY_MULTI), /** * A new set of metadata tags has been found in the stream. */ TAG(80, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY | Flags.STICKY_MULTI), /** * Notification of buffering requirements. Currently not used yet. */ BUFFERSIZE(90, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY), /** * An event that sinks turn into a message. Used to send messages that * should be emitted in sync with rendering. */ SINK_MESSAGE(100, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY | Flags.STICKY_MULTI), /** * Indicates that there is no more data for the stream group ID in the * message. Sent before EOS in some instances and should be handled mostly * the same. (Since 1.10) */ @Gst.Since(minor = 10) STREAM_GROUP_DONE(105, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY), /** * End-Of-Stream. No more data is to be expected to follow without a SEGMENT * event. */ EOS(110, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY), /** * An event which indicates that a new table of contents (TOC) was found or * updated. */ TOC(120, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY | Flags.STICKY_MULTI), /** * An event which indicates that new or updated encryption information has * been found in the stream. */ PROTECTION(130, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY | Flags.STICKY_MULTI), /* non-sticky downstream serialized */ /** * Marks the end of a segment playback. */ SEGMENT_DONE(150, Flags.DOWNSTREAM | Flags.SERIALIZED), /** * Marks a gap in the datastream. */ GAP(160, Flags.DOWNSTREAM | Flags.SERIALIZED), /* upstream events */ /** * A quality message. Used to indicate to upstream elements that the * downstream elements should adjust their processing rate. */ QOS(190, Flags.UPSTREAM), /** * A request for a new playback position and rate. */ SEEK(200, Flags.UPSTREAM), /** * Navigation events are usually used for communicating user requests, such * as mouse or keyboard movements, to upstream elements. */ NAVIGATION(210, Flags.UPSTREAM), /** * Notification of new latency adjustment. Sinks will use the latency * information to adjust their synchronisation. */ LATENCY(220, Flags.UPSTREAM), /** * A request for stepping through the media. Sinks will usually execute the * step operation. */ STEP(230, Flags.UPSTREAM), /** * A request for upstream renegotiating caps and reconfiguring. */ RECONFIGURE(240, Flags.UPSTREAM), /** * A request for a new playback position based on TOC entry's UID. */ TOC_SELECT(250, Flags.UPSTREAM), /** * A request to select one or more streams (Since 1.10) */ @Gst.Since(minor = 10) SELECT_STREAMS(260, Flags.UPSTREAM), /* custom events start here */ /** * Upstream custom event */ CUSTOM_UPSTREAM(270, Flags.UPSTREAM), /** * Downstream custom event that travels in the data flow. */ CUSTOM_DOWNSTREAM(280, Flags.DOWNSTREAM | Flags.SERIALIZED), /** * Custom out-of-band downstream event. */ CUSTOM_DOWNSTREAM_OOB(290, Flags.DOWNSTREAM), /** * Custom sticky downstream event. */ CUSTOM_DOWNSTREAM_STICKY(300, Flags.DOWNSTREAM | Flags.SERIALIZED | Flags.STICKY | Flags.STICKY_MULTI), /** * Custom upstream or downstream event. In-band when travelling downstream. */ CUSTOM_BOTH(310, Flags.BOTH | Flags.SERIALIZED), /** * Custom upstream or downstream out-of-band event. */ CUSTOM_BOTH_OOB(320, Flags.BOTH) ; private static final int SHIFT = 8; private final int value; private EventType(int num, int flags) { this.value = (num << SHIFT) | flags; } @Override public int intValue() { return value; } private static final class Flags { public static final int UPSTREAM = 1 << 0; public static final int DOWNSTREAM = 1 << 1; public static final int SERIALIZED = 1 << 2; public static final int STICKY = 1 << 3; public static final int STICKY_MULTI = 1 << 4; public static final int BOTH = UPSTREAM | DOWNSTREAM; } } ================================================ FILE: src/org/freedesktop/gstreamer/event/FlushStartEvent.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.event; import org.freedesktop.gstreamer.FlowReturn; import org.freedesktop.gstreamer.Pad; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API; /** * Start a flush operation. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-flush-start *

* The flush start event can be sent upstream and downstream and travels * out-of-bounds with the dataflow. *

* It marks pads as being flushing and will make them return * {@link FlowReturn#FLUSHING} when used for data flow with {@link Pad#pushEvent}, * {@link Pad#chain}, {@link Pad#getRange} and {@link Pad#pullRange}. Any event * (except a {@link FlushStopEvent}) received on a flushing pad will return * {@code false} immediately. *

* Elements should unlock any blocking functions and exit their streaming * functions as fast as possible when this event is received. *

* This event is typically generated after a seek to flush out all queued data * in the pipeline so that the new media is played as soon as possible. * */ public class FlushStartEvent extends Event { /** * This constructor is for internal use only. * * @param init initialization data. */ FlushStartEvent(Initializer init) { super(init); } /** * Creates a new flush start event. */ public FlushStartEvent() { super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_flush_start())); } } ================================================ FILE: src/org/freedesktop/gstreamer/event/FlushStopEvent.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.event; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API; /** * Stop a flush operation. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-flush-stop *

* The flush stop event can be sent upstream and downstream and travels * out-of-bounds with the dataflow. It is typically sent after sending a * {@link FlushStartEvent} event to make the pads accept data again. *

* Elements can process this event synchronized with the dataflow since the * preceeding FLUSH_START event stopped the dataflow. *

* This event is typically generated to complete a seek and to resume dataflow. */ public class FlushStopEvent extends Event { /** * This constructor is for internal use only. * * @param init initialization data. */ FlushStopEvent(Initializer init) { super(init); } /** * Creates a new flush stop event. */ public FlushStopEvent() { super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_flush_stop())); } } ================================================ FILE: src/org/freedesktop/gstreamer/event/LatencyEvent.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.event; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API; /** * Notification of new latency adjustment. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-latency *

* The event is sent upstream from the sinks and notifies elements that they * should add an additional latency to the timestamps before synchronising * against the clock. *

* The latency is mostly used in live sinks and is always expressed in the time * format. */ public class LatencyEvent extends Event { /** * This constructor is for internal use only. * * @param init initialization data. */ LatencyEvent(Initializer init) { super(init); } /** * Create a new latency event. * * @param latency the new latency value to add to timestamps. */ public LatencyEvent(long latency) { super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_latency(latency))); } /** * Gets the latency in the latency event. * * @return the latency. */ public long getLatency() { long[] latency = new long[1]; GSTEVENT_API.gst_event_parse_latency(this, latency); return latency[0]; } } ================================================ FILE: src/org/freedesktop/gstreamer/event/NavigationEvent.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.event; import org.freedesktop.gstreamer.Structure; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GType; import static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API; /** * Navigation events are usually used for communicating user requests, such as * mouse or keyboard movements, to upstream elements. */ // @TODO API seems OK but need to check and update against GstNavigation public class NavigationEvent extends Event { /** * This constructor is for internal use only. * * @param init initialization data. */ NavigationEvent(Initializer init) { super(init); } /** * Creates a new navigation event from the given description. *

* Unless you really need a custom navigation event, use one of the static * convenience methods for creating navigation events. * * @param structure the description of the navigation event. */ public NavigationEvent(Structure structure) { this(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_navigation(structure))); } /** * Gets a human-readable string representation of this navigation event. * * @return a string */ @Override public String toString() { Structure s = getStructure(); String event = s.getString("event"); if (event.startsWith("key-")) { return String.format("%s: [key=%s]", event, s.getString("key")); } else if (event.startsWith("mouse-")) { return String.format("%s: [x=%f, y=%f button=%x]", event, s.getDouble("pointer_x"), s.getDouble("pointer_y"), s.getInteger("button")); } else { return String.format("%s", s.getString("event")); } } /** * Creates a mouse navigation event. * * @param event the type of mouse event. * @param x the X location of the mouse cursor * @param y the Y location of the mouse cursor * @param button the button(s) currently pressed * @return a new navigation event */ public static NavigationEvent createMouseEvent(String event, double x, double y, int button) { return new MouseEvent(event, x, y, button); } /** * Creates a mouse move navigation event. * * @param x the X location of the mouse cursor * @param y the Y location of the mouse cursor * @param button the button(s) currently pressed * @return a new navigation event */ public static NavigationEvent createMouseMoveEvent(double x, double y, int button) { return createMouseEvent("mouse-move", x, y, button); } /** * Creates a mouse button press navigation event. * * @param x the X location of the mouse cursor * @param y the Y location of the mouse cursor * @param button the button(s) currently pressed * @return a new navigation event */ public static NavigationEvent createMouseButtonPressEvent(double x, double y, int button) { return createMouseEvent("mouse-button-press", x, y, button); } /** * Creates a mouse button release navigation event. * * @param x the X location of the mouse cursor * @param y the Y location of the mouse cursor * @param button the button(s) currently pressed * @return a new navigation event */ public static NavigationEvent createMouseButtonReleaseEvent(double x, double y, int button) { return createMouseEvent("mouse-button-release", x, y, button); } /** * Creates a new key navigation event. * * @param event the type of key event. * @param key the ascii key code for the key. * @return a new navigation event */ public static NavigationEvent createKeyEvent(String event, String key) { return new KeyEvent(event, key); } /** * Creates a new key press navigation event. * * @param key the ascii key code for the key. * @return a new navigation event */ public static NavigationEvent createKeyPressEvent(String key) { return createKeyEvent("key-press", key); } /** * Creates a new key release navigation event. * * @param key the ascii key code for the key. * @return a new navigation event */ public static NavigationEvent createKeyReleaseEvent(String key) { return createKeyEvent("key-release", key); } private static final class MouseEvent extends NavigationEvent { public MouseEvent(String event, double x, double y, int button) { super(new Structure("application/x-gst-navigation", "event", GType.STRING, event, "button", GType.INT, button, "pointer_x", GType.DOUBLE, x, "pointer_y", GType.DOUBLE, y)); } /** * Gets a human-readable string representation of this navigation event. * * @return a string */ @Override public String toString() { Structure s = getStructure(); return String.format("%s: [x=%f, y=%f button=%x]", s.getString("event"), s.getDouble("pointer_x"), s.getDouble("pointer_y"), s.getInteger("button")); } } private static final class KeyEvent extends NavigationEvent { public KeyEvent(String event, String key) { super(new Structure("application/x-gst-navigation", "event", GType.STRING, event, "key", GType.STRING, key)); } /** * Gets a human-readable string representation of this navigation event. * * @return a string */ @Override public String toString() { Structure s = getStructure(); return String.format("%s: [key=%s]", s.getString("event"), s.getString("key")); } } } ================================================ FILE: src/org/freedesktop/gstreamer/event/QOSEvent.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.event; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API; /** * A quality message. Used to indicate to upstream elements that the downstream * elements are being starved of or flooded with data. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-qos *

* proportion indicates the real-time performance of the streaming in * the element that generated the QoS event (usually the sink). The value is * generally computed based on more long term statistics about the streams * timestamps compared to the clock. *

* A value < 1.0 indicates that the upstream element is producing data faster * than real-time. A value > 1.0 indicates that the upstream element is not * producing data fast enough. 1.0 is the ideal proportion value. The * proportion value can safely be used to lower or increase the quality of the * element. *

* difference is the difference against the clock in running time of * the last buffer that caused the element to generate the QOS event. A negative * value means that the buffer with timestamp arrived in time. A * positive value indicates how late the buffer with timestamp was. *

* timestamp is the timestamp of the last buffer that cause the element * to generate the QOS event. It is expressed in running time and thus an ever * increasing value. *

* The upstream element can use the diff and timestamp values * to decide whether to process more buffers. For positive difference, * all buffers with timestamp <= timestamp + difference will * certainly arrive late in the sink as well. *

* The application can use general event probes to intercept the QoS event and * implement custom application specific QoS handling. * */ public class QOSEvent extends Event { /** * This constructor is for internal use only. * * @param init initialization data. */ QOSEvent(Initializer init) { super(init); } /** * Creates a new quality-of-service event. * * * @param proportion the proportion of the qos message * @param difference the time difference of the last Clock sync * @param timestamp the timestamp of the buffer */ public QOSEvent(QOSType type, double proportion, long difference, long timestamp) { super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_qos(type, proportion, difference, timestamp))); } /** * @return the proportion. */ public QOSType getType() { QOSType[] type = {null}; GSTEVENT_API.gst_event_parse_qos(this, type, null, null, (long[]) null); return type[0]; } /** * Gets the proportion value of this event. *

* The proportion indicates the real-time performance of the streaming in * the element that generated the QoS event (usually the sink). The value is * generally computed based on more long term statistics about the streams * timestamps compared to the clock. * * @return the proportion. */ public double getProportion() { double[] p = {0d}; GSTEVENT_API.gst_event_parse_qos(this, null, p, null, (long[]) null); return p[0]; } /** * Gets the difference value of this event. *

* This is the difference against the clock in running time of the last * buffer that caused the element to generate the QOS event. A negative * value means that the buffer with timestamp arrived in time. A * positive value indicates how late the buffer with timestamp was. * * @return the difference. */ public long getDifference() { long[] diff = {0}; GSTEVENT_API.gst_event_parse_qos(this, null, null, diff, (long[]) null); return diff[0]; } /** * Gets the timestamp from this event. *

* This is the timestamp of the last buffer that caused the element to * generate the QOS event. It is expressed in running time and thus an ever * increasing value. * * @return the timestamp */ public long getTimestamp() { long[] timestamp = new long[1]; GSTEVENT_API.gst_event_parse_qos(this, null, null, null, timestamp); return timestamp[0]; } } ================================================ FILE: src/org/freedesktop/gstreamer/event/QOSType.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.event; import org.freedesktop.gstreamer.glib.NativeEnum; /** * The different types of QoS events that can be given to the * gst_event_new_qos() method. */ public enum QOSType implements NativeEnum { /** * The QoS event type that is produced when downstream elements are * producing data too quickly and the element can't keep up processing the * data. Upstream should reduce their processing rate. This type is also * used when buffers arrive early or in time. */ OVERFLOW(0), /** * The QoS event type that is produced when downstream elements are * producing data too slowly and need to speed up their processing rate. */ UNDERFLOW(1), /** * The QoS event type that is produced when the application enabled * throttling to limit the datarate. */ THROTTLE(2); private final int value; private QOSType(int value) { this.value = value; } @Override public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/event/ReconfigureEvent.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2016 Christophe Lafolet * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.event; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API; /** * A reconfigure event. The purpose of the reconfigure event is to travel * upstream and make elements renegotiate their caps or reconfigure their buffer * pools. This is useful when changing properties on elements or changing the * topology of the pipeline. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-reconfigure *

*/ public class ReconfigureEvent extends Event { /** * This constructor is for internal use only. * * @param init initialization data. */ ReconfigureEvent(Initializer init) { super(init); } /** * Creates a new reconfigure event. */ public ReconfigureEvent() { super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_reconfigure())); } } ================================================ FILE: src/org/freedesktop/gstreamer/event/SeekEvent.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.event; import java.util.EnumSet; import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.glib.NativeFlags; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API; /** * A request for a new playback position and rate. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-seek *

* The seek event configures playback of the pipeline between start to stop * at the speed given in rate, also called a playback segment. *

* The start and stop values are expressed in format. *

* A rate of 1.0 means normal playback rate, 2.0 means double speed. * Negative values means backwards playback. A value of 0.0 for the * rate is not allowed and should be accomplished instead by PAUSING the * pipeline. *

* A pipeline has a default playback segment configured with a start * position of 0, a stop position of -1 and a rate of 1.0. The currently * configured playback segment can be queried with #GST_QUERY_SEGMENT. *

* startType and stopType specify how to adjust the currently configured * start and stop fields in segment. Adjustments can be made relative or * absolute to the last configured values. A type of {@link SeekType#NONE} means * that the position should not be updated. *

* When the rate is positive and start has been updated, playback will start * from the newly configured start position. *

* For negative rates, playback will start from the newly configured stop * position (if any). If the stop position if updated, it must be different from * -1 for negative rates. *

* It is not possible to seek relative to the current playback position, to do * this, PAUSE the pipeline, query the current playback position with * {@link org.gstreamer.Pipeline#queryPosition getPosition} and update the playback segment * current position with a {@link SeekType#SET} to the desired position. */ public class SeekEvent extends Event { /** * This constructor is for internal use only. * @param init initialization data. */ SeekEvent(Initializer init) { super(init); } /** * Creates a new seek event. * * @param rate the new playback rate * @param format the format of the seek values * @param flags the optional seek flags * @param startType the type and flags for the new start position * @param start the value of the new start position * @param stopType the type and flags for the new stop position * @param stop the value of the new stop position */ public SeekEvent(double rate, Format format, EnumSet flags, SeekType startType, long start, SeekType stopType, long stop) { super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_seek(sanitizeRate(rate), format, NativeFlags.toInt(flags), startType, start, stopType, stop))); } private static double sanitizeRate(double rate) { if (rate == 0d) { throw new IllegalArgumentException("Cannot have rate == 0.0"); } return rate; } /** * Gets the playback rate. * * A rate of 1.0 means normal playback rate, 2.0 means double speed. * Negative values means backwards playback. A value of 0.0 for the * rate is not allowed and should be accomplished instead by PAUSING the * pipeline. * * @return the playback rate. */ public double getRate() { double[] rate = { 0d }; GSTEVENT_API.gst_event_parse_seek(this, rate, null, null, null, null, null, null); return rate[0]; } /** * Gets the {@link Format} of the start and stop seek values. * * @return the format. */ public Format getFormat() { Format[] format = new Format[1]; GSTEVENT_API.gst_event_parse_seek(this, null, format, null, null, null, null, null); return format[0]; } /** * Gets the {@link SeekFlags} of this seek event. * * @return the seek flags. */ public EnumSet getFlags() { int[] flags = { 0 }; GSTEVENT_API.gst_event_parse_seek(this, null, null, flags, null, null, null, null); return NativeFlags.fromInt(SeekFlags.class, flags[0]); } /** * Gets the SeekType of the start value. * * @return the SeekType. */ public SeekType getStartType() { SeekType[] type = new SeekType[1]; GSTEVENT_API.gst_event_parse_seek(this, null, null, null, type, null, null, null); return type[0]; } /** * Gets the start of the seek segment. * * @return the start of the seek. */ public long getStart() { long[] value = { 0 }; GSTEVENT_API.gst_event_parse_seek(this, null, null, null, null, value, null, null); return value[0]; } /** * Gets the SeekType of the start value. * * @return the SeekType. */ public SeekType getStopType() { SeekType[] type = new SeekType[1]; GSTEVENT_API.gst_event_parse_seek(this, null, null, null, null, null, type, null); return type[0]; } /** * Gets the stop position of the seek. * * @return the stop position. */ public long getStop() { long[] value = { 0 }; GSTEVENT_API.gst_event_parse_seek(this, null, null, null, null, null, null, value); return value[0]; } } ================================================ FILE: src/org/freedesktop/gstreamer/event/SeekFlags.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.event; import org.freedesktop.gstreamer.glib.NativeFlags; /** * Flags to be used with {@link Pipeline#seek seek} or * {@link org.freedesktop.gstreamer.event.SeekEvent#SeekEvent SeekEvent} *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#GstSeekFlags *

* All flags can be used together. *

* A non flushing seek might take some time to perform as the currently playing * data in the pipeline will not be cleared. *

* An accurate seek might be slower for formats that don't have any indexes or * timestamp markers in the stream. Specifying this flag might require a * complete scan of the file in those cases. *

* When performing a segment seek: after the playback of the segment completes, * no EOS will be emitted by the element that performed the seek, but a * {@link Bus.SEGMENT_DONE} message will be posted on the bus by the element. * When this message is posted, it is possible to send a new seek event to * continue playback. With this seek method it is possible to perform seamless * looping or simple linear editing. */ public enum SeekFlags implements NativeFlags { // /** // * No flag. // */ // NONE(0), /** * Flush pipeline. */ FLUSH(1 << 0), /** * Accurate position is requested, this might be considerably slower for * some formats. */ ACCURATE(1 << 1), /** * Seek to the nearest keyframe. This might be faster but less accurate. */ KEY_UNIT(1 << 2), /** * Perform a segment seek. */ SEGMENT(1 << 3), /** * when doing fast forward or fast reverse playback, allow elements to skip * frames instead of generating all frames. (Since 1.6) */ TRICKMODE(1 << 4), /** * go to a location before the requested position, if * %GST_SEEK_FLAG_KEY_UNIT this means the keyframe at or before the * requested position the one at or before the seek target. */ SNAP_BEFORE(1 << 5), /** * go to a location after the requested position, if %GST_SEEK_FLAG_KEY_UNIT * this means the keyframe at of after the requested position. */ SNAP_AFTER(1 << 6), // /** // * go to a position near the requested position, if %GST_SEEK_FLAG_KEY_UNIT // * this means the keyframe closest to the requested position, if both // * keyframes are at an equal distance, behaves like // * %GST_SEEK_FLAG_SNAP_BEFORE. // */ // public final static int SNAP_NEAREST = SNAP_BEFORE | SNAP_AFTER; /** * when doing fast forward or fast reverse playback, request that elements * only decode keyframes and skip all other content, for formats that have * keyframes. */ TRICKMODE_KEY_UNITS(1 << 7), /** * when doing fast forward or fast reverse playback, request that audio * decoder elements skip decoding and output only gap events or silence. */ TRICKMODE_NO_AUDIO(1 << 8); private final int value; private SeekFlags(int value) { this.value = value; } @Override public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/event/SeekType.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.event; import org.freedesktop.gstreamer.glib.NativeEnum; /** * The different types of seek events. *

* When constructing a seek event with * gst_event_new_seek(), a format, a seek method and optional flags are to * be provided. The seek event is then inserted into the graph with * gst_pad_send_event() or gst_element_send_event(). */ public enum SeekType implements NativeEnum{ /** No change in position is required. */ NONE(0), /** Absolute position is requested. */ SET(1), /** Relative position to duration is requested. */ END(2); private final int value; private SeekType(int value) { this.value = value; } @Override public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/event/SegmentEvent.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.event; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.Segment; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstAPI; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstSegmentStruct; import static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API; /** * * An event for {@link Segment} *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-segment *

* The segment event marks the range of buffers to be processed. All data not * within the segment range is not to be processed. This can be used * intelligently by plugins to apply more efficient methods of skipping unneeded * data. The valid range is expressed with the start and stop values. *

* The time value of the segment is used in conjunction with the start value to * convert the buffer timestamps into the stream time. This is usually done in * sinks to report the current stream_time. time represents the stream_time of a * buffer carrying a timestamp of start . time cannot be -1. *

* start cannot be -1, stop can be -1. If there is a valid stop given, it must * be greater or equal the start , including when the indicated playback rate is * {@literal < 0} *

* The applied_rate value provides information about any rate adjustment that * has already been made to the timestamps and content on the buffers of the * stream. (rate * applied_rate ) should always equal the rate that has been * requested for playback. For example, if an element has an input segment with * intended playback rate of 2.0 and applied_rate of 1.0, it can adjust incoming * timestamps and buffer content by half and output a segment event with rate of * 1.0 and applied_rate of 2.0 *

* After a segment event, the buffer stream time is calculated with: *

* time + (TIMESTAMP(buf) - start) * ABS (rate * applied_rate) */ //@TODO needs work to parse segments public class SegmentEvent extends Event { /** * This constructor is for internal use only. * * @param init initialization data. */ SegmentEvent(Initializer init) { super(init); } /** * Allocates a new segment event with the given segment. */ SegmentEvent(GstSegmentStruct segment) { this(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_segment(segment))); } /** * Gets the {@link Segment} stored in this event. *

* Note: The Segment is owned by the event, so it should only be * accessed whilst holding a reference to this SegmentEvent. * * @return the Segment stored in this event. */ GstAPI.GstSegmentStruct getSegment() { Pointer[] segmentPointer = new Pointer[1]; GSTEVENT_API.gst_event_parse_segment(this, segmentPointer); GstSegmentStruct result = new GstAPI.GstSegmentStruct(segmentPointer[0]); result.read(); return result; } } ================================================ FILE: src/org/freedesktop/gstreamer/event/StepEvent.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2010 DHoyt * Copyright (c) 2010 Levente Farkas * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.event; import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API; /** * StepEvent. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-step *

* The purpose of the step event is to instruct a sink to skip amount (expressed * in format) of media. It can be used to implement stepping through the video * frame by frame or for doing fast trick modes. A rate of {@literal <= 0.0} is * not allowed, pause the pipeline or reverse the playback direction of the * pipeline to get the same effect. *

* The flush flag will clear any pending data in the pipeline before starting * the step operation. *

* The intermediate flag instructs the pipeline that this step operation is part * of a larger step operation. */ public class StepEvent extends Event { /** * This constructor is for internal use only. * * @param init initialization data. */ StepEvent(Initializer init) { super(init); } /** * Creates a new StepEvent event. * * @param format the format of amount * @param amount the amount of data to step * @param rate the step rate * @param flush flushing steps * @param intermediate intermediate steps */ public StepEvent(Format format, long amount, double rate, boolean flush, boolean intermediate) { super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_step(format, amount, rate, flush, intermediate))); } } ================================================ FILE: src/org/freedesktop/gstreamer/event/StreamStartEvent.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2016 Christophe Lafolet * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.event; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API; /** * Stream Start event. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-stream-start *

*/ public class StreamStartEvent extends Event { /** * This constructor is for internal use only. * @param init initialization data. */ StreamStartEvent(Initializer init) { super(init); } /** * Creates a new EOS event. * @param stream_id identifier for this stream */ public StreamStartEvent(final String stream_id) { super(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_stream_start(stream_id))); } } ================================================ FILE: src/org/freedesktop/gstreamer/event/TagEvent.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.event; import org.freedesktop.gstreamer.TagList; import org.freedesktop.gstreamer.lowlevel.ReferenceManager; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.glib.NativeObject; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API; /** * A metadata tag event. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstEvent.html#gst-event-new-tag *

* The scope of the taglist specifies if the taglist applies to the complete * medium or only to this specific stream. As the tag event is a sticky event, * elements should merge tags received from upstream with a given scope with * their own tags with the same scope and create a new tag event from it. */ public class TagEvent extends Event { /** * This constructor is for internal use only. * * @param init initialization data. */ TagEvent(Initializer init) { super(init); } /** * Creates a new TagEvent. *

* Note: This constructor takes ownership of the TagList. Attempts to * access the TagList after passing it to this constructor will throw an * exception. * * @param taglist the taglist to transmit with the event. */ public TagEvent(TagList taglist) { this(Natives.initializer(GSTEVENT_API.ptr_gst_event_new_tag(taglist))); } /** * Gets the {@link TagList} stored in this event. *

* Note: The TagList is owned by the event, so it should only be * accessed whilst holding a reference to this TagEvent. * * @return the TagList stored in this event. */ public TagList getTagList() { Pointer[] taglist = new Pointer[1]; GSTEVENT_API.gst_event_parse_tag(this, taglist); // TagList tl = new TagList(taglistInitializer(taglist[0], false, false)); TagList tl = Natives.objectFor(taglist[0], TagList.class, false, false); ReferenceManager.addKeepAliveReference(tl, this); return tl; } // private static Initializer taglistInitializer(Pointer ptr, boolean needRef, boolean ownsHandle) { // if (ptr == null) { // throw new IllegalArgumentException("Invalid native pointer"); // } // return new Initializer(ptr, needRef, ownsHandle); // } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/GCancellable.java ================================================ /* * Copyright (c) 2021 Neil C Smith * Copyright (c) 2016 Isaac Raño Jares * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.glib; import static org.freedesktop.gstreamer.lowlevel.GioAPI.GIO_API; public class GCancellable extends GObject{ public static final String GTYPE_NAME = "GCancellable"; public GCancellable() { this(Natives.initializer(GIO_API.g_cancellable_new())); } private GCancellable(Initializer init) { super(init); } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/GDate.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2016 Christophe Lafolet * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.glib; import org.freedesktop.gstreamer.lowlevel.GlibAPI; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.lowlevel.GPointer; /** * Wrapper to the GDate data structure. * * See upstream documentation at https://developer.gnome.org/glib/stable/glib-Date-and-Time-Functions.html */ public class GDate extends NativeObject { public static final String GTYPE_NAME = "GDate"; GDate(Initializer init) { this(new Handle(init.ptr, init.ownsHandle)); } GDate(Handle handle) { super(handle); } public int getDay() { return GlibAPI.GLIB_API.g_date_get_day(getRawPointer()); } public int getMonth() { return GlibAPI.GLIB_API.g_date_get_month(getRawPointer()); } public int getYear() { return GlibAPI.GLIB_API.g_date_get_year(getRawPointer()); } @Override public String toString() { return "" + getYear() + "-" + getMonth() + "-" + getDay(); } public static GDate createInstance(int day, int month, int year) { Pointer ptr = GlibAPI.GLIB_API.g_date_new_dmy(day, month, year); return new GDate(new Handle(new GPointer(ptr), true)); } public static GDate createInstance(int julian_day) { Pointer ptr = GlibAPI.GLIB_API.g_date_new_julian(julian_day); return new GDate(new Handle(new GPointer(ptr), true)); } private static final class Handle extends NativeObject.Handle { public Handle(GPointer ptr, boolean ownsHandle) { super(ptr, ownsHandle); } @Override protected void disposeNativeHandle(GPointer ptr) { GlibAPI.GLIB_API.g_date_free(ptr.getPointer()); } } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/GError.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.glib; import java.util.Objects; /** * Base GLib error type. */ public class GError { private final int code; private final String message; /** * Creates a new instance of GError * * @param code native int error code * @param message error message text */ public GError(int code, String message) { this.code = code; this.message = Objects.requireNonNull(message); } /** * Gets a numeric code representing this error. * * @return an integer code. */ public final int getCode() { return code; } /** * Gets a string representation of this error. * * @return a string representing the error. */ public String getMessage() { return message; } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/GInetAddress.java ================================================ /* * Copyright (c) 2021 Neil C Smith * Copyright (c) 2016 Isaac Raño Jares * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.glib; import static org.freedesktop.gstreamer.lowlevel.GioAPI.GIO_API; public class GInetAddress extends GObject{ public static final String GTYPE_NAME = "GInetAddress"; GInetAddress(Initializer init) { super(init); } public String getAddress() { return GIO_API.g_inet_address_to_string(getRawPointer()); } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/GInetSocketAddress.java ================================================ /* * Copyright (c) 2021 Neil C Smith * Copyright (c) 2016 Isaac Raño Jares * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.glib; import static org.freedesktop.gstreamer.lowlevel.GioAPI.GIO_API; import com.sun.jna.Pointer; public class GInetSocketAddress extends GSocketAddress { public static final String GTYPE_NAME = "GInetSocketAddress"; public GInetSocketAddress(String address, int port) { this(createRawAddress(address, port)); } GInetSocketAddress(Initializer init) { super(init); } public GInetAddress getAddress() { return (GInetAddress) get("address"); } public int getPort() { return (Integer) get("port"); } private static Initializer createRawAddress(String address, int port) { Pointer nativePointer = GIO_API.g_inet_socket_address_new_from_string(address, port); if (nativePointer == null) { throw new GLibException("Can not create "+GInetSocketAddress.class.getSimpleName()+" for "+address+":"+port+", please check that the IP address is valid, with format x.x.x.x"); } return Natives.initializer(nativePointer); } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/GLib.java ================================================ /* * * Copyright (c) 2019 Neil C Smith * Copyright (c) 2018 Ingo Randalf * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer.glib; import java.util.stream.Stream; import org.freedesktop.gstreamer.lowlevel.GlibAPI; import static org.freedesktop.gstreamer.glib.Natives.registration; /** * Miscellaneous Utility Functions — a selection of portable utility functions from GLib * * Documentation derived from https://developer.gnome.org/glib/stable/glib-Miscellaneous-Utility-Functions.html#g-setenv */ public class GLib { /** * Sets an environment variable. On UNIX, both the variable's name and value * can be arbitrary byte strings, except that the variable's name cannot * contain '='. On Windows, they should be in UTF-8. * * Note that on some systems, when variables are overwritten, the memory * used for the previous variables and its value isn't reclaimed. * * You should be mindful of the fact that environment variable handling in * UNIX is not thread-safe, and your program may crash if one thread calls * g_setenv() while another thread is calling getenv(). (And note that many * functions, such as gettext(), call getenv() internally.) This function is * only safe to use at the very start of your program, before creating any * other threads (or creating objects that create worker threads of their * own). * * @param variable the environment variable to set, must not contain '='. * @param value the value to set the variable to. * @param overwrite whether to change the variable if it already exists. * @return FALSE if the environment variable couldn't be set. */ public static boolean setEnv(String variable, final String value, boolean overwrite) { return GlibAPI.GLIB_API.g_setenv(variable, value, overwrite); } /** * Returns the value of an environment variable. * * On UNIX, the name and value are byte strings which might or might not be * in some consistent character set and encoding. On Windows, they are in * UTF-8. On Windows, in case the environment variable's value contains * references to other environment variables, they are expanded. * * @param variable the environment variable to get. * @return the value of the environment variable, or NULL if the environment * variable is not found. */ public static String getEnv(String variable) { return GlibAPI.GLIB_API.g_getenv(variable); } /** * Removes an environment variable from the environment. * * Note that on some systems, when variables are overwritten, the memory * used for the previous variables and its value isn't reclaimed. * * You should be mindful of the fact that environment variable handling in * UNIX is not thread-safe, and your program may crash if one thread calls * g_unsetenv() while another thread is calling getenv(). (And note that * many functions, such as gettext(), call getenv() internally.) This * function is only safe to use at the very start of your program, before * creating any other threads (or creating objects that create worker * threads of their own). * * @param variable the environment variable to remove, must not contain '='. */ public static void unsetEnv(String variable) { GlibAPI.GLIB_API.g_unsetenv(variable); } public static class Types implements NativeObject.TypeProvider { @Override public Stream> types() { return Stream.of( registration(GDate.class, GDate.GTYPE_NAME, GDate::new), registration(GInetAddress.class, GInetAddress.GTYPE_NAME, GInetAddress::new), registration(GSocket.class, GSocket.GTYPE_NAME, GSocket::new), registration(GSocketAddress.class, GSocketAddress.GTYPE_NAME, GSocketAddress::new), registration(GInetSocketAddress.class, GInetSocketAddress.GTYPE_NAME, GInetSocketAddress::new) ); } } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/GLibException.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.glib; /** * Thrown when a gstreamer error occurs. */ public class GLibException extends RuntimeException { /** * Creates a new instance of GLibException without detail message. */ public GLibException() { } /** * Constructs an instance of GLibException with the specified detail message. * * @param msg the detail message. */ public GLibException(String msg) { super(msg); } public GLibException(GError error) { super(error.getMessage()); } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/GMainContext.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.glib; import org.freedesktop.gstreamer.lowlevel.*; import com.sun.jna.Pointer; import static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API; /** * */ public class GMainContext extends RefCountedObject { public GMainContext() { this(Natives.initializer(GLIB_API.g_main_context_new())); } private GMainContext(Initializer init) { super(new Handle(init.ptr, init.ownsHandle), init.needRef); } public int attach(GSource source) { return GLIB_API.g_source_attach(source, this); } public static GMainContext getDefaultContext() { return new GMainContext(Natives.initializer(GLIB_API.g_main_context_default(), false, false)); } private static final class Handle extends RefCountedObject.Handle { public Handle(GPointer ptr, boolean ownsHandle) { super(ptr, ownsHandle); } @Override protected void disposeNativeHandle(GPointer ptr) { GLIB_API.g_main_context_unref(ptr); } @Override protected void ref() { GLIB_API.g_main_context_ref(getPointer()); } @Override protected void unref() { GLIB_API.g_main_context_unref(getPointer()); } } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/GObject.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (C) 2014 Tom Greenwood * Copyright (C) 2009 Levente Farkas * Copyright (C) 2009 Tamas Korodi * Copyright (c) 2009 Andres Colubri * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.glib; import static org.freedesktop.gstreamer.lowlevel.GObjectAPI.GOBJECT_API; import static org.freedesktop.gstreamer.lowlevel.GSignalAPI.GSIGNAL_API; import static org.freedesktop.gstreamer.lowlevel.GValueAPI.GVALUE_API; import java.net.URI; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; import org.freedesktop.gstreamer.lowlevel.GObjectAPI; import org.freedesktop.gstreamer.lowlevel.GObjectAPI.GParamSpec; import org.freedesktop.gstreamer.lowlevel.GType; import org.freedesktop.gstreamer.lowlevel.GValueAPI.GValue; import org.freedesktop.gstreamer.lowlevel.GstTypes; import org.freedesktop.gstreamer.lowlevel.IntPtr; import com.sun.jna.Callback; import com.sun.jna.CallbackThreadInitializer; import com.sun.jna.Native; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; import java.util.Arrays; import java.util.HashSet; import java.util.Set; import org.freedesktop.gstreamer.MiniObject; import org.freedesktop.gstreamer.lowlevel.GObjectPtr; import org.freedesktop.gstreamer.lowlevel.GPointer; import org.freedesktop.gstreamer.lowlevel.GstMiniObjectPtr; /** * GObject is the fundamental type providing the common attributes and methods * for all object types in libraries based on the GObject system. *

* See upstream documentation at https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html * */ public abstract class GObject extends RefCountedObject { private static final Level LIFECYCLE = Level.FINE; private static final Logger LOG = Logger.getLogger(GObject.class.getName()); private static final CallbackThreadInitializer GCALLBACK_THREAD_INIT = new CallbackThreadInitializer(true, Boolean.getBoolean("glib.detachCallbackThreads"), "GCallback"); private static final Map STRONG_REFS = new ConcurrentHashMap(); private static final GObjectAPI.GToggleNotify TOGGLE_NOTIFY = new ToggleNotify(); private final Handle handle; private Map, Map> callbackListeners; protected GObject(Initializer init) { this(new Handle(init.ptr.as(GObjectPtr.class, GObjectPtr::new), init.ownsHandle), init.needRef); } protected GObject(Handle handle, boolean needRef) { super(handle); this.handle = handle; if (handle.ownsReference()) { final boolean is_floating = GOBJECT_API.g_object_is_floating(handle.getPointer()); LOG.log(LIFECYCLE, () -> String.format( "Initialising owned handle for %s floating = %b refs = %d need ref = %b", this.getClass().getName(), is_floating, getRefCount(), needRef)); if (!needRef) { if (is_floating) { // Sink floating ref handle.sink(); } } // If only one ref then this is weak! This would only be the case where we didn't own if (getRefCount() >= 1) { STRONG_REFS.put(this, Boolean.TRUE); } GOBJECT_API.g_object_add_toggle_ref(handle.getPointer(), TOGGLE_NOTIFY, handle.objectID); if (!needRef) { // Toggle ref has created extra reference handle.unref(); } } } public void connect(Class listenerClass, T listener, Callback cb) { String signal = listenerClass.getSimpleName().toLowerCase().replaceAll("_", "-"); connect(signal, listenerClass, listener, cb); } public synchronized void connect(String signal, Class listenerClass, T listener, Callback cb) { Native.setCallbackThreadInitializer(cb, GCALLBACK_THREAD_INIT); addCallback(listenerClass, listener, new SignalCallback(signal, cb)); } public synchronized void disconnect(Class listenerClass, T listener) { removeCallback(listenerClass, listener); } public synchronized void emit(String signal, Object... arguments) { GSIGNAL_API.g_signal_emit_by_name(this, signal, arguments); } public synchronized T emit(Class resultType, String signal, Object... arguments) { PointerByReference pointerToResult = new PointerByReference(null); Object[] fullArguments = Arrays.copyOf(arguments, arguments.length + 1); fullArguments[arguments.length] = pointerToResult; emit(signal, fullArguments); Pointer result = pointerToResult.getValue(); if (result == null) { return null; } else { return Natives.objectFor(result, resultType, false, true); } } /** * Gets the current value of a GObject property. * * @param property The name of the property to get. * * @return A java value representing the GObject property value. */ public Object get(String property) { LOG.entering("GObject", "get", new Object[]{property}); GObjectAPI.GParamSpec propertySpec = findProperty(property); if (propertySpec == null) { throw new IllegalArgumentException("Unknown property: " + property); } final GType propType = propertySpec.value_type; GValue propValue = new GValue(); GVALUE_API.g_value_init(propValue, propType); GOBJECT_API.g_object_get_property(this, property, propValue); if (propType.equals(GType.INT)) { return GVALUE_API.g_value_get_int(propValue); } else if (propType.equals(GType.UINT)) { return GVALUE_API.g_value_get_uint(propValue); } else if (propType.equals(GType.CHAR)) { return Integer.valueOf(GVALUE_API.g_value_get_char(propValue)); } else if (propType.equals(GType.UCHAR)) { return Integer.valueOf(GVALUE_API.g_value_get_uchar(propValue)); } else if (propType.equals(GType.LONG)) { return GVALUE_API.g_value_get_long(propValue).longValue(); } else if (propType.equals(GType.ULONG)) { return GVALUE_API.g_value_get_ulong(propValue).longValue(); } else if (propType.equals(GType.INT64)) { return GVALUE_API.g_value_get_int64(propValue); } else if (propType.equals(GType.UINT64)) { return GVALUE_API.g_value_get_uint64(propValue); } else if (propType.equals(GType.BOOLEAN)) { return GVALUE_API.g_value_get_boolean(propValue); } else if (propType.equals(GType.FLOAT)) { return GVALUE_API.g_value_get_float(propValue); } else if (propType.equals(GType.DOUBLE)) { return GVALUE_API.g_value_get_double(propValue); } else if (propType.equals(GType.STRING)) { return GVALUE_API.g_value_get_string(propValue); } else if (propType.equals(GType.OBJECT)) { return GVALUE_API.g_value_dup_object(propValue); } else if (GVALUE_API.g_value_type_transformable(propType, GType.OBJECT)) { return GVALUE_API.g_value_dup_object(transform(propValue, GType.OBJECT)); } else if (GVALUE_API.g_value_type_transformable(propType, GType.INT)) { return GVALUE_API.g_value_get_int(transform(propValue, GType.INT)); } else if (GVALUE_API.g_value_type_transformable(propType, GType.INT64)) { return GVALUE_API.g_value_get_int64(transform(propValue, GType.INT64)); } else if (propValue.checkHolds(GType.BOXED)) { // @TODO we already know the GType here - optimise this! Class cls = GstTypes.classFor(propType); if (cls != null) { Pointer ptr = GVALUE_API.g_value_get_boxed(propValue); return Natives.objectFor(ptr, cls, true, true); } } throw new IllegalArgumentException("Unknown conversion from GType=" + propType); } /** * Gets the default value set to GObject property. * * @param property The name of the property. * @return A java value representing the GObject property's default * value. */ public Object getPropertyDefaultValue(String property) { GObjectAPI.GParamSpec propertySpec = findProperty(property); if (propertySpec == null) { throw new IllegalArgumentException("Unknown property: " + property); } final GType propType = propertySpec.value_type; return findProperty(property, propType).getDefault(); } /** * Gets the maximum value should be set to GObject property. * * @param property The name of the property. * @return A java value representing the GObject property's maximum * value. */ public Object getPropertyMaximumValue(String property) { GObjectAPI.GParamSpec propertySpec = findProperty(property); if (propertySpec == null) { throw new IllegalArgumentException("Unknown property: " + property); } final GType propType = propertySpec.value_type; return findProperty(property, propType).getMaximum(); } /** * Gets the minimum value should be set to GObject property. * * @param property The name of the property. * @return A java value representing the GObject property's minimum * value. */ public Object getPropertyMinimumValue(String property) { GObjectAPI.GParamSpec propertySpec = findProperty(property); if (propertySpec == null) { throw new IllegalArgumentException("Unknown property: " + property); } final GType propType = propertySpec.value_type; return findProperty(property, propType).getMinimum(); } /** * Get the reference count for an object. Should only really be used for * debugging * * @return The reference count for the object */ public int getRefCount() { // Check if disposed as a disposed object may // have been free'd and we mustn't access it's // memory or we face possible SEGFAULT GPointer ptr = handle.getPointer(); if (ptr != null) { // final GObjectStruct struct = new GObjectStruct(this); // return struct.ref_count; // ref count is after pointer to GTypeInstance int count = ptr.getPointer().getInt(Native.POINTER_SIZE); return count; } return 0; } /** * Get the native GType type name. * @return GType type name */ public String getTypeName() { return handle.getPointer().getGType().getTypeName(); } public List listPropertyNames() { GObjectAPI.GParamSpec[] lst = listProperties(); List result = new ArrayList(lst.length); for (int i = 0; i < lst.length; i++) { result.add(lst[i].g_name); } return result; } /** * Sets the value of a GObject property. * * @param property The property to set. * @param data The value for the property. This must be of the type expected * by gstreamer. As a convenience, NativeEnums will be converted to their * int value. */ public void set(String property, Object data) { LOG.entering("GObject", "set", new Object[]{property, data}); GObjectAPI.GParamSpec propertySpec = findProperty(property); if (propertySpec == null /*|| data == null*/) { throw new IllegalArgumentException("Unknown property: " + property); } if (data instanceof NativeEnum) { data = ((NativeEnum) data).intValue(); } final GType propType = propertySpec.value_type; GValue propValue = new GValue(); GVALUE_API.g_value_init(propValue, propType); if (propType.equals(GType.INT)) { GVALUE_API.g_value_set_int(propValue, intValue(data)); } else if (propType.equals(GType.UINT)) { GVALUE_API.g_value_set_uint(propValue, intValue(data)); } else if (propType.equals(GType.CHAR)) { GVALUE_API.g_value_set_char(propValue, (byte) intValue(data)); } else if (propType.equals(GType.UCHAR)) { GVALUE_API.g_value_set_uchar(propValue, (byte) intValue(data)); } else if (propType.equals(GType.LONG)) { GVALUE_API.g_value_set_long(propValue, new NativeLong(longValue(data))); } else if (propType.equals(GType.ULONG)) { GVALUE_API.g_value_set_ulong(propValue, new NativeLong(longValue(data))); } else if (propType.equals(GType.INT64)) { GVALUE_API.g_value_set_int64(propValue, longValue(data)); } else if (propType.equals(GType.UINT64)) { GVALUE_API.g_value_set_uint64(propValue, longValue(data)); } else if (propType.equals(GType.BOOLEAN)) { GVALUE_API.g_value_set_boolean(propValue, booleanValue(data)); } else if (propType.equals(GType.FLOAT)) { GVALUE_API.g_value_set_float(propValue, floatValue(data)); } else if (propType.equals(GType.DOUBLE)) { GVALUE_API.g_value_set_double(propValue, doubleValue(data)); } else if (propType.equals(GType.STRING)) { // // Special conversion of java URI to gstreamer compatible uri // if (data instanceof URI) { URI uri = (URI) data; String uriString = uri.toString(); // Need to fixup file:/ to be file:/// for gstreamer if ("file".equals(uri.getScheme()) && uri.getHost() == null) { final String path = uri.getRawPath(); uriString = "file://" + path; } GVALUE_API.g_value_set_string(propValue, uriString); } else if (data == null) { GVALUE_API.g_value_set_string(propValue, null); } else { GVALUE_API.g_value_set_string(propValue, data.toString()); } } else if (propType.equals(GType.OBJECT)) { GVALUE_API.g_value_set_object(propValue, (GObject) data); } else if (GVALUE_API.g_value_type_transformable(GType.INT64, propType)) { transform(data, GType.INT64, propValue); } else if (GVALUE_API.g_value_type_transformable(GType.LONG, propType)) { transform(data, GType.LONG, propValue); } else if (GVALUE_API.g_value_type_transformable(GType.INT, propType)) { transform(data, GType.INT, propValue); } else if (GVALUE_API.g_value_type_transformable(GType.DOUBLE, propType)) { transform(data, GType.DOUBLE, propValue); } else if (GVALUE_API.g_value_type_transformable(GType.FLOAT, propType)) { transform(data, GType.FLOAT, propValue); } else { // Old behaviour GOBJECT_API.g_object_set(this, property, data); return; } GOBJECT_API.g_param_value_validate(propertySpec, propValue); GOBJECT_API.g_object_set_property(this, property, propValue); GVALUE_API.g_value_unset(propValue); // Release any memory } protected synchronized void addCallback(Class listenerClass, T listener, GCallback cb) { final Map, Map> signals = getCallbackMap(); Map map = signals.get(listenerClass); if (map == null) { map = new HashMap(); signals.put(listenerClass, map); } map.put(listener, cb); } @Override public void dispose() { super.dispose(); STRONG_REFS.remove(this); } @Override public void invalidate() { try { // Need to increase the ref count before removing the toggle ref, so // ensure the native object is not destroyed. if (handle.ownsReference()) { handle.ref(); // Disconnect the callback. GOBJECT_API.g_object_remove_toggle_ref(handle.getPointer(), TOGGLE_NOTIFY, handle.objectID); } STRONG_REFS.remove(this); } finally { super.invalidate(); } } protected synchronized void removeCallback(Class listenerClass, T listener) { final Map, Map> signals = getCallbackMap(); Map map = signals.get(listenerClass); if (map != null) { GCallback cb = map.remove(listener); if (cb != null) { cb.remove(); } if (map.isEmpty()) { signals.remove(listenerClass); if (callbackListeners.isEmpty()) { callbackListeners = null; } } } } // public static T objectFor(Pointer ptr, Class defaultClass) { // return objectFor(ptr, defaultClass, true); // } private GObjectAPI.GParamSpec findProperty(String propertyName) { Pointer ptr = GOBJECT_API.g_object_class_find_property(getRawPointer().getPointer(0), propertyName); if (ptr == null) { return null; } return new GObjectAPI.GParamSpec(ptr); } private GObjectAPI.GParamSpecTypeSpecific findProperty(String propertyName, GType type) { Pointer ptr = GOBJECT_API.g_object_class_find_property(getRawPointer().getPointer(0), propertyName); if (type.equals(GType.INT)) { return new GObjectAPI.GParamSpecInt(ptr); } else if (type.equals(GType.UINT)) { return new GObjectAPI.GParamSpecUInt(ptr); } else if (type.equals(GType.CHAR)) { return new GObjectAPI.GParamSpecChar(ptr); } else if (type.equals(GType.UCHAR)) { return new GObjectAPI.GParamSpecUChar(ptr); } else if (type.equals(GType.BOOLEAN)) { return new GObjectAPI.GParamSpecBoolean(ptr); } else if (type.equals(GType.LONG)) { return new GObjectAPI.GParamSpecLong(ptr); } else if (type.equals(GType.ULONG)) { return new GObjectAPI.GParamSpecLong(ptr); } else if (type.equals(GType.INT64)) { return new GObjectAPI.GParamSpecInt64(ptr); } else if (type.equals(GType.UINT64)) { return new GObjectAPI.GParamSpecInt64(ptr); } else if (type.equals(GType.FLOAT)) { return new GObjectAPI.GParamSpecFloat(ptr); } else if (type.equals(GType.DOUBLE)) { return new GObjectAPI.GParamSpecDouble(ptr); } else if (type.equals(GType.STRING)) { return new GObjectAPI.GParamSpecString(ptr); } throw new IllegalArgumentException("Unknown conversion from GType=" + type); } private synchronized final Map, Map> getCallbackMap() { if (callbackListeners == null) { callbackListeners = new ConcurrentHashMap, Map>(); } return callbackListeners; } private GObjectAPI.GParamSpec[] listProperties() { IntByReference len = new IntByReference(); Pointer ptrs = GOBJECT_API.g_object_class_list_properties(getRawPointer().getPointer(0), len); if (ptrs == null) { return null; } GParamSpec[] props = new GParamSpec[len.getValue()]; int offset = 0; for (int i = 0; i < len.getValue(); i++) { props[i] = new GObjectAPI.GParamSpec(ptrs.getPointer(offset)); offset += Native.POINTER_SIZE; } return props; } private static boolean booleanValue(Object value) { if (value instanceof Boolean) { return ((Boolean) value).booleanValue(); } else if (value instanceof Number) { return ((Number) value).intValue() != 0; } else if (value instanceof String) { return Boolean.parseBoolean((String) value); } throw new IllegalArgumentException("Expected boolean value, not " + value.getClass()); } private static double doubleValue(Object value) { if (value instanceof Number) { return ((Number) value).doubleValue(); } else if (value instanceof String) { return Double.parseDouble((String) value); } throw new IllegalArgumentException("Expected double value, not " + value.getClass()); } private static float floatValue(Object value) { if (value instanceof Number) { return ((Number) value).floatValue(); } else if (value instanceof String) { return Float.parseFloat((String) value); } throw new IllegalArgumentException("Expected float value, not " + value.getClass()); } private static int intValue(Object value) { if (value instanceof Number) { return ((Number) value).intValue(); } else if (value instanceof String) { return Integer.parseInt((String) value); } throw new IllegalArgumentException("Expected integer value, not " + value.getClass()); } private static long longValue(Object value) { if (value instanceof Number) { return ((Number) value).longValue(); } else if (value instanceof String) { return Long.parseLong((String) value); } throw new IllegalArgumentException("Expected long value, not " + value.getClass()); } private static boolean setGValue(GValue value, GType type, Object data) { if (type.equals(GType.INT)) { GVALUE_API.g_value_set_int(value, intValue(data)); } else if (type.equals(GType.UINT)) { GVALUE_API.g_value_set_uint(value, intValue(data)); } else if (type.equals(GType.CHAR)) { GVALUE_API.g_value_set_char(value, (byte) intValue(data)); } else if (type.equals(GType.UCHAR)) { GVALUE_API.g_value_set_uchar(value, (byte) intValue(data)); } else if (type.equals(GType.LONG)) { GVALUE_API.g_value_set_long(value, new NativeLong(longValue(data))); } else if (type.equals(GType.ULONG)) { GVALUE_API.g_value_set_ulong(value, new NativeLong(longValue(data))); } else if (type.equals(GType.INT64)) { GVALUE_API.g_value_set_int64(value, longValue(data)); } else if (type.equals(GType.UINT64)) { GVALUE_API.g_value_set_uint64(value, longValue(data)); } else if (type.equals(GType.BOOLEAN)) { GVALUE_API.g_value_set_boolean(value, booleanValue(data)); } else if (type.equals(GType.FLOAT)) { GVALUE_API.g_value_set_float(value, floatValue(data)); } else if (type.equals(GType.DOUBLE)) { GVALUE_API.g_value_set_double(value, doubleValue(data)); } else { return false; } return true; } private static GValue transform(GValue src, GType dstType) { GValue dst = new GValue(); GVALUE_API.g_value_init(dst, dstType); GVALUE_API.g_value_transform(src, dst); return dst; } private static void transform(Object data, GType type, GValue dst) { GValue src = new GValue(); GVALUE_API.g_value_init(src, type); setGValue(src, type, data); GVALUE_API.g_value_transform(src, dst); } protected abstract class GCallback { protected final Callback cb; protected final NativeLong id; volatile boolean connected = false; protected GCallback(NativeLong id, Callback cb) { this.id = id != null ? id : new NativeLong(0); this.cb = cb; this.connected = this.id.longValue() != 0; } void remove() { if (connected) { disconnect(); connected = false; } } abstract protected void disconnect(); } /** * Base interface for classes that implement a GInterface */ public static interface GInterface { /** * Get the GObject implementing this interface. * * @return implementing GObject */ public GObject getGObject(); } private final class SignalCallback extends GCallback { protected SignalCallback(String signal, Callback cb) { super(handle.connectSignal(signal, cb), cb); if (!connected) { throw new IllegalArgumentException(String.format("Failed to connect signal '%s'", signal)); } } @Override synchronized protected void disconnect() { handle.disconnectSignal(id); } } protected static class Handle extends RefCountedObject.Handle { private final IntPtr objectID; private final Set signals; public Handle(GObjectPtr ptr, boolean ownsHandle) { super(ptr, ownsHandle); this.objectID = new IntPtr(System.identityHashCode(this)); signals = new HashSet<>(); } private synchronized NativeLong connectSignal(String signal, Callback cb) { NativeLong id = GOBJECT_API.g_signal_connect_data(getPointer(), signal, cb, null, null, 0); if (id.longValue() != 0) { signals.add(id); } return id; } private synchronized void disconnectSignal(NativeLong id) { if (signals.remove(id)) { GOBJECT_API.g_signal_handler_disconnect(getPointer(), id); } } private synchronized void clearSignals() { signals.forEach(id -> GOBJECT_API.g_signal_handler_disconnect(getPointer(), id)); signals.clear(); } @Override public void invalidate() { clearSignals(); super.dispose(); } @Override public void dispose() { clearSignals(); super.dispose(); } @Override protected void disposeNativeHandle(GPointer ptr) { GOBJECT_API.g_object_remove_toggle_ref((GObjectPtr) ptr, TOGGLE_NOTIFY, objectID); } @Override protected void ref() { GOBJECT_API.g_object_ref(getPointer()); } /** * Sink floating reference. This will turn a floating reference into a * real one. */ protected void sink() { GOBJECT_API.g_object_ref_sink(getPointer()); } @Override protected void unref() { GOBJECT_API.g_object_unref(getPointer()); } @Override protected GObjectPtr getPointer() { return (GObjectPtr) super.getPointer(); } @Override public String toString() { GObjectPtr ptr = getPointer(); if (ptr != null) { return ptr.getGType().getTypeName() + " : " + objectID; } else { return "Disposed handle"; } } } private static final class ToggleNotify implements GObjectAPI.GToggleNotify { @Override public void callback(Pointer data, Pointer ptr, boolean is_last_ref) { /* * Manage the strong reference to this instance. When this is the last * reference to the underlying object, remove the strong reference so * it can be garbage collected. If it is owned by someone else, then make * it a strong ref, so the java GObject for the underlying C object can * be retained for later retrieval */ GObject o = (GObject) NativeObject.instanceFor(ptr); if (o == null) { return; } LOG.log(LIFECYCLE, "toggle_ref " + o.getClass().getSimpleName() + " (" + ptr + ")" + " last_ref=" + is_last_ref); if (is_last_ref) { STRONG_REFS.remove(o); } else { STRONG_REFS.put(o, Boolean.TRUE); } } } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/GQuark.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2016 Christophe Lafolet * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.glib; import org.freedesktop.gstreamer.lowlevel.GObjectAPI; /** * Quarks — a 2-way association between a string and a unique integer identifier. * * See upstream documentation at https://developer.gnome.org/glib/stable/glib-Quarks.html * */ public class GQuark { private final int value; public GQuark(int value) { this.value = value; } public int intValue() { return value; } @Override public String toString() { return GObjectAPI.GOBJECT_API.g_quark_to_string(this); } public static GQuark valueOf(String quark) { return GObjectAPI.GOBJECT_API.g_quark_from_string(quark); } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/GSocket.java ================================================ /* * Copyright (c) 2025 Neil C Smith * Copyright (c) 2016 Isaac Raño Jares * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.glib; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.lowlevel.GstAPI.GErrorStruct; import static org.freedesktop.gstreamer.lowlevel.GioAPI.GIO_API; import static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API; public class GSocket extends GObject { public static final String GTYPE_NAME = "GSocket"; public GSocket(GSocketFamily family, GSocketType type, GSocketProtocol protocol) throws GLibException { this(makeRawSocket(family, type, protocol)); } GSocket(Initializer init) { super(init); } public GSocket bind(String address, int port) { GInetSocketAddress boundAddress = new GInetSocketAddress(address, port); GErrorStruct reference = new GErrorStruct(); GErrorStruct[] errorArray = (GErrorStruct[]) reference.toArray(1); if (!GIO_API.g_socket_bind(getRawPointer(), Natives.getRawPointer(boundAddress), true, reference.getPointer())) { throw new GLibException(extractAndClearError(errorArray[0])); } return this; } public void connect(String address, int port) { GInetSocketAddress connectedAddress = new GInetSocketAddress(address, port); GErrorStruct reference = new GErrorStruct(); GErrorStruct[] errorArray = (GErrorStruct[]) reference.toArray(1); if (!GIO_API.g_socket_connect(getRawPointer(), Natives.getRawPointer(connectedAddress), Natives.getRawPointer(new GCancellable()), reference.getPointer())) { throw new GLibException(extractAndClearError(errorArray[0])); } } public int getFD() { return (Integer) get("fd"); } public GInetSocketAddress getLocalAddress() { return (GInetSocketAddress) get("local-address"); } public GInetSocketAddress getRemoteAddress() { return (GInetSocketAddress) get("remote-address"); } public GSocketFamily getSocketFamily() { return GSocketFamily.fromGioValue((Integer) get("family")); } public GSocketProtocol getSocketProtocol() { return GSocketProtocol.fromGioValue((Integer) get("protocol")); } public GSocketType getSocketType() { return GSocketType.fromGioValue((Integer) get("type")); } public boolean isBlocking() { return (Boolean) get("blocking"); } private static String extractAndClearError(GErrorStruct struct) { struct.read(); String err = struct.getMessage(); GLIB_API.g_error_free(struct.getPointer()); return err; } private static Initializer makeRawSocket(GSocketFamily family, GSocketType type, GSocketProtocol protocol) throws GLibException { GErrorStruct reference = new GErrorStruct(); GErrorStruct[] errorArray = (GErrorStruct[]) reference.toArray(1); Pointer socketPointer = GIO_API.g_socket_new(family.toGioValue(), type.toGioValue(), protocol.toGioValue(), reference.getPointer()); if (socketPointer == null) { throw new GLibException(extractAndClearError(errorArray[0])); } return Natives.initializer(socketPointer); } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/GSocketAddress.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2016 Isaac Raño Jares * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.glib; public class GSocketAddress extends GObject{ public static final String GTYPE_NAME = "GSocketAddress"; public GSocketAddress(Initializer init) { super(init); } public GSocketFamily getFamily() { return GSocketFamily.fromGioValue((Integer) get("family")); } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/GSocketFamily.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2016 Isaac Raño Jares * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.glib; import java.util.HashMap; import java.util.Map; import org.freedesktop.gstreamer.lowlevel.GlibAPI; public enum GSocketFamily { INVALID (0x00), UNIX (GlibAPI.GLIB_SYSDEF_AF_UNIX), IPV4 (GlibAPI.GLIB_SYSDEF_AF_INET), IPV6 (GlibAPI.GLIB_SYSDEF_AF_INET6); private static final Map fastResolveMap = new HashMap(); static { for(GSocketFamily dataUnitType : values()) { fastResolveMap.put(dataUnitType.toGioValue(), dataUnitType); } } private int gioValue; private GSocketFamily(int gioValue) { this.gioValue = gioValue; } public int toGioValue() { return gioValue; } public static GSocketFamily fromGioValue(int gioValue) { return fastResolveMap.get(gioValue); } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/GSocketProtocol.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2016 Isaac Raño Jares * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.glib; import java.util.HashMap; import java.util.Map; public enum GSocketProtocol { UNKNOWN (-1), DEFAULT (0), TCP (6), UDP (17), SCTP (132); private static final Map fastResolveMap = new HashMap(); static { for(GSocketProtocol dataUnitType : values()) { fastResolveMap.put(dataUnitType.toGioValue(), dataUnitType); } } private int gioValue; private GSocketProtocol(int gioValue) { this.gioValue = gioValue; } public int toGioValue() { return gioValue; } public static GSocketProtocol fromGioValue(int gioValue) { return fastResolveMap.get(gioValue); } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/GSocketType.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2016 Isaac Raño Jares * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.glib; import java.util.HashMap; import java.util.Map; public enum GSocketType { INVALID (0), STREAM (1), DATAGRAM (2), SEQPACKET (3); private static final Map fastResolveMap = new HashMap(); static { for(GSocketType dataUnitType : values()) { fastResolveMap.put(dataUnitType.toGioValue(), dataUnitType); } } private int gioValue; private GSocketType(int gioValue) { this.gioValue = gioValue; } public int toGioValue() { return gioValue; } public static GSocketType fromGioValue(int gioValue) { return fastResolveMap.get(gioValue); } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/GSource.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.glib; import org.freedesktop.gstreamer.lowlevel.*; import static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API; import java.util.concurrent.Callable; import com.sun.jna.Pointer; /** * */ public class GSource extends RefCountedObject { GSource(Initializer init) { super(new Handle(init.ptr, init.ownsHandle), init.needRef); } public int attach(GMainContext context) { return GLIB_API.g_source_attach(this, context); } public void setCallback(final Callable call) { this.callback = new GlibAPI.GSourceFunc() { public boolean callback(Pointer data) { if (GLIB_API.g_source_is_destroyed(getRawPointer())) { return false; } try { return call.call().booleanValue(); } catch (Exception ex) { return false; } } }; GLIB_API.g_source_set_callback(this, callback, null, null); } private GlibAPI.GSourceFunc callback; private static final class Handle extends RefCountedObject.Handle { Handle(GPointer ptr, boolean ownsHandle) { super(ptr, ownsHandle); } @Override protected void disposeNativeHandle(GPointer ptr) { GLIB_API.g_source_destroy(ptr.getPointer()); GLIB_API.g_source_unref(ptr.getPointer()); } @Override protected void ref() { GLIB_API.g_source_ref(getPointer().getPointer()); } @Override protected void unref() { GLIB_API.g_source_unref(getPointer().getPointer()); } } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/MainContextExecutorService.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.glib; import static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.concurrent.AbstractExecutorService; import java.util.concurrent.Callable; import java.util.concurrent.Delayed; import java.util.concurrent.Executors; import java.util.concurrent.FutureTask; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; /** * Wraps the glib main loop/main context in a ScheduledExecutor interface. */ public class MainContextExecutorService extends AbstractExecutorService implements ScheduledExecutorService { private final List bgTasks = new LinkedList(); private final GMainContext context; private final Callable idleCallback = new Callable() { public Boolean call() throws Exception { // System.out.println("Running g_idle callbacks"); List tasks = new ArrayList(); synchronized (bgTasks) { tasks.addAll(bgTasks); bgTasks.clear(); } for (Runnable r : tasks) { r.run(); } return false; } }; private GSource idleSource = null; private volatile boolean running = true; public MainContextExecutorService(GMainContext context) { this.context = context; } public boolean awaitTermination(long timeout, TimeUnit units) throws InterruptedException { throw new UnsupportedOperationException("Not supported yet."); } public void execute(Runnable runnable) { invokeLater(runnable); } public boolean isShutdown() { return !running; } public boolean isTerminated() { synchronized (bgTasks) { return !isShutdown() && bgTasks.isEmpty(); } } public ScheduledFuture schedule(Runnable runnable, long delay, TimeUnit units) { return new ScheduledTimeout(Executors.callable(runnable), delay, units); } public ScheduledFuture schedule(Callable callable, long delay, TimeUnit units) { return new ScheduledTimeout(callable, delay, units); } public ScheduledFuture scheduleAtFixedRate(Runnable runnable, long initialiDelay, long period, TimeUnit units) { return new ScheduledTimeout(Executors.callable(runnable), initialiDelay, period, units); } public ScheduledFuture scheduleWithFixedDelay(Runnable runnable, long initialiDelay, long delay, TimeUnit units) { return new ScheduledTimeout(Executors.callable(runnable), initialiDelay, delay, units); } public void shutdown() { shutdownNow(); } public List shutdownNow() { List tasks = new ArrayList(); synchronized (bgTasks) { tasks.addAll(bgTasks); bgTasks.clear(); } return tasks; } private void invokeLater(final Runnable r) { // System.out.println("Scheduling idle callbacks"); synchronized (bgTasks) { boolean empty = bgTasks.isEmpty(); bgTasks.add(r); // Only trigger the callback if there were no existing elements in the list // otherwise it is already triggered if (empty) { idleSource = GLIB_API.g_idle_source_new(); idleSource.setCallback(idleCallback); idleSource.attach(context); } } } private class ScheduledTimeout extends FutureTask implements ScheduledFuture { private volatile GSource source; private Callable delayCallback = new Callable() { public Boolean call() { // Now start the periodic timer if (period != 0 && !isCancelled()) { start(period, periodCallback); } // If periodic, don't bother returning a result if (period != 0) { runAndReset(); } else { run(); } return false; } }; private Callable periodCallback = new Callable() { public Boolean call() { runAndReset(); return !isCancelled(); } }; private final long period; private final TimeUnit units; public ScheduledTimeout(Callable call, long delay, TimeUnit units) { this(call, delay, 0, units); } public ScheduledTimeout(Callable call, long delay, long period, TimeUnit units) { super(call); this.period = period; this.units = units; start(delay, delayCallback); } private final int getMilliseconds(long time) { return (int) units.toMillis(time); } private void start(long timeout, Callable callback) { int milliseconds = getMilliseconds(timeout); /* * If the timeout is a multiple of seconds, use the more efficient * g_timeout_add_seconds, if it is available. */ if ((milliseconds % 1000) == 0) { try { source = GLIB_API.g_timeout_source_new_seconds(milliseconds / 1000); } catch (UnsatisfiedLinkError e) { source = GLIB_API.g_timeout_source_new(milliseconds); } } else { source = GLIB_API.g_timeout_source_new(milliseconds); } source.setCallback(callback); source.attach(context); } public long getDelay(TimeUnit units) { throw new UnsupportedOperationException("Not supported yet."); } public int compareTo(Delayed delayed) { //return delayed.getDelay(TimeUnit.MILLISECONDS) throw new UnsupportedOperationException("Not supported yet."); } } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/NativeEnum.java ================================================ /* * Copyright (c) 2020 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.glib; /** * Interface for enums that wrap a native int-based enum. * * @param Java enum type */ public interface NativeEnum> { public int intValue(); /** * Convert a native int value to the specified NativeEnum type. * * @param enum type * @param type enum class * @param intValue native int value * @return enum value * @throws IllegalArgumentException if no enum value matches the specified * native int value */ public static & NativeEnum> T fromInt(Class type, int intValue) { for (T value : type.getEnumConstants()) { if (value.intValue() == intValue) { return value; } } throw new IllegalArgumentException("Value " + intValue + " is unacceptable for " + type.getSimpleName() + " enum"); } /** * Convert a native int value to the specified NativeEnum type, allowing for * a default value (or null) to be returned instead of throwing an exception * on invalid values. * * @param enum type * @param type enum class * @param defValue default value to return if no match (may be null) * @param intValue native int value * @return enum value */ public static & NativeEnum> T fromInt(Class type, T defValue, int intValue) { for (T value : type.getEnumConstants()) { if (value.intValue() == intValue) { return value; } } return defValue; } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/NativeFlags.java ================================================ /* * Copyright (c) 2020 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.glib; import java.util.EnumSet; import java.util.Set; /** * Interface for enums that represent native bit flags. * @param type of flag enum */ public interface NativeFlags> extends NativeEnum { public static & NativeFlags> int toInt(Set flags) { int ret = 0; for (FLAG flag : flags) { ret |= flag.intValue(); } return ret; } public static & NativeFlags> int toInt(EnumSet flags) { int ret = 0; for (FLAG flag : flags) { ret |= flag.intValue(); } return ret; } public static & NativeFlags> EnumSet fromInt(Class type, int val) { EnumSet set = EnumSet.allOf(type); set.removeIf(f -> ((val & f.intValue()) == 0)); return set; } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/NativeObject.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.glib; import java.lang.ref.WeakReference; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; import java.util.logging.Logger; import com.sun.jna.Pointer; import java.lang.ref.ReferenceQueue; import java.util.Objects; import java.util.ServiceLoader; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; import java.util.stream.Stream; import org.freedesktop.gstreamer.Gst; import org.freedesktop.gstreamer.lowlevel.GPointer; import org.freedesktop.gstreamer.lowlevel.GType; import org.freedesktop.gstreamer.lowlevel.GTypedPtr; import org.freedesktop.gstreamer.lowlevel.GstTypes; /** * */ public abstract class NativeObject implements AutoCloseable { private static final Level LIFECYCLE = Level.FINE; private static final Logger LOG = Logger.getLogger(NativeObject.class.getName()); private static final ConcurrentMap INSTANCES = new ConcurrentHashMap<>(); final Handle handle; private final Pointer ptr; // /** // * Creates a new instance of NativeObject // */ protected NativeObject(Handle handle) { this.handle = Objects.requireNonNull(handle); this.ptr = handle.ptrRef.get().getPointer(); if (handle.isCacheable()) { // need to put all nativeRef in map now so WeakReference doesn't go out of scope INSTANCES.put(this.ptr, new NativeRef(this, handle)); } } /** * Disown this object. The underlying native object will no longer be * disposed of when this Java object is explicitly or implicitly disposed. *

* The underlying reference will remain valid. */ public void disown() { LOG.log(LIFECYCLE, "Disowning " + getRawPointer()); handle.ownsReference.set(false); } /** * Implements {@link AutoCloseable#close()} by calling {@link #dispose() }. *

* If writing a NativeObject subclass you almost certainly want to override * dispose() to customize behaviour unless you have a very specific reason * that try-with-resources should work differently. */ @Override public void close() { dispose(); } /** * Dispose this object, and potentially clear (free, unref, etc.) the * underlying native object if this object owns the reference. *

* After calling this method this object should not be used. */ public void dispose() { LOG.log(LIFECYCLE, "Disposing object " + getClass().getName() + " = " + handle); handle.dispose(); } @Override public boolean equals(Object o) { return o instanceof NativeObject && ((NativeObject) o).ptr.equals(ptr); } protected GPointer getPointer() { GPointer ptr = handle.ptrRef.get(); if (ptr == null) { throw new IllegalStateException("Native object has been disposed"); } return ptr; } protected Pointer getRawPointer() { GPointer ptr = handle.ptrRef.get(); if (ptr == null) { throw new IllegalStateException("Native object has been disposed"); } return ptr.getPointer(); } @Override public int hashCode() { return ptr.hashCode(); } /** * Invalidate this object without clearing (free, unref, etc.) the * underlying native object. *

* After calling this method this object should not be used. */ public void invalidate() { LOG.log(LIFECYCLE, () -> "Invalidating object " + this + " = " + getRawPointer()); handle.invalidate(); } @Override public String toString() { return getClass().getSimpleName() + "(" + getRawPointer() + ")"; } static T objectFor(GPointer gptr, Class cls, int refAdjust, boolean ownsHandle) { // Ignore null pointers if (gptr == null) { return null; } NativeObject obj = NativeObject.instanceFor(gptr.getPointer()); if (obj != null && cls.isInstance(obj)) { if (ownsHandle && !obj.handle.ownsReference()) { obj.handle.ownsReference.set(true); } else if (refAdjust < 0) { try { // Lose the extra ref added by gstreamer ((RefCountedObject.Handle) obj.handle).unref(); } catch (ClassCastException ex) { // A none ref-counted object should not get here! LOG.log(LIFECYCLE, "None ref-counted object returned again from caller owns return.", ex); } } return cls.cast(obj); } final GType gtype = gptr instanceof GTypedPtr ? ((GTypedPtr) gptr).getGType() : null; // // For a GObject, MiniObject, ..., use the GType field to find the most // exact class match // if (gtype != null) { TypeRegistration reg = GstTypes.registrationFor(gtype); if (reg != null) { return cls.cast(reg.factory.apply( new Initializer(gptr, refAdjust > 0, ownsHandle))); } } LOG.log(Level.FINE, () -> String.format("Unregistered type requested : %s", cls.getSimpleName())); try { Constructor constructor = cls.getDeclaredConstructor(Initializer.class); constructor.setAccessible(true); T retVal = constructor.newInstance(new Initializer(gptr, refAdjust > 0, ownsHandle)); //retVal.initNativeHandle(ptr, refAdjust > 0, ownsHandle); return retVal; } catch (SecurityException ex) { throw new RuntimeException(ex); } catch (IllegalAccessException ex) { throw new RuntimeException(ex); } catch (InstantiationException ex) { throw new RuntimeException(ex); } catch (NoSuchMethodException ex) { throw new RuntimeException(ex); } catch (InvocationTargetException ex) { throw new RuntimeException(ex); } } static NativeObject instanceFor(Pointer ptr) { WeakReference ref = INSTANCES.get(ptr); // // If the reference was there, but the object it pointed to had been collected, remove it from the map // if (ref != null && ref.get() == null) { INSTANCES.remove(ptr); } return ref != null ? ref.get() : null; } /** * A class for propagating low level pointer arguments up the constructor * chain. * * @see Natives#initializer(com.sun.jna.Pointer, boolean, boolean) */ public static final class Initializer { public final GPointer ptr; public final boolean needRef, ownsHandle; Initializer(GPointer ptr, boolean needRef, boolean ownsHandle) { this.ptr = ptr; this.needRef = needRef; this.ownsHandle = ownsHandle; } } private static final class NativeRef extends WeakReference { private static final boolean REAP_ON_EDT = Boolean.getBoolean("glib.reapOnEDT"); private static final ReferenceQueue QUEUE = new ReferenceQueue<>(); private static final ExecutorService REAPER = Executors.newSingleThreadExecutor((r) -> { Thread t = new Thread(r, "NativeObject Reaper"); t.setDaemon(true); return t; }); static { REAPER.submit(() -> { while (true) { try { NativeRef ref = (NativeRef) QUEUE.remove(); LOG.log(LIFECYCLE, () -> "Disposing of " + ref.type + " : " + ref.handle.ptrRef.get()); if (REAP_ON_EDT) { Gst.invokeLater(ref.handle::dispose); } else { ref.handle.dispose(); } } catch (Throwable t) { LOG.log(Level.WARNING, "Reaper thread exception", t); } } }); } private final Handle handle; private final String type; private NativeRef(NativeObject obj, Handle handle) { super(obj, QUEUE); this.type = obj.getClass().getSimpleName(); this.handle = handle; } } /** * A class for managing the underlying native pointer. */ protected static abstract class Handle { private final AtomicReference ptrRef; private final AtomicBoolean ownsReference; /** * Construct a Handle for the supplied native reference. * * @param ptr native reference * @param ownsReference whether the Handle owns the native reference and * should dispose it when itself disposed. */ public Handle(GPointer ptr, boolean ownsReference) { this.ptrRef = new AtomicReference<>(ptr); this.ownsReference = new AtomicBoolean(ownsReference); } /** * Disown the native reference. After calling this method, * {@link #ownsReference()} will return {@code false}. */ public void disown() { ownsReference.set(false); } /** * Invalidate the handle. After calling this method, {@link #getPointer() * } will return {@code null}, {@link #ownsReference() } will return * {@code false}, and any NativeObject weak reference cached for this * pointer will be removed. Unlike calling {@link #dispose() } the * native handle will not be disposed - {@link #disposeNativeHandle(org.freedesktop.gstreamer.lowlevel.GPointer) * } will not be called. */ public void invalidate() { GPointer ptr = ptrRef.getAndSet(null); ownsReference.set(false); if (ptr != null) { INSTANCES.remove(ptr.getPointer()); } } /** * Dispose the handle, and dispose the native reference if owned by this * handle. After calling this method, {@link #getPointer() * } will return {@code null}, {@link #ownsReference() } will return * {@code false}, and any NativeObject weak reference cached for this * pointer will be removed. */ public void dispose() { GPointer ptr = ptrRef.getAndSet(null); if (ptr != null) { INSTANCES.remove(ptr.getPointer()); if (ownsReference.compareAndSet(true, false)) { disposeNativeHandle(ptr); } } } /** * Control whether a WeakReference to the NativeObject wrapping this * Handle should be created and cached. This means that the same * NativeObject instance will be returned for identical native pointers, * and that the Handle will be disposed automatically when the * NativeObject is garbage collected. *

* The default implementation always returns {@code true}. Subclasses * may override this behaviour if required. * * @return true if the NativeObject should be cached and automatically * disposed */ public boolean isCacheable() { return true; } /** * Subclasses should override this method to dispose of the native * reference (free, unref, etc.). The pointer supplied should be used - * {@link #getPointer()} will return {@code null} by the time this * method is called. * * @param ptr native reference */ protected abstract void disposeNativeHandle(GPointer ptr); /** * Get the native pointer, or null. Subclasses may override to return a * GPointer subclass. * * @return native pointer or null */ protected GPointer getPointer() { return ptrRef.get(); } /** * Test whether this Handle owns the underlying native reference - * should dispose the native reference on {@link #dispose() }. * * @return true if this Handle owns the reference. */ protected boolean ownsReference() { return ownsReference.get(); } } /** * Registration for creating native object subclasses for specific GTypes. * * @see Natives#registration(java.lang.Class, java.lang.String, * java.util.function.Function) * @param type */ public static class TypeRegistration { private final Class javaType; private final String gTypeName; private final Function factory; TypeRegistration(Class javaType, String gTypeName, Function factory) { this.javaType = javaType; this.gTypeName = gTypeName; this.factory = factory; } public Class getJavaType() { return javaType; } public String getGTypeName() { return gTypeName; } public Function getFactory() { return factory; } } /** * Register implementations of this interface via the {@link ServiceLoader} * mechanism to provide new native object registrations externally. */ public static interface TypeProvider { /** * A {@link Stream} of {@link TypeRegistration} to register. * * @return stream of type registrations */ public Stream> types(); } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/Natives.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.glib; import com.sun.jna.Pointer; import java.util.ServiceLoader; import java.util.function.Function; import org.freedesktop.gstreamer.MiniObject; import org.freedesktop.gstreamer.Structure; import org.freedesktop.gstreamer.lowlevel.GObjectPtr; import org.freedesktop.gstreamer.lowlevel.GPointer; import org.freedesktop.gstreamer.lowlevel.GstMiniObjectPtr; import org.freedesktop.gstreamer.lowlevel.GstStructurePtr; /** * Here be Dragons! *

* This class provides utility functions for working with the underlying native * bindings, creating {@link NativeObject} from pointers and extracting native * pointers from NativeObjects. It should normally only be necessary to make use * of these methods if extending the bindings externally or interacting with * other native code. */ public final class Natives { private Natives() { } /** * Create a {@link NativeObject.Initializer} for the provided Pointer. *

* This initializer will own the handle. *

* This initializer will not request a ref increase (only relevant if used * with instance of {@link RefCountedObject}) * * @param ptr native pointer * @return initializer */ public static final NativeObject.Initializer initializer(Pointer ptr) { NativeObject.Initializer initializer = initializer(ptr, false, true); return initializer; } /** * Create a {@link NativeObject.Initializer} for the provided Pointer. *

* This initializer will own the handle. * * @param ptr native pointer * @param needRef whether to request a ref increase (only relevant if used * with instance of {@link RefCountedObject}) * @return initializer */ public static final NativeObject.Initializer initializer(Pointer ptr, boolean needRef) { NativeObject.Initializer initializer = initializer(ptr, needRef, true); return initializer; } /** * Create a {@link NativeObject.Initializer} for the provided Pointer. * * @param ptr native pointer * @param needRef whether to request a ref increase (only relevant if used * with instance of {@link RefCountedObject}) * @param ownsHandle whether the NativeObject will own the handle, and * should dispose of the native resource when GC'd or explicitly disposed. * @return initializer */ public static final NativeObject.Initializer initializer(Pointer ptr, boolean needRef, boolean ownsHandle) { if (ptr == null) { throw new IllegalArgumentException("Invalid native pointer"); } return new NativeObject.Initializer(new GPointer(ptr), needRef, ownsHandle); } /** * Get a {@link NativeObject} instance of the requested type for the * provided Pointer. Will return a cached instance if one already exists. * * @param NativeObject type to return * @param ptr native Pointer * @param cls Class of type T * @param needRef whether to request a ref increase (only relevant if T is * subclass of {@link RefCountedObject}) * @param ownsHandle whether the NativeObject will own the handle, and * should dispose of the native resource when GC'd or explicitly disposed. * @return native object of type T */ public static T objectFor(Pointer ptr, Class cls, boolean needRef, boolean ownsHandle) { return objectFor(ptr, cls, needRef ? 1 : 0, ownsHandle); } /** * Get a {@link NativeObject} instance of the requested type for the * provided Pointer. Will return a cached instance if one already exists. * * @param NativeObject type to return * @param ptr native Pointer * @param cls Class of type T * @param needRef whether to request a ref increase (only relevant if T is * subclass of {@link RefCountedObject}) * @param ownsHandle whether the NativeObject will own the handle, and * should dispose of the native resource when GC'd or explicitly disposed. * @return native object of type T */ public static T objectFor(GPointer ptr, Class cls, boolean needRef, boolean ownsHandle) { return NativeObject.objectFor(ptr, cls, needRef ? 1 : 0, ownsHandle); } /** * Get a {@link NativeObject} instance of the requested type for the * provided Pointer, for use with native functions returning * {@code Transfer Full} or {@code Transfer Floating} results. *

* This method will return a cached instance if one already exists. If the * cached instance is a {@link RefCountedObject} this method will release a * reference. * * @param NativeObject type to return * @param ptr native Pointer * @param cls Class of type T * @return native object of type T */ public static T callerOwnsReturn(Pointer ptr, Class cls) { return objectFor(ptr, cls, -1, true); } /** * Get a {@link NativeObject} instance of the requested type for the * provided Pointer, for use with native functions returning * {@code Transfer Full} or {@code Transfer Floating} results. *

* This method will return a cached instance if one already exists. If the * cached instance is a {@link RefCountedObject} this method will release a * reference. * * @param NativeObject type to return * @param ptr native Pointer * @param cls Class of type T * @return native object of type T */ public static T callerOwnsReturn(GPointer ptr, Class cls) { return NativeObject.objectFor(ptr, cls, -1, true); } private static T objectFor(Pointer ptr, Class cls, int refAdjust, boolean ownsHandle) { final GPointer gptr = GObject.class.isAssignableFrom(cls) ? new GObjectPtr(ptr) : MiniObject.class.isAssignableFrom(cls) ? new GstMiniObjectPtr(ptr) : Structure.class.isAssignableFrom(cls) ? new GstStructurePtr(ptr) : new GPointer(ptr); return NativeObject.objectFor(gptr, cls, refAdjust, ownsHandle); } /** * Get the underlying raw native Pointer for a {@link NativeObject}. * * @param obj native object * @return native pointer * @throws IllegalStateException if the native reference has been * invalidated or disposed */ public static Pointer getRawPointer(NativeObject obj) { return obj.getRawPointer(); } /** * Get the underlying native typed GPointer for a {@link NativeObject}. * * @param obj native object * @return native typed pointer * @throws IllegalStateException if the native reference has been * invalidated or disposed */ public static GPointer getPointer(NativeObject obj) { return obj.getPointer(); } /** * Return whether underlying native pointer is owned by this object. * * @param obj native object which may hold a reference to native pointer * @return whether underlying native pointer is owned by this object */ public static boolean ownsReference(NativeObject obj) { return obj.handle.ownsReference(); } /** * Returns whether this object is valid or not. * * @param obj native object * @return whether this object is valid or not */ public static boolean validReference(NativeObject obj) { return obj.handle.getPointer() != null; } /** * Increase the reference count of a {@link RefCountedObject} * * @param type of object * @param obj object to increase reference count on * @return object */ public static T ref(T obj) { ((RefCountedObject.Handle) obj.handle).ref(); return obj; } /** * Decrease the reference count of a {@link RefCountedObject} * * @param type of object * @param obj object to decrease reference count on * @return object */ public static T unref(T obj) { ((RefCountedObject.Handle) obj.handle).unref(); return obj; } /** * Create a {@link NativeObject.TypeRegistration} for linking * {@link NativeObject} subclasses to GTypes. *

* Be careful to respect the link between Java type hierarchy of registered * classes and the underlying GType hierarchy. eg. if the GType is a * subclass of GObject then the Java type must extend from {@link GObject} *

* The factory function should normally be a constructor reference. *

* Registrations can be provided externally using * {@link NativeObject.TypeProvider} instances registered for use with * {@link ServiceLoader} * * @param Java type * @param javaType Java type class * @param gTypeName name of the GType * @param factory a factory function to return an instance of T given a * {@link NativeObject.Initializer}. Normally a constructor reference - * {@code T::new} * @return registration */ public static NativeObject.TypeRegistration registration(Class javaType, String gTypeName, Function factory) { return new NativeObject.TypeRegistration<>(javaType, gTypeName, factory); } } ================================================ FILE: src/org/freedesktop/gstreamer/glib/RefCountedObject.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.glib; import org.freedesktop.gstreamer.lowlevel.GPointer; /** * A {@link NativeObject} that has an associated reference count */ public abstract class RefCountedObject extends NativeObject { // /** // * Creates a new instance of RefCountedObject // */ // protected RefCountedObject(Initializer init) { // this(new Handle()) // if (init.ownsHandle && init.needRef) { // ref(); // } // } protected RefCountedObject(Handle handle) { super(handle); } protected RefCountedObject(Handle handle, boolean needRef) { super(handle); if (needRef) { handle.ref(); } } // overridden in subclasses // protected abstract void ref(); // // protected abstract void unref(); protected static abstract class Handle extends NativeObject.Handle { public Handle(GPointer ptr, boolean ownsHandle) { super(ptr, ownsHandle); } protected abstract void ref(); protected abstract void unref(); } } ================================================ FILE: src/org/freedesktop/gstreamer/interfaces/ColorBalance.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2009 Tamas Korodi * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.interfaces; import java.util.List; import org.freedesktop.gstreamer.Element; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback; import com.sun.jna.Pointer; import java.util.ArrayList; import org.freedesktop.gstreamer.lowlevel.GlibAPI; import static org.freedesktop.gstreamer.lowlevel.GstColorBalanceAPI.GSTCOLORBALANCE_API; public class ColorBalance extends GstInterface { /** * Wraps the {@link Element} in a ColorBalance interface * * @param element the element to use as a ColorBalance * @return a ColorBalance for the element */ public static final ColorBalance wrap(Element element) { return new ColorBalance(element); } /** * Creates a new ColorBalance instance * * @param element the element that implements the ColorBalance interface */ private ColorBalance(Element element) { super(element, GSTCOLORBALANCE_API.gst_color_balance_get_type()); } /** * Retrieves a list of ColorBalanceChannels from the ColorBalance * * @return a list of color balance channels available on this device */ public List getChannelList() { GlibAPI.GList glist = GSTCOLORBALANCE_API.gst_color_balance_list_channels(this); List list = new ArrayList<>(); GlibAPI.GList next = glist; while (next != null) { if (next.data != null) { list.add(channelFor(next.data, true)); } next = next.next(); } return list; } /** * Retrieves a ColorBalanceChannel for the given Pointer * * @param pointer * @param needRef * @return a ColorBalanceChannel instance */ private final ColorBalanceChannel channelFor(Pointer pointer, boolean needRef) { return new ColorBalanceChannel(this, pointer, needRef, true); } /** * Signal emitted when color balance value changed * * @see #connect(VALUE_CHANGED) * @see #disconnect(VALUE_CHANGED) */ public static interface VALUE_CHANGED { /** * Called when the color balance channel value changes */ public void colorBalanceValueChanged(ColorBalance colorBalance, ColorBalanceChannel channel, int value); } /** * Add a listener for norm-changed messages. * * @param listener the listener to be called when the norm changes */ public void connect(final VALUE_CHANGED listener) { element.connect(VALUE_CHANGED.class, listener, new GstCallback() { @SuppressWarnings("unused") public boolean callback(Pointer colorBalance, ColorBalanceChannel channel, int value) { listener.colorBalanceValueChanged(ColorBalance.this, channel, value); return true; } }); } /** * Disconnect the listener for norm-changed messages. * * @param listener the listener that was registered to receive the message. */ public void disconnect(VALUE_CHANGED listener) { element.disconnect(VALUE_CHANGED.class, listener); } } ================================================ FILE: src/org/freedesktop/gstreamer/interfaces/ColorBalanceChannel.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2009 Tamas Korodi * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.interfaces; import static org.freedesktop.gstreamer.lowlevel.GstColorBalanceAPI.GSTCOLORBALANCE_API; import org.freedesktop.gstreamer.glib.GObject; import org.freedesktop.gstreamer.lowlevel.GstColorBalanceAPI; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.glib.Natives; public class ColorBalanceChannel extends GObject { public static final String GTYPE_NAME = "GstColorBalanceChannel"; private final GstColorBalanceAPI.ColorBalanceChannelStruct struct; private final ColorBalance colorBalance; /** * For internal gstreamer-java use only * * @param init */ ColorBalanceChannel(Initializer init) { super(init); throw new IllegalArgumentException("Cannot instantiate"); } ColorBalanceChannel(ColorBalance colorBalance, Pointer ptr, boolean needRef, boolean ownsHandle) { super(Natives.initializer(ptr, needRef, ownsHandle)); struct = new GstColorBalanceAPI.ColorBalanceChannelStruct(ptr); this.colorBalance = colorBalance; } public String getName() { return struct.getLabel(); } public int getMinValue() { return struct.getMinValue(); } public int getMaxValue() { return struct.getMaxValue(); } public void setValue(int value) { GSTCOLORBALANCE_API.gst_color_balance_set_value(colorBalance, this, value); } public int getValue(int value) { return GSTCOLORBALANCE_API.gst_color_balance_get_value(colorBalance, this); } } ================================================ FILE: src/org/freedesktop/gstreamer/interfaces/GstInterface.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.interfaces; import org.freedesktop.gstreamer.lowlevel.GType; import org.freedesktop.gstreamer.Element; import org.freedesktop.gstreamer.glib.GObject; /** * Base type for all gstreamer interface proxies */ class GstInterface implements GObject.GInterface { protected final Element element; protected GstInterface(Element element, GType type) { this.element = element; } @Override public Element getGObject() { return element; } } ================================================ FILE: src/org/freedesktop/gstreamer/interfaces/Navigation.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2009 Tamas Korodi * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.interfaces; import org.freedesktop.gstreamer.Element; import org.freedesktop.gstreamer.Structure; import static org.freedesktop.gstreamer.lowlevel.GstNavigationAPI.GSTNAVIGATION_API; public class Navigation extends GstInterface { /** * Wraps the {@link Element} in a Navigation interface * * @param element * the element to use as a Navigation * @return a Navigation for the element */ public static final Navigation wrap(Element element) { return new Navigation(element); } /** * Creates a new Navigation instance * * @param element * the element that implements the Navigation interface */ private Navigation(Element element) { super(element, GSTNAVIGATION_API.gst_navigation_get_type()); } public void sendEvent(Structure structure) { GSTNAVIGATION_API.gst_navigation_send_event(this, structure); } public void sendKeyEvent(String event, String key) { GSTNAVIGATION_API.gst_navigation_send_key_event(this, event, key); } public void sendMouseEvent(String event, int button, double x, double y) { GSTNAVIGATION_API.gst_navigation_send_mouse_event(this, event, button, x, y); } } ================================================ FILE: src/org/freedesktop/gstreamer/interfaces/VideoOrientation.java ================================================ /* * Copyright (c) 2019 Neil c Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2009 Tamas Korodi * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.interfaces; import org.freedesktop.gstreamer.Element; import static org.freedesktop.gstreamer.lowlevel.GstVideoOrientationAPI.GSTVIDEOORIENTATION_API; public class VideoOrientation extends GstInterface { /** * Wraps the {@link Element} in a VideoOrientation interface * * @param element * the element to use as a VideoOrientation * @return a VideoOrientation for the element */ public static final VideoOrientation wrap(Element element) { return new VideoOrientation(element); } /** * Creates a new VideoOrientation instance * * @param element * the element that implements the VideoOrientation interface */ private VideoOrientation(Element element) { super(element, GSTVIDEOORIENTATION_API.gst_video_orientation_get_type()); } // public boolean getHflip(boolean flip) { // return GSTVIDEOORIENTATION_API.gst_video_orientation_get_hflip(this, flip); // } // // public boolean getVflip(boolean flip) { // return GSTVIDEOORIENTATION_API.gst_video_orientation_get_vflip(this, flip); // } // // public boolean getHcenter(int center) { // return GSTVIDEOORIENTATION_API.gst_video_orientation_get_hcenter(this, center); // } // // public boolean getVcenter(int center) { // return GSTVIDEOORIENTATION_API.gst_video_orientation_get_vcenter(this, center); // } public boolean setHflip(boolean flip) { return GSTVIDEOORIENTATION_API.gst_video_orientation_set_hflip(this, flip); } public boolean setVflip(boolean flip) { return GSTVIDEOORIENTATION_API.gst_video_orientation_set_vflip(this, flip); } public boolean setHcenter(int center) { return GSTVIDEOORIENTATION_API.gst_video_orientation_set_hcenter(this, center); } public boolean setVcenter(int center) { return GSTVIDEOORIENTATION_API.gst_video_orientation_set_vcenter(this, center); } } ================================================ FILE: src/org/freedesktop/gstreamer/interfaces/VideoOverlay.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2009 Levente Farkas * Copyright (C) 2009 Tamas Korodi * Copyright (C) 2008 Wayne Meissner * Copyright (C) 2003 Ronald Bultje * Copyright (C) 2014 Claus Holst * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.interfaces; import static org.freedesktop.gstreamer.lowlevel.GstVideoOverlayAPI.GSTVIDEOOVERLAY_API; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.BusSyncReply; import org.freedesktop.gstreamer.Element; import org.freedesktop.gstreamer.message.Message; /** * Interface for setting/getting a window system resource on elements * supporting it to configure a window into which to render a video. */ public class VideoOverlay extends GstInterface { /** * Wraps the {@link Element} in a XOverlay interface * * @param element the element to use as a XOverlay * @return a XOverlay for the element */ public static VideoOverlay wrap(Element element) { return new VideoOverlay(element); } /** * Convenience function to check if the given message is a "prepare-window-handle". * This useful for setup native window handles with {@link BusSyncReply}. * * @param message * @return */ public static boolean isPrepareWindowHandleMessage(Message message) { return GSTVIDEOOVERLAY_API.gst_is_video_overlay_prepare_window_handle_message(message); } /** * Creates a new VideoOverlay instance * * @param element the element that implements the overlay interface */ private VideoOverlay(Element element) { super(element, GSTVIDEOOVERLAY_API.gst_video_overlay_get_type()); } /** * Sets the native window for the {@link Element} to use to display video. * * @param handle A native handle to use to display video. */ public void setWindowHandle(long handle) { GSTVIDEOOVERLAY_API.gst_video_overlay_set_window_handle(this, new Pointer(handle)); } /** * Tell an overlay that it has been exposed. This will redraw the current frame * in the drawable even if the pipeline is PAUSED. */ public void expose() { GSTVIDEOOVERLAY_API.gst_video_overlay_expose(this); } /** * Tell an overlay that it should handle events from the window system. * These events are forwared upstream as navigation events. In some window * system, events are not propagated in the window hierarchy if a client is * listening for them. This method allows you to disable events handling * completely from the XOverlay. */ public void handleEvent(boolean handle_events) { GSTVIDEOOVERLAY_API.gst_video_overlay_handle_events(this, handle_events); } /** * Configure a subregion as a video target within the window set by * {@link #setWindowHandle(long)}. If this is not used or not supported * the video will fill the area of the window set as the overlay to 100%. * By specifying the rectangle, the video can be overlaid to a specific * region of that window only. After setting the new rectangle one should * call {@link #expose()} to force a redraw. To unset the region pass -1 * for the width and height parameters. * * This method is needed for non fullscreen video overlay in UI toolkits * that do not support subwindows. * * @param x * @param y * @param width * @param height */ public boolean setRenderRectangle(int x, int y, int width, int height) { return GSTVIDEOOVERLAY_API.gst_video_overlay_set_render_rectangle(this, x, y, width, height); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/AppAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2009 Andres Colubri * Copyright (c) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.Buffer; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.FlowReturn; import org.freedesktop.gstreamer.Sample; import org.freedesktop.gstreamer.elements.AppSink; import org.freedesktop.gstreamer.elements.AppSrc; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import org.freedesktop.gstreamer.lowlevel.annotations.Invalidate; import com.sun.jna.ptr.LongByReference; /** * * @author wayne */ public interface AppAPI extends com.sun.jna.Library { AppAPI APP_API = GstNative.load("gstapp", AppAPI.class); // AppSrc functions GType gst_app_src_get_type(); void gst_app_src_set_caps(AppSrc appsrc, Caps caps); @CallerOwnsReturn Caps gst_app_src_get_caps(AppSrc appsrc); void gst_app_src_set_size(AppSrc appsrc, long size); long gst_app_src_get_size(AppSrc appsrc); void gst_app_src_set_stream_type(AppSrc appsrc, AppSrc.StreamType type); AppSrc.StreamType gst_app_src_get_stream_type(AppSrc appsrc); void gst_app_src_set_max_bytes(AppSrc appsrc, long max); long gst_app_src_get_max_bytes(AppSrc appsrc); void gst_app_src_set_latency(AppSrc appsrc, long min, long max); void gst_app_src_get_latency(AppSrc appsrc, LongByReference min, LongByReference max); void gst_app_src_flush_queued(AppSrc appsrc); FlowReturn gst_app_src_push_buffer(AppSrc appsrc, @Invalidate Buffer buffer); FlowReturn gst_app_src_end_of_stream(AppSrc appsrc); // AppSink functions GType gst_app_sink_get_type(); void gst_app_sink_set_caps(AppSink appsink, Caps caps); @CallerOwnsReturn Caps gst_app_sink_get_caps(AppSink appsink); boolean gst_app_sink_is_eos(AppSink appsink); @CallerOwnsReturn Sample gst_app_sink_pull_preroll(AppSink appsink); @CallerOwnsReturn Sample gst_app_sink_pull_sample(AppSink appsink); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/BaseSinkAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.util.Arrays; import java.util.List; import org.freedesktop.gstreamer.PadMode; import org.freedesktop.gstreamer.Buffer; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.ClockReturn; import org.freedesktop.gstreamer.event.Event; import org.freedesktop.gstreamer.FlowReturn; import org.freedesktop.gstreamer.MiniObject; import org.freedesktop.gstreamer.Pad; import org.freedesktop.gstreamer.query.Query; import org.freedesktop.gstreamer.elements.BaseSink; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GList; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstSegmentStruct; import org.freedesktop.gstreamer.lowlevel.GstElementAPI.GstElementClass; import org.freedesktop.gstreamer.lowlevel.GstElementAPI.GstElementStruct; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import org.freedesktop.gstreamer.query.AllocationQuery; import com.sun.jna.Callback; import com.sun.jna.Library; import com.sun.jna.Pointer; /** * GstBaseSink methods and structures * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/libs/gst/base/gstbasesink.h?h=1.8 */ public interface BaseSinkAPI extends Library { BaseSinkAPI BASESINK_API = GstNative.load("gstbase", BaseSinkAPI.class); int GST_PADDING = GstAPI.GST_PADDING; int GST_PADDING_LARGE = GstAPI.GST_PADDING_LARGE; public static final class GstBaseSinkStruct extends com.sun.jna.Structure { public GstElementStruct element; /*< protected >*/ public volatile Pad sinkpad; public volatile PadMode pad_mode; /*< protected >*/ /* with LOCK */ public volatile long offset; public volatile boolean can_activate_pull; public volatile boolean can_activate_push; /*< protected >*/ /* with PREROLL_LOCK */ public volatile /* GMutex */ Pointer preroll_lock; public volatile /* GCond */ Pointer preroll_cond; public volatile boolean eos; public volatile boolean need_preroll; public volatile boolean have_preroll; public volatile boolean playing_async; /*< protected >*/ /* with STREAM_LOCK */ public volatile boolean have_newsegment; public volatile GstSegmentStruct segment; /*< private >*/ /* with LOCK */ public volatile Pointer /* GstClockID */ clock_id; public volatile boolean sync; public volatile boolean flushing; public volatile boolean running; public volatile long max_lateness; /*< private >*/ public volatile Pointer /* GstBaseSinkPrivate */ priv; /*< private >*/ public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING_LARGE]; public GstBaseSinkStruct(Pointer handle) { super(handle); } @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "element", "sinkpad", "pad_mode", "offset", "can_activate_pull", "can_activate_push", "preroll_lock", "preroll_cond", "eos", "need_preroll", "have_preroll", "playing_async", "have_newsegment", "segment", "clock_id", "sync", "flushing", "running", "max_lateness", "priv", "_gst_reserved" }); } } // -------------- Callbacks ----------------- public static interface GetCaps extends Callback { public Caps callback(BaseSink sink, Caps caps); } public static interface SetCaps extends Callback { public boolean callback(BaseSink sink, Caps caps); } public static interface Fixate extends Callback { public Caps callback(BaseSink sink, Caps caps); } public static interface ActivatePull extends Callback { public boolean callback(BaseSink sink, boolean active); } public static interface GetTimes extends Callback { public void callback(BaseSink sink, Buffer buffer, Pointer /* GstClockTime */ start, Pointer /* GstClockTime */ end); } public static interface ProposeAllocation extends Callback { public boolean callback(BaseSink sink, AllocationQuery query); } public static interface BooleanFunc1 extends Callback { public boolean callback(BaseSink sink); } public static interface QueryNotify extends Callback { public boolean callback(BaseSink sink, Query query); } public static interface EventNotify extends Callback { public boolean callback(BaseSink sink, Event event); } public static interface WaitEventNotify extends Callback { public FlowReturn callback(BaseSink sink, Event event); } public static interface Render extends Callback { public FlowReturn callback(BaseSink sink, Buffer buffer); } public static interface RenderList extends Callback { public FlowReturn callback(BaseSink sink, GList bufferList); } public static final class GstBaseSinkClass extends com.sun.jna.Structure { public GstBaseSinkClass() {} public GstBaseSinkClass(Pointer ptr) { super(ptr); } // // Actual data members // public GstElementClass parent_class; /* get caps from subclass */ public GetCaps get_caps; /* notify subclass of new caps */ public SetCaps set_caps; /* fixate sink caps during pull-mode negotiation */ public Fixate fixate; /* start or stop a pulling thread */ public ActivatePull activate_pull; /* get the start and end times for syncing on this buffer */ public GetTimes get_times; /* propose allocation parameters for upstream */ public ProposeAllocation propose_allocation; /* start and stop processing, ideal for opening/closing the resource */ public BooleanFunc1 start; public BooleanFunc1 stop; /* * unlock any pending access to the resource. subclasses should unlock * any function ASAP. */ public BooleanFunc1 unlock; /* Clear a previously indicated unlock request not that unlocking is * complete. Sub-classes should clear any command queue or indicator they * set during unlock */ public BooleanFunc1 unlock_stop; /* notify subclass of query */ public QueryNotify query; /* notify subclass of event */ public EventNotify event; /* wait for eos or gap, subclasses should chain up to parent first */ public WaitEventNotify wait_event; /* notify subclass of buffer or list before doing sync */ public Render prepare; public RenderList prepare_list; /* notify subclass of preroll buffer or real buffer */ public Render preroll; public Render render; /* Render a BufferList */ public RenderList render_list; /*< private >*/ public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING_LARGE]; @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "parent_class", "get_caps", "set_caps", "fixate", "activate_pull", "get_times", "propose_allocation", "start", "stop", "unlock", "unlock_stop", "query", "event", "wait_event", "prepare", "prepare_list", "preroll", "render", "render_list", "_gst_reserved" }); } } GType gst_base_sink_get_type(); FlowReturn gst_base_sink_do_preroll(BaseSink sink, MiniObject obj); FlowReturn gst_base_sink_wait_preroll(BaseSink sink); /* synchronizing against the clock */ void gst_base_sink_set_sync(BaseSink sink, boolean sync); boolean gst_base_sink_get_sync(BaseSink sink); /* dropping late buffers */ void gst_base_sink_set_max_lateness (BaseSink sink, long max_lateness); long gst_base_sink_get_max_lateness(BaseSink sink); /* performing QoS */ void gst_base_sink_set_qos_enabled(BaseSink sink, boolean enabled); boolean gst_base_sink_is_qos_enabled(BaseSink sink); /* doing async state changes */ void gst_base_sink_set_async_enabled(BaseSink sink, boolean enabled); boolean gst_base_sink_is_async_enabled(BaseSink sink); /* tuning synchronisation */ void gst_base_sink_set_ts_offset(BaseSink sink, long offset); long gst_base_sink_get_ts_offset(BaseSink sink); /* last buffer */ @CallerOwnsReturn Buffer gst_base_sink_get_last_buffer(BaseSink sink); void gst_base_sink_set_last_buffer_enabled(BaseSink sink, boolean enable); boolean gst_base_sink_is_last_buffer_enabled(BaseSink sink); /* latency */ boolean gst_base_sink_query_latency(BaseSink sink, boolean live, boolean upstream_live, long min_latency, long max_latency); long gst_base_sink_get_latency(BaseSink sink); /* render delay */ void gst_base_sink_set_render_delay(BaseSink sink, long delay); long gst_base_sink_get_render_delay(BaseSink sink); /* blocksize */ void gst_base_sink_set_blocksize(BaseSink sink, int blocksize); int gst_base_sink_get_blocksize(BaseSink sink); ClockReturn gst_base_sink_wait_clock(BaseSink sink, long time, /* GstlongDiff */ Pointer jitter); FlowReturn gst_base_sink_wait_eos(BaseSink sink, long time, /* GstlongDiff */ Pointer jitter); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/BaseSrcAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.Buffer; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.event.Event; import org.freedesktop.gstreamer.FlowReturn; import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.Pad; import org.freedesktop.gstreamer.elements.BaseSrc; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstSegmentStruct; import org.freedesktop.gstreamer.lowlevel.GstElementAPI.GstElementClass; import org.freedesktop.gstreamer.lowlevel.GstElementAPI.GstElementStruct; import com.sun.jna.Callback; import com.sun.jna.Library; import com.sun.jna.Pointer; import com.sun.jna.Union; import com.sun.jna.ptr.LongByReference; import java.util.Arrays; import java.util.List; import org.freedesktop.gstreamer.query.Query; /** * GstBaseSrc methods and structures * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/libs/gst/base/gstbasesrc.h?h=1.8 */ public interface BaseSrcAPI extends Library { BaseSrcAPI BASESRC_API = GstNative.load("gstbase", BaseSrcAPI.class); int GST_PADDING = GstAPI.GST_PADDING; int GST_PADDING_LARGE = GstAPI.GST_PADDING_LARGE; public static final class GstBaseSrcStruct extends com.sun.jna.Structure { public GstElementStruct element; /*< protected >*/ public volatile Pad srcpad; /* available to subclass implementations */ /* MT-protected (with LIVE_LOCK) */ public volatile /* GMutex */ Pointer live_lock; public volatile /* GCond */ Pointer live_cond; public volatile boolean is_live; public volatile boolean live_running; /* MT-protected (with LOCK) */ public volatile int blocksize; /* size of buffers when operating push based */ public volatile boolean can_activate_push; /* some scheduling properties */ public volatile boolean random_access; public volatile /* GstClockID */ Pointer clock_id; /* for syncing */ /* MT-protected (with STREAM_LOCK) */ public volatile GstSegmentStruct segment; /* MT-protected (with STREAM_LOCK) */ public volatile boolean need_newsegment; public volatile int num_buffers; public volatile int num_buffers_left; public volatile boolean typefind; public volatile boolean running; public volatile Event pending_seek; public volatile Pointer /* GstBaseSrcPrivate */ priv; /*< private >*/ public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING_LARGE]; @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "element", "srcpad", "live_lock", "live_cond", "is_live", "live_running", "blocksize", "can_activate_push", "random_access", "clock_id", "segment", "need_newsegment", "num_buffers", "num_buffers_left", "typefind", "running", "pending_seek", "priv", "_gst_reserved" }); } } public static final class GstBaseSrcAbiData extends Union { public volatile GstBaseSrcAbi abi; public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING_LARGE - 1]; } public static final class GstBaseSrcAbi extends com.sun.jna.Structure { public volatile boolean typefind; public volatile boolean running; public volatile Pointer /* GstEvent */ pending_seek; @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "typefind", "running", "pending_seek" }); } } // -------------- Callbacks ----------------- public static interface GetCaps extends Callback { public Caps callback(BaseSrc src, Caps filter); } public static interface SetCaps extends Callback { public boolean callback(BaseSrc src, Caps caps); } public static interface BooleanFunc1 extends Callback { public boolean callback(BaseSrc src); } public static interface DecideAllocation extends Callback { public boolean callback(BaseSrc src, Query query); } public static interface GetTimes extends Callback { public void callback(BaseSrc src, Buffer buffer, Pointer /* GstClockTime */ start, Pointer /* GstClockTime */ end); } public static interface GetSize extends Callback { boolean callback(BaseSrc src, LongByReference size); } public static interface EventNotify extends Callback { boolean callback(BaseSrc src, Event event); } public static interface Create extends Callback { public FlowReturn callback(BaseSrc src, long offset, int size, Pointer /* GstBuffer ** */ bufRef); } public static interface Fill extends Callback { public FlowReturn callback(BaseSrc src, long offset, int size, Buffer buffer); } public static interface Seek extends Callback { boolean callback(BaseSrc src, GstSegmentStruct segment); } public static interface QueryFunc extends Callback { boolean callback(BaseSrc src, Query query); } public static interface Fixate extends Callback { public Caps callback(BaseSrc src, Caps caps); } public static interface PrepareSeek extends Callback { boolean callback(BaseSrc src, Event seek, GstSegmentStruct segment); } public static final class GstBaseSrcClass extends com.sun.jna.Structure { public GstBaseSrcClass() {} public GstBaseSrcClass(Pointer ptr) { useMemory(ptr); read(); } // // Actual data members // public GstElementClass parent_class; /*< public >*/ /* virtual methods for subclasses */ /* get caps from subclass */ public GetCaps get_caps; /* decide on caps */ public BooleanFunc1 negotiate; /* called if, in negotation, caps need fixating */ public Fixate fixate; /* notify the subclass of new caps */ public SetCaps set_caps; /* setup allocation query */ public DecideAllocation decide_allocation; /* start and stop processing, ideal for opening/closing the resource */ public BooleanFunc1 start; public BooleanFunc1 stop; /* * Given a buffer, return start and stop time when it should be pushed * out. The base class will sync on the clock using these times. */ public GetTimes get_times; /* get the total size of the resource in bytes */ public GetSize get_size; /* check if the resource is seekable */ public BooleanFunc1 is_seekable; /* Prepare the segment on which to perform do_seek(), converting to the * current basesrc format. */ public PrepareSeek prepare_seek_segment; /* notify subclasses of a seek */ public Seek do_seek; /* unlock any pending access to the resource. subclasses should unlock * any function ASAP. */ public BooleanFunc1 unlock; /* Clear any pending unlock request, as we succeeded in unlocking */ public BooleanFunc1 unlock_stop; /* notify subclasses of a query */ public QueryFunc query; /* notify subclasses of an event */ public EventNotify event; /* ask the subclass to create a buffer with offset and size, the default * implementation will call alloc and fill. */ public Create create; /* ask the subclass to allocate an output buffer. The default implementation * will use the negotiated allocator. */ public Create alloc; public Fill fill; /*< private >*/ public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING_LARGE]; @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "parent_class", "get_caps", "negotiate", "fixate", "set_caps", "decide_allocation", "start", "stop", "get_times", "get_size", "is_seekable", "prepare_seek_segment", "do_seek", "unlock", "unlock_stop", "query", "event", "create", "alloc", "fill", "_gst_reserved" }); } } GType gst_base_src_get_type(); FlowReturn gst_base_src_wait_playing(BaseSrc src); void gst_base_src_set_live(BaseSrc src, boolean live); boolean gst_base_src_is_live(BaseSrc src); void gst_base_src_set_format(BaseSrc src, Format format); boolean gst_base_src_query_latency(BaseSrc src, boolean[] live, long[] min_latency, long[] max_latency); void gst_base_src_set_blocksize(BaseSrc src, long blocksize); long gst_base_src_get_blocksize(BaseSrc src); void gst_base_src_set_do_timestamp(BaseSrc src, boolean timestamp); boolean gst_base_src_get_do_timestamp(BaseSrc src); boolean gst_base_src_new_seamless_segment(BaseSrc src, long start, long stop, long position); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/BaseTransformAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.Buffer; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.event.Event; import org.freedesktop.gstreamer.FlowReturn; import org.freedesktop.gstreamer.Pad; import org.freedesktop.gstreamer.PadDirection; import org.freedesktop.gstreamer.elements.BaseTransform; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstSegmentStruct; import org.freedesktop.gstreamer.lowlevel.GstElementAPI.GstElementClass; import org.freedesktop.gstreamer.lowlevel.GstElementAPI.GstElementStruct; import com.sun.jna.Callback; import com.sun.jna.Library; import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; import java.util.Arrays; import java.util.List; import org.freedesktop.gstreamer.query.Query; /** * GstBaseTransform methods and structures * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/libs/gst/base/gstbasetransform.h?h=1.8 */ public interface BaseTransformAPI extends Library { BaseTransformAPI BASETRANSFORM_API = GstNative.load("gstbase", BaseTransformAPI.class); int GST_PADDING = GstAPI.GST_PADDING; int GST_PADDING_LARGE = GstAPI.GST_PADDING_LARGE; public static final class GstBaseTransformStruct extends com.sun.jna.Structure { public GstElementStruct element; /*< protected >*/ /* source and sink pads */ public volatile Pad sinkpad; public volatile Pad srcpad; /* MT-protected (with STREAM_LOCK) */ public volatile boolean have_segment; public volatile GstSegmentStruct segment; /* Default submit_input_buffer places the buffer here, * for consumption by the generate_output method: */ public volatile Buffer queued_buf; /*< private >*/ public volatile Pointer /* GstBaseTransformPrivate */ priv; public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING_LARGE - 1]; @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "element", "sinkpad", "srcpad", "have_segment", "segment", "queued_buf", "priv", "_gst_reserved" }); } } public static interface TransformCaps extends Callback { public Caps callback(BaseTransform trans, PadDirection direction, Caps caps, Caps filter); } public static interface FixateCaps extends Callback { public Caps callback(BaseTransform trans, PadDirection direction, Caps caps, Caps othercaps); } public static interface AcceptCaps extends Callback { public boolean callback(BaseTransform trans, PadDirection direction, Caps caps); } public static interface SetCaps extends Callback { public boolean callback(BaseTransform trans, Caps incaps, Caps outcaps); } public static interface QueryFunc extends Callback { public boolean callback(BaseTransform trans, PadDirection direction, Query query); } public static interface DecideAllocation extends Callback { public boolean callback(BaseTransform trans, Query query); } public static interface FilterMeta extends Callback { public boolean callback(BaseTransform trans, Query query, GType api, Pointer /* GstStructure */ params); } public static interface ProposeAllocation extends Callback { public boolean callback(BaseTransform trans, Query decide_query, Query query); } public static interface TransformSize extends Callback { public boolean callback(BaseTransform trans, PadDirection direction, Caps caps, int size, Caps othercaps, IntByReference othersize); } public static interface GetUnitSize extends Callback { public boolean callback(BaseTransform trans, Caps caps, IntByReference size); } public static interface BooleanFunc1 extends Callback { public boolean callback(BaseTransform sink); } public static interface EventNotify extends Callback { public boolean callback(BaseTransform trans, Event event); } public static interface PrepareOutput extends Callback { public FlowReturn callback(BaseTransform trans, Buffer input, Pointer /*GstBuffer ** */ outbuf); } public static interface CopyMetadata extends Callback { public boolean callback(BaseTransform trans, Buffer input, Buffer output); } public static interface TransformMeta extends Callback { public boolean callback(BaseTransform trans, Buffer outbuf, Pointer /* GstMeta */ meta, Buffer output); } public static interface BeforeTransform extends Callback { public void callback(BaseTransform trans, Buffer inbuf); } public static interface Transform extends Callback { public FlowReturn callback(BaseTransform trans, Buffer inbuf, Buffer outbuf); } public static interface TransformIp extends Callback { public FlowReturn callback(BaseTransform trans, Buffer buf); } public static interface SubmitInputBuffer extends Callback { public FlowReturn callback(BaseTransform trans, boolean is_discont, Buffer input); } public static interface GenerateOutput extends Callback { public FlowReturn callback(BaseTransform trans, Pointer /* GstBuffer ** */ outbuf); } public static final class GstBaseTransformClass extends com.sun.jna.Structure { public GstBaseTransformClass() {} public GstBaseTransformClass(Pointer ptr) { useMemory(ptr); read(); } // // Actual data members // public GstElementClass parent_class; /*< public >*/ public volatile boolean passthrough_on_same_caps; public volatile boolean transform_ip_on_passthrough; /* virtual methods for subclasses */ public TransformCaps transform_caps; public FixateCaps fixate_caps; public AcceptCaps accept_caps; public SetCaps set_caps; public QueryFunc query; /* decide allocation query for output buffers */ public DecideAllocation decide_allocation; public FilterMeta filter_meta; /* propose allocation query parameters for input buffers */ public ProposeAllocation propose_allocation; /* transform size */ public TransformSize transform_size; public GetUnitSize get_unit_size; /* states */ public BooleanFunc1 start; public BooleanFunc1 stop; /* sink and src pad event handlers */ public EventNotify sink_event; public EventNotify src_event; public PrepareOutput prepare_output_buffer; /* metadata */ public CopyMetadata copy_metadata; public TransformMeta transform_meta; public BeforeTransform before_transform; /* transform */ public Transform transform; public TransformIp transform_ip; public SubmitInputBuffer submit_input_buffer; public GenerateOutput generate_output; /*< private >*/ public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING_LARGE - 2]; @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "parent_class", "passthrough_on_same_caps", "transform_ip_on_passthrough", "transform_caps", "fixate_caps", "accept_caps", "set_caps", "query", "decide_allocation", "filter_meta", "propose_allocation", "transform_size", "get_unit_size", "start", "stop", "sink_event", "src_event", "prepare_output_buffer", "copy_metadata", "transform_meta", "before_transform", "transform", "transform_ip", "submit_input_buffer", "generate_output", "_gst_reserved" }); } } GType gst_base_transform_get_type(); void gst_base_transform_set_passthrough(BaseTransform trans, boolean passthrough); boolean gst_base_transform_is_passthrough(BaseTransform trans); void gst_base_transform_set_in_place(BaseTransform trans, boolean in_place); boolean gst_base_transform_is_in_place(BaseTransform trans); void gst_base_transform_update_qos(BaseTransform trans, double proportion, long diff, long timestamp); void gst_base_transform_set_qos_enabled(BaseTransform trans, boolean enabled); boolean gst_base_transform_is_qos_enabled(BaseTransform trans); void gst_base_transform_set_gap_aware(BaseTransform trans, boolean gap_aware); void gst_base_transform_suggest(BaseTransform trans, Caps caps, int size); void gst_base_transform_reconfigure(BaseTransform trans); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/EnumMapper.java ================================================ /* * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.lang.reflect.Field; import java.util.EnumSet; import org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue; import org.freedesktop.gstreamer.glib.NativeEnum; /** * Maps to and from native int and an Enum value. * @author wayne */ public class EnumMapper { private static final EnumMapper mapper = new EnumMapper(); public static EnumMapper getInstance() { return mapper; } public int intValue(Enum value) { return value instanceof NativeEnum ? ((NativeEnum) value).intValue() : value.ordinal(); } public > E valueOf(int value, Class enumClass) { // // Just loop around all the enum values and find one that matches. // Storing the values in a Map might be faster, but by the time you deal // with locking overhead, its hardly worth it for small enums. // if (NativeEnum.class.isAssignableFrom(enumClass)) { for (E e : EnumSet.allOf(enumClass)) { if (((NativeEnum) e).intValue() == value) { return e; } } } else { for (E e : EnumSet.allOf(enumClass)) { if (e.ordinal() == value) { return e; } } } // // No value found - try to find the default value for unknown values. // This is useful for enums that aren't fixed in stone and/or where you // don't want to throw an Exception for an unknown value. // try { for (Field f : enumClass.getDeclaredFields()) { if (f.getAnnotation(DefaultEnumValue.class) != null) { return Enum.valueOf(enumClass, f.getName()); } } throw new IllegalArgumentException(); } catch (IllegalArgumentException ex) { // // No default, so just give up and throw an exception // throw new IllegalArgumentException("No known Enum mapping for " + enumClass.getName() + " value=" + value); } } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GBoolean.java ================================================ /* * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; /** * */ public class GBoolean { public static final int TRUE = 1; public static final int FALSE = 0; public static int valueOf(boolean value) { return value ? 1 : 0; } public static int valueOf(Boolean value) { return Boolean.TRUE.equals(value) ? 1 : 0; } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GFunctionMapper.java ================================================ /* * Copyright (c) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.lang.reflect.Method; import java.util.Arrays; import java.util.List; import com.sun.jna.NativeLibrary; /** * * @author wayne */ public class GFunctionMapper implements com.sun.jna.FunctionMapper { private final static List stripPrefixes = Arrays.asList("ptr_"); public String getFunctionName(NativeLibrary library, Method method) { String name = method.getName(); for (String prefix : stripPrefixes) { if (name.startsWith(prefix)) { return name.substring(prefix.length()); } } // Default to just returning the name return name; } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GNative.java ================================================ /* * Copyright (c) 2021 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Map; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.NativeLibrary; import com.sun.jna.Platform; /** * */ public final class GNative { private final static String[] nameFormats; static { String defFormats = "%s"; if (Platform.isWindows()) { defFormats = "%s-0|%s|lib%s-0|lib%s"; } else if (Platform.isMac()) { defFormats = "%s.0|%s"; } nameFormats = System.getProperty("gstreamer.GNative.nameFormats", defFormats).split("\\|"); } private GNative() {} public static synchronized T loadLibrary(String name, Class interfaceClass, Map options) { for (String format : nameFormats) try { return loadNativeLibrary(String.format(format, name), interfaceClass, options); } catch (UnsatisfiedLinkError ex) { continue; } throw new UnsatisfiedLinkError("Could not load library: " + name); } private static T loadNativeLibrary(String name, Class interfaceClass, Map options) { T library = interfaceClass.cast(Native.loadLibrary(name, interfaceClass, options)); boolean needCustom = false; search: for (Method m : interfaceClass.getMethods()) for (Class cls : m.getParameterTypes()) if (cls.isArray() && getConverter(cls.getComponentType()) != null) { needCustom = true; break search; } if (!needCustom) return library; // System.out.println("Using custom library proxy for " + interfaceClass.getName()); return interfaceClass.cast( Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class[]{ interfaceClass }, new Handler(library, options))); } public static synchronized NativeLibrary getNativeLibrary(String name) { for (String format : nameFormats) try { return NativeLibrary.getInstance(String.format(format, name)); } catch (UnsatisfiedLinkError ex) { continue; } throw new UnsatisfiedLinkError("Could not load library: " + name); } private static interface Converter { Class nativeType(); Object toNative(Object value); Object fromNative(Object value, Class javaType); } private static final Converter enumConverter = new Converter() { public Class nativeType() { return int.class; } public Object toNative(Object value) { return value != null ? EnumMapper.getInstance().intValue((Enum) value) : 0; } @SuppressWarnings({"unchecked","rawtypes"}) public Object fromNative(Object value, Class javaType) { return EnumMapper.getInstance().valueOf((Integer) value, javaType); } }; private static final Converter booleanConverter = new Converter() { public Class nativeType() { return int.class; } public Object toNative(Object value) { return value != null ? Boolean.TRUE.equals(value) ? 1 : 0 : 0; } @SuppressWarnings("rawtypes") public Object fromNative(Object value, Class javaType) { return value != null ? ((Integer) value).intValue() != 0 : 0; } }; private static Converter getConverter(Class javaType) { if (Enum.class.isAssignableFrom(javaType)) return enumConverter; else if (boolean.class == javaType || Boolean.class == javaType) return booleanConverter; return null; } private static class Handler implements InvocationHandler { private final InvocationHandler proxy; @SuppressWarnings("unused") // Keep a reference to stop underlying Library being GC'd private final T library; public Handler(T library, Map options) { this.library = library; this.proxy = Proxy.getInvocationHandler(library); } @SuppressWarnings("null") public Object invoke(Object self, Method method, Object[] args) throws Throwable { int lastArg = args != null ? args.length : 0; if (method.isVarArgs()) --lastArg; Runnable[] postInvoke = null; int postCount = 0; for (int i = 0; i < lastArg; ++i) { if (args[i] == null) continue; final Class cls = args[i].getClass(); if (!cls.isArray() || cls.getComponentType().isPrimitive() || cls.getComponentType() == String.class) continue; final Converter converter = getConverter(cls.getComponentType()); if (converter != null) { final Object[] src = (Object[]) args[i]; final Object dst = java.lang.reflect.Array.newInstance(converter.nativeType(), src.length); final ArrayIO io = getArrayIO(converter.nativeType()); for (int a = 0; a < src.length; ++a) io.set(dst, a, converter.toNative(src[a])); if (postInvoke == null) postInvoke = new Runnable[lastArg]; postInvoke[postCount++] = new Runnable() { public void run() { for (int a = 0; a < src.length; ++a) src[a] = converter.fromNative(io.get(dst, a), cls.getComponentType()); } }; args[i] = dst; } } Object retval = proxy.invoke(self, method, args); // // Reload any native arrays into java arrays // for (int i = 0; i < postCount; ++i) postInvoke[i].run(); return retval; } @SuppressWarnings("unused") Class getNativeClass(Class cls) { if (cls == Integer.class) return int.class; else if (cls == Long.class) return long.class; return cls; } private static interface ArrayIO { public void set(Object array, int index, Object data); public Object get(Object array, int index); } private static final ArrayIO intArrayIO = new ArrayIO() { public void set(Object array, int index, Object data) { java.lang.reflect.Array.setInt(array, index, data != null ? (Integer) data : 0); } public Object get(Object array, int index) { return java.lang.reflect.Array.getInt(array, index); } }; private static final ArrayIO longArrayIO = new ArrayIO() { public void set(Object array, int index, Object data) { java.lang.reflect.Array.setLong(array, index, data != null ? (Long) data : 0); } public Object get(Object array, int index) { return java.lang.reflect.Array.getLong(array, index); } }; private static ArrayIO getArrayIO(final Class cls) { if (cls == int.class || cls == Integer.class) return intArrayIO; else if (cls == long.class || cls == Long.class) return longArrayIO; throw new IllegalArgumentException("No such conversion"); } } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GObjectAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2008 Andres Colubri * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import org.freedesktop.gstreamer.glib.GObject; import org.freedesktop.gstreamer.glib.GQuark; import org.freedesktop.gstreamer.lowlevel.GValueAPI.GValue; import com.sun.jna.Callback; import com.sun.jna.Library; import com.sun.jna.Native; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import com.sun.jna.Structure.ByReference; import com.sun.jna.ptr.IntByReference; /** * */ @SuppressWarnings("serial") public interface GObjectAPI extends Library { GObjectAPI GOBJECT_API = GNative.loadLibrary("gobject-2.0", GObjectAPI.class, new HashMap() {{ put(Library.OPTION_TYPE_MAPPER, new GTypeMapper()); }}); GType g_object_get_type(); void g_param_value_validate(GParamSpec spec, GValue data); void g_object_set_property(GObject obj, String property, GValue data); void g_object_get_property(GObject obj, String property, GValue data); void g_object_set(GObject obj, String propertyName, Object... data); void g_object_get(GObject obj, String propertyName, Object... data); Pointer g_object_class_list_properties(Pointer oclass, IntByReference size); Pointer g_object_new(GType object_type, Object... args); interface GClosureNotify extends Callback { void callback(Pointer data, Pointer closure); } // NativeLong g_signal_connect_data(GObject obj, String signal, Callback callback, Pointer data, // GClosureNotify destroy_data, int connect_flags); // void g_signal_handler_disconnect(GObject obj, NativeLong id); NativeLong g_signal_connect_data(GObjectPtr obj, String signal, Callback callback, Pointer data, GClosureNotify destroy_data, int connect_flags); void g_signal_handler_disconnect(GObjectPtr obj, NativeLong id); boolean g_object_is_floating(GObjectPtr obj); /** Sink floating ref * https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#g-object-ref-sink */ Pointer g_object_ref_sink(Pointer ptr); GObjectPtr g_object_ref_sink(GObjectPtr ptr); interface GToggleNotify extends Callback { void callback(Pointer data, Pointer obj, boolean is_last_ref); } void g_object_add_toggle_ref(Pointer object, GToggleNotify notify, Pointer data); void g_object_remove_toggle_ref(Pointer object, GToggleNotify notify, Pointer data); void g_object_add_toggle_ref(GObjectPtr object, GToggleNotify notify, IntPtr data); void g_object_remove_toggle_ref(GObjectPtr object, GToggleNotify notify, IntPtr data); interface GWeakNotify extends Callback { void callback(IntPtr data, Pointer obj); } void g_object_weak_ref(GObject object, GWeakNotify notify, IntPtr data); void g_object_weak_unref(GObject object, GWeakNotify notify, IntPtr data); Pointer g_object_ref(GObjectPtr object); void g_object_unref(GObjectPtr object); GParamSpec g_object_class_find_property(GObjectClass oclass, String property_name); Pointer g_object_class_find_property(Pointer oclass, String property_name); GQuark g_quark_try_string(String string); GQuark g_quark_from_static_string(String string); GQuark g_quark_from_string(String string); String g_quark_to_string(GQuark quark); String g_intern_string(String string); String g_intern_static_string(String string); void g_type_init(); void g_type_init_with_debug_flags(int flags); String g_type_name(GType type); //GQuark g_type_qname (GType type); GType g_type_from_name(String name); GType g_type_parent(GType type); int g_type_depth(GType type); Pointer g_type_create_instance(GType type); void g_type_free_instance(Pointer instance); boolean g_type_is_a(GType type, GType is_a_type); GType g_type_register_static(GType parent_type, String type_name, GTypeInfo info, /* GTypeFlags */ int flags); GType g_type_register_static(GType parent_type, Pointer type_name, GTypeInfo info, /* GTypeFlags */ int flags); GType g_type_register_static_simple(GType parent_type, String type_name, int class_size, GClassInitFunc class_init, int instance_size, GInstanceInitFunc instance_init, /* GTypeFlags */ int flags); GType g_type_register_static_simple(GType parent_type, Pointer type_name, int class_size, GClassInitFunc class_init, int instance_size, GInstanceInitFunc instance_init, /* GTypeFlags */ int flags); /* * Basic Type Structures */ public static class GTypeClass extends com.sun.jna.Structure { /*< private >*/ public volatile GType g_type; @Override protected List getFieldOrder() { return Collections.singletonList("g_type"); } } public static final class GTypeClassByReference extends GTypeClass implements ByReference { // } public static final class GTypeInstance extends com.sun.jna.Structure { /*< private >*/ public volatile GTypeClassByReference g_class; @Override protected List getFieldOrder() { return Collections.singletonList("g_class"); } } public static final class GObjectStruct extends com.sun.jna.Structure { public volatile GTypeInstance g_type_instance; public volatile int ref_count; public volatile Pointer qdata; public GObjectStruct() {} public GObjectStruct(GObjectPtr ptr) { super(ptr.getPointer()); read(); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "g_type_instance", "ref_count", "qdata" }); } } public static final class GObjectConstructParam { public volatile Pointer spec; public volatile Pointer value; } public static final class GObjectClass extends com.sun.jna.Structure { public volatile GTypeClass g_type_class; public volatile Pointer construct_properties; public Constructor constructor; public SetProperty set_property; public GetProperty get_property; public Dispose dispose; public Finalize finalize; public volatile Pointer dispatch_properties_changed; public Notify notify; public volatile byte[] p_dummy = new byte[8 * Native.POINTER_SIZE]; public static interface Constructor extends Callback { public Pointer callback(GType type, int n_construct_properties, GObjectConstructParam properties); }; public static interface SetProperty extends Callback { public void callback(GObject object, int property_id, Pointer value, Pointer spec); } public static interface GetProperty extends Callback { public void callback(GObject object, int property_id, Pointer value, Pointer spec); } public static interface Dispose extends Callback { public void callback(GObject object); } public static interface Finalize extends Callback { public void callback(GObject object); } public static interface Notify extends Callback { public void callback(GObject object, Pointer spec); } public GObjectClass() {} public GObjectClass(Pointer ptr) { super(ptr); read(); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "g_type_class", "construct_properties", "constructor", "set_property", "get_property", "dispose", "finalize", "dispatch_properties_changed", "notify", "p_dummy" }); } } public static interface GBaseInitFunc extends Callback { public void callback(Pointer g_class); } public static interface GBaseFinalizeFunc extends Callback { public void callback(Pointer g_class); } public static interface GClassInitFunc extends Callback { public void callback(Pointer g_class, Pointer class_data); } public static interface GClassFinalizeFunc extends Callback { public void callback(Pointer g_class, Pointer class_data); } public static interface GInstanceInitFunc extends Callback { void callback(GTypeInstance instance, Pointer g_class); } public static final class GTypeInfo extends com.sun.jna.Structure { public GTypeInfo() { clear(); } public GTypeInfo(Pointer ptr) { super(ptr); read(); } /* interface types, classed types, instantiated types */ public short class_size; public GBaseInitFunc base_init; public GBaseFinalizeFunc base_finalize; /* interface types, classed types, instantiated types */ public GClassInitFunc class_init; public GClassFinalizeFunc class_finalize; public Pointer class_data; /* instantiated types */ public short instance_size; public short n_preallocs; public GInstanceInitFunc instance_init; /* value handling */ public volatile /* GTypeValueTable */ Pointer value_table; @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "class_size", "base_init", "base_finalize", "class_init", "class_finalize", "class_data", "instance_size", "n_preallocs", "instance_init", "value_table" }); } } public static abstract class GParamSpecTypeSpecific extends com.sun.jna.Structure { public abstract Object getMinimum(); public abstract Object getMaximum(); public abstract Object getDefault(); public GParamSpecTypeSpecific() { clear(); } public GParamSpecTypeSpecific(Pointer ptr) { super(ptr); } } public static final class GParamSpecBoolean extends GParamSpecTypeSpecific { public volatile GParamSpec parent_instance; public volatile boolean default_value; public Object getMinimum() { return null; } public Object getMaximum() { return null; } public Object getDefault() { return default_value; } public GParamSpecBoolean(Pointer ptr) { super(ptr); read(); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "parent_instance", "default_value" }); } } public static final class GParamSpecInt extends GParamSpecTypeSpecific { public volatile GParamSpec parent_instance; public volatile int minimum; public volatile int maximum; public volatile int default_value; public Object getMinimum() { return minimum; } public Object getMaximum() { return maximum; } public Object getDefault() { return default_value; } public GParamSpecInt(Pointer ptr) { super(ptr); read(); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "parent_instance", "minimum", "maximum", "default_value" }); } } public static final class GParamSpecUInt extends GParamSpecTypeSpecific { public volatile GParamSpec parent_instance; public volatile int minimum; public volatile int maximum; public volatile int default_value; public Object getMinimum() { return ((long)minimum)&0xffffff; } public Object getMaximum() { return ((long)maximum)&0xffffff; } public Object getDefault() { return ((long)default_value)&0xffffff; } public GParamSpecUInt(Pointer ptr) { super(ptr); read(); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "parent_instance", "minimum", "maximum", "default_value" }); } } public static final class GParamSpecChar extends GParamSpecTypeSpecific { public volatile GParamSpec parent_instance; public volatile byte minimum; public volatile byte maximum; public volatile byte default_value; public Object getMinimum() { return minimum; } public Object getMaximum() { return maximum; } public Object getDefault() { return default_value; } public GParamSpecChar(Pointer ptr) { super(ptr); read(); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "parent_instance", "minimum", "maximum", "default_value" }); } } public static final class GParamSpecUChar extends GParamSpecTypeSpecific { public volatile GParamSpec parent_instance; public volatile byte minimum; public volatile byte maximum; public volatile byte default_value; public Object getMinimum() { return ((short)minimum)&0xff; } public Object getMaximum() { return ((short)maximum)&0xff; } public Object getDefault() { return ((short)default_value)&0xff; } public GParamSpecUChar(Pointer ptr) { super(ptr); read(); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "parent_instance", "minimum", "maximum", "default_value" }); } } public static final class GParamSpecLong extends GParamSpecTypeSpecific { public volatile GParamSpec parent_instance; public volatile NativeLong minimum; public volatile NativeLong maximum; public volatile NativeLong default_value; public Object getMinimum() { return minimum; } public Object getMaximum() { return maximum; } public Object getDefault() { return default_value; } public GParamSpecLong(Pointer ptr) { super(ptr); read(); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "parent_instance", "minimum", "maximum", "default_value" }); } } public static final class GParamSpecInt64 extends GParamSpecTypeSpecific { public volatile GParamSpec parent_instance; public volatile long minimum; public volatile long maximum; public volatile long default_value; public Object getMinimum() { return minimum; } public Object getMaximum() { return maximum; } public Object getDefault() { return default_value; } public GParamSpecInt64(Pointer ptr) { super(ptr); read(); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "parent_instance", "minimum", "maximum", "default_value" }); } } public static final class GParamSpecFloat extends GParamSpecTypeSpecific { public volatile GParamSpec parent_instance; public volatile float minimum; public volatile float maximum; public volatile float default_value; public volatile float epsilon; public Object getMinimum() { return minimum; } public Object getMaximum() { return maximum; } public Object getDefault() { return default_value; } public GParamSpecFloat(Pointer ptr) { super(ptr); read(); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "parent_instance", "minimum", "maximum", "default_value", "epsilon" }); } } public static final class GParamSpecDouble extends GParamSpecTypeSpecific { public volatile GParamSpec parent_instance; public volatile double minimum; public volatile double maximum; public volatile double default_value; public volatile double epsilon; public Object getMinimum() { return minimum; } public Object getMaximum() { return maximum; } public Object getDefault() { return default_value; } public GParamSpecDouble(Pointer ptr) { super(ptr); read(); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "parent_instance", "minimum", "maximum", "default_value", "epsilon" }); } } public static final class GParamSpecString extends GParamSpecTypeSpecific { public volatile GParamSpec parent_instance; public volatile String default_value; public volatile String cset_first; public volatile String cset_nth; public volatile byte substitutor; public volatile int null_fold_if_empty_ensure_non_null; public Object getMinimum() { return null; } public Object getMaximum() { return null; } public Object getDefault() { return default_value; } public GParamSpecString(Pointer ptr) { super(ptr); read(); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "parent_instance", "default_value", "cset_first", "cset_nth", "substitutor", "null_fold_if_empty_ensure_non_null" }); } } public static final class GParamSpec extends com.sun.jna.Structure { public volatile GTypeInstance g_type_instance; public volatile String g_name; public volatile /* GParamFlags */ int g_flags; public volatile GType value_type; public volatile GType owner_type; /*< private >*/ public volatile Pointer _nick; public volatile Pointer _blurb; public volatile Pointer qdata; public volatile int ref_count; public volatile int param_id; /* sort-criteria */ public GParamSpec() { clear(); } public GParamSpec(Pointer ptr) { super(ptr); read(); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "g_type_instance", "g_name", "g_flags", "value_type", "owner_type", "_nick", "_blurb", "qdata", "ref_count", "param_id" }); } /* public String getName() { return (String) readField("g_name"); } public int getFlags() { return (Integer) readField("g_flags"); } public GType getValueType() { return (GType) readField("value_type"); } public GType getOwnerType() { return (GType) readField("owner_type"); } public void read() {} public void write() {} */ } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GObjectPtr.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Native; import com.sun.jna.Pointer; /** * Base GObject pointer */ public class GObjectPtr extends GTypedPtr { public GObjectPtr() { } public GObjectPtr(Pointer ptr) { super(ptr); } @Override public GType getGType() { // Quick getter for GType without allocation // same as : new GObjectStruct(ptr).g_type_instance.g_class.g_type Pointer g_class = getPointer().getPointer(0); if (Native.SIZE_T_SIZE == 8) { return GType.valueOf(g_class.getLong(0)); } else if (Native.SIZE_T_SIZE == 4) { return GType.valueOf(((long) g_class.getInt(0)) & 0xffffffffL); } else { throw new IllegalStateException("SIZE_T size not supported: " + Native.SIZE_T_SIZE); } } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GPointer.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; import com.sun.jna.PointerType; import java.util.function.Function; /** * Base GLib pointer */ public class GPointer extends PointerType { public GPointer() { } public GPointer(Pointer ptr) { super(ptr); } public T as(Class cls, Function converter) { if (cls.isInstance(this)) { return cls.cast(this); } else { return converter.apply(this.getPointer()); } } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GSignalAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.util.Arrays; import java.util.HashMap; import java.util.List; import org.freedesktop.gstreamer.glib.GObject; import org.freedesktop.gstreamer.glib.GQuark; import org.freedesktop.gstreamer.lowlevel.GObjectAPI.GClosureNotify; import com.sun.jna.Callback; import com.sun.jna.Library; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; /** * * @author wayne */ @SuppressWarnings("serial") public interface GSignalAPI extends Library { GSignalAPI GSIGNAL_API = GNative.loadLibrary("gobject-2.0", GSignalAPI.class, new HashMap() {{ put(Library.OPTION_TYPE_MAPPER, new GTypeMapper()); }}); public static int G_CONNECT_AFTER = 1 << 0; public static int G_CONNECT_SWAPPED = 1 << 1; public static final class GSignalQuery extends com.sun.jna.Structure { public int signal_id; public String signal_name; public GType itype; public int /* GSignalFlags */ signal_flags; public GType return_type; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */ public int n_params; public Pointer param_types; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */ @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "signal_id", "signal_name", "itype", "signal_flags", "return_type", "n_params", "param_types" }); } } NativeLong g_signal_connect_data(GObject obj, String signal, Callback callback, Pointer data, GClosureNotify destroy_data, int connect_flags); void g_signal_handler_disconnect(GObject obj, NativeLong id); int g_signal_lookup(String name, GType itype); String g_signal_name(int signal_id); void g_signal_query(int signal_id, GSignalQuery query); int g_signal_list_ids(GType itype, int[] n_ids); void g_signal_emit(GObject obj, int signal_id, GQuark detail, Object... arguments); void g_signal_emit_by_name(GObject obj, String signal, Object... arguments); // Do nothing, but provide a base Callback class that gets automatic type conversion public static interface GSignalCallbackProxy extends com.sun.jna.CallbackProxy {} } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GType.java ================================================ /* * Copyright (c) 2020 Christophe Lafolet * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import com.sun.jna.FromNativeContext; import com.sun.jna.IntegerType; import com.sun.jna.Native; import static org.freedesktop.gstreamer.lowlevel.GObjectAPI.GOBJECT_API; /** * */ @SuppressWarnings("serial") public class GType extends IntegerType { /** Size of a native GType, in bytes. */ public static final int SIZE = Native.SIZE_T_SIZE; private static final int G_TYPE_FUNDAMENTAL_SHIFT = 2; private static final Map gTypeByValues = new ConcurrentHashMap(); private static final Map gTypeByNames = new ConcurrentHashMap(); public static final GType INVALID = init(0); public static final GType NONE = init(1); public static final GType INTERFACE = init(2); public static final GType CHAR = init(3); public static final GType UCHAR = init(4); public static final GType BOOLEAN = init(5); public static final GType INT = init(6); public static final GType UINT = init(7); public static final GType LONG = init(8); public static final GType ULONG = init(9); public static final GType INT64 = init(10); public static final GType UINT64 = init(11); public static final GType ENUM = init(12); public static final GType FLAGS = init(13); public static final GType FLOAT = init(14); public static final GType DOUBLE = init(15); public static final GType STRING = init(16); public static final GType POINTER = init(17); public static final GType BOXED = init(18); public static final GType PARAM = init(19); public static final GType OBJECT = init(20); public static final GType VARIANT = init(21); // descriptions set in lazy private GType parent; private String name; /** * @param value the fundamental type number. * @return the GType */ private static GType init(int value) { return valueOf(value << G_TYPE_FUNDAMENTAL_SHIFT); } protected GType(long t) { super(SIZE, t); } /** * Default constructor needed by NativeMappedConverter */ public GType() { this(0L); } public static GType valueOf(long value) { return gTypeByValues.computeIfAbsent(value, GType::new); } public static GType valueOf(String typeName) { GType result = gTypeByNames.get(typeName); if (result == null) { result = GOBJECT_API.g_type_from_name(typeName); if (result.equals(INVALID)) { // no type has been registered yet } else { gTypeByNames.put(typeName, result); result.name = typeName; } } return result; } // FIXME : to move in GstTypes public static GType valueOf(Class javaType) { if (Integer.class == javaType || int.class == javaType) { return INT; } else if (Long.class == javaType || long.class == javaType) { return INT64; } else if (Float.class == javaType || float.class == javaType) { return FLOAT; } else if (Double.class == javaType || double.class == javaType) { return DOUBLE; } else if (String.class == javaType) { return STRING; } else { throw new IllegalArgumentException("No GType for " + javaType); } } @Override public Object fromNative(Object nativeValue, FromNativeContext context) { return GType.valueOf(((Number) nativeValue).longValue()); } /** * Return the direct parent type of the current type. * @return the direct parent type or INVALID if the type has no parent */ public GType getParentType() { if (this.parent == null) this.parent = GOBJECT_API.g_type_parent(this); return this.parent; } public String getTypeName() { if (this.name == null) { this.name = GOBJECT_API.g_type_name(this); gTypeByNames.put(this.name, this); } return this.name; } @Override public String toString() { String gtypeName = this.equals(INVALID) ? "invalid" : this.getTypeName(); return "[" + gtypeName + ":" + super.longValue() + "]"; } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GTypeMapper.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.net.URI; import org.freedesktop.gstreamer.glib.GQuark; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import org.freedesktop.gstreamer.lowlevel.annotations.ConstField; import org.freedesktop.gstreamer.lowlevel.annotations.FreeReturnValue; import org.freedesktop.gstreamer.lowlevel.annotations.IncRef; import org.freedesktop.gstreamer.lowlevel.annotations.Invalidate; import com.sun.jna.CallbackParameterContext; import com.sun.jna.FromNativeContext; import com.sun.jna.FromNativeConverter; import com.sun.jna.MethodParameterContext; import com.sun.jna.MethodResultContext; import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.StructureReadContext; import com.sun.jna.ToNativeContext; import com.sun.jna.ToNativeConverter; import com.sun.jna.TypeConverter; import org.freedesktop.gstreamer.glib.GObject; import org.freedesktop.gstreamer.glib.NativeObject; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.glib.RefCountedObject; /** * * @author wayne */ public class GTypeMapper extends com.sun.jna.DefaultTypeMapper { public GTypeMapper() { addToNativeConverter(URI.class, uriConverter); } private static ToNativeConverter interfaceConverter = new ToNativeConverter() { public Object toNative(Object arg, ToNativeContext context) { return arg != null ? Natives.getRawPointer(((GObject.GInterface) arg).getGObject()) : null; } public Class nativeType() { return Void.class; // not really correct, but not used in this instance } }; private static TypeConverter nativeObjectConverter = new TypeConverter() { public Object toNative(Object arg, ToNativeContext context) { if (arg == null) { return null; } Pointer ptr = Natives.getRawPointer((NativeObject) arg); // // Deal with any adjustments to the proxy neccessitated by gstreamer // breaking their reference-counting idiom with special cases // if (context instanceof MethodParameterContext) { MethodParameterContext mcontext = (MethodParameterContext) context; Method method = mcontext.getMethod(); int index = mcontext.getParameterIndex(); Annotation[][] parameterAnnotations = method.getParameterAnnotations(); if (index < parameterAnnotations.length) { Annotation[] annotations = parameterAnnotations[index]; for (int i = 0; i < annotations.length; ++i) { if (annotations[i] instanceof Invalidate) { ((NativeObject) arg).invalidate(); break; } else if (annotations[i] instanceof IncRef) { Natives.ref((RefCountedObject) arg); } } } } return ptr; } @SuppressWarnings(value = "unchecked") public Object fromNative(Object result, FromNativeContext context) { if (result == null) { return null; } if (context instanceof MethodResultContext) { // // By default, gstreamer increments the refcount on objects // returned from functions, so drop a ref here // boolean ownsHandle = ((MethodResultContext) context).getMethod().isAnnotationPresent(CallerOwnsReturn.class); // int refadj = ownsHandle ? -1 : 0; // return NativeObject.objectFor((Pointer) result, (Class) context.getTargetType(), refadj, ownsHandle); if (ownsHandle) { return Natives.callerOwnsReturn((Pointer) result, (Class) context.getTargetType()); } else { return Natives.objectFor((Pointer) result, (Class) context.getTargetType(), false, false); } } if (context instanceof CallbackParameterContext) { // return NativeObject.objectFor((Pointer) result, (Class) context.getTargetType(), 1, true); return Natives.objectFor((Pointer) result, (Class) context.getTargetType(), true, true); } if (context instanceof StructureReadContext) { StructureReadContext sctx = (StructureReadContext) context; boolean ownsHandle = sctx.getField().getAnnotation(ConstField.class) == null; // return NativeObject.objectFor((Pointer) result, (Class) context.getTargetType(), 1, ownsHandle); return Natives.objectFor((Pointer) result, (Class) context.getTargetType(), true, true); } throw new IllegalStateException("Cannot convert to NativeObject from " + context); } public Class nativeType() { return Pointer.class; } }; private static TypeConverter enumConverter = new TypeConverter() { @SuppressWarnings(value = "unchecked") public Object fromNative(Object value, FromNativeContext context) { return EnumMapper.getInstance().valueOf((Integer) value, (Class) context.getTargetType()); } public Class nativeType() { return Integer.class; } @SuppressWarnings("rawtypes") public Object toNative(Object arg, ToNativeContext context) { if (arg == null) { return null; } return EnumMapper.getInstance().intValue((Enum) arg); } }; private TypeConverter stringConverter = new TypeConverter() { public Object fromNative(Object result, FromNativeContext context) { if (result == null) { return null; } if (context instanceof MethodResultContext) { MethodResultContext functionContext = (MethodResultContext) context; Method method = functionContext.getMethod(); Pointer ptr = (Pointer) result; String s = ptr.getString(0); if (method.isAnnotationPresent(FreeReturnValue.class) || method.isAnnotationPresent(CallerOwnsReturn.class)) { GlibAPI.GLIB_API.g_free(ptr); } return s; } else { return ((Pointer) result).getString(0); } } public Class nativeType() { return Pointer.class; } public Object toNative(Object arg, ToNativeContext context) { // Let the default String -> native conversion handle it return arg; } }; private TypeConverter booleanConverter = new TypeConverter() { public Object toNative(Object arg, ToNativeContext context) { return Integer.valueOf(Boolean.TRUE.equals(arg) ? 1 : 0); } public Object fromNative(Object arg0, FromNativeContext arg1) { return Boolean.valueOf(((Integer)arg0).intValue() != 0); } public Class nativeType() { return Integer.class; } }; private TypeConverter gquarkConverter = new TypeConverter() { public Object fromNative(Object arg0, FromNativeContext arg1) { return new GQuark((Integer) arg0); } public Class nativeType() { return Integer.class; } public Object toNative(Object arg0, ToNativeContext arg1) { return ((GQuark) arg0).intValue(); } }; private TypeConverter intptrConverter = new TypeConverter() { public Object toNative(Object arg, ToNativeContext context) { return ((IntPtr)arg).value; } public Object fromNative(Object arg0, FromNativeContext arg1) { return new IntPtr(((Number) arg0).intValue()); } public Class nativeType() { return Native.POINTER_SIZE == 8 ? Long.class : Integer.class; } }; // private TypeConverter querytypeConverter = new TypeConverter() { // // public Object toNative(Object arg, ToNativeContext context) { // return ((QueryType)arg).intValue(); // } // // public Object fromNative(Object arg0, FromNativeContext arg1) { // return QueryType.valueOf(((Number) arg0).intValue()); // } // // public Class nativeType() { // return Integer.class; // } // }; private static ToNativeConverter uriConverter = new ToNativeConverter() { public Object toNative(Object arg0, ToNativeContext arg1) { URI uri = (URI) arg0; String uriString = uri.toString(); // Need to fixup file:/ to be file:/// for gstreamer if ("file".equals(uri.getScheme()) && uri.getHost() == null) { final String path = uri.getRawPath(); if (com.sun.jna.Platform.isWindows()) { uriString = "file:/" + path; } else { uriString = "file://" + path; } } return uriString; } public Class nativeType() { return String.class; } }; @SuppressWarnings("rawtypes") public FromNativeConverter getFromNativeConverter(Class type) { if (Enum.class.isAssignableFrom(type)) { return enumConverter; } else if (NativeObject.class.isAssignableFrom(type)) { return nativeObjectConverter; } else if (Boolean.class == type || boolean.class == type) { return booleanConverter; } else if (String.class == type) { return stringConverter; } else if (IntPtr.class == type) { return intptrConverter; } else if (GQuark.class == type) { return gquarkConverter; } return super.getFromNativeConverter(type); } @SuppressWarnings("rawtypes") public ToNativeConverter getToNativeConverter(Class type) { if (NativeObject.class.isAssignableFrom(type)) { return nativeObjectConverter; } else if (GObject.GInterface.class.isAssignableFrom(type)) { return interfaceConverter; } else if (Enum.class.isAssignableFrom(type)) { return enumConverter; } else if (Boolean.class == type || boolean.class == type) { return booleanConverter; } else if (String.class == type) { return stringConverter; } else if (IntPtr.class == type) { return intptrConverter; } else if (GQuark.class == type) { return gquarkConverter; } return super.getToNativeConverter(type); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GTypedPtr.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; /** * Base GLib pointer with GType */ public abstract class GTypedPtr extends GPointer { public GTypedPtr() { } public GTypedPtr(Pointer ptr) { super(ptr); } public abstract GType getGType(); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GValueAPI.java ================================================ /* * Copyright (c) 2017 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2008 Andres Colubri * Copyright (c) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.util.Arrays; import java.util.HashMap; import java.util.List; import org.freedesktop.gstreamer.glib.GObject; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import org.freedesktop.gstreamer.lowlevel.annotations.Invalidate; import com.sun.jna.Library; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.glib.NativeObject; import org.freedesktop.gstreamer.glib.Natives; /** * * @author wayne */ @SuppressWarnings("serial") public interface GValueAPI extends Library { public interface NoMapperAPI extends Library { Pointer g_value_get_object(GValue value); Pointer g_value_dup_object(GValue value); } NoMapperAPI GVALUE_NOMAPPER_API = GNative.loadLibrary("gobject-2.0", NoMapperAPI.class, new HashMap() {}); GValueAPI GVALUE_API = GNative.loadLibrary("gobject-2.0", GValueAPI.class, new HashMap() {{ put(Library.OPTION_TYPE_MAPPER, new GTypeMapper()); }}); public static final class GValue extends com.sun.jna.Structure { public static final String GTYPE_NAME = "GValue"; /*< private >*/ public volatile GType g_type; @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "g_type", "data" }); } /* public for GTypeValueTable methods */ public static final class GValueData extends com.sun.jna.Union { public volatile int v_int; public volatile long v_long; public volatile long v_int64; public volatile float v_float; public volatile double v_double; public volatile Pointer v_pointer; } public volatile GValueData data[] = new GValueData[2]; public GValue(GType type) { this(); GVALUE_API.g_value_init(this, type); } public GValue(GType type, Object val) { this(type); setValue(val); } public GValue() {} public GValue(Pointer ptr) { useMemory(ptr); read(); } public void reset() { GValueAPI.GVALUE_API.g_value_reset(this); } private T validateVal(Object val, Class clazz) { return validateVal(val, clazz, false); } private T validateVal(Object val, Class clazz, boolean allowNull) { if (val == null) { if (allowNull) { return null; } else { throw new IllegalArgumentException("null value not allowed for GType." + g_type); } } return clazz.cast(val); } public void setValue(Object val) { if (g_type.equals(GType.INT)) { GVALUE_API.g_value_set_int(this, validateVal(val, Integer.class)); } else if (g_type.equals(GType.UINT)) { GVALUE_API.g_value_set_uint(this, validateVal(val, Integer.class)); } else if (g_type.equals(GType.CHAR)) { GVALUE_API.g_value_set_char(this, validateVal(val, Byte.class)); } else if (g_type.equals(GType.UCHAR)) { GVALUE_API.g_value_set_uchar(this, validateVal(val, Byte.class)); } else if (g_type.equals(GType.LONG)) { GVALUE_API.g_value_set_long(this, validateVal(val, NativeLong.class)); } else if (g_type.equals(GType.ULONG)) { GVALUE_API.g_value_set_ulong(this, validateVal(val, NativeLong.class)); } else if (g_type.equals(GType.INT64)) { GVALUE_API.g_value_set_int64(this, validateVal(val, Long.class)); } else if (g_type.equals(GType.UINT64)) { GVALUE_API.g_value_set_uint64(this, validateVal(val, Long.class)); } else if (g_type.equals(GType.BOOLEAN)) { GVALUE_API.g_value_set_boolean(this, validateVal(val, Boolean.class)); } else if (g_type.equals(GType.FLOAT)) { GVALUE_API.g_value_set_float(this, validateVal(val, Float.class)); } else if (g_type.equals(GType.DOUBLE)) { GVALUE_API.g_value_set_double(this, validateVal(val, Double.class)); } else if (g_type.equals(GType.STRING)) { GVALUE_API.g_value_set_string(this, validateVal(val, String.class)); } else if (g_type.equals(GType.OBJECT)) { GVALUE_API.g_value_set_object(this, validateVal(val, GObject.class, true)); } else if (g_type.equals(GType.POINTER)) { GVALUE_API.g_value_set_pointer(this, validateVal(val, Pointer.class)); } else { throw new IllegalStateException("setValue() not supported yet for GType." + g_type); } } public boolean checkHolds(GType type) { return GVALUE_API.g_type_check_value_holds(this, type); } public GType getType() { return g_type; } public Object getValue() { if (g_type.equals(GType.INT)) { return toInt(); } else if (g_type.equals(GType.UINT)) { return toUInt(); } else if (g_type.equals(GType.CHAR)) { return toChar(); } else if (g_type.equals(GType.UCHAR)) { return toUChar(); } else if (g_type.equals(GType.LONG)) { return toLong(); } else if (g_type.equals(GType.ULONG)) { return toULong(); } else if (g_type.equals(GType.INT64)) { return toInt64(); } else if (g_type.equals(GType.UINT64)) { return toUInt64(); } else if (g_type.equals(GType.BOOLEAN)) { return toBoolean(); } else if (g_type.equals(GType.FLOAT)) { return toFloat(); } else if (g_type.equals(GType.DOUBLE)) { return toDouble(); } else if (g_type.equals(GType.STRING)) { return toJavaString(); // } else if (g_type.equals(GType.OBJECT)) { return toObject(); } else if (g_type.equals(GType.POINTER)) { return toPointer(); } else if (g_type.equals(GValueArray.GTYPE)) { return new GValueArray(GVALUE_API.g_value_get_boxed(this)); } else if (g_type.getParentType().equals(GType.BOXED)) { Class cls = GstTypes.classFor(g_type); if (cls != null) { Pointer ptr = GVALUE_API.g_value_get_boxed(this); // return NativeObject.objectFor(ptr, cls, 1, true); return Natives.objectFor(ptr, cls, true, true); } } // return GVALUE_API.g_value_get_object(this); return GVALUE_API.g_value_dup_object(this); } public Integer toInt() { return g_type.equals(GType.INT) ? new Integer(GVALUE_API.g_value_get_int(this)) : null; } public Integer toUInt() { return g_type.equals(GType.UINT) ? new Integer(GVALUE_API.g_value_get_uint(this)) : null; } public Byte toChar() { return g_type.equals(GType.CHAR) ? new Byte(GVALUE_API.g_value_get_char(this)) : null; } public Byte toUChar() { return g_type.equals(GType.UCHAR) ? new Byte(GVALUE_API.g_value_get_uchar(this)) : null; } public Long toLong() { return g_type.equals(GType.LONG) ? new Long(GVALUE_API.g_value_get_long(this).longValue()) : null; } public Long toULong() { return g_type.equals(GType.ULONG) ? new Long(GVALUE_API.g_value_get_ulong(this).longValue()) : null; } public Long toInt64() { return g_type.equals(GType.INT64)? new Long(GVALUE_API.g_value_get_int64(this)) : null; } public Long toUInt64() { return g_type.equals(GType.UINT64) ? new Long(GVALUE_API.g_value_get_uint64(this)) : null; } public Boolean toBoolean() { return g_type.equals(GType.BOOLEAN) ? new Boolean(GVALUE_API.g_value_get_boolean(this)) : null; } public Float toFloat() { return g_type.equals(GType.FLOAT) ? new Float(GVALUE_API.g_value_get_float(this)) : null; } public Double toDouble() { return g_type.equals(GType.DOUBLE) ? new Double(GVALUE_API.g_value_get_double(this)) : null; } public String toJavaString() { return g_type.equals(GType.STRING) ? GVALUE_API.g_value_get_string(this) : null; } public Object toObject() { return g_type.equals(GType.OBJECT) ? GVALUE_API.g_value_get_object(this) : null; } public Pointer toPointer() { return g_type.equals(GType.POINTER) ? GVALUE_API.g_value_get_pointer(this) : null; } public String toString() { return GVALUE_API.g_strdup_value_contents(this); } } public static final class GValueArray extends com.sun.jna.Structure { public static final String GTYPE_NAME = "GValueArray"; static final GType GTYPE = GType.valueOf(GTYPE_NAME); public volatile int n_values; public volatile Pointer values; //< private > public volatile int n_prealloced; private boolean ownsMemory; private static final Pointer NO_MEMORY_POINTER = new Pointer(0); public GValueArray() { this(0); } public GValueArray(int n_prealloced) { this(n_prealloced, true); } public GValueArray(int n_prealloced, boolean ownsMemory) { this(GVALUE_API.g_value_array_new(n_prealloced)); this.ownsMemory = ownsMemory; } public GValueArray(Pointer pointer) { super(pointer); if (pointer != Pointer.NULL && !NO_MEMORY_POINTER.equals(pointer)) n_values = pointer.getInt(0); } @SuppressWarnings("unused") private static GValueArray valueOf(Pointer ptr) { return ptr != null ? new GValueArray(ptr) : null; } public int getNValues() { return n_values; } public GValueArray prepend(GValue value) { GVALUE_API.g_value_array_prepend(this, value); return this; } public GValueArray append(GValue value) { GVALUE_API.g_value_array_append(this, value); return this; } public GValueArray insert(int index, GValue value) { GVALUE_API.g_value_array_insert(this, index, value); return this; } public GValueArray remove(int index) { GVALUE_API.g_value_array_remove(this, index); return this; } public GValue nth(int i) { return GVALUE_API.g_value_array_get_nth(this, i); } public Object getValue(int i) { GValue v = nth(i); return v == null ? null : v.getValue(); } public void free() { if (ownsMemory) { GVALUE_API.g_value_array_free(this); ownsMemory = false; } } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "n_values", "values", "n_prealloced" }); } } GValue g_value_init(GValue value, GType g_type); GValue g_value_reset(GValue value); void g_value_unset(GValue value); void g_value_set_char(GValue value, byte v_char); byte g_value_get_char(GValue value); void g_value_set_uchar(GValue value, byte v_uchar); byte g_value_get_uchar(GValue value); void g_value_set_boolean(GValue value, boolean v_boolean); boolean g_value_get_boolean(GValue value); void g_value_set_int(GValue value, int v_int); int g_value_get_int(GValue value); void g_value_set_uint(GValue value, int v_int); int g_value_get_uint(GValue value); void g_value_set_long(GValue value, NativeLong v_long); NativeLong g_value_get_long(GValue value); void g_value_set_ulong(GValue value, NativeLong v_long); NativeLong g_value_get_ulong(GValue value); void g_value_set_int64(GValue value, long v_int64); long g_value_get_int64(GValue value); void g_value_set_uint64(GValue value, long v_uint64); long g_value_get_uint64(GValue value); void g_value_set_float(GValue value, float v_float); float g_value_get_float(GValue value); void g_value_set_double(GValue value, double v_double); double g_value_get_double(GValue value); void g_value_set_enum(GValue value, int v_enum); int g_value_get_enum(GValue value); void g_value_set_string(GValue value, String v_string); void g_value_set_static_string (GValue value, String v_string); String g_value_get_string(GValue value); Pointer g_value_get_pointer(GValue value); void g_value_set_pointer(GValue value, Pointer pointer); boolean g_value_type_compatible(GType src_type, GType dest_type); boolean g_value_type_transformable(GType src_type, GType dest_type); boolean g_value_transform(GValue src_value, GValue dest_value); @CallerOwnsReturn String g_strdup_value_contents(GValue value); void g_value_set_object(GValue value, GObject v_object); void g_value_take_object(GValue value, @Invalidate GObject v_object); GObject g_value_get_object(GValue value); @CallerOwnsReturn GObject g_value_dup_object(GValue value); Pointer g_value_get_boxed(GValue value); GValue g_value_array_get_nth(GValueArray value_array, int index); Pointer g_value_array_new(int n_prealloced); void g_value_array_free (GValueArray value_array); Pointer g_value_array_copy(GValueArray value_array); Pointer g_value_array_prepend(GValueArray value_array, GValue value); Pointer g_value_array_append(GValueArray value_array, GValue value); Pointer g_value_array_insert(GValueArray value_array, int index_, GValue value); Pointer g_value_array_remove(GValueArray value_array, int index); boolean g_type_check_value_holds(GValue value, GType type); /* * GCompareDataFunc needs to be implemented. Pointer g_value_array_sort(GValueArray value_array, GCompareFunc compare_func); Pointer g_value_array_sort_with_data (GValueArray value_array, GCompareDataFunc compare_func, Pointer user_data); */ } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GValueStruct.java ================================================ /* * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Structure; import java.util.Collections; import java.util.List; /** * */ public class GValueStruct extends Structure { public volatile int g_type; /** Creates a new instance of GValueStruct */ public GValueStruct() { } @Override protected List getFieldOrder() { return Collections.singletonList("g_type"); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GioAPI.java ================================================ /* * Copyright (c) 2021 Neil C Smith * Copyright (c) 2016 Isaac Raño Jares * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Library; import com.sun.jna.Pointer; import java.util.Collections; public interface GioAPI extends Library { public static final GioAPI GIO_API = GNative.loadLibrary("gio-2.0", GioAPI.class, Collections.emptyMap()); // GInetAddress public String g_inet_address_to_string(Pointer gInetAddress); // GstSocketAddress public Pointer g_inet_socket_address_new_from_string(String address, int port); // GstSocket public Pointer g_socket_new(int gSocketFamilyEnumValue, int gSocketTypeEnumValue, int gSocketProtcolEnumValue, Pointer gErrorStructArrayPointer); public boolean g_socket_bind(Pointer gSocketPointer, Pointer gSocketAddressPointer, boolean allowReuse, Pointer gErrorStructArrayPointer); public boolean g_socket_connect(Pointer gSocketPointer, Pointer gSocketAddressPointer, Pointer gCancellablePointer, Pointer gErrorStructArrayPointer); // GCancellable public Pointer g_cancellable_new(); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GlibAPI.java ================================================ /* * Copyright (c) 2025 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.util.Arrays; import java.util.HashMap; import java.util.List; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import com.sun.jna.Callback; import com.sun.jna.Library; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import com.sun.jna.ptr.PointerByReference; import org.freedesktop.gstreamer.glib.GMainContext; import org.freedesktop.gstreamer.glib.GSource; /** * */ @SuppressWarnings("serial") public interface GlibAPI extends Library { GlibAPI GLIB_API = GNative.loadLibrary("glib-2.0", GlibAPI.class, new HashMap() {{ put(Library.OPTION_TYPE_MAPPER, new GTypeMapper()); }}); public static final int GLIB_SYSDEF_AF_UNIX = 1; public static final int GLIB_SYSDEF_AF_INET = 2; public static final int GLIB_SYSDEF_AF_INET6 = 23; Pointer g_main_loop_new(GMainContext context, boolean running); void g_main_loop_run(MainLoop loop); boolean g_main_loop_is_running(MainLoop loop); @CallerOwnsReturn GMainContext g_main_loop_get_context(MainLoop loop); void g_main_loop_quit(MainLoop loop); void g_main_loop_ref(GPointer ptr); void g_main_loop_unref(GPointer ptr); /* * GMainContext functions */ Pointer g_main_context_new(); void g_main_context_ref(GPointer context); void g_main_context_unref(GPointer context); Pointer g_main_context_default(); boolean g_main_context_pending(GMainContext ctx); boolean g_main_context_acquire(GMainContext ctx); void g_main_context_release(GMainContext ctx); boolean g_main_context_is_owner(GMainContext ctx); boolean g_main_context_wait(GMainContext ctx); @CallerOwnsReturn GSource g_idle_source_new(); @CallerOwnsReturn GSource g_timeout_source_new(int interval); @CallerOwnsReturn GSource g_timeout_source_new_seconds(int interval); int g_source_attach(GSource source, GMainContext context); void g_source_destroy(Pointer source); void g_source_destroy(GSource source); Pointer g_source_ref(Pointer source); void g_source_unref(Pointer source); void g_source_set_callback(GSource source, GSourceFunc callback, Object data, GDestroyNotify destroy); boolean g_source_is_destroyed(Pointer source); boolean g_source_is_destroyed(GSource source); /* * GThread functions */ interface GThreadFunc extends Callback { Pointer callback(Pointer data); } Pointer g_thread_create(GThreadFunc func, Pointer data, boolean joinable, PointerByReference error); Pointer g_thread_self(); Pointer g_thread_join(Pointer thread); void g_thread_yield(); void g_thread_set_priority(Pointer thread, int priority); void g_thread_exit(Pointer retval); interface GSourceFunc extends Callback { boolean callback(Pointer data); } NativeLong g_idle_add(GSourceFunc function, Pointer data); interface GDestroyNotify extends Callback { void callback(Pointer data); } int g_timeout_add(int interval, GSourceFunc function, Pointer data); int g_timeout_add_full(int priority, int interval, GSourceFunc function, Pointer data, GDestroyNotify notify); int g_timeout_add_seconds(int interval, GSourceFunc function, Pointer data); GstAPI.GErrorStruct g_error_new(int quark, int code, String message); void g_error_free(Pointer error); void g_source_remove(int id); void g_free(Pointer ptr); // GType g_date_get_type(); Pointer g_date_new(); Pointer g_date_new_dmy(int day, int month, int year); Pointer g_date_new_julian(int julian_day); int g_date_get_year(Pointer date); int g_date_get_month(Pointer date); int g_date_get_day(Pointer date); void g_date_free(Pointer date); GList g_list_append(GList list, Pointer data); public static final class GList extends com.sun.jna.Structure { public volatile Pointer data; public volatile Pointer _next; public volatile Pointer _prev; public GList() { clear(); } public GList(Pointer ptr) { useMemory(ptr); read(); } public static GList valueOf(Pointer ptr) { return ptr != null ? new GList(ptr) : null; } public GList next() { return valueOf(_next); } public GList prev() { return valueOf(_prev); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "data", "_next", "_prev" }); } } public static final class GSList extends com.sun.jna.Structure { public volatile Pointer data; public volatile Pointer _next; public GSList() { clear(); } public GSList(Pointer ptr) { useMemory(ptr); read(); } public static GSList valueOf(Pointer ptr) { return ptr != null ? new GSList(ptr) : null; } public GSList next() { return valueOf(_next); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "data", "_next" }); } } /* * Miscellaneous Utility Functions */ /** * Returns the value of an environment variable. * * On UNIX, the name and value are byte strings which might or might not be * in some consistent character set and encoding. On Windows, they are in UTF-8. * On Windows, in case the environment variable's value contains references * to other environment variables, they are expanded. * * @param variable the environment variable to get. * @return the value of the environment variable, or NULL if the * environment variable is not found. */ String g_getenv(String variable); /** * Sets an environment variable. * * On UNIX, both the variable's name and value can be arbitrary byte strings, * except that the variable's name cannot contain '='. * On Windows, they should be in UTF-8. * * @param variable the environment variable to set, must not contain '='. * @param value the value for to set the variable to. * @param overwrite whether to change the variable if it already exists. * @return FALSE if the environment variable couldn't be set. */ boolean g_setenv(String variable, String value, boolean overwrite); /** * Removes an environment variable from the environment. * * @param variable the environment variable to remove, must not contain '='. */ void g_unsetenv(String variable); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import com.sun.jna.Library; import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; import java.util.Arrays; import java.util.List; /** * */ public interface GstAPI extends Library { GstAPI GST_API = GstNative.load(GstAPI.class); int GST_PADDING = 4; int GST_PADDING_LARGE = 20; GType gst_type_find_get_type(); @CallerOwnsReturn String gst_version_string(); void gst_version(long[] major, long[] minor, long[] micro, long[] nano); boolean gst_init(IntByReference argc, PointerByReference argv); boolean gst_init_check(IntByReference argc, PointerByReference argv, Pointer[] err); boolean gst_init_check(IntByReference argc, PointerByReference argv, GErrorStruct[] err); boolean gst_segtrap_is_enabled(); void gst_segtrap_set_enabled(boolean enabled); void gst_deinit(); /** * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstsegment.h?h=1.8 * * GstSegment: * @flags: flags for this segment * @rate: the playback rate of the segment * @applied_rate: the already applied rate to the segment * @format: the format of the segment values * @base: the running time (plus elapsed time, see offset) of the segment start * @offset: the amount (in buffer timestamps) that has already been elapsed in * the segment * @start: the start of the segment in buffer timestamp time (PTS) * @stop: the stop of the segment in buffer timestamp time (PTS) * @time: the stream time of the segment start * @position: the buffer timestamp position in the segment (used internally by * elements such as sources, demuxers or parsers to track progress) * @duration: the duration of the segment * * A helper structure that holds the configured region of * interest in a media file. */ public static final class GstSegmentStruct extends com.sun.jna.Structure { public GstSegmentStruct() { } public GstSegmentStruct(Pointer p) { super(p); } public GstSegmentStruct(int flags, double rate, double applied_rate, Format format, long base, long offset, long start, long stop, long time, long position, long duration) { this.flags = flags; this.rate = rate; this.applied_rate = applied_rate; this.format = format; this.base = base; this.offset = offset; this.start = start; this.stop = stop; this.time = time; this.position = position; this.duration = duration; } /*< public >*/ public int flags; public double rate; public double applied_rate; public Format format; public long base; public long offset; public long start; public long stop; public long time; public long position; public long duration; /*< private >*/ public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING]; @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "flags", "rate", "applied_rate", "format", "base", "offset", "start", "stop", "time", "position", "duration", "_gst_reserved" }); } }; public static final class GErrorStruct extends com.sun.jna.Structure { public volatile int domain; /* GQuark */ public volatile int code; public volatile String message; /** Creates a new instance of GError */ public GErrorStruct() { clear(); } public GErrorStruct(Pointer ptr) { useMemory(ptr); } public int getCode() { return (Integer) readField("code"); } public String getMessage() { return (String) readField("message"); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "domain", "code", "message" }); } } // Do nothing, but provide a base Callback class that gets automatic type conversion public static interface GstCallback extends com.sun.jna.Callback { static final com.sun.jna.TypeMapper TYPE_MAPPER = new GTypeMapper(); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstARGBControlBindingPtr.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; /** * */ public class GstARGBControlBindingPtr extends GstControlBindingPtr { public GstARGBControlBindingPtr() { } public GstARGBControlBindingPtr(Pointer ptr) { super(ptr); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstBinAPI.java ================================================ /* * Copyright (c) 2021 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.Bin; import org.freedesktop.gstreamer.Element; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import com.sun.jna.Pointer; /** * GstBin functions */ public interface GstBinAPI extends com.sun.jna.Library { GstBinAPI GSTBIN_API = GstNative.load(GstBinAPI.class); @CallerOwnsReturn Pointer ptr_gst_bin_new(String name); @CallerOwnsReturn Pointer ptr_gst_pipeline_new(String name); @CallerOwnsReturn Bin gst_bin_new(String name); GType gst_bin_get_type(); boolean gst_bin_add(Bin bin, Element element); void gst_bin_add_many(Bin bin, Element... elements); boolean gst_bin_remove(Bin bin, Element element); void gst_bin_remove_many(Bin bin, Element... elements); @CallerOwnsReturn Element gst_bin_get_by_name(Bin bin, String name); @CallerOwnsReturn Element gst_bin_get_by_name_recurse_up(Bin bin, String name); @CallerOwnsReturn Element gst_bin_get_by_interface(Bin bin, GType iface); GstIteratorPtr gst_bin_iterate_elements(Bin bin); GstIteratorPtr gst_bin_iterate_sorted(Bin bin); GstIteratorPtr gst_bin_iterate_recurse(Bin bin); GstIteratorPtr gst_bin_iterate_sinks(Bin bin); GstIteratorPtr gst_bin_iterate_sources(Bin bin); GstIteratorPtr gst_bin_iterate_all_by_interface(Bin bin, GType iface); //Debugging void gst_debug_bin_to_dot_file (Bin bin, int details, String file_name); void gst_debug_bin_to_dot_file_with_ts (Bin bin, int details, String file_name); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstBufferAPI.java ================================================ /* * Copyright (c) 2014 Tom Greenwood * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.util.Arrays; import java.util.List; import org.freedesktop.gstreamer.Buffer; import org.freedesktop.gstreamer.lowlevel.GstMiniObjectAPI.MiniObjectStruct; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import com.sun.jna.ptr.PointerByReference; import static org.freedesktop.gstreamer.lowlevel.GstAPI.GST_PADDING; /** * GstBuffer methods and structures * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstbuffer.h?h=1.8 */ public interface GstBufferAPI extends com.sun.jna.Library { GstBufferAPI GSTBUFFER_API = GstNative.load(GstBufferAPI.class); public static final int GST_LOCK_FLAG_READ = (1 << 0); public static final int GST_LOCK_FLAG_WRITE = (1 << 1); public static final int GST_MAP_READ = GST_LOCK_FLAG_READ; public static final int GST_MAP_WRITE = GST_LOCK_FLAG_WRITE; /** * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstmemory.h?h=1.8 * * GstMapInfo: * @memory: a pointer to the mapped memory * @flags: flags used when mapping the memory * @data: (array length=size): a pointer to the mapped data * @size: the valid size in @data * @maxsize: the maximum bytes in @data * @user_data: extra private user_data that the implementation of the memory * can use to store extra info. * * A structure containing the result of a map operation such as * gst_memory_map(). It contains the data and size. */ public static final class MapInfoStruct extends com.sun.jna.Structure { public volatile Pointer memory; // Pointer to GstMemory public volatile int flags; // GstMapFlags public volatile Pointer /* gunit8 */ data; public volatile NativeLong size; public volatile NativeLong maxSize; /*< protected >*/ public volatile Pointer[] user_data = new Pointer[4]; /*< private >*/ public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING]; /** * Creates a new instance of MessageStruct */ public MapInfoStruct() { } public MapInfoStruct(Pointer ptr) { super(ptr); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "memory", "flags", "data", "size", "maxSize", "user_data", "_gst_reserved" }); } } GType gst_buffer_get_type(); /* allocation */ @CallerOwnsReturn Buffer gst_buffer_new(); @CallerOwnsReturn Buffer gst_buffer_new_allocate(Pointer allocator, int size, Pointer params); @CallerOwnsReturn Pointer ptr_gst_buffer_new(); @CallerOwnsReturn Pointer ptr_gst_buffer_new_allocate(Pointer allocator, int size, Pointer params); /* memory blocks */ NativeLong gst_buffer_get_size(Buffer buffer); boolean gst_buffer_map(Buffer buffer, MapInfoStruct info, int flags); void gst_buffer_unmap(Buffer buffer, MapInfoStruct info); int gst_buffer_n_memory(Buffer buffer); boolean gst_buffer_map_range(Buffer buffer, int idx, int length, MapInfoStruct info, int flags); GstMetaPtr gst_buffer_get_meta(Buffer buffer, GType gType); int gst_buffer_get_n_meta(Buffer buffer,GType gType); GstMetaPtr gst_buffer_iterate_meta(Buffer buffer, PointerByReference state); // re-introduces in gstreamer 1.9 int gst_buffer_get_flags(Buffer buffer); boolean gst_buffer_set_flags(Buffer buffer, int flags); boolean gst_buffer_unset_flags(Buffer buffer, int flags); // boolean gst_buffer_is_metadata_writable(Buffer buf); // Buffer gst_buffer_make_metadata_writable(@Invalidate Buffer buf); // /* creating a subbuffer */ // @CallerOwnsReturn Buffer gst_buffer_create_sub(Buffer parent, int offset, int size); // // @CallerOwnsReturn Caps gst_buffer_get_caps(Buffer buffer); // void gst_buffer_set_caps(Buffer buffer, Caps caps); // /* span two buffers intelligently */ // boolean gst_buffer_is_span_fast(Buffer buf1, Buffer buf2); // @CallerOwnsReturn Buffer gst_buffer_span(Buffer buf1, int offset, Buffer buf2, int len); // /* buffer functions from gstutils.h */ // @CallerOwnsReturn Buffer gst_buffer_merge(Buffer buf1, Buffer buf2); // @CallerOwnsReturn Buffer gst_buffer_join(@Invalidate Buffer buf1, @Invalidate Buffer buf2); /** * GstBuffer: * @mini_object: the parent structure * @pool: pointer to the pool owner of the buffer * @pts: presentation timestamp of the buffer, can be #GST_CLOCK_TIME_NONE when the * pts is not known or relevant. The pts contains the timestamp when the * media should be presented to the user. * @dts: decoding timestamp of the buffer, can be #GST_CLOCK_TIME_NONE when the * dts is not known or relevant. The dts contains the timestamp when the * media should be processed. * @duration: duration in time of the buffer data, can be #GST_CLOCK_TIME_NONE * when the duration is not known or relevant. * @offset: a media specific offset for the buffer data. * For video frames, this is the frame number of this buffer. * For audio samples, this is the offset of the first sample in this buffer. * For file data or compressed data this is the byte offset of the first * byte in this buffer. * @offset_end: the last offset contained in this buffer. It has the same * format as @offset. * * The structure of a #GstBuffer. Use the associated macros to access the public * variables. */ public static final class BufferStruct extends com.sun.jna.Structure { volatile public MiniObjectStruct mini_object; /*< public >*/ /* with COW */ public Pointer /* BufferPool */ pool; /* timestamp */ public long pts; public long dts; public long duration; /* media specific offset */ public long offset; public long offset_end; public BufferStruct(Pointer ptr) { super(ptr); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "mini_object", "pool", "pts", "dts", "duration", "offset", "offset_end" }); } @Override public String toString() { return super.toString() + " " + pts + " " + dts + " " + duration; } } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstBufferPoolAPI.java ================================================ /* * Copyright (c) 2016 Christophe Lafolet * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.BufferPool; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.Structure; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import com.sun.jna.Pointer; /** * GstBufferPool methods and structures * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstbufferpool.h?h=1.8 */ public interface GstBufferPoolAPI extends com.sun.jna.Library { GstBufferPoolAPI GSTBUFFERPOOL_API = GstNative.load(GstBufferPoolAPI.class); GType gst_buffer_pool_get_type(); /* allocation */ @CallerOwnsReturn BufferPool gst_buffer_pool_new(); Pointer ptr_gst_buffer_pool_new(); /* state management */ Structure gst_buffer_pool_get_config(BufferPool pool); /* helpers for configuring the config structure */ boolean gst_buffer_pool_config_get_params(Structure config, /* Caps ** */ Pointer[] caps, /* guint * */ int[] size, /* guint * */ int[] min_buffers, /* guint * */ int[] max_buffers); void gst_buffer_pool_config_set_params(Structure config, Caps caps, int size, int min_buffers, int max_buffers); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstBusAPI.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2014 Tom Greenwood * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.Bus; import org.freedesktop.gstreamer.BusSyncReply; import org.freedesktop.gstreamer.message.Message; import org.freedesktop.gstreamer.message.MessageType; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GDestroyNotify; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import org.freedesktop.gstreamer.lowlevel.annotations.IncRef; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; /** * GstBus functions */ public interface GstBusAPI extends com.sun.jna.Library { GstBusAPI GSTBUS_API = GstNative.load(GstBusAPI.class); // GType gst_bus_get_type(); - Unused Bus gst_bus_new(); boolean gst_bus_post(Bus bus, @IncRef Message message); boolean gst_bus_have_pending(Bus bus); @CallerOwnsReturn Message gst_bus_peek(Bus bus); @CallerOwnsReturn Message gst_bus_pop(Bus bus); @CallerOwnsReturn Message gst_bus_pop_filtered(Bus bus, MessageType types); @CallerOwnsReturn Message gst_bus_timed_pop(Bus bus, long timeout); @CallerOwnsReturn Message gst_bus_timed_pop_filtered(Bus bus, long timeout, MessageType types); /* polling the bus */ @CallerOwnsReturn Message gst_bus_poll(Bus bus, MessageType events, /* GstlongDiff */ long timeout); // @CallerOwnsReturn Message gst_bus_poll(Bus bus, MessageType events, long timeout); void gst_bus_set_flushing(Bus ptr, int flushing); interface BusCallback extends GstCallback { boolean callback(GstBusPtr bus, GstMessagePtr msg, Pointer data); } public interface BusSyncHandler extends GstCallback { BusSyncReply callback(GstBusPtr bus, GstMessagePtr msg, Pointer userData); } NativeLong gst_bus_add_watch(Bus bus, BusCallback function, Pointer data); void gst_bus_set_sync_handler(Bus bus, BusSyncHandler function, Pointer data, GDestroyNotify destroyCallback); void gst_bus_enable_sync_message_emission(Bus bus); void gst_bus_disable_sync_message_emission(Bus bus); void gst_bus_add_signal_watch(Bus bus); void gst_bus_remove_signal_watch(Bus bus); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstBusPtr.java ================================================ /* * Copyright (c) 2020 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; /** * GstBus pointer. */ public class GstBusPtr extends GstObjectPtr { public GstBusPtr() { } public GstBusPtr(Pointer ptr) { super(ptr); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstCapsAPI.java ================================================ /* * Copyright (c) 2015 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.Structure; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import org.freedesktop.gstreamer.lowlevel.annotations.FreeReturnValue; import org.freedesktop.gstreamer.lowlevel.annotations.Invalidate; import com.sun.jna.Pointer; /** * GstCaps functions */ public interface GstCapsAPI extends com.sun.jna.Library { GstCapsAPI GSTCAPS_API = GstNative.load(GstCapsAPI.class); GType gst_caps_get_type(); @CallerOwnsReturn Pointer ptr_gst_caps_new_empty(); @CallerOwnsReturn Pointer ptr_gst_caps_new_any(); @CallerOwnsReturn Pointer ptr_gst_caps_new_simple(String media_type, String fieldName, Object... args); @CallerOwnsReturn Pointer ptr_gst_caps_new_full(Structure... data); @CallerOwnsReturn Caps gst_caps_new_empty(); @CallerOwnsReturn Caps gst_caps_new_any(); @CallerOwnsReturn Caps gst_caps_new_simple(String media_type, String fieldName, Object... args); @CallerOwnsReturn Caps gst_caps_new_full(Structure... data); @CallerOwnsReturn Pointer ptr_gst_caps_copy(Caps caps); @CallerOwnsReturn Pointer ptr_gst_caps_from_string(String string); @CallerOwnsReturn Caps gst_caps_copy(Caps caps); @CallerOwnsReturn Caps gst_caps_from_string(String string); @CallerOwnsReturn Caps gst_caps_make_writable(@Invalidate Caps caps); /* manipulation */ void gst_caps_append(Caps caps1, @Invalidate Caps caps2); @CallerOwnsReturn Caps gst_caps_merge(@Invalidate Caps caps1, @Invalidate Caps caps2); void gst_caps_append_structure(Caps caps, @Invalidate Structure structure); void gst_caps_remove_structure(Caps caps, int idx); void gst_caps_merge_structure(Caps caps, @Invalidate Structure structure); int gst_caps_get_size(Caps caps); Structure gst_caps_get_structure(Caps caps, int index); @CallerOwnsReturn Structure gst_caps_steal_structure(Caps caps, int index); @CallerOwnsReturn Caps gst_caps_copy_nth(Caps caps, int nth); @CallerOwnsReturn Caps gst_caps_truncate(Caps caps); void gst_caps_set_simple(Caps caps, String field, Object... values); /* operations */ @CallerOwnsReturn Caps gst_caps_intersect( Caps caps1, Caps caps2); @CallerOwnsReturn Caps gst_caps_subtract( Caps minuend, Caps subtrahend); @CallerOwnsReturn Caps gst_caps_normalize( Caps caps); @CallerOwnsReturn Caps gst_caps_simplify(Caps caps); @FreeReturnValue String gst_caps_to_string(Caps caps); /* tests */ boolean gst_caps_is_any(Caps caps); boolean gst_caps_is_empty(Caps caps); boolean gst_caps_is_fixed(Caps caps); boolean gst_caps_is_always_compatible(Caps caps1, Caps caps2); boolean gst_caps_is_subset(Caps subset, Caps superset); boolean gst_caps_is_equal(Caps caps1, Caps caps2); boolean gst_caps_is_equal_fixed(Caps caps1, Caps caps2); boolean gst_caps_can_intersect(Caps caps1, Caps caps2); GType gst_static_caps_get_type(); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstClockAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.Clock; import org.freedesktop.gstreamer.ClockID; import org.freedesktop.gstreamer.ClockReturn; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import com.sun.jna.Pointer; /** * GstClock functions */ public interface GstClockAPI extends com.sun.jna.Library { GstClockAPI GSTCLOCK_API = GstNative.load(GstClockAPI.class); GType gst_clock_get_type(); long gst_clock_set_resolution(Clock clock, long resolution); long gst_clock_get_resolution(Clock clock); long gst_clock_get_time(Clock clock); void gst_clock_set_calibration(Clock clock, long internal, long external, long rate_num, long rate_denom); void gst_clock_get_calibration(Clock clock, long[] internal, long[] external, long[] rate_num, long[] rate_denom); /* master/slave clocks */ boolean gst_clock_set_master(Clock clock, Clock master); @CallerOwnsReturn Clock gst_clock_get_master(Clock clock); boolean gst_clock_add_observation(Clock clock, long slave, long Master, double[] r_squared); /* getting and adjusting internal time */ long gst_clock_get_internal_time(Clock clock); long gst_clock_adjust_unlocked(Clock clock, long internal); long gst_clock_unadjust_unlocked(Clock clock, long external); /* creating IDs that can be used to get notifications */ @CallerOwnsReturn ClockID gst_clock_new_single_shot_id(Clock clock, long time); @CallerOwnsReturn ClockID gst_clock_new_periodic_id(Clock clock, long start_time, long interval); /* reference counting */ void gst_clock_id_ref(ClockID id); void gst_clock_id_ref(GPointer id); void gst_clock_id_unref(ClockID id); void gst_clock_id_unref(GPointer id); /* operations on IDs */ int gst_clock_id_compare_func(ClockID id1, ClockID id2); long gst_clock_id_get_time(ClockID id); ClockReturn gst_clock_id_wait(ClockID id, /* GstlongDiff * */ long[] jitter); public static interface GstClockCallback { /** * @param clock The clock that triggered the callback * @param time The time it was triggered * @param id The {@link ClockID} that expired * @return currently unused. */ boolean callback(Clock clock, long time, ClockID id, Pointer user_data); } ClockReturn gst_clock_id_wait_async(ClockID id, GstClockCallback func, Pointer user_data); void gst_clock_id_unschedule(ClockID id); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstColorBalanceAPI.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2009 Tamas Korodi * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.interfaces.ColorBalance; import org.freedesktop.gstreamer.interfaces.ColorBalanceChannel; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GList; import com.sun.jna.Library; import com.sun.jna.Pointer; import java.util.Arrays; import java.util.List; public interface GstColorBalanceAPI extends Library { GstColorBalanceAPI GSTCOLORBALANCE_API = GstNative.load("gstvideo", GstColorBalanceAPI.class); GType gst_color_balance_channel_get_type(); GType gst_color_balance_get_type(); /* vitrual class functions */ GList gst_color_balance_list_channels(ColorBalance balance); void gst_color_balance_set_value(ColorBalance balance, ColorBalanceChannel channel, int value); int gst_color_balance_get_value(ColorBalance balance, ColorBalanceChannel channel); public static final class ColorBalanceChannelStruct extends com.sun.jna.Structure { public volatile GObjectAPI.GObjectStruct parent; public volatile String label; public volatile int min_value; public volatile int max_value; public String getLabel() { return (String) readField("label"); } public int getMinValue() { return (Integer) readField("min_value"); } public int getMaxValue() { return (Integer) readField("max_value"); } public void read() {} public void write() {} public ColorBalanceChannelStruct(Pointer ptr) { useMemory(ptr); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "parent", "label", "min_value", "max_value" }); } } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstContextAPI.java ================================================ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.Structure; /** * GstContext API * * https://gstreamer.freedesktop.org/documentation/gstreamer/gstcontext.html * * https://gitlab.freedesktop.org/gstreamer/gstreamer/blob/master/gst/gstcontext.h * https://gitlab.freedesktop.org/gstreamer/gstreamer/blob/master/gst/gstcontext.c */ public interface GstContextAPI extends com.sun.jna.Library { GstContextAPI GSTCONTEXT_API = GstNative.load(GstContextAPI.class); /*@CallerOwnsReturn*/ GstContextPtr gst_context_new(String context_type, boolean persistent); String gst_context_get_context_type(GstContextPtr context); boolean gst_context_has_context_type(GstContextPtr context, String context_type); Structure gst_context_get_structure(GstContextPtr context); Structure gst_context_writable_structure(GstContextPtr context); boolean gst_context_is_persistent(GstContextPtr context); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstContextPtr.java ================================================ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; public class GstContextPtr extends GstMiniObjectPtr { public GstContextPtr() { } public GstContextPtr(Pointer ptr) { super(ptr); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstControlBindingAPI.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Library; /** * GstControlBinding API * * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstControlBinding.html * https://gitlab.freedesktop.org/gstreamer/gstreamer/tree/master/libs/gst/controller */ public interface GstControlBindingAPI extends Library { GstControlBindingAPI GSTCONTROLBINDING_API = GstNative.load(GstControlBindingAPI.class); boolean gst_control_binding_sync_values(GstControlBindingPtr binding, GstObjectPtr object, long timestamp, long lastSync); GValueAPI.GValue gst_control_binding_get_value(GstControlBindingPtr binding, long timestamp); boolean gst_control_binding_get_g_value_array(GstControlBindingPtr binding, long timestamp, long internal, int n_values, GValueAPI.GValue[] values); void gst_control_binding_set_disabled(GstControlBindingPtr binding, boolean disabled); boolean gst_control_binding_is_disabled(GstControlBindingPtr binding); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstControlBindingPtr.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; /** * */ public class GstControlBindingPtr extends GstObjectPtr { public GstControlBindingPtr() { } public GstControlBindingPtr(Pointer ptr) { super(ptr); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstControlSourceAPI.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Library; import com.sun.jna.Pointer; import com.sun.jna.Structure; /** * GstControlSource API * * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstControlBinding.html * https://gitlab.freedesktop.org/gstreamer/gstreamer/tree/master/libs/gst/controller */ public interface GstControlSourceAPI extends Library { GstControlSourceAPI GSTCONTROLSOURCE_API = GstNative.load(GstControlSourceAPI.class); boolean gst_control_source_get_value(GstControlSourcePtr self, long timestamp, double[] value); boolean gst_control_source_get_value_array(GstControlSourcePtr self, long timestamp, long interval, int n_values, double[] values); // static class Direct implements GstControlSourceAPI { // // @Override // public native boolean gst_control_source_get_value(GstControlSourcePtr self, long timestamp, double[] value); // // @Override // public native boolean gst_control_source_get_value_array(GstControlSourcePtr self, long timestamp, long interval, int n_values, double[] values); // // } @Structure.FieldOrder({"timestamp", "value"}) public static final class GstTimedValue extends Structure { public volatile long timestamp; public volatile double value; public GstTimedValue() { super(); } public GstTimedValue(Pointer ptr) { super(ptr); } } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstControlSourcePtr.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; /** * */ public class GstControlSourcePtr extends GstObjectPtr { public GstControlSourcePtr() { } public GstControlSourcePtr(Pointer ptr) { super(ptr); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstControllerAPI.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Library; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; /** * GstController API functions * * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstTimedValueControlSource.html * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstInterpolationControlSource.html * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstLFOControlSource.html * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstTriggerControlSource.html * https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-libs/html/GstDirectControlBinding.html * */ public interface GstControllerAPI extends Library { GstControllerAPI GSTCONTROLLER_API = GstNative.load("gstcontroller", GstControllerAPI.class); @CallerOwnsReturn GstTriggerControlSourcePtr gst_trigger_control_source_new(); @CallerOwnsReturn GstInterpolationControlSourcePtr gst_interpolation_control_source_new(); @CallerOwnsReturn GstLFOControlSourcePtr gst_lfo_control_source_new(); @CallerOwnsReturn GstDirectControlBindingPtr gst_direct_control_binding_new( GstObjectPtr object, String property_name, GstControlSourcePtr cs); @CallerOwnsReturn GstDirectControlBindingPtr gst_direct_control_binding_new_absolute( GstObjectPtr object, String property_name, GstControlSourcePtr cs); @CallerOwnsReturn GstARGBControlBindingPtr gst_argb_control_binding_new( GstObjectPtr object, String property_name, GstControlSourcePtr cs_a, GstControlSourcePtr cs_r, GstControlSourcePtr cs_g, GstControlSourcePtr cs_b); // since 1.12 @CallerOwnsReturn GstProxyControlBindingPtr gst_proxy_control_binding_new( GstObjectPtr object, String property_name, GstObjectPtr ref_object, String ref_property_name); // GSequenceIter gst_timed_value_control_source_find_control_point_iter( // GstTimedValueControlSourcePtr self, // long timestamp); boolean gst_timed_value_control_source_set(GstTimedValueControlSourcePtr self, long timestamp, double value); boolean gst_timed_value_control_source_set_from_list( GstTimedValueControlSourcePtr self, GlibAPI.GSList timedvalues); // transfer container // caller owns list, not contained values! @CallerOwnsReturn GlibAPI.GList gst_timed_value_control_source_get_all( GstTimedValueControlSourcePtr self); boolean gst_timed_value_control_source_unset(GstTimedValueControlSourcePtr self, long timestamp); void gst_timed_value_control_source_unset_all(GstTimedValueControlSourcePtr self); int gst_timed_value_control_source_get_count(GstTimedValueControlSourcePtr self); void gst_timed_value_control_invalidate_cache(GstTimedValueControlSourcePtr self); // gst_control_point_copy // gst_control_point_free } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstDateTimeAPI.java ================================================ /* * Copyright (c) 2010 Levente Farkas * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import com.sun.jna.Pointer; /** * GstDateTime functions * * A date, time and timezone structure * * Struct to store date, time and timezone information altogether. * GstDateTime is refcounted and immutable. * * Date information is handled using the proleptic Gregorian calendar. * * Provides basic creation functions and accessor functions to its fields. */ public interface GstDateTimeAPI extends com.sun.jna.Library { GstDateTimeAPI GSTDATETIME_API = GstNative.load(GstDateTimeAPI.class); GType gst_date_time_get_type(); int gst_date_time_get_year(Pointer datetime); int gst_date_time_get_month(Pointer datetime); int gst_date_time_get_day(Pointer datetime); int gst_date_time_get_hour(Pointer datetime); int gst_date_time_get_minute(Pointer datetime); int gst_date_time_get_second(Pointer datetime); int gst_date_time_get_microsecond(Pointer datetime); float gst_date_time_get_time_zone_offset(Pointer datetime); @CallerOwnsReturn Pointer gst_date_time_new_from_unix_epoch_local_time(long secs); @CallerOwnsReturn Pointer gst_date_time_new_from_unix_epoch_utc(long secs); @CallerOwnsReturn Pointer gst_date_time_new_local_time(int year, int month, int day, int hour, int minute, double seconds); @CallerOwnsReturn Pointer gst_date_time_new(float tzoffset, int year, int month, int day, int hour, int minute, double seconds); @CallerOwnsReturn Pointer gst_date_time_new_now_local_time(); @CallerOwnsReturn Pointer gst_date_time_new_now_utc(); Pointer gst_date_time_ref(Pointer datetime); void gst_date_time_unref(Pointer datetime); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstDeviceAPI.java ================================================ /* * Copyright (c) 2017 Neil C Smith * Copyright (c) 2015 Andres Colubri * Copyright (C) 2013 Olivier Crete * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.Element; import org.freedesktop.gstreamer.Structure; import org.freedesktop.gstreamer.device.Device; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; /** * * http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstDevice.html */ public interface GstDeviceAPI extends com.sun.jna.Library { GstDeviceAPI GSTDEVICE_API = GstNative.load(GstDeviceAPI.class); @CallerOwnsReturn Element gst_device_create_element(Device device, String name); @CallerOwnsReturn Caps gst_device_get_caps(Device device); Pointer gst_device_get_device_class(Device device); Pointer gst_device_get_display_name(Device device); boolean gst_device_has_classes(Device device, String classes); boolean gst_device_has_classesv(Device device, String[] classes); boolean gst_device_reconfigure_element(Device device, Element element); Structure gst_device_get_properties(Device device); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstDeviceMonitorAPI.java ================================================ /* * Copyright (c) 2015 Andres Colubri * Copyright (C) 2013 Olivier Crete * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.Bus; import org.freedesktop.gstreamer.device.DeviceMonitor; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GList; import org.freedesktop.gstreamer.Caps; /** * * http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstDeviceMonitor.html */ public interface GstDeviceMonitorAPI extends com.sun.jna.Library { GstDeviceMonitorAPI GSTDEVICEMONITOR_API = GstNative.load(GstDeviceMonitorAPI.class); @CallerOwnsReturn DeviceMonitor gst_device_monitor_new(); @CallerOwnsReturn Pointer ptr_gst_device_monitor_new(); @CallerOwnsReturn Bus gst_device_monitor_get_bus(DeviceMonitor monitor); int gst_device_monitor_add_filter(DeviceMonitor monitor, String classes, Caps caps); boolean gst_device_monitor_remove_filter(DeviceMonitor monitor, int filterId); boolean gst_device_monitor_start(DeviceMonitor monitor); void gst_device_monitor_stop(DeviceMonitor monitor); GList gst_device_monitor_get_devices(DeviceMonitor monitor); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstDeviceProviderAPI.java ================================================ /* * Copyright (c) 2015 Andres Colubri * Copyright (C) 2013 Olivier Crete * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; import java.util.Arrays; import java.util.List; import org.freedesktop.gstreamer.Bus; import org.freedesktop.gstreamer.Plugin; import org.freedesktop.gstreamer.device.Device; import org.freedesktop.gstreamer.device.DeviceProvider; import org.freedesktop.gstreamer.device.DeviceProviderFactory; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GList; /** * * http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/gstreamer-GstDeviceProvider.html */ public interface GstDeviceProviderAPI extends com.sun.jna.Library { GstDeviceProviderAPI GSTDEVICEPROVIDER_API = GstNative.load(GstDeviceProviderAPI.class); boolean gst_device_provider_can_monitor(DeviceProvider provider); void gst_device_provider_class_add_metadata(GstDeviceProviderClass klass, String key, String value); void gst_device_provider_class_add_static_metadata(GstDeviceProviderClass klass, String key, String value); String gst_device_provider_class_get_metadata(GstDeviceProviderClass klass, String key); void gst_device_provider_class_set_metadata(GstDeviceProviderClass klass, String longname, String classification, String description, String author); void gst_device_provider_class_set_static_metadata(GstDeviceProviderClass klass, String longname, String classification, String description, String author); void gst_device_provider_device_add(DeviceProvider provider, Device device); void gst_device_provider_device_remove(DeviceProvider provider, Device device); Bus gst_device_provider_get_bus(DeviceProvider provider); GList gst_device_provider_get_devices(DeviceProvider provider); DeviceProviderFactory gst_device_provider_get_factory(DeviceProvider provider); boolean gst_device_provider_register(Plugin plugin, String name, int rank, GType type); boolean gst_device_provider_start(DeviceProvider provider); void gst_device_provider_stop(DeviceProvider provider); public static final class GstDeviceProviderClass extends com.sun.jna.Structure { public GObjectAPI.GObjectClass parent_class; public volatile Pointer factory; public volatile Pointer probe; public volatile Pointer start; public volatile Pointer provider; public volatile Pointer metadata; public volatile Pointer[] _gst_reserved = new Pointer[GstAPI.GST_PADDING]; @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "parent_class", "factory", "probe", "start", "provider", "metadata", "_gst_reserved" }); } } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstDeviceProviderFactoryAPI.java ================================================ /* * Copyright (c) 2015 Andres Colubri * Copyright (C) 2013 Olivier Crete * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.PluginFeature.Rank; import org.freedesktop.gstreamer.device.DeviceProvider; import org.freedesktop.gstreamer.device.DeviceProviderFactory; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GList; /** * * http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstDeviceProviderFactory.html */ public interface GstDeviceProviderFactoryAPI extends com.sun.jna.Library { GstDeviceProviderFactoryAPI GSTDEVICEPROVIDERFACTORY_API = GstNative.load(GstDeviceProviderFactoryAPI.class); DeviceProviderFactory gst_device_provider_factory_find(String name); DeviceProvider gst_device_provider_factory_get(DeviceProviderFactory factory); DeviceProvider gst_device_provider_factory_get_by_name(String factoryName); GType gst_device_provider_factory_get_device_provider_type(DeviceProviderFactory factory); String gst_device_provider_factory_get_metadata(DeviceProviderFactory factory, String key); String[] gst_device_provider_factory_get_metadata_keys(DeviceProviderFactory factory); boolean gst_device_provider_factory_has_classes(DeviceProviderFactory factory, String classes); boolean gst_device_provider_factory_has_classesv(DeviceProviderFactory factory, String[] classes); GList gst_device_provider_factory_list_get_device_providers(Rank minRank); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstDirectControlBindingPtr.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; /** * */ public class GstDirectControlBindingPtr extends GstControlBindingPtr { public GstDirectControlBindingPtr() { } public GstDirectControlBindingPtr(Pointer ptr) { super(ptr); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstElementAPI.java ================================================ /* * Copyright (c) 2021 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.util.Arrays; import java.util.List; import org.freedesktop.gstreamer.Bus; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.Clock; import org.freedesktop.gstreamer.Element; import org.freedesktop.gstreamer.ElementFactory; import org.freedesktop.gstreamer.event.Event; import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.message.Message; import org.freedesktop.gstreamer.Pad; import org.freedesktop.gstreamer.query.Query; import org.freedesktop.gstreamer.event.SeekType; import org.freedesktop.gstreamer.State; import org.freedesktop.gstreamer.StateChangeReturn; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GList; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback; import org.freedesktop.gstreamer.lowlevel.GstObjectAPI.GstObjectClass; import org.freedesktop.gstreamer.lowlevel.GstObjectAPI.GstObjectStruct; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import org.freedesktop.gstreamer.lowlevel.annotations.IncRef; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; /** * GstElement methods and structures * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstelement.h?h=1.8 */ public interface GstElementAPI extends com.sun.jna.Library { GstElementAPI GSTELEMENT_API = GstNative.load(GstElementAPI.class); GType gst_element_get_type(); StateChangeReturn gst_element_set_state(Element elem, State state); StateChangeReturn gst_element_get_state(Element elem, State[] state, State[] pending, long timeout); boolean gst_element_set_locked_state(Element element, boolean locked_state); boolean gst_element_sync_state_with_parent(Element elem); boolean gst_element_query_position(Element elem, Format fmt, long[] pos); boolean gst_element_query_duration(Element elem, Format fmt, long[] pos); boolean gst_element_query(Element elem, Query query); boolean gst_element_seek(Element element, double rate, Format format, int flags, SeekType start_type, long start, SeekType stop_type, long stop); boolean gst_element_seek_simple(Element elem, Format format, int seek_flags, long seek_pos); boolean gst_element_link(Element elem1, Element elem2); boolean gst_element_link_filtered(Element elem1, Element elem2, Caps filter); boolean gst_element_link_many(Element... elements); void gst_element_unlink_many(Element... elements); void gst_element_unlink(Element elem1, Element elem2); @CallerOwnsReturn Pad gst_element_get_pad(Element elem, String name); @CallerOwnsReturn Pad gst_element_get_static_pad(Element element, String name); // pads returned from get_request have to be freed via release_request_pad @CallerOwnsReturn Pad gst_element_get_request_pad(Element element, String name); void gst_element_release_request_pad(Element element, Pad pad); boolean gst_element_add_pad(Element elem, Pad pad); boolean gst_element_remove_pad(Element elem, @IncRef Pad pad); boolean gst_element_link_pads(Element src, String srcpadname, Element dest, String destpadname); void gst_element_unlink_pads(Element src, String srcpadname, Element dest, String destpadname); boolean gst_element_link_pads_filtered(Element src, String srcpadname, Element dest, String destpadname, Caps filter); GstIteratorPtr gst_element_iterate_pads(Element element); GstIteratorPtr gst_element_iterate_src_pads(Element element); GstIteratorPtr gst_element_iterate_sink_pads(Element element); /* factory management */ ElementFactory gst_element_get_factory(Element element); @CallerOwnsReturn Bus gst_element_get_bus(Element element); boolean gst_element_send_event(Element element, @IncRef Event event); boolean gst_element_post_message(Element element, @IncRef Message message); boolean gst_element_implements_interface(Element element, NativeLong iface_type); /* clocking */ Clock gst_element_get_clock(Element element); boolean gst_element_set_clock(Element element, Clock clock); void gst_element_set_base_time(Element element, long time); long gst_element_get_base_time(Element element); void gst_element_set_start_time(Element element, long time); long gst_element_get_start_time(Element element); /* context */ void gst_element_set_context(Element element, GstContextPtr context); GList gst_element_get_contexts(Element element); @CallerOwnsReturn GstContextPtr gst_element_get_context(Element element, String context_type); @CallerOwnsReturn GstContextPtr gst_element_get_context_unlocked(Element element, String context_type); /** * GstElement: * @state_lock: Used to serialize execution of gst_element_set_state() * @state_cond: Used to signal completion of a state change * @state_cookie: Used to detect concurrent execution of * gst_element_set_state() and gst_element_get_state() * @target_state: the target state of an element as set by the application * @current_state: the current state of an element * @next_state: the next state of an element, can be #GST_STATE_VOID_PENDING if * the element is in the correct state. * @pending_state: the final state the element should go to, can be * #GST_STATE_VOID_PENDING if the element is in the correct state * @last_return: the last return value of an element state change * @bus: the bus of the element. This bus is provided to the element by the * parent element or the application. A #GstPipeline has a bus of its own. * @clock: the clock of the element. This clock is usually provided to the * element by the toplevel #GstPipeline. * @base_time: the time of the clock right before the element is set to * PLAYING. Subtracting @base_time from the current clock time in the PLAYING * state will yield the running_time against the clock. * @start_time: the running_time of the last PAUSED state * @numpads: number of pads of the element, includes both source and sink pads. * @pads: (element-type Gst.Pad): list of pads * @numsrcpads: number of source pads of the element. * @srcpads: (element-type Gst.Pad): list of source pads * @numsinkpads: number of sink pads of the element. * @sinkpads: (element-type Gst.Pad): list of sink pads * @pads_cookie: updated whenever the a pad is added or removed * * GStreamer element abstract base class. */ public static final class GstElementStruct extends com.sun.jna.Structure { public GstObjectStruct object; /*< public >*/ /* with LOCK */ public volatile Pointer /* GRecMutex */ state_lock; /* element state */ public volatile Pointer /* GCond */ state_cond; public volatile int state_cookie; public volatile State target_state; public volatile State current_state; public volatile State next_state; public volatile State pending_state; public volatile StateChangeReturn last_return; public volatile Pointer /* GstBus */ bus; /* allocated clock */ public volatile Pointer /* GstClock */ clock; public volatile long base_time; public volatile long start_time; /* element pads, these lists can only be iterated while holding * the LOCK or checking the cookie after each LOCK. */ public volatile short numpads; public volatile Pointer /* GList */pads; public volatile short numsrcpads; public volatile Pointer /* GList */ srcpads; public volatile short numsinkpads; public volatile Pointer /* GList */sinkpads; public volatile int pads_cookie; /* with object LOCK */ public volatile Pointer /* GList */contexts; /*< private >*/ public volatile Pointer[] _gst_reserved = new Pointer[GstAPI.GST_PADDING-1]; public GstElementStruct(Pointer handle) { super(handle); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "object", "state_lock", "state_cond", "state_cookie", "target_state", "current_state", "next_state", "pending_state", "last_return", "bus", "clock", "base_time", "start_time", "numpads", "pads", "numsrcpads", "srcpads", "numsinkpads", "sinkpads", "pads_cookie", "contexts", "_gst_reserved" }); } } /** * GstElementClass: * @parent_class: the parent class structure * @metadata: metadata for elements of this class * @elementfactory: the #GstElementFactory that creates these elements * @padtemplates: a #GList of #GstPadTemplate * @numpadtemplates: the number of padtemplates * @pad_templ_cookie: changed whenever the padtemplates change * @request_new_pad: called when a new pad is requested * @release_pad: called when a request pad is to be released * @get_state: get the state of the element * @set_state: set a new state on the element * @change_state: called by @set_state to perform an incremental state change * @set_bus: set a #GstBus on the element * @provide_clock: gets the #GstClock provided by the element * @set_clock: set the #GstClock on the element * @send_event: send a #GstEvent to the element * @query: perform a #GstQuery on the element * @state_changed: called immediately after a new state was set. * @post_message: called when a message is posted on the element. Chain up to * the parent class' handler to have it posted on the bus. * @set_context: set a #GstContext on the element * * GStreamer element class. Override the vmethods to implement the element * functionality. */ public static final class GstElementClass extends com.sun.jna.Structure { // // Callbacks for this class // public static interface PadAdded extends GstCallback { public void callback(Element element, Pad pad); } public static interface PadRemoved extends GstCallback { public void callback(Element element, Pad pad); } public static interface NoMorePads extends GstCallback { public void callback(Element element); } public static interface RequestNewPad extends GstCallback { public Pad callback(Element element, /* PadTemplate */ Pointer templ, String name, Caps caps); } public static interface ReleasePad extends GstCallback { public void callback(Element element, Pad pad); } public static interface GetState extends GstCallback { public StateChangeReturn callback(Element element, Pointer /* GstState */ state, Pointer /* GstState */ pending, long timeout); } public static interface SetState extends GstCallback { public StateChangeReturn callback(Element element, State state); } public static interface ChangeState extends GstCallback { public StateChangeReturn callback(Element element, int transition); } public static interface StateChanged extends GstCallback { public StateChangeReturn callback(Element element, State oldState, State newState, State pending); } public static interface SetBus extends GstCallback { public void callback(Element element, Bus bus); } public static interface ProvideClock extends GstCallback { public void callback(Element element); } public static interface SetClock extends GstCallback { public void callback(Element element, Clock clock); } public static interface SendEvent extends GstCallback { boolean callback(Element element, Event event); } public static interface QueryNotify extends GstCallback { boolean callback(Element element, Query query); } public static interface PostMessage extends GstCallback { boolean callback(Element element, Message message); } // // Actual data members // public GstObjectClass parent_class; /*< public >*/ /* the element metadata */ public volatile Pointer metadata; /* factory that the element was created from */ public volatile ElementFactory elementfactory; /* templates for our pads */ public volatile Pointer /* GList */ padtemplates; public volatile int numpadtemplates; public volatile int pad_templ_cookie; /*< private >*/ /* signal callbacks */ public PadAdded pad_added; public PadRemoved pad_removed; public NoMorePads no_more_pads; /* request/release pads */ public RequestNewPad request_new_pad; public ReleasePad release_pad; /* state changes */ public GetState get_state; public SetState set_state; public ChangeState change_state; public StateChanged state_changed; /* bus */ public volatile SetBus set_bus; /* set/get clocks */ public volatile ProvideClock provide_clock; public volatile SetClock set_clock; /* query functions */ public volatile SendEvent send_event; public volatile QueryNotify query; public volatile PostMessage post_message; public volatile Pointer set_context; /*< private >*/ // Use an array of byte if arrays of Pointer don't work public volatile Pointer[] _gst_reserved = new Pointer[GstAPI.GST_PADDING_LARGE-2]; public GstElementClass(Pointer ptr) { super(ptr); //this.read(); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "parent_class", "metadata", "elementfactory", "padtemplates", "numpadtemplates", "pad_templ_cookie", "pad_added", "pad_removed", "no_more_pads", "request_new_pad", "release_pad", "get_state", "set_state", "change_state", "state_changed", "set_bus", "provide_clock", "set_clock", "send_event", "query", "post_message", "set_context", "_gst_reserved" }); } } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstElementFactoryAPI.java ================================================ /* Copyright (c) 2016 Christophe Lafolet * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.Element; import org.freedesktop.gstreamer.ElementFactory; import org.freedesktop.gstreamer.PadDirection; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GList; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import org.freedesktop.gstreamer.lowlevel.annotations.Const; import com.sun.jna.Pointer; /** * GstElementFactory methods */ public interface GstElementFactoryAPI extends com.sun.jna.Library { GstElementFactoryAPI GSTELEMENTFACTORY_API = GstNative.load(GstElementFactoryAPI.class); GType gst_element_factory_get_type(); ElementFactory gst_element_factory_find(String factoryName); @CallerOwnsReturn Pointer ptr_gst_element_factory_make(String factoryName, String elementName); @CallerOwnsReturn Pointer ptr_gst_element_factory_create(ElementFactory factory, String elementName); @CallerOwnsReturn Element gst_element_factory_make(String factoryName, String elementName); @CallerOwnsReturn Element gst_element_factory_create(ElementFactory factory, String elementName); GType gst_element_factory_get_element_type(ElementFactory factory); String gst_element_factory_get_metadata(ElementFactory factory, String key); int gst_element_factory_get_num_pad_templates(ElementFactory factory); int gst_element_factory_get_uri_type(ElementFactory factory); GList gst_element_factory_get_static_pad_templates(ElementFactory factory); GList gst_element_factory_list_get_elements(long type, int minrank); GList gst_element_factory_list_filter(GList list, @Const Caps caps, PadDirection direction, boolean subsetonly); /* util elementfactory functions */ boolean gst_element_factory_can_src_caps(ElementFactory factory, @Const Caps caps); boolean gst_element_factory_can_sink_caps(ElementFactory factory, @Const Caps caps); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstEventAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.util.Arrays; import java.util.List; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.event.Event; import org.freedesktop.gstreamer.event.EventType; import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.event.QOSType; import org.freedesktop.gstreamer.event.SeekType; import org.freedesktop.gstreamer.Structure; import org.freedesktop.gstreamer.TagList; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import org.freedesktop.gstreamer.lowlevel.annotations.Invalidate; import com.sun.jna.Pointer; import com.sun.jna.ptr.PointerByReference; import org.freedesktop.gstreamer.lowlevel.GstMiniObjectAPI.MiniObjectStruct; /** * GstEvent functions and structures * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstevent.h?h=1.8 */ public interface GstEventAPI extends com.sun.jna.Library { GstEventAPI GSTEVENT_API = GstNative.load(GstEventAPI.class); String gst_event_type_get_name(EventType type); int gst_event_type_get_flags(EventType type); GType gst_event_get_type(); Structure gst_event_get_structure(Event event); /* custom event */ Event gst_event_new_custom(EventType type, @Invalidate Structure structure); /* flush events */ @CallerOwnsReturn Event gst_event_new_flush_start(); Pointer ptr_gst_event_new_flush_start(); @CallerOwnsReturn Event gst_event_new_flush_stop(); Pointer ptr_gst_event_new_flush_stop(); /* EOS event */ @CallerOwnsReturn Event gst_event_new_eos(); Pointer ptr_gst_event_new_eos(); /* newsegment events */ @CallerOwnsReturn Event gst_event_new_segment( GstAPI.GstSegmentStruct segmentStruct ); Pointer ptr_gst_event_new_segment( GstAPI.GstSegmentStruct segment); void gst_event_parse_segment(Event event, Pointer[] pointer); /* tag event */ @CallerOwnsReturn Event gst_event_new_tag(@Invalidate TagList taglist); Pointer ptr_gst_event_new_tag(@Invalidate TagList taglist); void gst_event_parse_tag(Event event, PointerByReference taglist); void gst_event_parse_tag(Event event, Pointer[] taglist); /* buffer event */ @CallerOwnsReturn Event gst_event_new_buffer_size(Format format, long minsize, long maxsize, boolean async); Pointer ptr_gst_event_new_buffer_size(Format format, long minsize, long maxsize, boolean async); void gst_event_parse_buffer_size(Event event, Format[] format, long[] minsize, long[] maxsize, boolean[] async); /* QOS events */ @CallerOwnsReturn Event gst_event_new_qos(QOSType type, double proportion, long diff, long timestamp); Pointer ptr_gst_event_new_qos(QOSType type, double proportion, long diff, long timestamp); void gst_event_parse_qos(Event event, QOSType[] type, double[] proportion, long[] diff, long[] timestamp); /* seek event */ @CallerOwnsReturn Event gst_event_new_seek(double rate, Format format, int flags, SeekType start_type, long start, SeekType stop_type, long stop); Pointer ptr_gst_event_new_seek(double rate, Format format, int flags, SeekType start_type, long start, SeekType stop_type, long stop); void gst_event_parse_seek(Event event, double[] rate, Format[] format, int[] flags, SeekType[] start_type, long[] start, SeekType[] stop_type, long[] stop); /* navigation event */ @CallerOwnsReturn Event gst_event_new_navigation(@Invalidate Structure structure); Pointer ptr_gst_event_new_navigation(@Invalidate Structure structure); /* latency event */ @CallerOwnsReturn Event gst_event_new_latency(long latency); Pointer ptr_gst_event_new_latency(long latency); void gst_event_parse_latency(Event event, long[] latency); /* step event */ @CallerOwnsReturn Event gst_event_new_step(Format format, long amount, double rate, boolean flush, boolean intermediate); Pointer ptr_gst_event_new_step(Format format, long amount, double rate, boolean flush, boolean intermediate); /* caps event */ @CallerOwnsReturn Event gst_event_new_caps(Caps caps); Pointer ptr_gst_event_new_caps(Caps caps); /* reconfigure event */ @CallerOwnsReturn Event gst_event_new_reconfigure(); Pointer ptr_gst_event_new_reconfigure(); /* stream start event */ @CallerOwnsReturn Event gst_event_new_stream_start(final String stream_id); Pointer ptr_gst_event_new_stream_start(final String stream_id); /** * GstEvent: * @mini_object: the parent structure * @type: the #GstEventType of the event * @timestamp: the timestamp of the event * @seqnum: the sequence number of the event * * A #GstEvent. */ public static final class EventStruct extends com.sun.jna.Structure { public volatile MiniObjectStruct mini_object; /*< public >*/ /* with COW */ public volatile EventType type; public volatile long timestamp; public volatile int seqnum; public EventStruct(Pointer ptr) { useMemory(ptr); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "mini_object", "type", "timestamp", "seqnum" }); } } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstGhostPadAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.GhostPad; import org.freedesktop.gstreamer.Pad; import org.freedesktop.gstreamer.PadTemplate; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import com.sun.jna.Pointer; /** * GstGhostPad functions */ public interface GstGhostPadAPI extends com.sun.jna.Library { GstGhostPadAPI GSTGHOSTPAD_API = GstNative.load(GstGhostPadAPI.class); GType gst_ghost_pad_get_type(); @CallerOwnsReturn Pointer ptr_gst_ghost_pad_new(String name, Pad target); @CallerOwnsReturn Pointer ptr_gst_ghost_pad_new_no_target(String name, int direction); @CallerOwnsReturn Pointer ptr_gst_ghost_pad_new_from_template(String name, Pad target, PadTemplate templ); @CallerOwnsReturn Pointer ptr_gst_ghost_pad_new_no_target_from_template(String name, PadTemplate templ); @CallerOwnsReturn GhostPad gst_ghost_pad_new(String name, Pad target); @CallerOwnsReturn GhostPad gst_ghost_pad_new_no_target(String name, int direction); @CallerOwnsReturn GhostPad gst_ghost_pad_new_from_template(String name, Pad target, PadTemplate templ); @CallerOwnsReturn GhostPad gst_ghost_pad_new_no_target_from_template(String name, PadTemplate templ); @CallerOwnsReturn Pad gst_ghost_pad_get_target(GhostPad gpad); boolean gst_ghost_pad_set_target(GhostPad gpad, Pad newtarget); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstInterpolationControlSourceAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; //import org.freedesktop.gstreamer.controller.ControlSource; //import org.freedesktop.gstreamer.controller.InterpolationControlSource; import org.freedesktop.gstreamer.lowlevel.GValueAPI.GValue; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GList; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GSList; import com.sun.jna.Library; import com.sun.jna.Pointer; import java.util.Arrays; import java.util.List; // @TODO review in line with https://gitlab.freedesktop.org/gstreamer/gstreamer/blob/master/libs/gst/controller/gstinterpolationcontrolsource.h public interface GstInterpolationControlSourceAPI extends Library { // GstInterpolationControlSourceAPI GSTINTERPOLATIONCONTROLSOURCE_API // = GstNative.load("gstcontroller", GstInterpolationControlSourceAPI.class); // int GST_PADDING = GstAPI.GST_PADDING; // // public enum InterpolateMode { // NONE, // TRIGGER, // LINEAR, // QUADRATIC, // CUBIC, // USER; // } // // public static final class GstInterpolationControlSourceStruct extends com.sun.jna.Structure { // public volatile ControlSource parent; // // /* */ // public volatile Pointer /* GMutex */ lock; // public volatile Pointer /* GstInterpolationControlSourcePrivate */ priv; // public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING]; // // @Override // protected List getFieldOrder() { // return Arrays.asList(new String[]{ // "parent", "lock", "priv", // "_gst_reserved" // }); // } // } // // public static final class GstInterpolationControlSourceClass extends com.sun.jna.Structure { // public volatile ControlSource parent_class; // // /*< private >*/ // public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING]; // // @Override // protected List getFieldOrder() { // return Arrays.asList(new String[]{ // "parent_class", "_gst_reserved" // }); // } // } // // GType gst_interpolation_control_source_get_type(); // // /* Functions */ // InterpolationControlSource gst_interpolation_control_source_new(); // boolean gst_interpolation_control_source_set_interpolation_mode(InterpolationControlSource self, InterpolateMode mode); // boolean gst_interpolation_control_source_set(InterpolationControlSource self, long timestamp, GValue value); // boolean gst_interpolation_control_source_set_from_list(InterpolationControlSource self, GSList timedvalues); // boolean gst_interpolation_control_source_unset(InterpolationControlSource self, long timestamp); // void gst_interpolation_control_source_unset_all(InterpolationControlSource self); // GList gst_interpolation_control_source_get_all(InterpolationControlSource self); // int gst_interpolation_control_source_get_count(InterpolationControlSource self); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstInterpolationControlSourcePtr.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; /** * */ public class GstInterpolationControlSourcePtr extends GstTimedValueControlSourcePtr { public GstInterpolationControlSourcePtr() { } public GstInterpolationControlSourcePtr(Pointer ptr) { super(ptr); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstIteratorAPI.java ================================================ /* * Copyright (c) 2021 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; /** * GstIterator functions */ public interface GstIteratorAPI extends com.sun.jna.Library { GstIteratorAPI GSTITERATOR_API = GstNative.load(GstIteratorAPI.class); void gst_iterator_free(GstIteratorPtr iter); int gst_iterator_next(GstIteratorPtr iter, GValueAPI.GValue next); void gst_iterator_resync(GstIteratorPtr iter); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstIteratorPtr.java ================================================ /* * Copyright (c) 2021 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; /** * GstIterator pointer. */ public class GstIteratorPtr extends GPointer { public GstIteratorPtr() { } public GstIteratorPtr(Pointer ptr) { super(ptr); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstLFOControlSourcePtr.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; /** * */ public class GstLFOControlSourcePtr extends GstControlSourcePtr { public GstLFOControlSourcePtr() { } public GstLFOControlSourcePtr(Pointer ptr) { super(ptr); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstMessageAPI.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2014 Tom Greenwood * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.Clock; import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.GstObject; import org.freedesktop.gstreamer.message.Message; import org.freedesktop.gstreamer.message.MessageType; import org.freedesktop.gstreamer.State; import org.freedesktop.gstreamer.Structure; import org.freedesktop.gstreamer.TagList; import org.freedesktop.gstreamer.lowlevel.GstAPI.GErrorStruct; import org.freedesktop.gstreamer.lowlevel.GstMiniObjectAPI.MiniObjectStruct; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import org.freedesktop.gstreamer.lowlevel.annotations.ConstReturn; import org.freedesktop.gstreamer.lowlevel.annotations.Invalidate; import com.sun.jna.Pointer; import com.sun.jna.Structure.FieldOrder; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.LongByReference; import com.sun.jna.ptr.PointerByReference; /* * GstMessage functions */ public interface GstMessageAPI extends com.sun.jna.Library { GstMessageAPI GSTMESSAGE_API = GstNative.load(GstMessageAPI.class); @FieldOrder({"mini_object", "type", "timestamp", "src", "seqnum", "lock", "cond"}) public static final class MessageStruct extends com.sun.jna.Structure { public volatile MiniObjectStruct mini_object; public volatile int type; public volatile long timestamp; public volatile GstObjectPtr src; public volatile int seqnum; public volatile Pointer lock; public volatile Pointer cond; /** * Creates a new instance of MessageStruct */ public MessageStruct() { } public MessageStruct(Pointer ptr) { useMemory(ptr); } int typeOffset() { return fieldOffset("type"); } int srcOffset() { return fieldOffset("src"); } } GType gst_message_get_type(); String gst_message_type_get_name(MessageType type); void gst_message_parse_state_changed(Message msg, State[] old, State[] current, State[] pending); void gst_message_parse_state_changed(GstMessagePtr msg, IntByReference old, IntByReference current, IntByReference pending); void gst_message_parse_tag(Message msg, PointerByReference tagList); void gst_message_parse_tag(GstMessagePtr msg, PointerByReference tagList); void gst_message_parse_clock_provide(Message msg, PointerByReference clock, int[] reader); void gst_message_parse_new_clock(Message msg, PointerByReference clock); void gst_message_parse_error(Message msg, PointerByReference err, PointerByReference debug); void gst_message_parse_error(GstMessagePtr msg, PointerByReference err, PointerByReference debug); void gst_message_parse_error(Message msg, GErrorStruct[] err, Pointer[] debug); void gst_message_parse_warning(Message msg, PointerByReference err, PointerByReference debug); void gst_message_parse_warning(GstMessagePtr msg, PointerByReference err, PointerByReference debug); void gst_message_parse_warning(Message msg, GErrorStruct[] err, Pointer[] debug); void gst_message_parse_info(Message msg, PointerByReference err, PointerByReference debug); void gst_message_parse_info(GstMessagePtr msg, PointerByReference err, PointerByReference debug); void gst_message_parse_info(Message msg, GErrorStruct[] err, Pointer[] debug); void gst_message_parse_buffering(Message msg, int[] percent); void gst_message_parse_buffering(GstMessagePtr msg, IntByReference percent); void gst_message_parse_segment_start(Message message, Format[] format, long[] position); void gst_message_parse_segment_start(GstMessagePtr msg, IntByReference format, LongByReference position); void gst_message_parse_segment_done(Message message, Format[] format, long[] position); void gst_message_parse_segment_done(GstMessagePtr msg, IntByReference format, LongByReference position); void gst_message_parse_duration(Message message, Format[] format, long[] position); void gst_message_parse_duration(GstMessagePtr msg, IntByReference format, LongByReference position); void gst_message_parse_async_start(Message message, boolean[] new_base_time); boolean gst_message_parse_context_type(Message message, String[] context_type); boolean gst_message_parse_context_type(GstMessagePtr msg, PointerByReference /*String*/ context_type); @CallerOwnsReturn Message gst_message_new_eos(GstObject src); Pointer ptr_gst_message_new_eos(GstObject src); @CallerOwnsReturn GstMessagePtr gst_message_new_eos(GstObjectPtr src); @CallerOwnsReturn Message gst_message_new_error(GstObject src, GErrorStruct error, String debug); @CallerOwnsReturn Message gst_message_new_warning(GstObject src, GErrorStruct error, String debug); @CallerOwnsReturn Message gst_message_new_info(GstObject src, GErrorStruct error, String debug); @CallerOwnsReturn Message gst_message_new_tag(GstObject src, @Invalidate TagList tag_list); Pointer ptr_gst_message_new_tag(GstObject src, @Invalidate TagList tag_list); @CallerOwnsReturn Message gst_message_new_buffering(GstObject src, int percent); Pointer ptr_gst_message_new_buffering(GstObject src, int percent); @CallerOwnsReturn Message gst_message_new_state_changed(GstObject src, State oldstate, State newstate, State pending); Pointer ptr_gst_message_new_state_changed(GstObject src, State oldstate, State newstate, State pending); @CallerOwnsReturn Message gst_message_new_state_dirty(GstObject src); @CallerOwnsReturn Message gst_message_new_clock_provide(GstObject src, Clock clock, boolean ready); @CallerOwnsReturn Message gst_message_new_clock_lost(GstObject src, Clock clock); @CallerOwnsReturn Message gst_message_new_new_clock(GstObject src, Clock clock); @CallerOwnsReturn Message gst_message_new_application(GstObject src, Structure structure); @CallerOwnsReturn Message gst_message_new_element(GstObject src, Structure structure); @CallerOwnsReturn Message gst_message_new_segment_start(GstObject src, Format format, long position); @CallerOwnsReturn Message gst_message_new_segment_done(GstObject src, Format format, long position); Pointer ptr_gst_message_new_segment_done(GstObject src, Format format, long position); @CallerOwnsReturn Message gst_message_new_duration_changed(GstObject src); Pointer ptr_gst_message_new_duration_changed(GstObject src); @CallerOwnsReturn Message gst_message_new_async_start(GstObject src, boolean new_base_time); @CallerOwnsReturn Message gst_message_new_async_done(GstObject src); @CallerOwnsReturn Message gst_message_new_latency(GstObject src); Pointer ptr_gst_message_new_latency(GstObject source); @CallerOwnsReturn Message gst_message_new_custom(MessageType type, GstObject src, @Invalidate Structure structure); @ConstReturn Structure gst_message_get_structure(Message message); Pointer ptr_gst_message_new_need_context(GstObject source, String context_type); @CallerOwnsReturn Message gst_message_new_need_context(GstObject source, String context_type); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstMessagePtr.java ================================================ /* * Copyright (c) 2020 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; /** * GstMessage pointer. */ public class GstMessagePtr extends GstMiniObjectPtr { private static final int TYPE_OFFSET; private static final int SRC_OFFSET; static { GstMessageAPI.MessageStruct struct = new GstMessageAPI.MessageStruct(); TYPE_OFFSET = struct.typeOffset(); SRC_OFFSET = struct.srcOffset(); } public GstMessagePtr() { } public GstMessagePtr(Pointer ptr) { super(ptr); } public int getMessageType() { return getPointer().getInt(TYPE_OFFSET); } public GstObjectPtr getSource() { Pointer raw = getPointer().getPointer(SRC_OFFSET); return raw == null ? null : new GstObjectPtr(raw); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstMetaAPI.java ================================================ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Library; import com.sun.jna.Pointer; import com.sun.jna.Structure; /** */ public interface GstMetaAPI extends Library { GstMetaAPI GST_META_API = GstNative.load(GstMetaAPI.class); @Structure.FieldOrder({"flags", "info"}) class GstMetaStruct extends Structure { public static final class ByValue extends GstMetaStruct implements Structure.ByValue { } public int flags; public GstMetaInfoStruct.ByReference info; int infoOffset() { return fieldOffset("info"); } } @Structure.FieldOrder({"api", "type", "size"}) class GstMetaInfoStruct extends Structure { public static class ByReference extends GstMetaInfoStruct implements Structure.ByReference { } public GstMetaInfoStruct() { } public GstMetaInfoStruct(Pointer p) { super(p); read(); } public GType api; public GType type; public long size; int typeOffset() { return fieldOffset("type"); } } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstMetaPtr.java ================================================ /* * Copyright (c) 2020 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Native; import com.sun.jna.Pointer; /** * Base GstMeta pointer */ public class GstMetaPtr extends GTypedPtr { private static final int INFO_OFFSET; private static final int IMPL_TYPE_OFFSET; static { INFO_OFFSET = new GstMetaAPI.GstMetaStruct().infoOffset(); IMPL_TYPE_OFFSET = new GstMetaAPI.GstMetaInfoStruct().typeOffset(); } public GstMetaPtr() { } public GstMetaPtr(Pointer ptr) { super(ptr); } @Override public GType getGType() { // Quick getter for GType without allocation Pointer metaInfo = getPointer().getPointer(INFO_OFFSET); if (Native.SIZE_T_SIZE == 8) { return GType.valueOf(metaInfo.getLong(IMPL_TYPE_OFFSET)); } else if (Native.SIZE_T_SIZE == 4) { return GType.valueOf(((long) metaInfo.getInt(IMPL_TYPE_OFFSET)) & 0xffffffffL); } else { throw new IllegalStateException("SIZE_T size not supported: " + Native.SIZE_T_SIZE); } } public GType getAPIGType() { // Quick getter for GType without allocation Pointer metaInfo = getPointer().getPointer(INFO_OFFSET); if (Native.SIZE_T_SIZE == 8) { return GType.valueOf(metaInfo.getLong(0)); } else if (Native.SIZE_T_SIZE == 4) { return GType.valueOf(((long) metaInfo.getInt(0)) & 0xffffffffL); } else { throw new IllegalStateException("SIZE_T size not supported: " + Native.SIZE_T_SIZE); } } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstMiniObjectAPI.java ================================================ /* * Copyright (c) 2016 Christophe Lafolet * Copyright (c) 2014 Tom Greenwood * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Callback; import java.util.Arrays; import java.util.List; import org.freedesktop.gstreamer.MiniObject; import org.freedesktop.gstreamer.glib.GQuark; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GDestroyNotify; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import org.freedesktop.gstreamer.lowlevel.annotations.Invalidate; import com.sun.jna.Pointer; /** * GstMiniObject functions */ public interface GstMiniObjectAPI extends com.sun.jna.Library { GstMiniObjectAPI GSTMINIOBJECT_API = GstNative.load(GstMiniObjectAPI.class); void gst_mini_object_ref(GstMiniObjectPtr ptr); void gst_mini_object_unref(GstMiniObjectPtr ptr); void gst_mini_object_unref(Pointer ptr); void gst_mini_object_weak_ref(GstMiniObjectPtr ptr, GstMiniObjectNotify notify, IntPtr data); void gst_mini_object_weak_unref(GstMiniObjectPtr ptr, GstMiniObjectNotify notify, IntPtr data); @CallerOwnsReturn MiniObject gst_mini_object_make_writable(@Invalidate MiniObject mini_object); @CallerOwnsReturn MiniObject gst_mini_object_copy(MiniObject mini_object); boolean gst_mini_object_is_writable(MiniObject mini_object); void gst_mini_object_set_qdata(MiniObject mini_object, GQuark quark, Object data, GDestroyNotify destroyCallback); Pointer gst_mini_object_get_qdata(MiniObject mini_object, GQuark quark); Pointer gst_mini_object_steal_qdata(MiniObject mini_object, GQuark quark); public static interface GstMiniObjectNotify extends Callback { public void callback(IntPtr userData, Pointer obj); } public static final class MiniObjectStruct extends com.sun.jna.Structure { public volatile GType type; public volatile int refcount; public volatile int lockstate; public volatile int flags; public volatile Pointer copyFn; public volatile Pointer disposeFn; public volatile Pointer freeFn; public volatile int n_qdata; // Private parts - there for alignment public volatile Pointer qdata; /** Creates a new instance of GstMiniObjectStructure */ public MiniObjectStruct() {} public MiniObjectStruct(Pointer ptr) { super(ptr); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "type", "refcount", "lockstate", "flags", "copyFn", "disposeFn", "freeFn", "n_qdata", "qdata" }); } } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstMiniObjectPtr.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Native; import com.sun.jna.Pointer; /** * Base MiniObject pointer */ public class GstMiniObjectPtr extends GTypedPtr { public GstMiniObjectPtr() { } public GstMiniObjectPtr(Pointer ptr) { super(ptr); } @Override public GType getGType() { // Quick getter for GType without allocation // same as : new MiniObjectStruct(ptr).type if (Native.SIZE_T_SIZE == 8) { return GType.valueOf(getPointer().getLong(0)); } else if (Native.SIZE_T_SIZE == 4) { return GType.valueOf( ((long) getPointer().getInt(0)) & 0xffffffffL ); } else { throw new IllegalStateException("SIZE_T size not supported: " + Native.SIZE_T_SIZE); } } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstNative.java ================================================ /* * Copyright (c) 2016 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.util.HashMap; import java.util.Map; import com.sun.jna.Library; /** * A convenience wrapper to aid in loading an API interface. */ @SuppressWarnings("serial") public final class GstNative { // gstreamer library names the files one of libfoo-0.10 and libfoo-1.0 // private static String[] nameFormats = { /*"%s-0.10",*/ "%s-1.0" }; private final static String[] nameFormats = System.getProperty("gstreamer.GstNative.nameFormats", "%s-1.0").split("\\|"); private GstNative() {} private static final Map options = new HashMap() {{ put(Library.OPTION_TYPE_MAPPER, new GTypeMapper()); put(Library.OPTION_FUNCTION_MAPPER, new GFunctionMapper()); }}; public static T load(Class interfaceClass) { return load("gstreamer", interfaceClass); } public static T load(String libraryName, Class interfaceClass) { for (String format : nameFormats) try { return GNative.loadLibrary(String.format(format, libraryName), interfaceClass, options); } catch (UnsatisfiedLinkError ex) { continue; } throw new UnsatisfiedLinkError("Could not load library: " + libraryName); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstNavigationAPI.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2009 Tamas Korodi * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.Structure; import org.freedesktop.gstreamer.interfaces.Navigation; import com.sun.jna.Library; public interface GstNavigationAPI extends Library { GstNavigationAPI GSTNAVIGATION_API = GstNative.load("gstvideo", GstNavigationAPI.class); GType gst_navigation_get_type(); /* vitrual class functions */ void gst_navigation_send_event(Navigation navigation, Structure structure); void gst_navigation_send_key_event(Navigation navigation, String event, String key); void gst_navigation_send_mouse_event(Navigation navigation, String event, int button, double x, double y); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstObjectAPI.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Callback; import org.freedesktop.gstreamer.GstObject; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import org.freedesktop.gstreamer.lowlevel.annotations.FreeReturnValue; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import java.util.Arrays; import java.util.List; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GList; /** * GstObject method and structures * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstobject.h?h=1.8 */ public interface GstObjectAPI extends com.sun.jna.Library { GstObjectAPI GSTOBJECT_API = GstNative.load(GstObjectAPI.class); GType gst_object_get_type(); void gst_object_ref(GstObjectPtr ptr); void gst_object_unref(GstObjectPtr ptr); void gst_object_ref_sink(GstObjectPtr ptr); boolean gst_object_set_name(GstObject obj, String name); @FreeReturnValue String gst_object_get_name(GstObject obj); void gst_object_set_name_prefix(GstObject object, String name_prefix); @FreeReturnValue String gst_object_get_name_prefix(GstObject object); /* parentage routines */ boolean gst_object_set_parent(GstObject object, GstObject parent); @CallerOwnsReturn GstObject gst_object_get_parent(GstObject object); void gst_object_unparent(GstObject object); boolean gst_object_has_ancestor(GstObject object, GstObject ancestor); Pointer gst_implements_interface_cast(GstObject obj, NativeLong gtype); boolean gst_implements_interface_check(GstObject from, NativeLong type); /* controller functions */ long gst_object_suggest_next_sync(GstObjectPtr object); boolean gst_object_sync_values(GstObjectPtr object, long timestamp); boolean gst_object_has_active_control_bindings(GstObjectPtr object); void gst_object_set_control_bindings_disabled(GstObjectPtr object, boolean disabled); void gst_object_set_control_binding_disabled(GstObjectPtr object, String property_name, boolean disabled); boolean gst_object_add_control_binding(GstObjectPtr object, GstControlBindingPtr binding); GstControlBindingPtr gst_object_get_control_binding(GstObjectPtr object, String property_name); boolean gst_object_remove_control_binding(GstObjectPtr object, GstControlBindingPtr binding); /** * GstObject: * @lock: object LOCK * @name: The name of the object * @parent: this object's parent, weak ref * @flags: flags for this object * * GStreamer base object class. */ public static final class GstObjectStruct extends com.sun.jna.Structure { public GObjectAPI.GObjectStruct object; /*< public >*/ /* with LOCK */ public volatile Pointer /* GMutex */ lock; /* object LOCK */ public volatile String name; /* object name */ public volatile Pointer /* GstObject */ parent; /* this object's parent, weak ref */ public volatile int flags; /*< private >*/ public volatile GList control_bindings; public volatile long control_rate; public volatile long last_sync; public volatile Pointer _gst_reserved; @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "object", "lock", "name", "parent", "flags", "control_bindings", "control_rate", "last_sync", "_gst_reserved" }); } } // -------------- Callbacks ----------------- public static interface DeepNotify extends Callback { public void callback(GstObject object, GstObject orig, GObjectAPI.GParamSpec pspec); } /** * GstObjectClass: * @parent_class: parent * @path_string_separator: separator used by gst_object_get_path_string() * @deep_notify: default signal handler * * GStreamer base object class. */ public static final class GstObjectClass extends com.sun.jna.Structure { public GObjectAPI.GObjectClass parent_class; public volatile String path_string_separator; /* signals */ public DeepNotify deep_notify; public volatile Pointer[] _gst_reserved = new Pointer[GstAPI.GST_PADDING]; @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "parent_class", "path_string_separator", "deep_notify", "_gst_reserved" }); } } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstObjectPtr.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; /** * Base GObject pointer */ public class GstObjectPtr extends GObjectPtr { public GstObjectPtr() { } public GstObjectPtr(Pointer ptr) { super(ptr); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstPadAPI.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2018 Antonio Morales * Copyright (c) 2014 Tom Greenwood * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.Buffer; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.Element; import org.freedesktop.gstreamer.event.Event; import org.freedesktop.gstreamer.FlowReturn; import org.freedesktop.gstreamer.Pad; import org.freedesktop.gstreamer.PadDirection; import org.freedesktop.gstreamer.PadLinkReturn; import org.freedesktop.gstreamer.PadProbeReturn; import org.freedesktop.gstreamer.PadTemplate; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GDestroyNotify; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import org.freedesktop.gstreamer.lowlevel.annotations.FreeReturnValue; import org.freedesktop.gstreamer.lowlevel.annotations.IncRef; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.query.Query; /** * GstPad functions */ public interface GstPadAPI extends com.sun.jna.Library { public static final int GST_PAD_PROBE_TYPE_INVALID = 0; /* flags to control blocking */ public static final int GST_PAD_PROBE_TYPE_IDLE = (1 << 0); public static final int GST_PAD_PROBE_TYPE_BLOCK = (1 << 1); /* flags to select datatypes */ public static final int GST_PAD_PROBE_TYPE_BUFFER = (1 << 4); public static final int GST_PAD_PROBE_TYPE_BUFFER_LIST = (1 << 5); public static final int GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM = (1 << 6); public static final int GST_PAD_PROBE_TYPE_EVENT_UPSTREAM = (1 << 7); public static final int GST_PAD_PROBE_TYPE_EVENT_FLUSH = (1 << 8); public static final int GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM = (1 << 9); public static final int GST_PAD_PROBE_TYPE_QUERY_UPSTREAM = (1 << 10); /* flags to select scheduling mode */ public static final int GST_PAD_PROBE_TYPE_PUSH = (1 << 12); public static final int GST_PAD_PROBE_TYPE_PULL = (1 << 13); public static final int GST_PAD_PROBE_TYPE_BLOCKING = GST_PAD_PROBE_TYPE_IDLE | GST_PAD_PROBE_TYPE_BLOCK; public static final int GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM = GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_BUFFER_LIST | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM; public static final int GST_PAD_PROBE_TYPE_DATA_UPSTREAM = GST_PAD_PROBE_TYPE_EVENT_UPSTREAM; public static final int GST_PAD_PROBE_TYPE_DATA_BOTH = GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM | GST_PAD_PROBE_TYPE_DATA_UPSTREAM; public static final int GST_PAD_PROBE_TYPE_BLOCK_DOWNSTREAM = GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_DATA_DOWNSTREAM; public static final int GST_PAD_PROBE_TYPE_BLOCK_UPSTREAM = GST_PAD_PROBE_TYPE_BLOCK | GST_PAD_PROBE_TYPE_DATA_UPSTREAM; public static final int GST_PAD_PROBE_TYPE_EVENT_BOTH = GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM | GST_PAD_PROBE_TYPE_EVENT_UPSTREAM; public static final int GST_PAD_PROBE_TYPE_QUERY_BOTH = GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM | GST_PAD_PROBE_TYPE_QUERY_UPSTREAM; public static final int GST_PAD_PROBE_TYPE_ALL_BOTH = GST_PAD_PROBE_TYPE_DATA_BOTH | GST_PAD_PROBE_TYPE_QUERY_BOTH; public static final int GST_PAD_PROBE_TYPE_SCHEDULING = GST_PAD_PROBE_TYPE_PUSH | GST_PAD_PROBE_TYPE_PULL; static GstPadAPI GSTPAD_API = GstNative.load(GstPadAPI.class); GType gst_pad_get_type(); GType gst_ghost_pad_get_type(); @CallerOwnsReturn Pad gst_pad_new(String name, PadDirection direction); @CallerOwnsReturn Pad gst_pad_new_from_template(PadTemplate templ, String name); @CallerOwnsReturn Pointer ptr_gst_pad_new(String name, PadDirection direction); @CallerOwnsReturn Pointer ptr_gst_pad_new_from_template(PadTemplate templ, String name); @FreeReturnValue String gst_pad_get_name(Pad pad); PadLinkReturn gst_pad_link(Pad src, Pad sink); boolean gst_pad_unlink(Pad src, Pad sink); boolean gst_pad_is_linked(Pad pad); @CallerOwnsReturn Pad gst_pad_get_peer(Pad pad); PadDirection gst_pad_get_direction(Pad pad); /* pad functions from gstutils.h */ boolean gst_pad_can_link(Pad srcpad, Pad sinkpad); void gst_pad_use_fixed_caps(Pad pad); @CallerOwnsReturn Caps gst_pad_get_fixed_caps_func(Pad pad); @CallerOwnsReturn Caps gst_pad_proxy_getcaps(Pad pad); boolean gst_pad_proxy_setcaps(Pad pad, Caps caps); @CallerOwnsReturn Element gst_pad_get_parent_element(Pad pad); boolean gst_pad_set_active(Pad pad, boolean active); boolean gst_pad_is_active(Pad pad); boolean gst_pad_activate_pull(Pad pad, boolean active); boolean gst_pad_activate_push(Pad pad, boolean active); boolean gst_pad_is_blocked(Pad pad); boolean gst_pad_is_blocking(Pad pad); boolean gst_pad_has_current_caps(Pad pad); /* get_pad_template returns a non-refcounted PadTemplate */ PadTemplate gst_pad_get_pad_template(Pad pad); /* capsnego function for connected/unconnected pads */ @CallerOwnsReturn Caps gst_pad_query_caps(Pad pad, Caps caps); void gst_pad_fixate_caps(Pad pad, Caps caps); boolean gst_pad_query_accept_caps(Pad pad, Caps caps); // boolean gst_pad_set_caps(Pad pad, Caps caps); @CallerOwnsReturn Caps gst_pad_peer_query_caps(Pad pad, Caps caps); boolean gst_pad_peer_query_accept_caps(Pad pad, Caps caps); /* capsnego for connected pads */ @CallerOwnsReturn Caps gst_pad_get_allowed_caps(Pad pad); @CallerOwnsReturn Caps gst_pad_get_current_caps(Pad pad); /* data passing functions to peer */ FlowReturn gst_pad_push(Pad pad, @IncRef Buffer buffer); boolean gst_pad_check_pull_range(Pad pad); FlowReturn gst_pad_pull_range(Pad pad, /* guint64 */ long offset, /* guint */ int size, Buffer[] buffer); boolean gst_pad_push_event(Pad pad, @IncRef Event event); boolean gst_pad_event_default(Pad pad, Event event); /* data passing functions on pad */ FlowReturn gst_pad_chain(Pad pad, @IncRef Buffer buffer); FlowReturn gst_pad_get_range(Pad pad, /* guint64 */ long offset, /* guint */ int size, Buffer[] buffer); boolean gst_pad_send_event(Pad pad, @IncRef Event event); public static interface PadFixateCaps extends GstCallback { void callback(Pad pad, Caps caps); } void gst_pad_set_fixatecaps_function(Pad pad, PadFixateCaps fixate); /* probes */ // public static interface PadDataProbe extends GstCallback { // void callback(Pad pad, Buffer buffer, Pointer user_data); // } // public static interface PadEventProbe extends GstCallback { // boolean callback(Pad pad, Event ev, Pointer user_data); // } public static interface PadProbeCallback extends GstCallback { public PadProbeReturn callback(Pad pad, GstPadProbeInfo probeInfo, Pointer user_data); } /** * * @param pad * @param mask The type comes from the constants in GstPadProbeType * @param callback * @param user_data * @param destroy_data * @return */ NativeLong gst_pad_add_probe(GstPadPtr pad, int mask, PadProbeCallback callback, Pointer user_data, GDestroyNotify destroy_data); void gst_pad_remove_probe(GstPadPtr pad, NativeLong id); Event gst_pad_probe_info_get_event(GstPadProbeInfo probeInfo); Buffer gst_pad_probe_info_get_buffer(GstPadProbeInfo probeInfo); Query gst_pad_probe_info_get_query(GstPadProbeInfo probeInfo); // NativeLong /* gulong */ gst_pad_add_data_probe(Pad pad, PadDataProbe handler, Pointer data); // // void gst_pad_remove_data_probe(Pad pad, NativeLong handler_id); // // NativeLong /* gulong */ gst_pad_add_event_probe(Pad pad, PadEventProbe handler, Pointer data); // // void gst_pad_remove_event_probe(Pad pad, NativeLong handler_id); // // NativeLong /* gulong */ gst_pad_add_buffer_probe(Pad pad, GstCallback handler, Pointer data); // // void gst_pad_remove_buffer_probe(Pad pad, NativeLong handler_id); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstPadProbeInfo.java ================================================ /* * Copyright (c) 2014 Tom Greenwood * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.util.Arrays; import java.util.List; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import com.sun.jna.Structure; import static org.freedesktop.gstreamer.lowlevel.GstAPI.GST_PADDING; /** * GstPadProbeInfo structure * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstpad.h?h=1.8 */ public class GstPadProbeInfo extends Structure { public volatile int padProbeType; // GstPadProbeInfo enum constants public volatile NativeLong id; // id of the probe public volatile Pointer data; // (allow-none): type specific data, check the @type field to know the datatype. This field can be %NULL. public volatile long offset; // offset of pull probe, this field is valid when type contains GST_PAD_PROBE_TYPE_PULL public volatile int size; // size of pull probe, this field is valid when type contains GST_PAD_PROBE_TYPE_PULL /*< private >*/ public volatile Pointer[] _gst_reserved = new Pointer[GST_PADDING]; @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "padProbeType", "id", "data", "offset", "size", "_gst_reserved" }); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstPadPtr.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; /** * Base GObject pointer */ public class GstPadPtr extends GstObjectPtr { public GstPadPtr() { } public GstPadPtr(Pointer ptr) { super(ptr); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstPadTemplateAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Native; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.Pad; import org.freedesktop.gstreamer.PadDirection; import org.freedesktop.gstreamer.PadPresence; import org.freedesktop.gstreamer.PadTemplate; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import org.freedesktop.gstreamer.lowlevel.annotations.IncRef; import com.sun.jna.Pointer; import com.sun.jna.PointerType; /** * GstPadTemplate functions */ public interface GstPadTemplateAPI extends com.sun.jna.Library { GstPadTemplateAPI GSTPADTEMPLATE_API = GstNative.load(GstPadTemplateAPI.class); /* element class pad templates */ void gst_element_class_add_pad_template(Pointer klass, PadTemplate templ); PadTemplate gst_element_class_get_pad_template(Pointer /*GstElementClass*/ element_class, String name); /* templates and factories */ GType gst_pad_template_get_type(); GType gst_static_pad_template_get_type(); @CallerOwnsReturn Pointer ptr_gst_pad_template_new(String name_template, PadDirection direction, PadPresence presence, @IncRef Caps caps); @CallerOwnsReturn PadTemplate gst_pad_template_new(String name_template, PadDirection direction, PadPresence presence, @IncRef Caps caps); @CallerOwnsReturn PadTemplate gst_static_pad_template_get(GstStaticPadTemplate pad_template); @CallerOwnsReturn Caps gst_static_pad_template_get_caps(GstStaticPadTemplate template); @CallerOwnsReturn Caps gst_pad_template_get_caps(PadTemplate template); void gst_pad_template_pad_created(PadTemplate templ, Pad pad); public static final class GstStaticPadTemplate extends PointerType { public GstStaticPadTemplate() { } public GstStaticPadTemplate(Pointer p) { super(p); } public String getName() { return getPointer().getPointer(0).getString(0); } public PadDirection getPadDirection() { return PadDirection.values()[getPointer().getInt(Native.POINTER_SIZE)]; } public PadPresence getPadPresence() { return PadPresence.values()[getPointer().getInt(Native.POINTER_SIZE + 4)]; } } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstParseAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.Bin; import org.freedesktop.gstreamer.Pipeline; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.Element; /** * gstparse functions */ public interface GstParseAPI extends com.sun.jna.Library { GstParseAPI GSTPARSE_API = GstNative.load(GstParseAPI.class); @CallerOwnsReturn Element gst_parse_launch(String pipeline_description, Pointer[] error); @CallerOwnsReturn Element gst_parse_launchv(String[] pipeline_description, Pointer[] error); @CallerOwnsReturn Element gst_parse_launch(String pipeline_description, GstAPI.GErrorStruct[] error); @CallerOwnsReturn Element gst_parse_launchv(String[] pipeline_description, GstAPI.GErrorStruct[] error); @CallerOwnsReturn Bin gst_parse_bin_from_description(String bin_description, boolean ghost_unlinked_pads,Pointer[] error); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstPipelineAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.Bus; import org.freedesktop.gstreamer.Clock; import org.freedesktop.gstreamer.Pipeline; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import com.sun.jna.Pointer; /** * GstPipeline */ public interface GstPipelineAPI extends com.sun.jna.Library { GstPipelineAPI GSTPIPELINE_API = GstNative.load(GstPipelineAPI.class); @CallerOwnsReturn Pipeline gst_pipeline_new(String name); @CallerOwnsReturn Pointer ptr_gst_pipeline_new(String name); GType gst_pipeline_get_type(); @CallerOwnsReturn Bus gst_pipeline_get_bus(Pipeline pipeline); void gst_pipeline_set_auto_flush_bus(Pipeline pipeline, boolean flush); boolean gst_pipeline_get_auto_flush_bus(Pipeline pipeline); void gst_pipeline_set_new_stream_time(Pipeline pipeline, long time); long gst_pipeline_get_last_stream_time(Pipeline pipeline); void gst_pipeline_use_clock(Pipeline pipeline, Clock clock); boolean gst_pipeline_set_clock(Pipeline pipeline, Clock clock); @CallerOwnsReturn Clock gst_pipeline_get_clock(Pipeline pipeline); void gst_pipeline_auto_clock(Pipeline pipeline); void gst_pipeline_set_delay(Pipeline pipeline, long delay); long gst_pipeline_get_delay(Pipeline pipeline); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstPluginAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.Plugin; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GList; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; /** * GstPlugin functions */ public interface GstPluginAPI extends com.sun.jna.Library { GstPluginAPI GSTPLUGIN_API = GstNative.load(GstPluginAPI.class); GType gst_plugin_get_type(); String gst_plugin_get_name(Plugin plugin); String gst_plugin_get_description(Plugin plugin); String gst_plugin_get_filename(Plugin plugin); String gst_plugin_get_version(Plugin plugin); String gst_plugin_get_license(Plugin plugin); String gst_plugin_get_source(Plugin plugin); String gst_plugin_get_package(Plugin plugin); String gst_plugin_get_origin(Plugin plugin); String gst_plugin_get_release_date_string(Plugin plugin); boolean gst_plugin_is_loaded(Plugin plugin); boolean gst_plugin_name_filter(Plugin plugin, String name); //Plugin gst_plugin_load_file (String filename, GError** error); @CallerOwnsReturn Plugin gst_plugin_load(Plugin plugin); @CallerOwnsReturn Plugin gst_plugin_load_by_name(String name); void gst_plugin_list_free(GList list); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstPluginFeatureAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.Plugin; import org.freedesktop.gstreamer.PluginFeature; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GList; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; /** * GstPluginFeature functions */ public interface GstPluginFeatureAPI extends com.sun.jna.Library { GstPluginFeatureAPI GSTPLUGINFEATURE_API = GstNative.load(GstPluginFeatureAPI.class); /* normal GObject stuff */ GType gst_plugin_feature_get_type(); @CallerOwnsReturn PluginFeature gst_plugin_feature_load(PluginFeature feature); void gst_plugin_feature_set_rank(PluginFeature feature, int rank); int gst_plugin_feature_get_rank(PluginFeature feature); String gst_plugin_feature_get_plugin_name(PluginFeature feature); @CallerOwnsReturn Plugin gst_plugin_feature_get_plugin(PluginFeature feature); boolean gst_plugin_feature_check_version(PluginFeature feature, int min_major, int min_minor, int min_micro); void gst_plugin_feature_list_free (GList list); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstPromiseAPI.java ================================================ /* * Copyright (c) 2018 Vinicius Tona * Copyright (c) 2018 Antonio Morales * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.util.Arrays; import java.util.List; import org.freedesktop.gstreamer.Promise; import org.freedesktop.gstreamer.PromiseResult; import org.freedesktop.gstreamer.Structure; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback; import org.freedesktop.gstreamer.lowlevel.GstMiniObjectAPI.MiniObjectStruct; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.lowlevel.annotations.Invalidate; /** * GstPromise methods and structures * * @see https://github.com/GStreamer/gstreamer/blob/master/gst/gstpromise.h * available since GStreamer 1.14 */ public interface GstPromiseAPI extends com.sun.jna.Library { GstPromiseAPI GSTPROMISE_API = GstNative.load(GstPromiseAPI.class); public static final class PromiseStruct extends com.sun.jna.Structure { public volatile MiniObjectStruct parent; public PromiseStruct() { } public PromiseStruct(Pointer ptr) { useMemory(ptr); } @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "parent" }); } } GType gst_promise_get_type(); GType gst_static_promise_get_type(); @CallerOwnsReturn Promise gst_promise_new(); @CallerOwnsReturn Pointer ptr_gst_promise_new(); @CallerOwnsReturn Promise gst_promise_new_with_change_func(GstCallback callback, Pointer userData, Pointer destroyNotify); @CallerOwnsReturn Pointer ptr_gst_promise_new_with_change_func(GstCallback callback, Pointer userData, Pointer destroyNotify); PromiseResult gst_promise_wait(Promise promise); void gst_promise_reply(Promise promise, @Invalidate Structure s); void gst_promise_interrupt(Promise promise); void gst_promise_expire(Promise promise); @CallerOwnsReturn Structure gst_promise_get_reply(Promise promise); @CallerOwnsReturn Pointer ptr_gst_promise_get_reply(Promise promise); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstProxyControlBindingPtr.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; /** * */ public class GstProxyControlBindingPtr extends GstControlBindingPtr { public GstProxyControlBindingPtr() { } public GstProxyControlBindingPtr(Pointer ptr) { super(ptr); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstQueryAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.util.Arrays; import java.util.List; import org.freedesktop.gstreamer.BufferPool; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.query.Query; import org.freedesktop.gstreamer.query.QueryType; import org.freedesktop.gstreamer.Structure; import org.freedesktop.gstreamer.glib.GQuark; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import com.sun.jna.Pointer; /** * GstQueryAPI functions and structure * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstquery.h?h=1.8 */ public interface GstQueryAPI extends com.sun.jna.Library { GstQueryAPI GSTQUERY_API = GstNative.load(GstQueryAPI.class); String gst_query_type_get_name(QueryType query); GQuark gst_query_type_to_quark(QueryType query); /* position query */ @CallerOwnsReturn Query gst_query_new_position(Format format); @CallerOwnsReturn Pointer ptr_gst_query_new_position(Format format); void gst_query_set_position(Query query, Format format, /* gint64 */ long cur); void gst_query_parse_position(Query query, Format[] format, /* gint64 * */ long[] cur); /* duration query */ @CallerOwnsReturn Query gst_query_new_duration(Format format); @CallerOwnsReturn Pointer ptr_gst_query_new_duration(Format format); void gst_query_set_duration(Query query, Format format, /* gint64 */ long duration); void gst_query_parse_duration(Query query, /* Format **/ Format[] format, /* gint64 * */ long[] duration); /* latency query */ @CallerOwnsReturn Query gst_query_new_latency(); @CallerOwnsReturn Pointer ptr_gst_query_new_latency(); void gst_query_set_latency(Query query, boolean live, long min_latency, long max_latency); void gst_query_parse_latency(Query query, boolean[] live, long[] min_latency, long[] max_latency); /* convert query */ @CallerOwnsReturn Query gst_query_new_convert(Format src_format, /* gint64 */ long value, Format dest_format); @CallerOwnsReturn Pointer ptr_gst_query_new_convert(Format src_format, /* gint64 */ long value, Format dest_format); void gst_query_set_convert(Query query, Format src_format, /* gint64 */ long src_value, Format dest_format, /* gint64 */ long dest_value); void gst_query_parse_convert(Query query, Format[] src_format, /*gint64 **/ long[] src_value, Format[] dest_format, /*gint64 **/ long[] dest_value); /* segment query */ @CallerOwnsReturn Query gst_query_new_segment(Format format); @CallerOwnsReturn Pointer ptr_gst_query_new_segment(Format format); void gst_query_set_segment(Query query, double rate, Format format, /* gint64 */ long start_value, /* gint64 */ long stop_value); void gst_query_parse_segment(Query query, double[] rate, Format[] format, /* gint64 * */ long[] start_value, /* gint64 * */ long[] stop_value); Structure gst_query_get_structure(Query query); /* seeking query */ @CallerOwnsReturn Query gst_query_new_seeking(Format format); @CallerOwnsReturn Pointer ptr_gst_query_new_seeking(Format format); void gst_query_set_seeking(Query query, Format format, boolean seekable, /* gint64 */ long segment_start, /* gint64 */ long segment_end); void gst_query_parse_seeking(Query query, Format[] format, boolean[] seekable, /* gint64 * */ long[] segment_start, /* gint64 * */ long[] segment_end); /* formats query */ @CallerOwnsReturn Query gst_query_new_formats(); Pointer ptr_gst_query_new_formats(); void gst_query_set_formats(Query query, int n_formats, Format... formats); void gst_query_set_formatsv(Query query, int n_formats, Format[] formats); void gst_query_parse_n_formats(Query query, int[] n_formats); void gst_query_parse_nth_format(Query query, int nth, Format[] format); /* allocation query */ @CallerOwnsReturn Query gst_query_new_allocation(Caps caps, boolean need_pool); Pointer ptr_gst_query_new_allocation(Caps caps, boolean need_pool); void gst_query_parse_allocation(Query query, /* Caps ** */ Pointer[] caps, boolean[] need_pool); void gst_query_add_allocation_meta(Query query, GType api, Structure params); void gst_query_add_allocation_pool(Query query, BufferPool pool, /* guint */ int size, /* guint */ int min_buffers, /* guint */ int max_buffers); int gst_query_get_n_allocation_pools(Query query); public static final class QueryStruct extends com.sun.jna.Structure { public volatile GstMiniObjectAPI.MiniObjectStruct mini_object; /*< public > *//* with COW */ public volatile QueryType type; public QueryStruct(Pointer ptr) { useMemory(ptr); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "mini_object", "type" }); } } public interface GstQueryTypeFlags { public static final int UPSTREAM = 1; public static final int DOWNSTREAM = 1 << 1; public static final int SERIALIZED = 1 << 2; public static final int BOTH = UPSTREAM | DOWNSTREAM; } public static final int GST_QUERY_NUM_SHIFT = 8; } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstRegistryAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.Plugin; import org.freedesktop.gstreamer.PluginFeature; import org.freedesktop.gstreamer.Registry; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.lowlevel.GlibAPI.GList; /** * GstRegistry functions */ public interface GstRegistryAPI extends com.sun.jna.Library { GstRegistryAPI GSTREGISTRY_API = GstNative.load(GstRegistryAPI.class); /* function for filters */ static interface PluginFilter extends GstCallback { /** * * A function that can be used with e.g. gst_registry_plugin_filter() * to get a list of plugins that match certain criteria. * * @param plugin the plugin to check * @param user_data the user_data that has been passed on e.g. {@link GstRegistryAPI#gst_registry_feature_filter} * @return true for a positive match, false otherwise */ boolean callback(Plugin plugin, Pointer user_data); } static interface PluginFeatureFilter extends GstCallback { /** * A function that can be used with e.g. gst_registry_feature_filter() * to get a list of pluginfeature that match certain criteria. * @param feature the pluginfeature to check * @param user_data the user_data that has been passed on e.g. {@link GstRegistryAPI#gst_registry_feature_filter} * @return true if this plugin feature is accepted. */ boolean callback(PluginFeature feature, Pointer user_data); } /* normal GObject stuff */ GType gst_registry_get_type(); /* registry_get_default returns a non-refcounted object */ Pointer gst_registry_get(); GList gst_registry_get_feature_list(Registry registry, GType type); int gst_registry_get_feature_list_cookie (Registry registry); GList gst_registry_get_feature_list_by_plugin(Registry registry, String name); GList gst_registry_get_plugin_list(Registry registry); boolean gst_registry_add_plugin(Registry registry, Plugin plugin); void gst_registry_remove_plugin(Registry registry, Plugin plugin); GList gst_registry_plugin_filter(Registry registry, PluginFilter filter, boolean first, Pointer user_data); GList gst_registry_feature_filter(Registry registry, PluginFeatureFilter filter, boolean first, Pointer user_data); @CallerOwnsReturn Plugin gst_registry_find_plugin(Registry registry, String name); @CallerOwnsReturn PluginFeature gst_registry_find_feature(Registry registry, String name, GType type); @CallerOwnsReturn PluginFeature gst_registry_lookup_feature(Registry registry, String name); void gst_registry_add_path(Registry registry, String path); GList gst_registry_get_path_list(Registry registry); boolean gst_registry_scan_path(Registry registry, String path); @CallerOwnsReturn Plugin gst_registry_lookup(Registry registry, String filename); void gst_registry_remove_feature(Registry registry, PluginFeature feature); boolean gst_registry_add_feature(Registry registry, PluginFeature feature); boolean gst_registry_check_feature_version (Registry registry, String feature_name, int min_major, int min_minor, int min_micro); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstSDPMessageAPI.java ================================================ /* * Copyright (c) 2018 Antonio Morales * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.util.Arrays; import java.util.List; import org.freedesktop.gstreamer.SDPResult; import org.freedesktop.gstreamer.SDPMessage; import org.freedesktop.gstreamer.lowlevel.GValueAPI.GValueArray; import com.sun.jna.Pointer; /** * GstSDPMessage methods and structures * * @see https://github.com/GStreamer/gst-plugins-base/blob/master/gst-libs/gst/sdp/gstsdpmessage.h */ public interface GstSDPMessageAPI extends com.sun.jna.Library { GstSDPMessageAPI GSTSDPMESSAGE_API = GstNative.load("gstsdp", GstSDPMessageAPI.class); public static final class SDPMessageStruct extends com.sun.jna.Structure { public volatile String version; public volatile SDPOriginStruct origin; public volatile String session_name; public volatile String information; public volatile String uri; public volatile GValueArray emails; public volatile GValueArray phones; public volatile SDPConnectionStruct connection; public volatile GValueArray bandwidths; public volatile GValueArray times; public volatile GValueArray zones; public volatile SDPKeyStruct key; public volatile GValueArray attributes; public volatile GValueArray medias; public SDPMessageStruct(final Pointer ptr) { useMemory(ptr); } @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "version", "origin", "session_name", "information", "uri", "emails", "phones", "connection", "bandwidths", "times", "zones", "key", "attributes", "medias" }); } } public static final class SDPOriginStruct extends com.sun.jna.Structure { public volatile String username; public volatile String sess_id; public volatile String sess_version; public volatile String nettype; public volatile String addrtype; public volatile String addr; public SDPOriginStruct(final Pointer ptr) { useMemory(ptr); } @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "username", "sess_id", "sess_version", "nettype", "addrtype", "addr" }); } } public static final class SDPKeyStruct extends com.sun.jna.Structure { public volatile String type; public volatile String data; public SDPKeyStruct(final Pointer ptr) { useMemory(ptr); } @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "type", "data" }); } } public static final class SDPConnectionStruct extends com.sun.jna.Structure { public volatile String nettype; public volatile String addrtype; public volatile String address; public volatile int ttl; public volatile int addr_number; public SDPConnectionStruct(final Pointer ptr) { useMemory(ptr); } @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "nettype", "addrtype", "address", "ttl", "addr_number" }); } } SDPResult gst_sdp_connection_set(SDPConnectionStruct conn, String nettype, String address, int ttl, int addr_number); SDPResult gst_sdp_connection_clear(SDPConnectionStruct conn); SDPResult gst_sdp_message_free(Pointer msg); SDPResult ptr_gst_sdp_message_free(Pointer msg); SDPResult gst_sdp_message_new(Pointer[] msg); SDPResult gst_sdp_message_parse_buffer(byte[] data, int size, Pointer[] msg); SDPResult gst_sdp_message_parse_buffer(byte[] data, int size, SDPMessage msg); SDPResult gst_sdp_message_copy(SDPMessage msg, Pointer[] copy); String gst_sdp_message_as_text(SDPMessage msg); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstSampleAPI.java ================================================ /* * Copyright (c) 2020 Christophe Lafolet * Copyright (c) 2015 Neil C Smith * Copyright (c) 2014 Tom Greenwood * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.util.Arrays; import java.util.List; import org.freedesktop.gstreamer.Buffer; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.Sample; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstSegmentStruct; import org.freedesktop.gstreamer.lowlevel.GstMiniObjectAPI.MiniObjectStruct; import com.sun.jna.Pointer; /** * GstSampleAPI functions and structure * @see https://cgit.freedesktop.org/gstreamer/gstreamer/tree/gst/gstsample.c?h=1.8 */ public interface GstSampleAPI extends com.sun.jna.Library { GstSampleAPI GSTSAMPLE_API = GstNative.load(GstSampleAPI.class); public static final class SampleStruct extends com.sun.jna.Structure { public volatile MiniObjectStruct mini_object; public volatile Pointer /* GstBuffer* */buffer; // to Buffer public volatile Pointer /* GstCaps* */ caps; // to Caps public volatile GstSegmentStruct segment; // Segment public volatile Pointer /* GstStructure* */ info; // to Strucutre public volatile Pointer /* GstBufferList* */ buffer_list; // to buffer_list /** * Creates a new instance of MessageStruct */ public SampleStruct() { } public SampleStruct(Pointer ptr) { useMemory(ptr); } @Override protected List getFieldOrder() { return Arrays.asList(new String[]{ "mini_object", "buffer", "caps", "segment", "info", "buffer_list" }); } } /*@CallerOwnsReturn*/ Caps gst_sample_get_caps(Sample sample); /*@CallerOwnsReturn*/ Buffer gst_sample_get_buffer(Sample sample); void gst_sample_set_buffer(Sample sample, Buffer buffer); void gst_sample_set_caps(Sample sample, Caps caps); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstStructureAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.Structure; import org.freedesktop.gstreamer.lowlevel.GValueAPI.GValue; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import org.freedesktop.gstreamer.lowlevel.annotations.FreeReturnValue; import com.sun.jna.Pointer; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; /** * GstStructure functions */ public interface GstStructureAPI extends com.sun.jna.Library { GstStructureAPI GSTSTRUCTURE_API = GstNative.load(GstStructureAPI.class); GType gst_structure_get_type(); boolean gst_structure_get_int(Structure structure, String fieldname, IntByReference value); boolean gst_structure_fixate_field_nearest_int(Structure structure, String field, int target); @FreeReturnValue String gst_structure_to_string(Structure structure); @CallerOwnsReturn Structure gst_structure_from_string(String data, PointerByReference end); @CallerOwnsReturn Structure gst_structure_new_empty(String name); @CallerOwnsReturn Structure gst_structure_new(String name, String firstField, Object... args); @CallerOwnsReturn Pointer ptr_gst_structure_from_string(String data, PointerByReference end); @CallerOwnsReturn Pointer ptr_gst_structure_new_empty(String name); @CallerOwnsReturn Pointer ptr_gst_structure_new(String name, String firstField, Object... args); @CallerOwnsReturn Structure gst_structure_copy(Structure src); void gst_structure_remove_field(Structure structure, String fieldName); void gst_structure_remove_fields(Structure structure, String... fieldNames); void gst_structure_remove_all_fields(Structure structure); String gst_structure_get_name(Structure structure); void gst_structure_set_name(Structure structure, String name); boolean gst_structure_has_name(Structure structure, String name); int gst_structure_n_fields(Structure structure); String gst_structure_nth_field_name(Structure structure, int index); boolean gst_structure_has_field(Structure structure, String fieldname); boolean gst_structure_has_field_typed(Structure structure, String fieldname, GType type); boolean gst_structure_is_equal(Structure structure1, Structure structure2); /* utility functions */ boolean gst_structure_get_boolean(Structure structure, String fieldname, int[] value); boolean gst_structure_get_int(Structure structure, String fieldname, int[] value); boolean gst_structure_get_uint(Structure structure, String fieldname, int[] value); boolean gst_structure_get_fourcc(Structure structure, String fieldname, int[] value); boolean gst_structure_get_double(Structure structure, String fieldname, double[] value); boolean gst_structure_get_date(Structure structure, String fieldname, PointerByReference value); boolean gst_structure_get_date(Structure structure, String fieldname, Pointer[] value); //boolean gst_structure_get_clock_time(Structure structure, String fieldname, Gstlong *value); String gst_structure_get_string(Structure structure, String fieldname); boolean gst_structure_get_enum(Structure structure, String fieldname, GType enumtype, int[] value); boolean gst_structure_get_fraction(Structure structure, String fieldname, int[] value_numerator, int[] value_denominator); GValue gst_structure_get_value(Structure structure, String fieldname); void gst_structure_set(Structure structure, String fieldname, Object... args); void gst_structure_free(Pointer ptr); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstStructurePtr.java ================================================ /* * Copyright (c) 2020 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Native; import com.sun.jna.Pointer; /** * GstStructure pointer */ public class GstStructurePtr extends GTypedPtr { public GstStructurePtr() { } public GstStructurePtr(Pointer ptr) { super(ptr); } @Override public GType getGType() { // Quick getter for GType without allocation if (Native.SIZE_T_SIZE == 8) { return GType.valueOf(getPointer().getLong(0)); } else if (Native.SIZE_T_SIZE == 4) { return GType.valueOf( ((long) getPointer().getInt(0)) & 0xffffffffL ); } else { throw new IllegalStateException("SIZE_T size not supported: " + Native.SIZE_T_SIZE); } } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstTagAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.TagFlag; public interface GstTagAPI extends com.sun.jna.Library { GstTagAPI GSTTAG_API = GstNative.load(GstTagAPI.class); boolean gst_tag_exists(String tag); GType gst_tag_get_type(String tag); String gst_tag_get_nick(String tag); String gst_tag_get_description(String tag); TagFlag gst_tag_get_flag(String tag); boolean gst_tag_is_fixed(String tag); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstTagListAPI.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.TagList; import org.freedesktop.gstreamer.TagMergeMode; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import com.sun.jna.Pointer; import com.sun.jna.ptr.PointerByReference; /** * GstTagList functions */ public interface GstTagListAPI extends com.sun.jna.Library { GstTagListAPI GSTTAGLIST_API = GstNative.load(GstTagListAPI.class); interface TagForeachFunc extends GstCallback { void callback(Pointer list, String tag, Pointer user_data); } interface TagMergeFunc extends GstCallback { void callback(Pointer dest, Pointer src); } @CallerOwnsReturn Pointer ptr_gst_tag_list_new_empty(); void gst_tag_list_add(TagList list, TagMergeMode mode, String tag, Object... tags); @CallerOwnsReturn TagList gst_tag_list_copy(TagList list); @CallerOwnsReturn Pointer ptr_gst_tag_list_copy(TagList list); boolean gst_tag_list_is_empty(TagList list); void gst_tag_list_insert(TagList into, TagList from, TagMergeMode mode); @CallerOwnsReturn TagList gst_tag_list_merge(TagList list1, TagList list2, TagMergeMode mode); @CallerOwnsReturn Pointer ptr_gst_tag_list_merge(TagList list1, TagList list2, TagMergeMode mode); int gst_tag_list_get_tag_size(TagList list, String tag); void gst_tag_list_remove_tag(TagList list, TagList tag); void gst_tag_list_foreach(TagList list, TagForeachFunc func, Pointer user_data); boolean gst_tag_list_get_char(TagList list, String tag, byte[] value); boolean gst_tag_list_get_char_index(TagList list, String tag, int index, byte[] value); boolean gst_tag_list_get_uchar(TagList list, String tag, byte[] value); boolean gst_tag_list_get_uchar_index(TagList list, String tag, int index, byte[] value); boolean gst_tag_list_get_boolean(TagList list, String tag, int[] value); boolean gst_tag_list_get_boolean_index(TagList list, String tag, int index, int[] value); boolean gst_tag_list_get_int(TagList list, String tag, int[] value); boolean gst_tag_list_get_int_index(TagList list, String tag, int index, int[] value); boolean gst_tag_list_get_uint(TagList list, String tag, int[] value); boolean gst_tag_list_get_uint_index(TagList list, String tag, int index, int[] value); boolean gst_tag_list_get_int64(TagList list, String tag, long[] value); boolean gst_tag_list_get_int64_index(TagList list, String tag, int index, long[] value); boolean gst_tag_list_get_double(TagList list, String tag, double[] value); boolean gst_tag_list_get_double_index(TagList list, String tag, int index, double[] value); boolean gst_tag_list_get_string(TagList list, String tag, PointerByReference value); boolean gst_tag_list_get_string_index(TagList list, String tag, int index, PointerByReference value); boolean gst_tag_list_get_string_index(TagList list, String tag, int index, Pointer[] value); boolean gst_tag_list_get_date_index(TagList list, String tag, int index, PointerByReference value); boolean gst_tag_list_get_date_index(TagList list, String tag, int index, Pointer[] value); boolean gst_tag_list_get_date_time(TagList list, String tag, PointerByReference value); boolean gst_tag_list_get_date_time_index(TagList list, String tag, int index, PointerByReference value); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstTimedValueControlSourcePtr.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; /** * */ public class GstTimedValueControlSourcePtr extends GstControlSourcePtr { public GstTimedValueControlSourcePtr() { } public GstTimedValueControlSourcePtr(Pointer ptr) { super(ptr); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstTriggerControlSourcePtr.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; /** * */ public class GstTriggerControlSourcePtr extends GstTimedValueControlSourcePtr { public GstTriggerControlSourcePtr() { } public GstTriggerControlSourcePtr(Pointer ptr) { super(ptr); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstTypes.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2016 Christophe Lafolet * Copyright (c) 2009 Levente Farkas * Copyright (c) 2008 Andres Colubri * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; import org.freedesktop.gstreamer.glib.NativeObject; import org.freedesktop.gstreamer.glib.NativeObject.TypeRegistration; /** * */ public class GstTypes { private static final Logger logger = Logger.getLogger(GstTypes.class.getName()); // private static final Map> gtypeNameMap // = new ConcurrentHashMap>(); private static final Map> TYPES = new ConcurrentHashMap<>(); private GstTypes() { } /** * Register a class with its GType name */ // public static void registerType(Class cls, String gTypeName) { // gtypeNameMap.put(gTypeName, cls); // } public static void register(TypeRegistration registration) { TYPES.putIfAbsent(registration.getGTypeName(), registration); } /** * Retrieve the class of a GType * * @param gType The type of Class * @return The Class of the desired type or null. */ public static final TypeRegistration registrationFor(final GType gType) { final String gTypeName = gType.getTypeName(); // Is this GType still registered in the map ? TypeRegistration reg = TYPES.get(gTypeName); if (reg != null) { return reg; } // Search for a parent class registration GType type = gType.getParentType(); while (!type.equals(GType.OBJECT) && !type.equals(GType.POINTER) && !type.equals(GType.INVALID)) { reg = TYPES.get(type.getTypeName()); if (reg != null) { if (GstTypes.logger.isLoggable(Level.FINER)) { GstTypes.logger.finer("Found type of " + gType + " = " + reg.getJavaType()); } // The following line is an optimisation but not compatible with current implementation of GstTypes.typeFor() // Uncomment the following line after refactoring of GstTypes.typeFor() // gtypeNameMap.put(gTypeName, cls); return reg; } type = type.getParentType(); } // No registered class found for this gType return null; } public static final Class classFor(final GType gType) { TypeRegistration reg = registrationFor(gType); return reg != null ? reg.getJavaType() : null; } //TODO : need refactoring to take into account derived class public static final GType typeFor(Class cls) { for (Map.Entry> e : TYPES.entrySet()) { if (e.getValue().getJavaType().equals(cls)) { return GType.valueOf(e.getKey()); } } return GType.INVALID; } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstValueAPI.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.lowlevel.GValueAPI.GValue; /** * GstValue functions */ public interface GstValueAPI extends com.sun.jna.Library { GstValueAPI GSTVALUE_API = GstNative.load(GstValueAPI.class); GType gst_fourcc_get_type(); GType gst_int_range_get_type(); GType gst_double_range_get_type(); GType gst_fraction_range_get_type(); GType gst_value_list_get_type(); GType gst_fraction_get_type(); int gst_value_get_fraction_numerator(GValue value); int gst_value_get_fraction_denominator(GValue value); GValue gst_value_get_fraction_range_min(GValue value); GValue gst_value_get_fraction_range_max(GValue value); double gst_value_get_double_range_min(GValue value); double gst_value_get_double_range_max(GValue value); int gst_value_get_int_range_min(GValue value); int gst_value_get_int_range_max(GValue value); int gst_value_list_get_size(GValue value); GValue gst_value_list_get_value(GValue value, int index); boolean gst_value_deserialize(GValue value, String src); Pointer gst_value_serialize(GValue value); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstVideoAPI.java ================================================ /* * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.Pad; import org.freedesktop.gstreamer.lowlevel.GValueAPI.GValue; import com.sun.jna.Library; import com.sun.jna.Pointer; import com.sun.jna.Structure; import org.freedesktop.gstreamer.Gst; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import org.freedesktop.gstreamer.video.VideoTimeCodeFlags; public interface GstVideoAPI extends Library { public final static GstVideoAPI GSTVIDEO_API = GstNative.load("gstvideo", GstVideoAPI.class); @CallerOwnsReturn Pointer gst_video_time_code_new_empty(); void gst_video_time_code_free(Pointer gstVideoTimeCode); GValue gst_video_frame_rate(Pad pad); boolean gst_video_get_size(Pad pad, int [] width, int [] height); /* */ Pointer ptr_gst_video_event_new_downstream_force_key_unit( long timestamp, long stream_time, long running_time, boolean all_headers, int count); Pointer ptr_gst_video_event_new_upstream_force_key_unit( long running_time, boolean all_headers, int count); GType gst_video_time_code_meta_api_get_type(); GType gst_video_crop_meta_api_get_type(); GType gst_video_gl_texture_upload_meta_api_get_type(); GType gst_video_meta_api_get_type(); GType gst_video_region_of_interest_meta_api_get_type(); // MetaInfo gst_video_time_code_meta_get_info(); @Structure.FieldOrder({"meta", "tc"}) class GstVideoTimeCodeMetaStruct extends Structure { public GstMetaAPI.GstMetaStruct.ByValue meta; public GstVideoTimeCodeStruct.ByValue tc; public GstVideoTimeCodeMetaStruct(Pointer p) { super(p); read(); } } @Structure.FieldOrder({"config", "hours", "minutes", "seconds", "frames", "field_count"}) @Gst.Since(minor = 10) class GstVideoTimeCodeStruct extends Structure { public static class ByValue extends GstVideoTimeCodeStruct implements Structure.ByValue { } public GstVideoTimeCodeConfigStruct.ByValue config; public int hours; public int minutes; public int seconds; public int frames; public int field_count; public GstVideoTimeCodeStruct() { } public GstVideoTimeCodeStruct(Pointer p) { super(p); read(); } } @Structure.FieldOrder({"fps_n", "fps_d", "flags", "latest_daily_jam"}) @Gst.Since(minor = 10) class GstVideoTimeCodeConfigStruct extends Structure { public static class ByValue extends GstVideoTimeCodeConfigStruct implements Structure.ByValue { } public int fps_n; public int fps_d; public int flags; public Pointer latest_daily_jam; public GstVideoTimeCodeConfigStruct() { } public GstVideoTimeCodeConfigStruct(Pointer p) { super(p); read(); } } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstVideoOrientationAPI.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2009 Tamas Korodi * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.interfaces.VideoOrientation; import com.sun.jna.Library; public interface GstVideoOrientationAPI extends Library { GstVideoOrientationAPI GSTVIDEOORIENTATION_API = GstNative.load("gstvideo", GstVideoOrientationAPI.class); GType gst_video_orientation_get_type(); // @TODO need implementing to use pointers // boolean gst_video_orientation_get_hflip(VideoOrientation video_orientation, boolean flip); // // boolean gst_video_orientation_get_vflip(VideoOrientation video_orientation, boolean flip); // // boolean gst_video_orientation_get_hcenter(VideoOrientation video_orientation, int center); // // boolean gst_video_orientation_get_vcenter(VideoOrientation video_orientation, int center); boolean gst_video_orientation_set_hflip(VideoOrientation video_orientation, boolean flip); boolean gst_video_orientation_set_vflip(VideoOrientation video_orientation, boolean flip); boolean gst_video_orientation_set_hcenter(VideoOrientation video_orientation, int center); boolean gst_video_orientation_set_vcenter(VideoOrientation video_orientation, int center); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstVideoOverlayAPI.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2009 Tamas Korodi * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.message.Message; import org.freedesktop.gstreamer.interfaces.VideoOverlay; import com.sun.jna.Library; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; public interface GstVideoOverlayAPI extends Library { GstVideoOverlayAPI GSTVIDEOOVERLAY_API = GstNative.load("gstvideo", GstVideoOverlayAPI.class); GType gst_video_overlay_get_type(); void gst_video_overlay_set_window_handle(VideoOverlay overlay, Pointer xwindow_id); void gst_video_overlay_got_window_handle(VideoOverlay overlay, NativeLong xwindow_id); void gst_video_overlay_prepare_xwindow_id(VideoOverlay overlay); void gst_video_overlay_expose(VideoOverlay overlay); void gst_video_overlay_handle_events(VideoOverlay overlay, boolean handle_events); boolean gst_video_overlay_set_render_rectangle(VideoOverlay overlay, int x, int y, int width, int height); boolean gst_is_video_overlay_prepare_window_handle_message(Message message); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/GstWebRTCSessionDescriptionAPI.java ================================================ /* * Copyright (c) 2018 Vinicius Tona * Copyright (c) 2018 Antonio Morales * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.util.Arrays; import java.util.List; import org.freedesktop.gstreamer.webrtc.WebRTCSessionDescription; import org.freedesktop.gstreamer.webrtc.WebRTCSDPType; import org.freedesktop.gstreamer.SDPMessage; import org.freedesktop.gstreamer.lowlevel.annotations.CallerOwnsReturn; import org.freedesktop.gstreamer.lowlevel.GValueAPI.GValueArray; import com.sun.jna.Pointer; /** * GstWebRTCSessionDescription methods and structures * * @see https://github.com/GStreamer/gst-plugins-bad/blob/master/gst-libs/gst/webrtc/rtcsessiondescription.h * Available since GStreamer 1.14 */ public interface GstWebRTCSessionDescriptionAPI extends com.sun.jna.Library { GstWebRTCSessionDescriptionAPI GSTWEBRTCSESSIONDESCRIPTION_API = GstNative.load("gstwebrtc", GstWebRTCSessionDescriptionAPI.class); public static final class WebRTCSessionDescriptionStruct extends com.sun.jna.Structure { public volatile WebRTCSDPType type; public volatile SDPMessage sdp; public WebRTCSessionDescriptionStruct(final Pointer ptr) { useMemory(ptr); } @Override protected List getFieldOrder() { return Arrays.asList(new String[] { "type", "sdp" }); } } GType gst_webrtc_session_description_get_type(); @CallerOwnsReturn WebRTCSessionDescription gst_webrtc_session_description_new(WebRTCSDPType type, SDPMessage sdp); @CallerOwnsReturn Pointer ptr_gst_webrtc_session_description_new(WebRTCSDPType type, SDPMessage sdp); @CallerOwnsReturn WebRTCSessionDescription gst_webrtc_session_description_copy(WebRTCSessionDescription src); @CallerOwnsReturn Pointer ptr_gst_webrtc_session_description_copy(WebRTCSessionDescription src); void gst_webrtc_session_description_free(Pointer desc); } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/IntPtr.java ================================================ /* * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import com.sun.jna.Native; @SuppressWarnings("serial") public class IntPtr extends Number { public final Number value; public IntPtr(int value) { this.value = Native.POINTER_SIZE == 8 ? new Long(value) : new Integer(value); } public String toString() { return Integer.toHexString(intValue()); } public int intValue() { return value.intValue(); } public long longValue() { return value.longValue(); } public float floatValue() { return value.floatValue(); } public double doubleValue() { return value.doubleValue(); } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/MainLoop.java ================================================ /* * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; import org.freedesktop.gstreamer.Gst; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.glib.GMainContext; import org.freedesktop.gstreamer.glib.GSource; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.glib.RefCountedObject; /** * The GLib main loop. */ public class MainLoop extends RefCountedObject { private static final List bgTasks = new LinkedList(); private Thread bgThread; /** * Creates a new instance of {@code MainLoop} * *

* This will create a new main loop on the default gstreamer main context. * */ public MainLoop() { this(Natives.initializer(GLIB_API.g_main_loop_new(Gst.getMainContext(), false))); } public MainLoop(GMainContext ctx) { this(Natives.initializer(GLIB_API.g_main_loop_new(ctx, false))); } /** * Creates a new instance of {@code MainLoop} * *

* This variant is used internally. * * @param init internal initialization data. */ public MainLoop(Initializer init) { super(new Handle(init.ptr, init.ownsHandle), init.needRef); } /** * Instructs a main loop to stop processing and return from {@link #run}. */ public void quit() { invokeLater(new Runnable() { public void run() { GLIB_API.g_main_loop_quit(MainLoop.this); } }); } /** * Enter a loop, processing all events. *

* The loop will continue processing events until {@link #quit} is called. */ public void run() { GLIB_API.g_main_loop_run(this); } /** * Returns whether this main loop is currently processing or not. * * @return true if the main loop is currently being run. */ public boolean isRunning() { return GLIB_API.g_main_loop_is_running(this); } /** * Gets the main context for this main loop. * * @return a main context. */ public GMainContext getMainContext() { return GLIB_API.g_main_loop_get_context(this); } /** * Runs the main loop in a background thread. */ public void startInBackground() { bgThread = new java.lang.Thread(new Runnable() { public void run() { MainLoop.this.run(); } }); bgThread.setDaemon(true); bgThread.setName("gmainloop"); bgThread.start(); } /** * Invokes a task on the main loop thread. *

* This method will wait until the task has completed before returning. * * @param r the task to invoke. */ public void invokeAndWait(Runnable r) { FutureTask task = new FutureTask(r, null); invokeLater(task); try { task.get(); } catch (InterruptedException ex) { throw new RuntimeException(ex.getCause()); } catch (ExecutionException ex) { throw new RuntimeException(ex.getCause()); } } private static final GlibAPI.GSourceFunc bgCallback = new GlibAPI.GSourceFunc() { public boolean callback(Pointer source) { // System.out.println("Running g_idle callbacks"); List tasks = new ArrayList(); synchronized (bgTasks) { tasks.addAll(bgTasks); bgTasks.clear(); } for (Runnable r : tasks) { r.run(); } GLIB_API.g_source_unref(source); return false; } }; /** * Invokes a task on the main loop thread. *

* This method returns immediately, without waiting for the task to * complete. * * @param r the task to invoke. */ public void invokeLater(final Runnable r) { // System.out.println("Scheduling idle callbacks"); synchronized (bgTasks) { boolean empty = bgTasks.isEmpty(); bgTasks.add(r); // Only trigger the callback if there were no existing elements in the list // otherwise it is already triggered if (empty) { GSource source = GLIB_API.g_idle_source_new(); GLIB_API.g_source_set_callback(source, bgCallback, source, null); source.attach(Gst.getMainContext()); source.disown(); // gets destroyed in the callback } } } private final static class Handle extends RefCountedObject.Handle { public Handle(GPointer ptr, boolean ownsHandle) { super(ptr, ownsHandle); } @Override protected void disposeNativeHandle(GPointer ptr) { GLIB_API.g_main_loop_unref(ptr); } @Override protected void ref() { GLIB_API.g_main_loop_ref(getPointer()); } @Override protected void unref() { GLIB_API.g_main_loop_unref(getPointer()); } } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/README ================================================ lowlevel cleanup log structures in the following classes were aligned to 1.8: (https://cgit.freedesktop.org/gstreamer/gstreamer/tree/?h=1.8) - BaseSinkAPI - BaseSrcAPI - BaseTransformAPI - GstAPI - GstBufferAPI - GstBufferPoolAPI - GstControlSourceAPI - GstControllerAPI - removed - GstElementAPI - GstEvent - GstObject - GstPadProbeInfo - GstQueryAPI - GstSampleAPI ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/ReferenceManager.java ================================================ /* * Copyright (C) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.freedesktop.gstreamer.glib.RefCountedObject; /** * Manages keep alive links from one object to another. */ public class ReferenceManager { private ReferenceManager() {} /** * Adds a link from ref to target that keeps target alive * whilst ref is alive. * * @param ref * @param target */ public static T addKeepAliveReference(T ref, RefCountedObject target) { if (ref != null) { StaticData.map.put(new WeakReference(ref, StaticData.queue), target); } return ref; } /** * Holds static data for lazy loading. */ private static class StaticData { private static final Map map = new ConcurrentHashMap(); private static final ReferenceQueue queue = new ReferenceQueue(); static { Thread t = new Thread(new Runnable() { public void run() { while (true) { try { map.remove(queue.remove()); } catch (InterruptedException ex) { break; } catch (Throwable ex) { // Don't break out of the loop for any other reason continue; } } } }); t.setName("Reference reaper"); t.setDaemon(true); t.start(); } } } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/annotations/CallerOwnsReturn.java ================================================ /* * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Indicates that the returned value is owned by the method caller, so appropriate * action should be taken when the object is garbage collected. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface CallerOwnsReturn { } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/annotations/Const.java ================================================ /* * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * * @author wayne */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.PARAMETER, ElementType.METHOD}) public @interface Const { } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/annotations/ConstField.java ================================================ /* * Copyright (C) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * * @author wayne */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface ConstField { } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/annotations/ConstReturn.java ================================================ /* * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * * @author wayne */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface ConstReturn { } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/annotations/DefaultEnumValue.java ================================================ /* * Copyright (C) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Used to flag the Enum value to use for converting from a native value, * when no exact match is found. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface DefaultEnumValue { } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/annotations/FreeReturnValue.java ================================================ /* * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * * @author wayne */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface FreeReturnValue { } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/annotations/HasSubtype.java ================================================ /* * Copyright (c) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface HasSubtype { } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/annotations/IncRef.java ================================================ /* * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Signal that the Handle parameter's refcount should be incremented */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface IncRef { } ================================================ FILE: src/org/freedesktop/gstreamer/lowlevel/annotations/Invalidate.java ================================================ /* * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.lowlevel.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Signal that the Handle parameter should be invalidated (not used after this call) */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface Invalidate { } ================================================ FILE: src/org/freedesktop/gstreamer/message/BufferingMessage.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * Copyright (C) 2004 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.message; import org.freedesktop.gstreamer.GstObject; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API; /** * This message can be posted by an element that * needs to buffer data before it can continue processing. {@code percent} should be a * value between 0 and 100. A value of 100 means that the buffering completed. *

* See upstream documentation * at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-buffering *

* When percent is < 100 the application should PAUSE a PLAYING pipeline. When * percent is 100, the application can set the pipeline (back) to PLAYING. * The application must be prepared to receive BUFFERING messages in the * PREROLLING state and may only set the pipeline to PLAYING after receiving a * message with percent set to 100, which can happen after the pipeline * completed prerolling. */ public class BufferingMessage extends Message { /** * Creates a new Buffering message. * @param init internal initialization data. */ BufferingMessage(Initializer init) { super(init); } /** * Creates a new Buffering message. * @param src The object originating the message. * @param percent The buffering percent */ public BufferingMessage(GstObject src, int percent) { this(Natives.initializer(GSTMESSAGE_API.ptr_gst_message_new_buffering(src, percent))); } /** * Gets the buffering percentage. * * @return the percentage that is being buffered. */ public int getPercent() { int[] percent = { 0 }; GSTMESSAGE_API.gst_message_parse_buffering(this, percent); return percent[0]; } } ================================================ FILE: src/org/freedesktop/gstreamer/message/DurationChangedMessage.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * Copyright (C) 2004 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.message; import org.freedesktop.gstreamer.GstObject; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API; /** * A duration changed message. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-duration-changed *

* This message is posted by elements that know the duration of a stream when * the duration changes. This message is received by bins and is used to * calculate the total duration of a pipeline. */ public class DurationChangedMessage extends Message { /** * Creates a new DurationChanged message. * * @param init internal initialization data. */ DurationChangedMessage(Initializer init) { super(init); } /** * Creates a new DurationChanged Message * * @param src The object originating the message. */ public DurationChangedMessage(GstObject src) { this(Natives.initializer(GSTMESSAGE_API.ptr_gst_message_new_duration_changed(src))); } } ================================================ FILE: src/org/freedesktop/gstreamer/message/EOSMessage.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * Copyright (C) 2004 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.message; import org.freedesktop.gstreamer.Bin; import org.freedesktop.gstreamer.GstObject; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API; /** * An End-of-Stream Message. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-eos *

* This message is generated and posted in the sink elements of a {@link Bin}. * The bin will only forward the EOS message to the application if all sinks * have posted an EOS message. */ public class EOSMessage extends Message { /** * Creates a new eos message. * * @param init internal initialization data. */ EOSMessage(Initializer init) { super(init); } /** * Creates a new eos message. * * @param src The object originating the message. */ public EOSMessage(GstObject src) { this(Natives.initializer(GSTMESSAGE_API.ptr_gst_message_new_eos(src))); } } ================================================ FILE: src/org/freedesktop/gstreamer/message/ErrorMessage.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * Copyright (C) 2004 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.message; import org.freedesktop.gstreamer.lowlevel.GstAPI.GErrorStruct; import static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API; /** * This message is posted by element when a fatal event occurs. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-error *

* The pipeline will probably (partially) stop. The application * receiving this message should stop the pipeline. */ public class ErrorMessage extends GErrorMessage { /** * Creates a new error message. * * @param init internal initialization data. */ ErrorMessage(Initializer init) { super(init); } /** * Retrieves the GError structure contained in this message. * * @return the GError contained in this message. */ @Override GErrorStruct parseMessage() { GErrorStruct[] err = { null }; GSTMESSAGE_API.gst_message_parse_error(this, err, null); return err[0]; } } ================================================ FILE: src/org/freedesktop/gstreamer/message/GErrorMessage.java ================================================ /* * Copyright (C) 2025 Neil C Smith * Copyright (C) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.message; import org.freedesktop.gstreamer.lowlevel.GstAPI; import org.freedesktop.gstreamer.lowlevel.GstAPI.GErrorStruct; import static org.freedesktop.gstreamer.lowlevel.GlibAPI.GLIB_API; /** * Package private base class for ERROR, WARNING and INFO messages. */ abstract class GErrorMessage extends Message { /** * Creates a new GError message. * @param init internal initialization data. */ GErrorMessage(Initializer init) { super(init); } abstract GstAPI.GErrorStruct parseMessage(); /** * Gets the error code from this message. * * @return the error code. */ public int getCode() { GErrorStruct err = parseMessage(); if (err == null) { throw new NullPointerException("Could not parse message"); } int code = err.code; GLIB_API.g_error_free(err.getPointer()); return code; } /** * Gets the message contained in this message. * * @return the message contained in this message. */ public String getMessage() { GErrorStruct err = parseMessage(); if (err == null) { throw new NullPointerException("Could not parse message"); } String message = err.getMessage(); GLIB_API.g_error_free(err.getPointer()); return message; } } ================================================ FILE: src/org/freedesktop/gstreamer/message/InfoMessage.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * Copyright (C) 2004 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.message; import org.freedesktop.gstreamer.lowlevel.GstAPI.GErrorStruct; import static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API; /** * This message is posted by element to provide information to the application. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-info *

*/ public class InfoMessage extends GErrorMessage { /** * Creates a new info message. * * @param init internal initialization data. */ InfoMessage(Initializer init) { super(init); } /** * Retrieves the GError structure contained in this message. * * @return the GError contained in this message. */ @Override GErrorStruct parseMessage() { GErrorStruct[] err = {null}; GSTMESSAGE_API.gst_message_parse_info(this, err, null); return err[0]; } } ================================================ FILE: src/org/freedesktop/gstreamer/message/LatencyMessage.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * Copyright (C) 2004 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.message; import org.freedesktop.gstreamer.GstObject; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API; /** * Message posted by elements when their latency requirements have changed. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-latency *

*/ public class LatencyMessage extends Message { /** * Creates a new Latency message. * * @param init internal initialization data. */ LatencyMessage(Initializer init) { super(init); } /** * Creates a new Latency message. * * @param source the object originating the message. */ public LatencyMessage(GstObject source) { this(Natives.initializer(GSTMESSAGE_API.ptr_gst_message_new_latency(source))); } } ================================================ FILE: src/org/freedesktop/gstreamer/message/Message.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2007, 2008 Wayne Meissner * Copyright (C) 2004 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.message; import java.util.EnumMap; import java.util.Map; import java.util.function.Function; import java.util.stream.Stream; import org.freedesktop.gstreamer.GstObject; import org.freedesktop.gstreamer.MiniObject; import org.freedesktop.gstreamer.Structure; import org.freedesktop.gstreamer.glib.NativeEnum; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstMessagePtr; import org.freedesktop.gstreamer.lowlevel.ReferenceManager; import org.freedesktop.gstreamer.lowlevel.annotations.HasSubtype; import static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API; /** * Lightweight objects to signal the occurrence of pipeline events. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html *

* Messages are implemented as a subclass of {@link MiniObject} with a generic * {@link Structure} as the content. This allows for writing custom messages * without requiring an API change while allowing a wide range of different * types of messages. *

* Messages are posted by objects in the pipeline and are passed to the * application using the {@link Bus}. * * The basic use pattern of posting a message on a Bus is as follows: * * * Posting a Message * * bus.post(new EOSMessage(source)); * * * * An {@link Element} usually posts messages on the bus provided by the parent * container using {@link Element#postMessage postMessage()}. */ @HasSubtype public class Message extends MiniObject { public static final String GTYPE_NAME = "GstMessage"; private static final Map> TYPE_MAP = new EnumMap<>(MessageType.class); static { TYPE_MAP.put(MessageType.EOS, EOSMessage::new); TYPE_MAP.put(MessageType.ERROR, ErrorMessage::new); TYPE_MAP.put(MessageType.BUFFERING, BufferingMessage::new); TYPE_MAP.put(MessageType.DURATION_CHANGED, DurationChangedMessage::new); TYPE_MAP.put(MessageType.INFO, InfoMessage::new); TYPE_MAP.put(MessageType.LATENCY, LatencyMessage::new); TYPE_MAP.put(MessageType.SEGMENT_DONE, SegmentDoneMessage::new); TYPE_MAP.put(MessageType.STATE_CHANGED, StateChangedMessage::new); TYPE_MAP.put(MessageType.TAG, TagMessage::new); TYPE_MAP.put(MessageType.WARNING, WarningMessage::new); TYPE_MAP.put(MessageType.NEED_CONTEXT, NeedContextMessage::new); } private final Handle handle; /** * Creates a new instance of Message. * * @param init internal initialization data. */ Message(Initializer init) { this(new Handle(init.ptr.as(GstMessagePtr.class, GstMessagePtr::new), init.ownsHandle), init.needRef); } Message(Handle handle, boolean needRef) { super(handle, needRef); this.handle = handle; } /** * Gets the Element that posted this message. * * @return the element that posted the message. */ public GstObject getSource() { return Natives.objectFor(handle.getPointer().getSource(), GstObject.class, true, true); } /** * Gets the structure containing the data in this message. * * @return a structure. */ public Structure getStructure() { return ReferenceManager.addKeepAliveReference(GSTMESSAGE_API.gst_message_get_structure(this), this); } /** * Gets the type of this message. * * @return the message type. */ public MessageType getType() { return NativeEnum.fromInt(MessageType.class, MessageType.UNKNOWN, handle.getPointer().getMessageType()); } private static Message create(Initializer init) { MessageType type = NativeEnum.fromInt(MessageType.class, MessageType.UNKNOWN, init.ptr.as(GstMessagePtr.class, GstMessagePtr::new).getMessageType() ); return TYPE_MAP.getOrDefault(type, Message::new).apply(init); } public static class Types implements TypeProvider { @Override public Stream> types() { return Stream.of( Natives.registration(Message.class, GTYPE_NAME, Message::create) ); } } static class Handle extends MiniObject.Handle { Handle(GstMessagePtr ptr, boolean ownsHandle) { super(ptr, ownsHandle); } @Override protected GstMessagePtr getPointer() { return (GstMessagePtr) super.getPointer(); } } } ================================================ FILE: src/org/freedesktop/gstreamer/message/MessageType.java ================================================ /* * Copyright (C) 2020 Neil C Smith * Copyright (C) 2009 Levente Farkas * Copyright (C) 2008 Wayne Meissner * Copyright (C) 2004 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.message; import org.freedesktop.gstreamer.Gst; import org.freedesktop.gstreamer.device.Device; import org.freedesktop.gstreamer.device.DeviceProvider; import org.freedesktop.gstreamer.glib.NativeEnum; /** * The different message types that are available. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#GstMessageType *

*/ // use NativeEnum not NativeFlags - from upstream definition // FIXME: 2.0: Make it NOT flags, just a regular 1,2,3,4.. enumeration public enum MessageType implements NativeEnum { /** * An undefined message */ UNKNOWN(0), /** * end-of-stream reached in a pipeline. The application will only receive * this message in the PLAYING state and every time it sets a pipeline to * PLAYING that is in the EOS state. The application can perform a flushing * seek in the pipeline, which will undo the EOS state again. */ EOS(1 << 0), /** * An error occurred. When the application receives an error message it * should stop playback of the pipeline and not assume that more data will * be played. */ ERROR(1 << 1), /** * A warning occurred. */ WARNING(1 << 2), /** * An info message occurred. */ INFO(1 << 3), /** * A tag was found. */ TAG(1 << 4), /** * The pipeline is buffering. When the application receives a buffering * message in the PLAYING state for a non-live pipeline it must PAUSE the * pipeline until the buffering completes, when the percentage field in the * message is 100%. For live pipelines, no action must be performed and the * buffering percentage can be used to inform the user about the progress. */ BUFFERING(1 << 5), /** * A state change happened */ STATE_CHANGED(1 << 6), /** * an element changed state in a streaming thread. This message is * deprecated. */ STATE_DIRTY(1 << 7), /** * a framestep finished. This message is not yet implemented. */ STEP_DONE(1 << 8), /** * an element notifies its capability of providing a clock. This message is * used internally and never forwarded to the application. */ CLOCK_PROVIDE(1 << 9), /** * The current clock as selected by the pipeline became unusable. The * pipeline will select a new clock on the next PLAYING state change. */ CLOCK_LOST(1 << 10), /** * A new clock was selected in the pipeline. */ NEW_CLOCK(1 << 11), /** * The structure of the pipeline changed. Not implemented yet. */ STRUCTURE_CHANGE(1 << 12), /** * Status about a stream, emitted when it starts, stops, errors, etc.. Not * implemented yet. */ STREAM_STATUS(1 << 13), /** * Message posted by the application, possibly via an application-specific * element. */ APPLICATION(1 << 14), /** * Element specific message, see the specific element's documentation */ ELEMENT(1 << 15), /** * Pipeline started playback of a segment. This message is used internally * and never forwarded to the application. */ SEGMENT_START(1 << 16), /** * Pipeline completed playback of a segment. This message is forwarded to * the application after all elements that posted {@link #SEGMENT_START} * have posted a SEGMENT_DONE message. */ SEGMENT_DONE(1 << 17), /** * The duration of a pipeline changed. The application can get the new * duration with a duration query. */ DURATION_CHANGED(1 << 18), /** * Posted by elements when their latency changes. The pipeline will * calculate and distribute a new latency. Since: 0.10.12 */ LATENCY(1 << 19), /** * Posted by elements when they start an ASYNC state change. This message is * not forwarded to the application but is used internally. Since: 0.10.13. */ ASYNC_START(1 << 20), /** * Posted by elements when they complete an ASYNC state change. The * application will only receive this message from the toplevel pipeline. * Since: 0.10.13 */ ASYNC_DONE(1 << 21), /** * Posted by elements when they want the pipeline to change state. This * message is a suggestion to the application which can decide to perform * the state change on (part of) the pipeline. Since: 0.10.23. */ REQUEST_STATE(1 << 22), /** * A stepping operation was started. */ STEP_START(1 << 23), /** * A buffer was dropped or an element changed its processing strategy for * Quality of Service reasons. */ QOS(1 << 24), /** * A progress message. Since: 0.10.33 */ PROGRESS(1 << 25), /** * A new table of contents (TOC) was found or previously found TOC was * updated. Since: 0.10.37 */ TOC(1 << 26), /** * Message to request resetting the pipeline's running time from the * pipeline. This is an internal message which applications will likely * never receive. */ RESET_TIME(1 << 27), /** * Message indicating start of a new stream. Useful e.g. when using playbin * in gapless playback mode, to get notified when the next title actually * starts playing (which will be some time after the URI for the next title * has been set). */ STREAM_START(1 << 28), /** * Message indicating that an element wants a specific context (Since 1.2) */ NEED_CONTEXT(1 << 29), /** * Message indicating that an element created a context (Since 1.2) */ HAVE_CONTEXT(1 << 30), /** * Message is an extended message type (see below). These extended message * IDs can't be used directly with mask-based API like gst_bus_poll() or * gst_bus_timed_pop_filtered(), but you can still filter for * GST_MESSAGE_EXTENDED and then check the result for the specific type. * (Since 1.4) */ EXTENDED(1 << 31), /** * Message indicating a #GstDevice was added to a #GstDeviceProvider (Since * 1.4) */ DEVICE_ADDED(EXTENDED.intValue() + 1), /** * Message indicating a #GstDevice was removed from a #GstDeviceProvider * (Since 1.4) */ DEVICE_REMOVED(EXTENDED.intValue() + 2), /** * Message indicating a {@link GObject} property has changed (Since 1.10) */ @Gst.Since(minor = 10) PROPERTY_NOTIFY(EXTENDED.intValue() + 3), /** * Message indicating a new {@link GstStreamCollection} is available (Since * 1.10) */ @Gst.Since(minor = 10) STREAM_COLLECTION(EXTENDED.intValue() + 4), /** * Message indicating the active selection of {@link GstStreams} has changed * (Since 1.10) */ @Gst.Since(minor = 10) STREAMS_SELECTED(EXTENDED.intValue() + 5), /** * Message indicating to request the application to try to play the given * URL(s). Useful if for example a HTTP 302/303 response is received with a * non-HTTP URL inside. (Since 1.10) */ @Gst.Since(minor = 10) REDIRECT(EXTENDED.intValue() + 6), /** * Message indicating a {@link Device} was changed by a * {@link DeviceProvider} (Since 1.16) */ @Gst.Since(minor = 16) DEVICE_CHANGED(EXTENDED.intValue() + 7), /** * Message sent by elements to request the running time from the pipeline * when an instant rate change should be applied (which may be in the past * when the answer arrives). (Since 1.18) */ @Gst.Since(minor = 18) INSTANT_RATE_REQUEST(EXTENDED.intValue() + 8), /** * mask for all of the above messages. */ ANY(~0); private final int type; private MessageType(int type) { this.type = type; } /** * Gets the native integer value for this type. * * @return the native gstreamer value. */ @Override public int intValue() { return type; } } ================================================ FILE: src/org/freedesktop/gstreamer/message/NeedContextMessage.java ================================================ /* * * Copyright (c) 2019 Christophe Lafolet * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.message; import static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API; import org.freedesktop.gstreamer.GstObject; import org.freedesktop.gstreamer.glib.Natives; /** * Message indicating that an element wants a specific context. */ public class NeedContextMessage extends Message { /** * Creates a new Need-Context message. * * @param init internal initialization data. */ NeedContextMessage(Initializer init) { super(init); } /** * Creates a new Need-Context message. * * @param src the object originating the message. */ public NeedContextMessage(GstObject src, String context_type) { this(Natives.initializer(GSTMESSAGE_API.ptr_gst_message_new_need_context(src, context_type))); } /** * Gets the context type contained in this message. * * @return the context type. */ public String getContextType() { String context_type[] = new String[1]; boolean isOk = GSTMESSAGE_API.gst_message_parse_context_type(this, context_type); return isOk ? context_type[0] : null; } } ================================================ FILE: src/org/freedesktop/gstreamer/message/SegmentDoneMessage.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * Copyright (C) 2004 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.message; import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.GstObject; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API; /** * This message is posted by elements that finish playback of a segment as a * result of a segment seek. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-segment-done *

* This message is received by the application after all elements that posted a segment_start * have posted the segment_done. */ public class SegmentDoneMessage extends Message { /** * Creates a new segment-done message. * * @param init internal initialization data. */ SegmentDoneMessage(Initializer init) { super(init); } /** * Creates a new segment done message. * * @param src the object originating the message. * @param format the format of the position being done * @param position the position of the segment being done */ public SegmentDoneMessage(GstObject src, Format format, long position) { this(Natives.initializer(GSTMESSAGE_API.ptr_gst_message_new_segment_done(src, format, position))); } /** * Gets the format of the position in this message. * * @return the format of the position. */ public Format getFormat() { Format[] format = new Format[1]; GSTMESSAGE_API.gst_message_parse_segment_done(this, format, null); return format[0]; } /** * Gets the position of the segment that is done. * * @return the position. */ public long getPosition() { long[] position = { 0 }; GSTMESSAGE_API.gst_message_parse_segment_done(this, null, position); return position[0]; } } ================================================ FILE: src/org/freedesktop/gstreamer/message/StateChangedMessage.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * Copyright (C) 2004 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.message; import org.freedesktop.gstreamer.GstObject; import org.freedesktop.gstreamer.State; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API; /** * A state change message. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-state-changed *

* This message is posted whenever an element changes its state. */ public class StateChangedMessage extends Message { /** * Creates a new Buffering message. * @param init internal initialization data. */ StateChangedMessage(Initializer init) { super(init); } /** * Creates a new state-changed message. * * @param src the source object emitting this message. * @param old the previous state. * @param current the new (current) state. * @param pending the pending (target) state. */ public StateChangedMessage(GstObject src, State old, State current, State pending) { super(Natives.initializer(GSTMESSAGE_API.ptr_gst_message_new_state_changed(src, old, current, pending))); } /** * Gets the previous state. * * @return the previous state. */ public State getOldState() { State[] state = new State[1]; GSTMESSAGE_API.gst_message_parse_state_changed(this, state, null, null); return state[0]; } /** * Gets the new (current) state. * * @return the new state. */ public State getNewState() { State[] state = new State[1]; GSTMESSAGE_API.gst_message_parse_state_changed(this, null, state, null); return state[0]; } /** * Gets the pending (target) state. * * @return the pending state. */ public State getPendingState() { State[] state = new State[1]; GSTMESSAGE_API.gst_message_parse_state_changed(this, null, null, state); return state[0]; } } ================================================ FILE: src/org/freedesktop/gstreamer/message/TagMessage.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * Copyright (C) 2004 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.message; import org.freedesktop.gstreamer.GstObject; import org.freedesktop.gstreamer.TagList; import com.sun.jna.ptr.PointerByReference; import org.freedesktop.gstreamer.glib.Natives; import static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API; /** * This message is posted by elements that have discovered new tags. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-tag *

*/ public class TagMessage extends Message { /** * Creates a new Tag message. * * @param init internal initialization data. */ TagMessage(Initializer init) { super(init); } /** * Creates a new Tag message. * * @param src The object originating the message. * @param tagList the tag list for this message. *

* Note: the message takes ownership of the taglist, so do not use * it again after adding it to this message. */ public TagMessage(GstObject src, TagList tagList) { this(Natives.initializer(GSTMESSAGE_API.ptr_gst_message_new_tag(src, tagList))); } /** * Gets the list of tags contained in this message. * * @return the list of tags in this message. */ public TagList getTagList() { PointerByReference list = new PointerByReference(); GSTMESSAGE_API.gst_message_parse_tag(this, list); return Natives.objectFor(list.getValue(), TagList.class, false, true); } } ================================================ FILE: src/org/freedesktop/gstreamer/message/WarningMessage.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * Copyright (C) 2004 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.message; import org.freedesktop.gstreamer.lowlevel.GstAPI.GErrorStruct; import static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API; /** * This message is posted by element when a warning notice is required. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstMessage.html#gst-message-new-warning *

*/ public class WarningMessage extends GErrorMessage { /** * Creates a new warning message. * * @param init internal initialization data. */ WarningMessage(Initializer init) { super(init); } /** * Retrieves the GError structure contained in this message. * * @return the GError contained in this message. */ @Override GErrorStruct parseMessage() { GErrorStruct[] err = {null}; GSTMESSAGE_API.gst_message_parse_warning(this, err, null); return err[0]; } } ================================================ FILE: src/org/freedesktop/gstreamer/query/AllocationQuery.java ================================================ /* * Copyright (c) 2022 Neil C Smith * Copyright (c) 2016 Christophe Lafolet * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.query; import org.freedesktop.gstreamer.BufferPool; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.Structure; import org.freedesktop.gstreamer.lowlevel.GType; import org.freedesktop.gstreamer.lowlevel.GstQueryAPI; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.glib.Natives; /** * An allocation query for querying allocation properties. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-allocation *

* */ public class AllocationQuery extends Query { /** * This constructor is for internal use only. * * @param init initialization data. */ AllocationQuery(Initializer init) { super(init); } /** * Create a new allocation query. * * @param caps the negotiated {@link Caps} * @param need_pool return a pool. */ public AllocationQuery(Caps caps, boolean need_pool) { this(Natives.initializer(GstQueryAPI.GSTQUERY_API.ptr_gst_query_new_allocation(caps, need_pool))); } /** * Whether a {@link BufferPool} is needed. * * @return true if BufferPool needed */ public boolean isPoolNeeded() { boolean[] need_pool = {false}; GstQueryAPI.GSTQUERY_API.gst_query_parse_allocation(this, null, need_pool); return need_pool[0]; } /** * Get the requested {@link Caps} * * @return requested Caps */ public Caps getCaps() { Pointer[] ptr = new Pointer[1]; GstQueryAPI.GSTQUERY_API.gst_query_parse_allocation(this, ptr, null); // return new Caps(new Initializer(ptr[0], false, true)); return Natives.objectFor(ptr[0], Caps.class, false, true); } // @TODO how best not to expose GType? void addAllocationMeta(GType api, Structure params) { GstQueryAPI.GSTQUERY_API.gst_query_add_allocation_meta(this, api, params); } /** * Set the pool parameters of the query. * * @param pool the {@link BufferPool} * @param size the buffer size * @param min_buffers the min buffers * @param max_buffers the max buffers */ public void addAllocationPool(BufferPool pool, int size, int min_buffers, int max_buffers) { GstQueryAPI.GSTQUERY_API.gst_query_add_allocation_pool(this, pool, size, min_buffers, max_buffers); } } ================================================ FILE: src/org/freedesktop/gstreamer/query/ConvertQuery.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.query; import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstQueryAPI; /** * A convert query used to ask for a conversion between one format and another. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-convert *

*/ public class ConvertQuery extends Query { ConvertQuery(Initializer init) { super(init); } /** * Construct a new convert query object. * * @param srcFormat the source {@link Format} for the new query * @param value the value to convert * @param destFormat the target {@link Format} */ public ConvertQuery(Format srcFormat, long value, Format destFormat) { this(Natives.initializer(GstQueryAPI.GSTQUERY_API.ptr_gst_query_new_convert(srcFormat, value, destFormat))); } /** * Answer a convert query by setting the requested values. * * @param srcFormat the source {@link Format} * @param srcValue the source value * @param dstFormat the destination {@link Format} * @param dstValue the destination value */ public void setConvert(Format srcFormat, long srcValue, Format dstFormat, long dstValue) { GstQueryAPI.GSTQUERY_API.gst_query_set_convert(this, srcFormat, srcValue, dstFormat, dstValue); } /** * Get the source {@link Format} of this query. * * @return source Format */ public Format getSourceFormat() { Format[] fmt = new Format[1]; GstQueryAPI.GSTQUERY_API.gst_query_parse_convert(this, fmt, null, null, null); return fmt[0]; } /** * Get the destination {@link Format} of this query. * * @return destination Format */ public Format getDestinationFormat() { Format[] fmt = new Format[1]; GstQueryAPI.GSTQUERY_API.gst_query_parse_convert(this, null, null, fmt, null); return fmt[0]; } /** * Get the source value of this query. * * @return source value */ public long getSourceValue() { long[] value = new long[1]; GstQueryAPI.GSTQUERY_API.gst_query_parse_convert(this, null, value, null, null); return value[0]; } /** * Get the destination value of this query. * * @return destination value */ public long getDestinationValue() { long[] value = new long[1]; GstQueryAPI.GSTQUERY_API.gst_query_parse_convert(this, null, null, null, value); return value[0]; } } ================================================ FILE: src/org/freedesktop/gstreamer/query/DurationQuery.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.query; import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstQueryAPI; /** * A duration query used to get the total length of a stream. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-duration *

* @see Format */ public class DurationQuery extends Query { DurationQuery(Initializer init) { super(init); } /** * Constructs a new stream duration query object to query in the given * format. A duration query will give the total length of the stream. * * @param format the {@link Format} for this duration query. */ public DurationQuery(Format format) { super(Natives.initializer(GstQueryAPI.GSTQUERY_API.ptr_gst_query_new_duration(format))); } /** * Answers a duration query by setting the requested value in the given * format. * * @param format the {@link Format} for the duration * @param duration the duration of the stream */ public void setDuration(Format format, long duration) { GstQueryAPI.GSTQUERY_API.gst_query_set_duration(this, format, duration); } /** * Gets the format of this duration query. * * @return The {@link Format} of the duration value. */ public Format getFormat() { Format[] fmt = new Format[1]; GstQueryAPI.GSTQUERY_API.gst_query_parse_duration(this, fmt, null); return fmt[0]; } /** * Gets the duration answer for this query, in the format available from * {@link #getFormat() } * * @return The total duration. */ public long getDuration() { long[] duration = new long[1]; GstQueryAPI.GSTQUERY_API.gst_query_parse_duration(this, null, duration); return duration[0]; } /** * Gets the duration as a user-readable string. * * @return A string representing the duration. */ @Override public String toString() { return String.format("duration: [format=%s, duration=%d]", getFormat(), getDuration()); } } ================================================ FILE: src/org/freedesktop/gstreamer/query/FormatsQuery.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.query; import java.util.AbstractList; import java.util.List; import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstQueryAPI; /** * Used for querying formats of the stream. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-formats *

* @see Format */ public class FormatsQuery extends Query { /** * Constructs a new query object for querying formats of the stream. */ public FormatsQuery() { this(Natives.initializer(GstQueryAPI.GSTQUERY_API.ptr_gst_query_new_formats())); } FormatsQuery(Initializer init) { super(init); } /** * Sets the formats query result fields. * * @param formats the formats to set. */ public void setFormats(Format... formats) { GstQueryAPI.GSTQUERY_API.gst_query_set_formats(this, formats.length, formats); } /** * Gets the number of formats in this query. * * @return the number of formats in this query. */ public int getCount() { int[] count = {0}; GstQueryAPI.GSTQUERY_API.gst_query_parse_n_formats(this, count); return count[0]; } /** * Gets a format at {@code index}. * * @param index the index of the format to retrieve. * @return the format. */ public Format getFormat(int index) { Format[] fmt = new Format[1]; GstQueryAPI.GSTQUERY_API.gst_query_parse_nth_format(this, index, fmt); return fmt[0]; } /** * Gets all formats in this query. * * @return a {@link List} of {@link Format}. */ public List getFormats() { final int count = getCount(); return new AbstractList() { @Override public Format get(int index) { return getFormat(index); } @Override public int size() { return count; } }; } } ================================================ FILE: src/org/freedesktop/gstreamer/query/LatencyQuery.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.query; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstQueryAPI; /** * Used for querying the latency of the stream. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-latency *

*/ public class LatencyQuery extends Query { LatencyQuery(Initializer init) { super(init); } /** * Constructs a new query stream position query object. A position query is * used to query the current position of playback in the streams, in some * format. */ public LatencyQuery() { super(Natives.initializer(GstQueryAPI.GSTQUERY_API.ptr_gst_query_new_latency())); } /** * Answers a latency query. * * @param live if there is a live element upstream * @param minLatency the minimal latency of the live element * @param maxLatency the maximal latency of the live element */ public void setLatency(boolean live, long minLatency, long maxLatency) { GstQueryAPI.GSTQUERY_API.gst_query_set_latency(this, live, minLatency, maxLatency); } /** * Gets whether the element has a live element upstream or not. * * @return true if the element has a live element upstream. */ public boolean isLive() { boolean[] live = new boolean[1]; GstQueryAPI.GSTQUERY_API.gst_query_parse_latency(this, live, null, null); return live[0]; } /** * Gets the minimum latency of the live element. * * @return The minimum latency of the live element. */ public long getMinimumLatency() { long[] latency = new long[1]; GstQueryAPI.GSTQUERY_API.gst_query_parse_latency(this, null, latency, null); return latency[0]; } /** * Gets the maximum latency of the live element. * * @return The maximum latency of the live element. */ public long getMaximumLatency() { long[] latency = new long[1]; GstQueryAPI.GSTQUERY_API.gst_query_parse_latency(this, null, null, latency); return latency[0]; } /** * Gets the latency as a user-readable string. * * @return A string representing the latency. */ @Override public String toString() { return String.format("latency:[live=%b, min=%s, max=%s]", isLive(), getMinimumLatency(), getMaximumLatency()); } } ================================================ FILE: src/org/freedesktop/gstreamer/query/PositionQuery.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.query; import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstQueryAPI; /** * Used to query an element for the current position in the stream. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-position *

*/ public class PositionQuery extends Query { PositionQuery(Initializer init) { super(init); } /** * Constructs a new query stream position query object. A position query is * used to query the current position of playback in the streams, in some * format. * * @param format the default {@link Format} for the new query */ public PositionQuery(Format format) { super(Natives.initializer(GstQueryAPI.GSTQUERY_API.ptr_gst_query_new_position(format))); } /** * Answers a position query by setting the requested value in the given * format. * * @param format the requested {@link Format} * @param position the position to set in the answer */ public void setPosition(Format format, long position) { GstQueryAPI.GSTQUERY_API.gst_query_set_position(this, format, position); } /** * Gets the {@link Format} of this position query. * * @return The format of the query. */ public Format getFormat() { Format[] fmt = new Format[1]; GstQueryAPI.GSTQUERY_API.gst_query_parse_position(this, fmt, null); return fmt[0]; } /** * Gets the position in terms of the {@link Format} of the query. * * @return the position. */ public long getPosition() { long[] pos = new long[1]; GstQueryAPI.GSTQUERY_API.gst_query_parse_position(this, null, pos); return pos[0]; } /** * Gets the position as a user-readable string. * * @return A string representation of the position. */ @Override public String toString() { return String.format("position: [format=%s, position=%d]", getFormat(), getPosition()); } } ================================================ FILE: src/org/freedesktop/gstreamer/query/Query.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.query; import java.util.EnumMap; import java.util.Map; import java.util.function.Function; import java.util.stream.Stream; import org.freedesktop.gstreamer.Element; import org.freedesktop.gstreamer.MiniObject; import org.freedesktop.gstreamer.Pad; import org.freedesktop.gstreamer.Structure; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstQueryAPI; import org.freedesktop.gstreamer.lowlevel.ReferenceManager; import org.freedesktop.gstreamer.lowlevel.annotations.HasSubtype; import static org.freedesktop.gstreamer.lowlevel.GstQueryAPI.GSTQUERY_API; /** * Base query type. Queries can be performed on {@link Pad} and {@link Element}. * Some queries might need a running pipeline to work. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html */ @HasSubtype public class Query extends MiniObject { public static final String GTYPE_NAME = "GstQuery"; private static final Map> TYPE_MAP = new EnumMap<>(QueryType.class); static { TYPE_MAP.put(QueryType.ALLOCATION, AllocationQuery::new); TYPE_MAP.put(QueryType.CONVERT, ConvertQuery::new); TYPE_MAP.put(QueryType.DURATION, DurationQuery::new); TYPE_MAP.put(QueryType.FORMATS, FormatsQuery::new); TYPE_MAP.put(QueryType.LATENCY, LatencyQuery::new); TYPE_MAP.put(QueryType.POSITION, PositionQuery::new); TYPE_MAP.put(QueryType.SEEKING, SeekingQuery::new); TYPE_MAP.put(QueryType.SEGMENT, SegmentQuery::new); } /** * Internally used constructor. Do not use. * * @param init internal initialization data. */ Query(Initializer init) { super(init); } /** * Get the structure of this query. * * @return The structure of this Query. */ public Structure getStructure() { return ReferenceManager.addKeepAliveReference(GSTQUERY_API.gst_query_get_structure(this), this); } private static Query create(Initializer init) { GstQueryAPI.QueryStruct struct = new GstQueryAPI.QueryStruct(init.ptr.getPointer()); QueryType type = (QueryType) struct.readField("type"); return TYPE_MAP.getOrDefault(type, Query::new).apply(init); } public static class Types implements TypeProvider { @Override public Stream> types() { return Stream.of( Natives.registration(Query.class, GTYPE_NAME, Query::create) ); } } } ================================================ FILE: src/org/freedesktop/gstreamer/query/QueryType.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.query; import org.freedesktop.gstreamer.Gst; import org.freedesktop.gstreamer.glib.NativeEnum; /** * Standard predefined Query types */ public enum QueryType implements NativeEnum { /** * invalid query type */ UNKNOWN(0, 0), /** * current position in stream */ POSITION(10, Flags.BOTH), /** * total duration of the stream */ DURATION(20, Flags.BOTH), /** * latency of stream */ LATENCY(30, Flags.BOTH), /** * current jitter of stream */ JITTER(40, Flags.BOTH), /** * current rate of the stream */ RATE(50, Flags.BOTH), /** * seeking capabilities */ SEEKING(60, Flags.BOTH), /** * segment start/stop positions */ SEGMENT(70, Flags.BOTH), /** * convert values between formats */ CONVERT(80, Flags.BOTH), /** * query supported formats for convert */ FORMATS(90, Flags.BOTH), /** * query available media for efficient seeking */ BUFFERING(110, Flags.BOTH), /** * a custom application or element defined query */ CUSTOM(120, Flags.BOTH), /** * query the URI of the source or sink */ URI(130, Flags.BOTH), /** * the buffer allocation properties */ ALLOCATION(140, Flags.DOWNSTREAM | Flags.SERIALIZED), /** * the scheduling properties */ SCHEDULING(150, Flags.UPSTREAM), /** * the accept caps query */ ACCEPT_CAPS(160, Flags.BOTH), /** * the caps query */ CAPS(170, Flags.BOTH), /** * wait till all serialized data is consumed downstream */ DRAIN(180, Flags.DOWNSTREAM | Flags.SERIALIZED), /** * query the pipeline-local context from downstream or upstream (since 1.2) */ CONTEXT(190, Flags.BOTH), /** * the bitrate query (since 1.16) */ @Gst.Since(minor = 16) BITRATE(200, Flags.DOWNSTREAM); private static final int SHIFT = 8; private final int value; private QueryType(int num, int flags) { this.value = (num << SHIFT) | flags; } private QueryType(int value) { this.value = value; } /** * Gets the integer value of the enum. * * @return the integer value for this enum. */ public int intValue() { return value; } private static final class Flags { public static final int UPSTREAM = 1 << 0; public static final int DOWNSTREAM = 1 << 1; public static final int SERIALIZED = 1 << 2; public static final int BOTH = UPSTREAM | DOWNSTREAM; } } ================================================ FILE: src/org/freedesktop/gstreamer/query/SeekingQuery.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.query; import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstQueryAPI; /** * Used for querying the seeking properties of the stream. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-seeking *

*/ public class SeekingQuery extends Query { SeekingQuery(Initializer init) { super(init); } /** * Constructs a new query object for querying seeking properties of the * stream. * * @param format the default {@link Format} for the new query. */ public SeekingQuery(Format format) { this(Natives.initializer(GstQueryAPI.GSTQUERY_API.ptr_gst_query_new_seeking(format))); } /** * Sets the seeking query result fields. * * @param format the format to set for the {@code start} and {@code end} * values. * @param seekable the seekable flag to set * @param start the start of the segment. * @param end the end of the segment. */ public void setSeeking(Format format, boolean seekable, long start, long end) { GstQueryAPI.GSTQUERY_API.gst_query_set_seeking(this, format, seekable, start, end); } /** * Checks if the stream is seekable. * * @return {@code true} if the stream is seekable. */ public boolean isSeekable() { boolean[] value = {false}; GstQueryAPI.GSTQUERY_API.gst_query_parse_seeking(this, null, value, null, null); return value[0]; } /** * Gets the {@link Format} of the start and end values for the segment. * * @return the format of the start and end values. */ public Format getFormat() { Format[] value = {Format.UNDEFINED}; GstQueryAPI.GSTQUERY_API.gst_query_parse_seeking(this, value, null, null, null); return value[0]; } /** * Gets the start of the segment. * * @return the start of the segment. */ public long getStart() { long[] value = {0}; GstQueryAPI.GSTQUERY_API.gst_query_parse_seeking(this, null, null, value, null); return value[0]; } /** * Gets the end of the segment. * * @return the end of the segment. */ public long getEnd() { long[] value = {0}; GstQueryAPI.GSTQUERY_API.gst_query_parse_seeking(this, null, null, null, value); return value[0]; } } ================================================ FILE: src/org/freedesktop/gstreamer/query/SegmentQuery.java ================================================ /* * Copyright (C) 2019 Neil C Smith * Copyright (C) 2008 Wayne Meissner * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2005 Wim Taymans * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.query; import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstQueryAPI; /** * Used to discover information about the currently configured segment for * playback. *

* See upstream documentation at * https://gstreamer.freedesktop.org/data/doc/gstreamer/stable/gstreamer/html/GstQuery.html#gst-query-new-segment *

*/ public class SegmentQuery extends Query { SegmentQuery(Initializer init) { super(init); } /** * Constructs a new segment query object. * * @param format the {@link Format} for the new query. */ public SegmentQuery(Format format) { this(Natives.initializer(GstQueryAPI.GSTQUERY_API.ptr_gst_query_new_segment(format))); } /** * Answers a segment query by setting the requested values. *

* The normal playback segment of a pipeline is 0 to duration at the default * rate of 1.0. If a seek was performed on the pipeline to play a different * segment, this query will return the range specified in the last seek. * * {@code startValue} and {@code stopValue} will respectively contain the * configured playback range start and stop values expressed in format. The * values are always between 0 and the duration of the media and * {@code startValue <= stopValue}. {@code rate} will contain the playback * rate. For negative rates, playback will actually happen from * {@code stopValue} to {@code startValue}. * * @param rate the rate of the segment. * @param format the {@link Format} of the segment values. * @param startValue the start value. * @param stopValue the stop value. */ public void setSegment(double rate, Format format, long startValue, long stopValue) { GstQueryAPI.GSTQUERY_API.gst_query_set_segment(this, rate, format, startValue, stopValue); } /** * Gets the rate of the segment Query. * * @return the rate of the segment. */ public double getRate() { double[] rate = new double[1]; GstQueryAPI.GSTQUERY_API.gst_query_parse_segment(this, rate, null, null, null); return rate[0]; } /** * Gets the format of the start and stop values in the segment query. * * @return The format for the start and stop values. */ public Format getFormat() { Format[] fmt = new Format[1]; GstQueryAPI.GSTQUERY_API.gst_query_parse_segment(this, null, fmt, null, null); return fmt[0]; } /** * Gets the start of the playback range. * * @return the start of the playback range. */ public long getStart() { long[] value = new long[1]; GstQueryAPI.GSTQUERY_API.gst_query_parse_segment(this, null, null, value, null); return value[0]; } /** * Gets the end of the playback range. * * @return the end of the playback range. */ public long getEnd() { long[] value = new long[1]; GstQueryAPI.GSTQUERY_API.gst_query_parse_segment(this, null, null, null, value); return value[0]; } } ================================================ FILE: src/org/freedesktop/gstreamer/video/Video.java ================================================ /* * Copyright (c) 2020 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.video; import java.util.stream.Stream; import org.freedesktop.gstreamer.glib.NativeObject; import static org.freedesktop.gstreamer.glib.Natives.registration; /** * Utility class for GStreamer Video library. */ public final class Video { private Video() { } /** * TypeProvider implementation for GStreamer Video library. */ public static class Types implements NativeObject.TypeProvider { @Override public Stream> types() { return Stream.of( registration(VideoTimeCodeMeta.class, VideoTimeCodeMeta.GTYPE_NAME, VideoTimeCodeMeta::new) ); } } } ================================================ FILE: src/org/freedesktop/gstreamer/video/VideoTimeCode.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2020 Petr Lastovka * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.video; import org.freedesktop.gstreamer.Gst; import org.freedesktop.gstreamer.glib.NativeObject; import org.freedesktop.gstreamer.lowlevel.GPointer; import org.freedesktop.gstreamer.lowlevel.GstVideoAPI; import org.freedesktop.gstreamer.lowlevel.GstVideoAPI.GstVideoTimeCodeStruct; /** * A representation of a SMPTE time code. * * See https://gstreamer.freedesktop.org/documentation/video/gstvideotimecode.html */ @Gst.Since(minor = 10) public class VideoTimeCode extends NativeObject { private final GstVideoTimeCodeStruct timeCodeStruct; private final VideoTimeCodeConfig timeCodeConfig; // public VideoTimeCode(){ // this(Natives.initializer(GstVideoAPI.GSTVIDEO_API.gst_video_time_code_new_empty())); // } VideoTimeCode(GstVideoTimeCodeStruct struct) { this(struct, new Handle(new GPointer(struct.getPointer()), false)); } private VideoTimeCode(GstVideoTimeCodeStruct struct, Handle handle) { super(handle); this.timeCodeStruct = struct; timeCodeConfig = new VideoTimeCodeConfig(timeCodeStruct.config); } public VideoTimeCodeConfig getConfig() { return timeCodeConfig; } /** * Hours field, must be less than 24. * * @return number of hours */ public int getHours() { return timeCodeStruct.hours; } /** * Minutes field, must be less than 60. * * @return number of minutes */ public int getMinutes() { return timeCodeStruct.minutes; } /** * Second field, must be less than 60. * * @return number of seconds */ public int getSeconds() { return timeCodeStruct.seconds; } /** * Frames field. * * @return number of seconds */ public int getFrames() { return timeCodeStruct.frames; } @Override public String toString() { return "GstVideoTimeCode{" + getHours() + ":" + getMinutes() + ":" + getSeconds() + ":" + getFrames() + ", timeconfig=" + timeCodeConfig + "}"; } @Override public void disown() { timeCodeConfig.disown(); super.disown(); } private static final class Handle extends NativeObject.Handle{ /** * Construct a Handle for the supplied native reference. * * @param ptr native reference * @param ownsReference whether the Handle owns the native reference and */ public Handle(GPointer ptr, boolean ownsReference) { super(ptr, ownsReference); } @Override protected void disposeNativeHandle(GPointer ptr) { GstVideoAPI.GSTVIDEO_API.gst_video_time_code_free(ptr.getPointer()); } @Override protected GPointer getPointer() { return super.getPointer(); } } } ================================================ FILE: src/org/freedesktop/gstreamer/video/VideoTimeCodeConfig.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2020 Petr Lastovka * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.video; import java.util.EnumSet; import org.freedesktop.gstreamer.Gst; import org.freedesktop.gstreamer.glib.NativeFlags; import org.freedesktop.gstreamer.glib.NativeObject; import org.freedesktop.gstreamer.lowlevel.GPointer; import org.freedesktop.gstreamer.lowlevel.GstVideoAPI.GstVideoTimeCodeConfigStruct; /** * The configuration of the time code. *

* See upstream documentation at * * https://gstreamer.freedesktop.org/documentation/video/gstvideotimecode.html#GstVideoTimeCodeConfig */ @Gst.Since(minor = 10) public class VideoTimeCodeConfig extends NativeObject { private final GstVideoTimeCodeConfigStruct timeCodeConfig; VideoTimeCodeConfig(GstVideoTimeCodeConfigStruct struct) { this(struct, new Handle(new GPointer(struct.getPointer()), false)); } private VideoTimeCodeConfig(GstVideoTimeCodeConfigStruct struct, Handle handle) { super(handle); timeCodeConfig = struct; } /** * The corresponding {@link VideoTimeCodeFlags}. * * @return return flags for current timecode */ public EnumSet getFlags() { return NativeFlags.fromInt(VideoTimeCodeFlags.class, timeCodeConfig.flags); } /** * Numerator of the frame rate. * * @return numerator */ public int getNumerator() { return timeCodeConfig.fps_n; } /** * Denominator of the frame rate. * * @return denominator */ public int getDenominator() { return timeCodeConfig.fps_d; } @Override public String toString() { final StringBuffer sb = new StringBuffer("GstVideoTimeCodeConfig{"); sb.append("flags=").append(getFlags()) .append(", numerator=").append(getNumerator()) .append(", denominator=").append(getDenominator()) .append('}'); return sb.toString(); } private static final class Handle extends NativeObject.Handle { /** * Construct a Handle for the supplied native reference. * * @param ptr native reference * @param ownsReference whether the Handle owns the native reference and */ public Handle(GPointer ptr, boolean ownsReference) { super(ptr, ownsReference); } @Override protected void disposeNativeHandle(GPointer ptr) { // usually video timecode config will be released together with video timecode // GlibAPI.GLIB_API.g_free(ptr.getPointer()); } @Override protected GPointer getPointer() { return super.getPointer(); } } } ================================================ FILE: src/org/freedesktop/gstreamer/video/VideoTimeCodeFlags.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2020 Petr Lastovka * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.video; import org.freedesktop.gstreamer.glib.NativeFlags; /** * Flags related to the time code information. For drop frame, only 30000/1001 * and 60000/1001 frame rates are supported. *

* See upstream documentation at * https://gstreamer.freedesktop.org/documentation/video/gstvideotimecode.html#GstVideoTimeCodeFlags */ public enum VideoTimeCodeFlags implements NativeFlags { // /** // * No flags // */ // GST_VIDEO_TIME_CODE_FLAGS_NONE(0), // No flags /** * Whether we have drop frame rate */ GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME(1), /** * Whether we have interlaced video */ GST_VIDEO_TIME_CODE_FLAGS_INTERLACED(2); private final int value; VideoTimeCodeFlags(int value) { this.value = value; } @Override public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/video/VideoTimeCodeMeta.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2020 Petr Lastovka * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.video; import org.freedesktop.gstreamer.Gst; import org.freedesktop.gstreamer.Meta; import static org.freedesktop.gstreamer.lowlevel.GstVideoAPI.GstVideoTimeCodeMetaStruct; /** * Extra buffer metadata describing the GstVideoTimeCode of the frame. *

* See upstream documentation at * https://gstreamer.freedesktop.org/documentation/video/gstvideometa.html#GstVideoTimeCodeMeta */ @Gst.Since(minor = 10) public class VideoTimeCodeMeta extends Meta { /** * Meta.API for VideoTimeCodeMeta. */ public static final API API = new API(VideoTimeCodeMeta.class, "GstVideoTimeCodeMetaAPI"); /** * Underlying GType name. */ public static final String GTYPE_NAME = "GstVideoTimeCodeMeta"; private final VideoTimeCode timeCode; VideoTimeCodeMeta(Initializer init) { super(init); GstVideoTimeCodeMetaStruct metaStruct = new GstVideoTimeCodeMetaStruct(init.ptr.getPointer()); timeCode = new VideoTimeCode(metaStruct.tc); } /** * Retrieve the time code attached to frame. * * @return time code */ public VideoTimeCode getTimeCode() { return timeCode; } @Override public void disown() { timeCode.disown(); super.disown(); } } ================================================ FILE: src/org/freedesktop/gstreamer/webrtc/WebRTC.java ================================================ /* * Copyright (c) 2019 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.webrtc; import java.util.stream.Stream; import org.freedesktop.gstreamer.glib.NativeObject; import static org.freedesktop.gstreamer.glib.Natives.registration; /** * * @author Neil C Smith - https://www.neilcsmith.net */ public class WebRTC { private WebRTC() { } public static class Types implements NativeObject.TypeProvider { @Override public Stream> types() { return Stream.of( registration(WebRTCSessionDescription.class, WebRTCSessionDescription.GTYPE_NAME, WebRTCSessionDescription::new), registration(WebRTCBin.class, WebRTCBin.GTYPE_NAME, WebRTCBin::new)); } } } ================================================ FILE: src/org/freedesktop/gstreamer/webrtc/WebRTCBin.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2018 Antonio Morales * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.webrtc; import org.freedesktop.gstreamer.Bin; import org.freedesktop.gstreamer.Element; import org.freedesktop.gstreamer.Gst; import org.freedesktop.gstreamer.Promise; import org.freedesktop.gstreamer.Structure; import org.freedesktop.gstreamer.glib.NativeEnum; import org.freedesktop.gstreamer.lowlevel.GstAPI.GstCallback; /** * WebRTCBin is an abstraction over gstreamers webrtcbin element It is * structured to mimic the RTCPeerConnection API that is available in web * browsers * * @see https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection * * @see * https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/ext/webrtc/gstwebrtcbin.c * available since Gstreamer 1.14 */ @Gst.Since(minor = 14) public class WebRTCBin extends Bin { public static final String GST_NAME = "webrtcbin"; public static final String GTYPE_NAME = "GstWebRTCBin"; WebRTCBin(Initializer init) { super(init); } public WebRTCBin(String name) { super(makeRawElement(GST_NAME, name)); } /** * Signal emitted when this {@link WebRTCBin} is ready to do negotiation to * setup a WebRTC connection Good starting point to have the WebRTCBin send * an offer to potential clients */ public static interface ON_NEGOTIATION_NEEDED { /** * @param elem the original webrtc bin that had the callback attached to */ public void onNegotiationNeeded(Element elem); } /* * Signal emmited when this {@link WebRTCBin} gets a new ice candidate */ public static interface ON_ICE_CANDIDATE { /** * @param sdpMLineIndex the zero-based index of the m-line attribute * within the SDP to which the candidate should be associated to * @param candidate the ICE candidate */ public void onIceCandidate(int sdpMLineIndex, String candidate); } /** * Signal emitted when this {@link WebRTCBin} creates an offer */ public static interface CREATE_OFFER { /** * @param a @WebRTCSessionDescription of the offer */ public void onOfferCreated(WebRTCSessionDescription offer); } /** * Signal emitted when this {@link WebRTCBin} creates an answer */ public static interface CREATE_ANSWER { /** * @param a @WebRTCSessionDescription of the answer */ public void onAnswerCreated(WebRTCSessionDescription answer); } /** * Adds a listener for the on-negotiation-needed signal. * * @param listener */ public void connect(final ON_NEGOTIATION_NEEDED listener) { connect(ON_NEGOTIATION_NEEDED.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(Element elem) { listener.onNegotiationNeeded(elem); } }); } /** * Adds a listener for the on-ice-candidate signal. * * @param listener */ public void connect(final ON_ICE_CANDIDATE listener) { connect(ON_ICE_CANDIDATE.class, listener, new GstCallback() { @SuppressWarnings("unused") public void callback(Element elem, int sdpMLineIndex, String candidate) { listener.onIceCandidate(sdpMLineIndex, candidate); } }); } /** * Create an offer that can be sent to other clients to setup a WebRTC * connection. *

* In most cases {@link #setLocalDescription} should be called after an * answer is created * * @param listener callback that is called when a offer is created */ public void createOffer(final CREATE_OFFER listener) { Promise promise = new Promise(new Promise.PROMISE_CHANGE() { @SuppressWarnings("unused") public void onChange(Promise promise) { Structure reply = promise.getReply(); WebRTCSessionDescription description = (WebRTCSessionDescription) reply.getValue("offer"); listener.onOfferCreated(description); promise.dispose(); } }); emit("create-offer", null, promise); } /** * Create an answer in response to an offer received in order for the WebRTC * signaling protocol to start. *

* Should be called after {@link #setRemoteDescription} is called *

* In most cases {@link #setLocalDescription} should be called after an * answer is created * * @param listener callback that is called when an answer is created. */ public void createAnswer(final CREATE_ANSWER listener) { Promise promise = new Promise(new Promise.PROMISE_CHANGE() { @SuppressWarnings("unused") public void onChange(Promise promise) { Structure reply = promise.getReply(); WebRTCSessionDescription description = (WebRTCSessionDescription) reply.getValue("answer"); listener.onAnswerCreated(description); promise.dispose(); } }); emit("create-answer", null, promise); } /** * Adds a remote ice candidate to the bin * * @param sdpMLineIndex the zero-based index of the m-line attribute within * the SDP to which the candidate should be associated to * @param candidate the ICE candidate */ public void addIceCandidate(int sdpMLineIndex, String candidate) { emit("add-ice-candidate", sdpMLineIndex, candidate); } /** * Sets the local description for the WebRTC connection. Should be called * after {@link #createOffer} or {@link #createAnser} is called. * * @param description the {@link WebRTCSessionDescription} to set for the * local description */ public void setLocalDescription(WebRTCSessionDescription description) { Promise promise = new Promise(); // the raw WebRTCBin element gets ownership of the description so it must be disown in order to prevent it from being deallocated description.disown(); emit("set-local-description", description, promise); promise.interrupt(); promise.dispose(); } /** * Sets the remote description for the WebRTC connection. Shoud be called * after receiving an offer or answer from other clients. * * @param description the {@link WebRTCSessionDescription} to set for the * remote description */ public void setRemoteDescription(WebRTCSessionDescription description) { Promise promise = new Promise(); // the raw WebRTCBin element gets ownership of the description so it must be disown in order to prevent it from being deallocated description.disown(); emit("set-remote-description", description, promise); promise.interrupt(); promise.dispose(); } /** * Sets the stun-server property for this {@link WebRTCBin} * which is use to gather ICE data * * @param server STUN server url */ public void setStunServer(String server) { set("stun-server", server); } /** * Retrieves the STUN server that is used. * * @return the url for the STUN server */ public String getStunServer() { return (String) get("stun-server"); } /** * Sets the turn-server property for this {@link WebRTCBin} * which is used whenever a direct peer-to-peer connection can be * established * * @param server TURN server url */ public void setTurnServer(String server) { set("turn-server", server); } /** * Retrieves the TURN server that is used. * * @return the url for the TURN server */ public String getTurnServer() { return (String) get("turn-server"); } /** * Retrieve the connection state this {@link WebRTCBin} is currently in * * @return a {@link WebRTCPeerConnectionState} describing the connection * state */ public WebRTCPeerConnectionState getConnectionState() { return NativeEnum.fromInt(WebRTCPeerConnectionState.class, (Integer) get("connection-state")); } /** * Retrieve ICE gathering state this {@link WebRTCBin} is currently in * * @return a {@link WebRTCICEGatheringState} describing gathering state */ public WebRTCICEGatheringState getICEGatheringState() { return NativeEnum.fromInt(WebRTCICEGatheringState.class, (Integer) get("ice-gathering-state")); } /** * Retrieve the local description for this {@link WebRTCBin} * * @return the local {@link WebRTCSessionDescription} */ public WebRTCSessionDescription getLocalDescription() { WebRTCSessionDescription description = (WebRTCSessionDescription) get("local-description"); description.disown(); return description; } /** * Retrieve the remote description for this {@link WebRTCBin} * * @return the remote {@link WebRTCSessionDescription} */ public WebRTCSessionDescription getRemoteDescription() { WebRTCSessionDescription description = (WebRTCSessionDescription) get("remote-description"); description.disown(); return description; } } ================================================ FILE: src/org/freedesktop/gstreamer/webrtc/WebRTCICEGatheringState.java ================================================ package org.freedesktop.gstreamer.webrtc; import org.freedesktop.gstreamer.Gst; import org.freedesktop.gstreamer.glib.NativeEnum; /** * The ICE gathering state of WebRTC peer * Available since GStreamer 1.14 */ @Gst.Since(minor = 14) public enum WebRTCICEGatheringState implements NativeEnum { /** New gathering */ NEW(0), /** Gathering in progress */ GATHERING(1), /** Gathering completed */ COMPLETE(2); private final int value; private WebRTCICEGatheringState(int value) { this.value = value; } @Override public int intValue() { return this.value; } } ================================================ FILE: src/org/freedesktop/gstreamer/webrtc/WebRTCPeerConnectionState.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2018 Antonio Morales * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.webrtc; import org.freedesktop.gstreamer.Gst; import org.freedesktop.gstreamer.glib.NativeEnum; /** * The state of a WebRTC peer connection * Available since GStreamer 1.14 */ @Gst.Since(minor = 14) public enum WebRTCPeerConnectionState implements NativeEnum { /** New WebRTC connection */ NEW(0), /** A WebRTC connection is being made */ CONNECTING(1), /** A WebRTC connection has been made */ CONNECTED(2), /** A WebRTC connection has been disconnected */ DISCONNECTED(3), /** Attempt to make a WebRTC connection failed */ FAILED(4), /** A WebRTC connection has been closed */ CLOSED(5); private final int value; private WebRTCPeerConnectionState(int value) { this.value = value; } @Override public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/webrtc/WebRTCSDPType.java ================================================ /* * Copyright (c) 2018 Antonio Morales * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer.webrtc; import org.freedesktop.gstreamer.Gst; import org.freedesktop.gstreamer.glib.NativeEnum; /** * The type of a {@link WebRTCSessionDescription} *

* @see https://w3c.github.io/webrtc-pc/#rtcsdptype * Available since GStreamer 1.12 */ @Gst.Since(minor = 12) public enum WebRTCSDPType implements NativeEnum { OFFER(1), PRANSWER(2), ANSWER(3), ROLLBACK(4); private final int value; private WebRTCSDPType(int value) { this.value = value; } /** * Gets the integer value of the enum * @return the integer value for this enum. */ @Override public int intValue() { return value; } } ================================================ FILE: src/org/freedesktop/gstreamer/webrtc/WebRTCSessionDescription.java ================================================ /* * Copyright (c) 2019 Neil C Smith * Copyright (c) 2018 Vinicius Tona * Copyright (c) 2018 Antonio Morales * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License version 3 only, as published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License version 3 along with * this work. If not, see . */ package org.freedesktop.gstreamer.webrtc; import static org.freedesktop.gstreamer.lowlevel.GstWebRTCSessionDescriptionAPI.GSTWEBRTCSESSIONDESCRIPTION_API; import org.freedesktop.gstreamer.lowlevel.GstWebRTCSessionDescriptionAPI; import org.freedesktop.gstreamer.glib.NativeObject; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.SDPMessage; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GPointer; import static org.freedesktop.gstreamer.lowlevel.GstSDPMessageAPI.GSTSDPMESSAGE_API; /** * Wraps a GstWebRTCSessionDescription *

* See https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/blob/master/gst-libs/gst/webrtc/rtcsessiondescription.h */ public class WebRTCSessionDescription extends NativeObject { public static final String GTYPE_NAME = "GstWebRTCSessionDescription"; private GstWebRTCSessionDescriptionAPI.WebRTCSessionDescriptionStruct sessionDescriptionStruct; /** * Internally used constructor. Do not use. * * @param init internal initialization data. */ WebRTCSessionDescription(Initializer init) { super(new Handle(init.ptr, init.ownsHandle)); sessionDescriptionStruct = new GstWebRTCSessionDescriptionAPI.WebRTCSessionDescriptionStruct(init.ptr.getPointer()); } /** * Creates a new instance of WebRTCSessionDescription. * * @param type The {@link WebRTCSDPType} type of the session description * @param sdpMessage The {@link SDPMessage} of the session description */ public WebRTCSessionDescription(WebRTCSDPType type, SDPMessage sdpMessage) { this(Natives.initializer(GSTWEBRTCSESSIONDESCRIPTION_API.ptr_gst_webrtc_session_description_new(type, sdpMessage))); } /** * Gets the SDPMessage from the WebRTCSessionDescription. * * @return the {@link SDPMessage} for the WebRTCSessionDescription */ public SDPMessage getSDPMessage() { SDPMessage originalSDP = (SDPMessage) sessionDescriptionStruct.readField("sdp"); // making a copy of the SDPMessage since the original SDPMessage in the struct belongs to WebRTCSessionDescription. // Once WebRTCSessionDescription is disposed it would also dispose of SDPMessage leading to any objects with a reference // to the original SDPMessage to be invalid and potentially lead to runtime errors. // return originalSDP.copy(true); Pointer[] ptr = new Pointer[1]; GSTSDPMESSAGE_API.gst_sdp_message_copy(originalSDP, ptr); originalSDP.invalidate(); return Natives.objectFor(ptr[0], SDPMessage.class, false, true); } private static final class Handle extends NativeObject.Handle { public Handle(GPointer ptr, boolean ownsHandle) { super(ptr, ownsHandle); } @Override protected void disposeNativeHandle(GPointer ptr) { GSTWEBRTCSESSIONDESCRIPTION_API.gst_webrtc_session_description_free(ptr.getPointer()); } } } ================================================ FILE: test/org/freedesktop/gstreamer/BinTest.java ================================================ /* * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.GError; import java.util.ArrayList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.util.Iterator; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import org.freedesktop.gstreamer.lowlevel.GstBinAPI; import org.freedesktop.gstreamer.lowlevel.GstPipelineAPI; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; /** * * @author wayne */ public class BinTest { public BinTest() { } @BeforeClass public static void setUpClass() throws Exception { Gst.init("BinTest", new String[] {}); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { } @Test public void testGetElements() { Bin bin = new Bin("test"); Element e1 = ElementFactory.make("fakesrc", "source"); Element e2 = ElementFactory.make("fakesink", "sink"); bin.addMany(e1, e2); List elements = bin.getElements(); assertFalse("Bin returned empty list from getElements", elements.isEmpty()); assertTrue("Element list does not contain e1", elements.contains(e1)); assertTrue("Element list does not contain e2", elements.contains(e2)); } @Test public void testGetSinks() throws Exception { Bin bin = new Bin("test"); Element e1 = ElementFactory.make("fakesrc", "source"); Element e2 = ElementFactory.make("fakesink", "sink"); bin.addMany(e1, e2); List elements = bin.getSinks(); assertFalse("Bin returned empty list from getElements", elements.isEmpty()); assertTrue("Element list does not contain sink", elements.contains(e2)); } @Test public void testGetSources() throws Exception { Bin bin = new Bin("test"); Element e1 = ElementFactory.make("fakesrc", "source"); Element e2 = ElementFactory.make("fakesink", "sink"); bin.addMany(e1, e2); List elements = bin.getSources(); assertFalse("Bin returned empty list from getElements", elements.isEmpty()); assertTrue("Element list does not contain source", elements.contains(e1)); } @Test public void testGetElementByName() throws Exception { Bin bin = new Bin("test"); Element e1 = ElementFactory.make("fakesrc", "source"); Element e2 = ElementFactory.make("fakesink", "sink"); bin.addMany(e1, e2); assertEquals("source not returned", e1, bin.getElementByName("source")); assertEquals("sink not returned", e2, bin.getElementByName("sink")); } @Test public void testElementAddedCallback() throws Exception { Bin bin = new Bin("test"); final Element e1 = ElementFactory.make("fakesrc", "source"); final Element e2 = ElementFactory.make("fakesink", "sink"); final AtomicInteger added = new AtomicInteger(0); bin.connect(new Bin.ELEMENT_ADDED() { public void elementAdded(Bin bin, Element elem) { if (elem == e1 || elem == e2) { added.incrementAndGet(); } } }); bin.addMany(e1, e2); assertEquals("Callback not called", 2, added.get()); } @Test public void testElementRemovedCallback() { Bin bin = new Bin("test"); final Element e1 = ElementFactory.make("fakesrc", "source"); final Element e2 = ElementFactory.make("fakesink", "sink"); final AtomicInteger removed = new AtomicInteger(0); bin.connect(new Bin.ELEMENT_ADDED() { public void elementAdded(Bin bin, Element elem) { if (elem == e1 || elem == e2) { removed.incrementAndGet(); } } }); bin.addMany(e1, e2); assertEquals("Callback not called", 2, removed.get()); } @Test public void addLinked() throws PadLinkException { /* adding an element with linked pads to a bin unlinks the pads */ Pipeline pipeline = new Pipeline((String) null); assertNotNull("Could not create pipeline", pipeline); Element src = ElementFactory.make("fakesrc", null); assertNotNull("Could not create fakesrc", src); Element sink = ElementFactory.make("fakesink", null); assertNotNull("Could not create fakesink", sink); Pad srcpad = src.getStaticPad("src"); assertNotNull("Could not get src pad", srcpad); Pad sinkpad = sink.getStaticPad("sink"); assertNotNull("Could not get sink pad", sinkpad); srcpad.link(sinkpad); /* pads are linked now */ assertTrue("srcpad not linked", srcpad.isLinked()); assertTrue("sinkpad not linked", sinkpad.isLinked()); /* adding element to bin voids hierarchy so pads are unlinked */ pipeline.add(src); /* check if pads really are unlinked */ assertFalse("srcpad is still linked after being added to bin", srcpad.isLinked()); assertFalse("sinkpad is still linked after being added to bin", sinkpad.isLinked()); /* cannot link pads in wrong hierarchy */ try { srcpad.link(sinkpad); fail("Should not be able to link pads in different hierarchy"); } catch (PadLinkException e) { assertEquals("Should not be able to link pads in different hierarchy", PadLinkReturn.WRONG_HIERARCHY, e.getLinkResult()); } /* adding other element to bin as well */ pipeline.add(sink); /* now we can link again */ srcpad.link(sinkpad); /* check if pads really are linked */ assertTrue("srcpad not linked", srcpad.isLinked()); assertTrue("sinkpad not linked", sinkpad.isLinked()); // Force disposal to flush out any refcounting bugs. pipeline.dispose(); src.dispose(); sink.dispose(); srcpad.dispose(); sinkpad.dispose(); } @Test public void addSelf() { Bin bin = new Bin(""); // Enable the line below once we know how to avoid gstreamer spitting out warnings //assertFalse("Should not be able to add bin to itself", bin.add(bin)); bin.dispose(); } // This test doesn't work correctly on older gstreamer? //@Test public void iterateSorted() { Pipeline pipeline = GstPipelineAPI.GSTPIPELINE_API.gst_pipeline_new(null); assertNotNull("Failed to create Pipeline", pipeline); Bin bin = GstBinAPI.GSTBIN_API.gst_bin_new(null); assertNotNull("Failed to create bin", bin); Element src = ElementFactory.make("fakesrc", null); assertNotNull("Failed to create fakesrc", src); Element tee = ElementFactory.make("tee", null); assertNotNull("Failed to create tee", tee); Element sink1 = ElementFactory.make("fakesink", null); assertNotNull("Failed to create fakesink", sink1); bin.addMany(src, tee, sink1); assertTrue("Could not link fakesrc to tee", src.link(tee)); assertTrue("Could not link tee to fakesink", tee.link(sink1)); Element identity = ElementFactory.make("identity", null); assertNotNull("Failed to create identity", identity); Element sink2 = ElementFactory.make("fakesink", null); assertNotNull("Failed to create fakesink", sink2); pipeline.addMany(bin, identity, sink2); // gst_bin_add_many (GST_BIN (pipeline), bin, identity, sink2, NULL); assertTrue("Could not link tee to identity", tee.link(identity)); assertTrue("Could not link identity to second fakesink", identity.link(sink2)); Iterator it = pipeline.getElementsSorted().iterator(); assertEquals("First sorted element should be sink2", sink2, it.next()); assertEquals("Second sorted element should be identity", identity, it.next()); assertEquals("Third sorted element should be bin", bin, it.next()); pipeline.dispose(); } @Test public void testParseBin() { ArrayList errors = new ArrayList(); Bin bin = Gst.parseBinFromDescription("fakesrc ! fakesink", false, errors); assertNotNull("Bin not created", bin); assertEquals("parseBinFromDescription with error!", errors.size(), 0); } @Test public void testParseBinElementCount() { ArrayList errors = new ArrayList(); Bin bin = Gst.parseBinFromDescription("fakesrc ! fakesink", false, errors); assertEquals("Number of elements in pipeline incorrect", 2, bin.getElements().size()); assertEquals("parseBinFromDescription with error!", errors.size(), 0); } @Test public void testParseBinSrcElement() { ArrayList errors = new ArrayList(); Bin bin = Gst.parseBinFromDescription("fakesrc ! fakesink", false, errors); assertEquals("First element not a fakesrc", "fakesrc", bin.getSources().get(0).getFactory().getName()); assertEquals("parseBinFromDescription with error!", errors.size(), 0); } @Test public void testParseBinSinkElement() { ArrayList errors = new ArrayList(); Bin bin = Gst.parseBinFromDescription("fakesrc ! fakesink", false, errors); assertEquals("First element not a fakesink", "fakesink", bin.getSinks().get(0).getFactory().getName()); assertEquals("parseBinFromDescription with error!", errors.size(), 0); } @Test public void testParseBinDisabledGhostPadsForSource() { ArrayList errors = new ArrayList(); Bin bin = Gst.parseBinFromDescription("fakesrc", false, errors); assertEquals("Number of src pads incorrect", 0, bin.getSrcPads().size()); assertEquals("parseBinFromDescription with error!", errors.size(), 0); } @Test public void testParseBinDisabledGhostPadsForSink() { ArrayList errors = new ArrayList(); Bin bin = Gst.parseBinFromDescription("fakesink", false, errors); assertEquals("Number of sink pads incorrect", 0, bin.getSinkPads().size()); assertEquals("parseBinFromDescription with error!", errors.size(), 0); } @Test public void testParseBinEnabledGhostPadsForSource() { ArrayList errors = new ArrayList(); Bin bin = Gst.parseBinFromDescription("fakesrc", true, errors); assertEquals("Number of src pads incorrect", 1, bin.getSrcPads().size()); assertEquals("parseBinFromDescription with error!", errors.size(), 0); } @Test public void testParseBinEnabledGhostPadsForSink() { ArrayList errors = new ArrayList(); Bin bin = Gst.parseBinFromDescription("fakesink", true, errors); assertEquals("Number of sink pads incorrect", 1, bin.getSinkPads().size()); assertEquals("parseBinFromDescription with error!", errors.size(), 0); } @Test public void testParseBinEnabledGhostPadsForSourceWithNoUsablePads() { ArrayList errors = new ArrayList(); Bin bin = Gst.parseBinFromDescription("fakesrc ! fakesink", true, errors); assertEquals("Number of src pads incorrect", 0, bin.getSrcPads().size()); assertEquals("parseBinFromDescription with error!", errors.size(), 0); } @Test public void testParseBinEnabledGhostPadsForSinkWithNoUsablePads() { ArrayList errors = new ArrayList(); Bin bin = Gst.parseBinFromDescription("fakesrc ! fakesink", true, errors); assertEquals("Number of sink pads incorrect", 0, bin.getSinkPads().size()); assertEquals("parseBinFromDescription with error!", errors.size(), 0); } @Test public void testParseBinEnabledGhostPadsWithNoUsablePads() { ArrayList errors = new ArrayList(); Bin bin = Gst.parseBinFromDescription("fakesrc ! fakesink", true, errors); assertEquals("Number of pads incorrect", 0, bin.getPads().size()); assertEquals("parseBinFromDescription with error!", errors.size(), 0); } } ================================================ FILE: test/org/freedesktop/gstreamer/BufferFieldsTest.java ================================================ package org.freedesktop.gstreamer; import org.junit.*; import static org.junit.Assert.*; /** *

* Copyright (C) 2018 Robert Forsman, Ericsson SATV $Author thoth $ $Date 3/8/18 * $ */ public class BufferFieldsTest { @BeforeClass public static void setUpClass() throws Exception { Gst.init("BufferFieldsTest"); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } private Buffer buf; @Before public void setUp() { buf = new Buffer(12); } @Test public void setPTS() { buf.setPresentationTimestamp(ClockTime.fromMicros(5004003)); long val = buf.getPresentationTimestamp(); assertEquals(5004003, ClockTime.toMicros(val)); } @Test public void setDTS() { buf.setDecodeTimestamp(ClockTime.fromMicros(9001004)); long val = buf.getDecodeTimestamp(); assertEquals(9001004, ClockTime.toMicros(val)); } @Test public void setDuration() { buf.setDuration(ClockTime.fromMicros(4006008)); long val = buf.getDuration(); assertEquals(4006008, ClockTime.toMicros(val)); } @Test public void setOffset() { buf.setOffset(2009006); long val = buf.getOffset(); assertEquals(2009006, val); } @Test public void setOffsetEnd() { buf.setOffsetEnd(7005003); long val = buf.getOffsetEnd(); assertEquals(7005003, val); } @Test // cannot test on GStreamer 1.8 public void setFlags() { // assertTrue(buf.setFlags(7)); // int val = buf.getFlags(); // assertEquals(7, val); // // assertTrue(buf.setFlags(10)); // val = buf.getFlags(); // assertEquals(15, val); // // assertTrue(buf.unsetFlags(20)); // val = buf.getFlags(); // assertEquals(11, val); } } ================================================ FILE: test/org/freedesktop/gstreamer/BufferProbeTester.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2020 John Cortell * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.Consumer; /** * Utility class for unit testing API that operates on a Buffer. *

* Call {@link BufferTester#test(Consumer)} and pass a callback which will * perform the test on a Buffer it is supplied. The callback runs in a Pad data * probe. The buffer is produced by a simple, ephemeral pipeline that is fed by * a video test source. */ public class BufferProbeTester { public static void test(Consumer callback) { test(callback, "videotestsrc ! videoconvert ! fakesink name=sink"); } public static void test(Consumer callback, String pipelineDescription) { test(callback, pipelineDescription, 0); } public static void test(Consumer callback, String pipelineDescription, int skipFrames) { assertNotNull("Pipeline description can not be null", pipelineDescription); assertFalse("Pipeline description can not be empty", pipelineDescription.isEmpty()); Pipeline pipe = (Pipeline) Gst.parseLaunch(pipelineDescription); assertNotNull("Unable to create Pipeline from pipeline description: ", pipe); Element sink = pipe.getElementByName("sink"); Pad pad = sink.getStaticPad("sink"); BufferProbe probe = new BufferProbe(callback, skipFrames); pad.addDataProbe(probe); pipe.play(); // Wait for the sample to arrive and for the client supplied test function to // complete try { probe.await(5000); } catch (Exception ex) { fail("Unexpected exception waiting for buffer\n" + ex); } finally { pipe.stop(); } // If the test threw an exception on the sample listener thread, throw it here // (on the main thread) if (probe.exception != null) { throw new AssertionError(probe.exception); } } private static class BufferProbe implements Pad.DATA_PROBE { private final int skipFrames; private final CountDownLatch latch; private final Consumer callback; private Throwable exception; private int counter = 0; BufferProbe(Consumer callback) { this(callback, 0); } BufferProbe(Consumer callback, int skip) { this.callback = callback; skipFrames = skip; latch = new CountDownLatch(1); } @Override public PadProbeReturn dataReceived(Pad pad, Buffer buffer) { if (latch.getCount() > 0) { if (counter < skipFrames) { counter++; return PadProbeReturn.OK; } try { // Run the client's test logic on the buffer (only once) try { callback.accept(buffer); } catch (Throwable exc) { exception = exc; } } finally { latch.countDown(); } } return PadProbeReturn.OK; } void await(long millis) throws InterruptedException, TimeoutException { if (!latch.await(millis, TimeUnit.MILLISECONDS)) { throw new TimeoutException(); } } } } ================================================ FILE: test/org/freedesktop/gstreamer/BusTest.java ================================================ /* * Copyright (c) 2025 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import org.freedesktop.gstreamer.lowlevel.GlibAPI; import org.freedesktop.gstreamer.lowlevel.GstAPI.GErrorStruct; import org.freedesktop.gstreamer.message.EOSMessage; import org.freedesktop.gstreamer.message.Message; import org.freedesktop.gstreamer.message.MessageType; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.freedesktop.gstreamer.lowlevel.GstElementAPI.GSTELEMENT_API; import static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API; import static org.junit.Assert.*; public class BusTest { public BusTest() { } @BeforeClass public static void setUpClass() throws Exception { Gst.init("BusTest"); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { } @Test public void endOfStream() { final TestPipe pipe = new TestPipe("endOfStream"); final AtomicBoolean signalFired = new AtomicBoolean(false); final AtomicReference signalSource = new AtomicReference<>(); Bus.EOS eosSignal = (GstObject source) -> { signalFired.set(true); signalSource.set(source); pipe.quit(); }; pipe.play(); pipe.getBus().connect(eosSignal); // // For the pipeline to post an EOS message, all sink elements must post it // for (Element elem : pipe.pipe.getSinks()) { GSTELEMENT_API.gst_element_post_message(elem, GSTMESSAGE_API.gst_message_new_eos(elem)); } pipe.run(); pipe.getBus().disconnect(eosSignal); assertTrue("EOS signal not received", signalFired.get()); pipe.dispose(); } @Test public void stateChanged() { final TestPipe pipe = new TestPipe("stateChanged"); final AtomicBoolean signalFired = new AtomicBoolean(false); Bus.STATE_CHANGED stateChanged = (GstObject source, State old, State current, State pending) -> { if (pending == State.PLAYING || current == State.PLAYING) { signalFired.set(true); pipe.quit(); } }; pipe.getBus().connect(stateChanged); pipe.play().run(); pipe.getBus().disconnect(stateChanged); assertTrue("STATE_CHANGED signal not received", signalFired.get()); pipe.dispose(); } @Test public void asyncDone() { final TestPipe pipe = new TestPipe("asyncDone"); final AtomicBoolean signalFired = new AtomicBoolean(false); Bus.ASYNC_DONE asyncDone = (GstObject source) -> { signalFired.set(true); pipe.quit(); }; pipe.getBus().connect(asyncDone); pipe.play().run(); pipe.getBus().disconnect(asyncDone); assertTrue("ASYNC_DONE message not received", signalFired.get()); pipe.dispose(); } @Test public void errorMessage() { final TestPipe pipe = new TestPipe("errorMessage"); final AtomicBoolean signalFired = new AtomicBoolean(false); final AtomicReference signalSource = new AtomicReference<>(); Bus.ERROR errorSignal = (GstObject source, int code, String message) -> { signalFired.set(true); signalSource.set(source); pipe.quit(); }; pipe.getBus().connect(errorSignal); GErrorStruct msg = GlibAPI.GLIB_API.g_error_new(1, 1, "MSG"); GSTELEMENT_API.gst_element_post_message(pipe.src, GSTMESSAGE_API.gst_message_new_error(pipe.src, msg, "testing error messages")); pipe.play().run(); pipe.getBus().disconnect(errorSignal); pipe.dispose(); assertTrue("ERROR signal not received", signalFired.get()); assertEquals("Incorrect source object on signal", pipe.src, signalSource.get()); GlibAPI.GLIB_API.g_error_free(msg.getPointer()); } @Test public void warningMessage() { final TestPipe pipe = new TestPipe("warningMessage"); final AtomicBoolean signalFired = new AtomicBoolean(false); final AtomicReference signalSource = new AtomicReference<>(); Bus.WARNING signal = (GstObject source, int code, String message) -> { signalFired.set(true); signalSource.set(source); pipe.quit(); }; pipe.getBus().connect(signal); GErrorStruct msg = GlibAPI.GLIB_API.g_error_new(1, 1, "MSG"); pipe.play(); GSTELEMENT_API.gst_element_post_message(pipe.src, GSTMESSAGE_API.gst_message_new_warning(pipe.src, msg, "testing warning messages")); pipe.run(); pipe.getBus().disconnect(signal); pipe.dispose(); assertTrue("WARNING signal not received", signalFired.get()); assertEquals("Incorrect source object on signal", pipe.src, signalSource.get()); GlibAPI.GLIB_API.g_error_free(msg.getPointer()); } @Test public void infoMessage() { final TestPipe pipe = new TestPipe("infoMessage"); final AtomicBoolean signalFired = new AtomicBoolean(false); final AtomicReference signalSource = new AtomicReference<>(); Bus.INFO signal = (GstObject source, int code, String message) -> { signalFired.set(true); signalSource.set(source); pipe.quit(); }; pipe.getBus().connect(signal); GErrorStruct msg = GlibAPI.GLIB_API.g_error_new(1, 1, "MSG"); pipe.play(); GSTELEMENT_API.gst_element_post_message(pipe.src, GSTMESSAGE_API.gst_message_new_info(pipe.src, msg, "testing info messages")); pipe.run(); pipe.getBus().disconnect(signal); pipe.dispose(); assertTrue("INFO signal not received", signalFired.get()); assertEquals("Incorrect source object on signal", pipe.src, signalSource.get()); GlibAPI.GLIB_API.g_error_free(msg.getPointer()); } @Test public void bufferingData() { final TestPipe pipe = new TestPipe("bufferingData"); final AtomicBoolean signalFired = new AtomicBoolean(false); final AtomicInteger signalValue = new AtomicInteger(-1); final AtomicReference signalSource = new AtomicReference<>(); final int PERCENT = 95; Bus.BUFFERING signal = (GstObject source, int percent) -> { signalFired.set(true); signalValue.set(percent); signalSource.set(source); pipe.quit(); }; pipe.getBus().connect(signal); GSTELEMENT_API.gst_element_post_message(pipe.src, GSTMESSAGE_API.gst_message_new_buffering(pipe.src, PERCENT)); pipe.play().run(); pipe.getBus().disconnect(signal); pipe.dispose(); assertTrue("BUFFERING signal not received", signalFired.get()); assertEquals("Wrong percent value received for signal", PERCENT, signalValue.get()); assertEquals("Incorrect source object on signal", pipe.src, signalSource.get()); } @Test public void tagsFound() { final TestPipe pipe = new TestPipe("tagsFound"); final AtomicBoolean signalFired = new AtomicBoolean(false); final AtomicReference signalSource = new AtomicReference<>(); Bus.TAG signal = (GstObject source, TagList tagList) -> { signalFired.set(true); signalSource.set(source); pipe.quit(); }; pipe.getBus().connect(signal); TagList tagList = new TagList(); GSTELEMENT_API.gst_element_post_message(pipe.src, GSTMESSAGE_API.gst_message_new_tag(pipe.src, tagList)); pipe.play().run(); pipe.getBus().disconnect(signal); pipe.dispose(); assertTrue("TAG signal not received", signalFired.get()); assertEquals("Incorrect source object on signal", pipe.src, signalSource.get()); } @Test public void durationChanged() { final TestPipe pipe = new TestPipe("testDurationChanged"); final AtomicBoolean signalFired = new AtomicBoolean(false); final AtomicReference signalSource = new AtomicReference<>(null); Bus.DURATION_CHANGED signal = (GstObject source) -> { signalFired.set(true); signalSource.set(source); pipe.quit(); }; pipe.getBus().connect(signal); GSTELEMENT_API.gst_element_post_message(pipe.src, GSTMESSAGE_API.gst_message_new_duration_changed(pipe.src)); pipe.play().run(); pipe.getBus().disconnect(signal); pipe.dispose(); assertTrue("DURATION signal not received", signalFired.get()); assertEquals("Incorrect source object on signal", pipe.src, signalSource.get()); } @Test public void segmentDone() { final TestPipe pipe = new TestPipe("segmentDone"); final AtomicBoolean signalFired = new AtomicBoolean(false); final AtomicReference formatReceived = new AtomicReference<>(null); final AtomicLong positionReceived = new AtomicLong(0); Bus.SEGMENT_DONE segmentDone = (source, format, position) -> { signalFired.set(true); formatReceived.set(format); positionReceived.set(position); }; pipe.getBus().connect(segmentDone); final long POSITION = 0xdeadbeef; GSTELEMENT_API.gst_element_post_message(pipe.src, GSTMESSAGE_API.gst_message_new_segment_done(pipe.src, Format.TIME, POSITION)); pipe.run(); assertTrue("No segment done message received", signalFired.get()); assertEquals("Wrong format", Format.TIME, formatReceived.get()); assertEquals("Wrong position", POSITION, positionReceived.get()); pipe.dispose(); } @Test public void anyMessage() { final TestPipe pipe = new TestPipe("anyMessage"); final AtomicReference firstMessage = new AtomicReference<>(); Bus.MESSAGE listener = (Bus bus, Message msg) -> { firstMessage.compareAndSet(null, msg); pipe.quit(); }; pipe.getBus().connect(listener); pipe.play().run(); pipe.getBus().disconnect(listener); pipe.dispose(); Message message = firstMessage.getAndSet(null); assertNotNull("No message received", message); GCTracker gc = new GCTracker(message); message = null; assertTrue("Message not garbage collected", gc.waitGC()); assertTrue("Message not destroyed", gc.waitDestroyed()); } @Test public void postMessage() { final TestPipe pipe = new TestPipe(); final AtomicBoolean signalFired = new AtomicBoolean(false); final AtomicReference signalSource = new AtomicReference<>(); Bus.MESSAGE listener = (Bus bus, Message msg) -> { signalFired.set(true); signalSource.set(msg.getSource()); pipe.quit(); }; pipe.getBus().connect(listener); Message message = new EOSMessage(pipe.src); pipe.getBus().post(message); pipe.run(); assertTrue("Message not posted", signalFired.get()); assertEquals("Wrong source in message", pipe.src, signalSource.get()); pipe.dispose(); GCTracker gc = new GCTracker(message); message = null; assertTrue("Message not garbage collected", gc.waitGC()); assertTrue("Message not destroyed", gc.waitDestroyed()); } @Test public void syncHandler() { final TestPipe pipe = new TestPipe("syncHandler"); final AtomicReference firstMessageSync = new AtomicReference<>(); final AtomicReference firstMessageAsync = new AtomicReference<>(); BusSyncHandler syncHandler = (Message message) -> { firstMessageSync.compareAndSet(null, message); return BusSyncReply.PASS; }; Bus.MESSAGE listener = (Bus bus, Message msg) -> { firstMessageAsync.compareAndSet(null, msg); pipe.quit(); }; pipe.getBus().setSyncHandler(syncHandler); pipe.getBus().connect(listener); pipe.play().run(); pipe.getBus().disconnect(listener); pipe.dispose(); Message message = firstMessageSync.getAndSet(null); Message asyncMessage = firstMessageAsync.getAndSet(null); assertNotNull("No message received", message); assertTrue("Sync and listeners messages not equal", message == asyncMessage); GCTracker gc = new GCTracker(message); message = null; asyncMessage = null; assertTrue("Message not garbage collected", gc.waitGC()); assertTrue("Message not destroyed", gc.waitDestroyed()); } @Test public void syncHandlerRemoval() { final TestPipe pipe = new TestPipe("syncHandlerRemoval"); final AtomicReference firstMessageSync = new AtomicReference<>(); final AtomicReference firstMessageAsync = new AtomicReference<>(); BusSyncHandler syncHandler = (Message message) -> { firstMessageSync.compareAndSet(null, message); return BusSyncReply.PASS; }; Bus.MESSAGE listener = (Bus bus, Message msg) -> { firstMessageAsync.compareAndSet(null, msg); pipe.quit(); }; pipe.getBus().setSyncHandler(syncHandler); pipe.getBus().connect(listener); pipe.getBus().setSyncHandler(null); pipe.play().run(); pipe.getBus().disconnect(listener); pipe.dispose(); assertNull("Removed sync handler received message", firstMessageSync.getAndSet(null)); Message message = firstMessageAsync.getAndSet(null); assertNotNull("No message received", message); GCTracker gc = new GCTracker(message); message = null; assertTrue("Message not garbage collected", gc.waitGC()); assertTrue("Message not destroyed", gc.waitDestroyed()); } @Test public void listenerRemoval() { final TestPipe pipe = new TestPipe("checkListenerRemoval"); final AtomicReference firstMessage = new AtomicReference<>(null); final AtomicBoolean stateChangedFired = new AtomicBoolean(false); Bus.MESSAGE listener = (Bus bus, Message msg) -> { firstMessage.compareAndSet(null, msg); pipe.quit(); }; Bus.STATE_CHANGED stateListener = (GstObject source, State old, State current, State pending) -> { stateChangedFired.set(true); }; pipe.getBus().connect(listener); pipe.getBus().connect(stateListener); pipe.getBus().disconnect(stateListener); pipe.play().run(); pipe.getBus().disconnect(listener); pipe.dispose(); Message message = firstMessage.getAndSet(null); assertNotNull("No message received", message); assertFalse("State changed fired after removal", stateChangedFired.get()); GCTracker gc = new GCTracker(message); message = null; assertTrue("Message not garbage collected", gc.waitGC()); assertTrue("Message not destroyed", gc.waitDestroyed()); } @Test public void extendedMessageIssue202() { final TestPipe pipe = new TestPipe("issue202"); final AtomicBoolean signalFired = new AtomicBoolean(false); Bus.MESSAGE msgListener = (Bus bus, Message msg) -> { signalFired.set(true); }; Bus.ERROR errListener = (GstObject source, int code, String message) -> { // @TODO If used as flags, DEVICE_REMOVED and ERROR overlap. // but an exception will be thrown in the executor and logged // rather than this method being called - need a way to fail with // executor exceptions in tests? }; pipe.getBus().connect(errListener); pipe.getBus().connect(msgListener); for (Element elem : pipe.pipe.getSources()) { GSTELEMENT_API.gst_element_post_message(elem, GSTMESSAGE_API .gst_message_new_custom(MessageType.DEVICE_REMOVED, elem, null) ); } pipe.play().run(); pipe.getBus().disconnect(msgListener); pipe.getBus().disconnect(errListener); assertTrue("Custom message not received", signalFired.get()); pipe.dispose(); } } ================================================ FILE: test/org/freedesktop/gstreamer/CapsTest.java ================================================ /* * Copyright (c) 2007 Wayne Meissner * Copyright (C) 2005 Andy Wingo * Copyright (C) <2005> Thomas Vander Stichele * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; /** * Unit test for GstCaps */ public class CapsTest { public CapsTest() { } @BeforeClass public static void setUpClass() throws Exception { Gst.init("CapsTest", new String[] {}); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Test public void capsMerge() { Caps c1 = new Caps("video/x-raw, format=RGB, bpp=32, depth=24"); Caps c2 = new Caps("video/x-raw, format=RGB, width=640, height=480"); Caps c3 = Caps.merge(c1, c2); // Verify that the victim caps were invalidated and cannot be used. try { c1.toString(); fail("merged caps not invalidated"); } catch (IllegalStateException ex) {} try { c2.toString(); fail("merged caps not invalidated"); } catch (IllegalStateException ex) {} boolean widthFound = false, heightFound = false; for (int i = 0; i < c3.size(); ++i) { Structure s = c3.getStructure(i); if (s.hasIntField("width")) { widthFound = true; } if (s.hasIntField("height")) { heightFound = true; } } assertTrue("width not appended", widthFound); assertTrue("height not appended", heightFound); // Verify reference count before dispose Assert.assertEquals(1, c3.getRefCount()); // Force cleanup to bring out any memory bugs c3.dispose(); } @Test public void capsAppend() { Caps c1 = new Caps("video/x-raw, format=RGB, bpp=32, depth=24"); Caps c2 = new Caps("video/x-raw, format=RGB, width=640, height=480"); c1.append(c2); // Verify that the victim caps were invalidated and cannot be used. try { c2.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} boolean widthFound = false, heightFound = false; for (int i = 0; i < c1.size(); ++i) { Structure s = c1.getStructure(i); if (s.hasIntField("width")) { widthFound = true; } if (s.hasIntField("height")) { heightFound = true; } } assertTrue("width not appended", widthFound); assertTrue("height not appended", heightFound); // Verify reference count before dispose Assert.assertEquals(1, c1.getRefCount()); // Force cleanup to bring out any memory bugs c1.dispose(); } private static final String non_simple_caps_string = "video/x-raw, format=I420, framerate=(fraction)[ 1/100, 100 ], " + "width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ]; video/x-raw, " + "format=YUY2, framerate=(fraction)[ 1/100, 100 ], width=(int)[ 16, 4096 ], " + "height=(int)[ 16, 4096 ]; video/x-raw, format=RGB, bpp=(int)8, depth=(int)8, " + "endianness=(int)1234, framerate=(fraction)[ 1/100, 100 ], width=(int)[ 16, 4096 ], " + "height=(int)[ 16, 4096 ]; video/x-raw, " + "format={ I420, YUY2, YV12 }, width=(int)[ 16, 4096 ], " + "height=(int)[ 16, 4096 ], framerate=(fraction)[ 1/100, 100 ]"; @Test public void simplify() { Caps c1 = new Caps(non_simple_caps_string); assertNotNull("Caps not created", c1); Caps c2 = c1.simplify(); assertNotNull("Simplify returned null", c2); /* check simplified caps, should be: * * video/x-raw, format=RGB, bpp=(int)8, depth=(int)8, endianness=(int)1234, * framerate=(fraction)[ 1/100, 100 ], width=(int)[ 16, 4096 ], * height=(int)[ 16, 4096 ]; * video/x-raw, format={ YV12, YUY2, I420 }, * width=(int)[ 16, 4096 ], height=(int)[ 16, 4096 ], * framerate=(fraction)[ 1/100, 100 ] */ assertEquals("Caps not simplified to 2 structures", 2, c2.size()); Structure s1 = c2.getStructure(0); assertNotNull("Caps.getStructure(0) failed", s1); Structure s2 = c2.getStructure(1); assertNotNull("Caps.getStructure(1) failed", s2); if (!s1.hasName("video/x-raw")) { Structure tmp = s1; s1 = s2; s2 = tmp; } assertTrue("Could not locate video/x-raw structure", s1.hasName("video/x-raw")); assertEquals("bpp not retrieved", 8, s1.getInteger("bpp")); assertEquals("depth not retrieved", 8, s1.getInteger("depth")); assertTrue("Could not locate video/x-raw structure", s2.hasName("video/x-raw")); // Verify reference count before dispose Assert.assertEquals(1, c1.getRefCount()); Assert.assertEquals(1, c2.getRefCount()); // Force cleanup to bring out any memory bugs c1.dispose(); c2.dispose(); } @Test public void truncate() { Caps c1 = Caps.fromString(non_simple_caps_string); assertNotNull("Caps.fromString failed", c1); assertEquals("Incorrect number of structures in caps", 4, c1.size()); Caps c2 = c1.truncate(); assertEquals("Caps not truncated", 1, c2.size()); assertEquals("Original caps untouched", 4, c1.size()); // Verify reference count before dispose Assert.assertEquals(1, c1.getRefCount()); Assert.assertEquals(1, c2.getRefCount()); // Force cleanup to bring out any memory bugs c1.dispose(); c2.dispose(); } @Test public void mergeANYAndSpecific() { /* ANY + specific = ANY */ Caps c1 = Caps.anyCaps(); Caps c2 = Caps.fromString("audio/x-raw,rate=44100"); Caps c3 = Caps.merge(c1, c2); assertEquals("Too many structures in merged caps", 0, c3.size()); assertTrue("Merged caps should be ANY", c3.isAny()); // Verify that the victim caps were invalidated and cannot be used. try { c1.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} try { c2.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} // Verify reference count before dispose Assert.assertEquals(1, c3.getRefCount()); // Force cleanup to bring out any memory bugs c3.dispose(); } @Test public void mergeSpecificAndANY() { /* specific + ANY = ANY */ Caps c1 = Caps.fromString("audio/x-raw,rate=44100"); Caps c2 = Caps.anyCaps(); Caps c3 = Caps.merge(c1, c2); assertEquals("Too many structures in merged caps", 0, c3.size()); assertTrue("Merged caps should be ANY", c3.isAny()); // Verify that the victim caps were invalidated and cannot be used. try { c1.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} try { c2.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} // Verify reference count before dispose Assert.assertEquals(1, c3.getRefCount()); // Force cleanup to bring out any memory bugs c3.dispose(); } @Test public void mergeSpecificAndEMPTY() { /* specific + EMPTY = specific */ Caps c1 = Caps.fromString("audio/x-raw,rate=44100"); Caps c2 = Caps.emptyCaps(); Caps c3 = Caps.merge(c1, c2); assertEquals("Wrong number of structures in merged structure", 1, c3.size()); assertFalse("Merged caps should not be empty", c3.isEmpty()); // Verify that the victim caps were invalidated and cannot be used. try { c1.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} try { c2.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} // Verify reference count before dispose Assert.assertEquals(1, c3.getRefCount()); // Force cleanup to bring out any memory bugs c3.dispose(); } @Test public void mergeEMPTYAndSpecific() { /* EMPTY + specific = specific */ Caps c1 = Caps.emptyCaps(); Caps c2 = Caps.fromString("audio/x-raw,rate=44100"); Caps c3 = Caps.merge(c1, c2); assertEquals("Merged Caps structure count incorrect", 1, c3.size()); assertFalse("Merged caps should not be empty", c3.isEmpty()); // Verify that the victim caps were invalidated and cannot be used. try { c1.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} try { c2.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} // Verify reference count before dispose Assert.assertEquals(1, c3.getRefCount()); // Force cleanup to bring out any memory bugs c3.dispose(); } @Test public void mergeSame() { /* this is the same */ Caps c1 = Caps.fromString("audio/x-raw,rate=44100,channels=1"); Caps c2 = Caps.fromString("audio/x-raw,rate=44100,channels=1"); Caps c3 = Caps.merge(c1, c2); assertEquals("Merged Caps structure count incorrect", 1, c3.size()); // Verify that the victim caps were invalidated and cannot be used. try { c1.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} try { c2.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} // Verify reference count before dispose Assert.assertEquals(1, c3.getRefCount()); // Force cleanup to bring out any memory bugs c3.dispose(); } @Test public void mergeSameWithDifferentOrder() { /* and so is this */ Caps c1 = Caps.fromString("audio/x-raw,rate=44100,channels=1"); Caps c2 = Caps.fromString("audio/x-raw,channels=1,rate=44100"); Caps c3 = Caps.merge(c1, c2); assertEquals("Merged Caps structure count incorrect", 1, c3.size()); // Verify that the victim caps were invalidated and cannot be used. try { c1.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} try { c2.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} // Verify reference count before dispose Assert.assertEquals(1, c3.getRefCount()); // Force cleanup to bring out any memory bugs c3.dispose(); } @Test public void mergeSameWithBufferData() { Caps c1 = Caps.fromString("video/x-foo, data=(buffer)AA"); Caps c2 = Caps.fromString("video/x-foo, data=(buffer)AABB"); Caps c3 = Caps.merge(c1, c2); assertEquals("Merged Caps structure count incorrect", 2, c3.size()); // Verify that the victim caps were invalidated and cannot be used. try { c1.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} try { c2.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} // Verify reference count before dispose Assert.assertEquals(1, c3.getRefCount()); // Force cleanup to bring out any memory bugs c3.dispose(); } @Test public void mergeSameWithBufferDataReversed() { Caps c1 = Caps.fromString("video/x-foo, data=(buffer)AABB"); Caps c2 = Caps.fromString("video/x-foo, data=(buffer)AA"); Caps c3 = Caps.merge(c1, c2); assertEquals("Merged Caps structure count incorrect", 2, c3.size()); // Verify that the victim caps were invalidated and cannot be used. try { c1.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} try { c2.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} // Verify reference count before dispose Assert.assertEquals(1, c3.getRefCount()); // Force cleanup to bring out any memory bugs c3.dispose(); } @Test public void mergeSameWithBufferDataSame() { Caps c1 = Caps.fromString("video/x-foo, data=(buffer)AA"); Caps c2 = Caps.fromString("video/x-foo, data=(buffer)AA"); Caps c3 = Caps.merge(c1, c2); assertEquals("Merged Caps structure count incorrect", 1, c3.size()); // Verify that the victim caps were invalidated and cannot be used. try { c1.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} try { c2.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} // Verify reference count before dispose Assert.assertEquals(1, c3.getRefCount()); // Force cleanup to bring out any memory bugs c3.dispose(); } @Test public void mergeDifferentWithBufferDataSame() { Caps c1 = Caps.fromString("video/x-foo, data=(buffer)AA"); Caps c2 = Caps.fromString("video/x-bar, data=(buffer)AA"); Caps c3 = Caps.merge(c1, c2); assertEquals("Merged Caps structure count incorrect", 2, c3.size()); // Verify that the victim caps were invalidated and cannot be used. try { c1.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} try { c2.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} // Verify reference count before dispose Assert.assertEquals(1, c3.getRefCount()); // Force cleanup to bring out any memory bugs c3.dispose(); } @Test public void mergeSubset() { /* the 2nd is already covered */ Caps c2 = Caps.fromString("audio/x-raw,channels=[1,2]"); Caps c1 = Caps.fromString("audio/x-raw,channels=1"); Caps c3 = Caps.merge(c1, c2).simplify(); System.out.println(c3.toString()); assertEquals("Merged Caps structure count incorrect", 1, c3.size()); // Verify that the victim caps were invalidated and cannot be used. try { c1.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} try { c2.toString(); fail("appended caps not invalidated"); } catch (IllegalStateException ex) {} // Verify reference count before dispose Assert.assertEquals(1, c3.getRefCount()); // Force cleanup to bring out any memory bugs c3.dispose(); } @Test public void intersect() { Caps c2 = Caps.fromString("video/x-raw,format=I420,width=20"); Caps c1 = Caps.fromString("video/x-raw,format=I420,height=30"); Caps ci1 = c2.intersect(c1); assertEquals("Intersected Caps structure count incorrect", 1, ci1.size()); Structure s = ci1.getStructure(0); assertTrue("Incorrect name on intersected structure", s.hasName("video/x-raw")); assertTrue("Intersected structure does not have 'format' field", s.hasField("format")); assertTrue("Intersected structure does not have 'width' field", s.hasField("width")); assertTrue("Intersected structure does not have 'height' field", s.hasField("height")); /* with changed order */ Caps ci2 = c1.intersect(c2); assertEquals("Intersected Caps structure count incorrect", 1, ci2.size()); s = ci2.getStructure(0); assertTrue("Incorrect name on intersected structure", s.hasName("video/x-raw")); assertTrue("Intersected structure does not have 'format' field", s.hasField("format")); assertTrue("Intersected structure does not have 'width' field", s.hasField("width")); assertTrue("Intersected structure does not have 'height' field", s.hasField("height")); assertTrue("Intersection should be same in both directions", ci1.isEqual(ci2)); // Force cleanup to bring out any memory bugs c2.dispose(); c1.dispose(); ci1.dispose(); ci2.dispose(); } @Test public void intersectUnspecified() { /* field not specified = any value possible, so the intersection * should keep fields which are only part of one set of caps */ Caps c2 = Caps.fromString("video/x-raw,format=I420,width=20"); Caps c1 = Caps.fromString("video/x-raw,format=I420"); Caps ci1 = c2.intersect(c1); assertEquals("Intersected Caps structure count incorrect", 1, ci1.size()); Structure s = ci1.getStructure(0); assertTrue("Incorrect name on intersected structure", s.hasName("video/x-raw")); assertTrue("Intersected structure does not have 'format' field", s.hasField("format")); assertTrue("Intersected structure does not have 'width' field", s.hasField("width")); /* with changed order */ Caps ci2 = c1.intersect(c2); assertEquals("Intersected Caps structure count incorrect", 1, ci2.size()); s = ci2.getStructure(0); assertTrue("Incorrect name on intersected structure", s.hasName("video/x-raw")); assertTrue("Intersected structure does not have 'format' field", s.hasField("format")); assertTrue("Intersected structure does not have 'width' field", s.hasField("width")); assertTrue("Intersection should be same in both directions", ci1.isEqual(ci2)); // Force cleanup to bring out any memory bugs c2.dispose(); c1.dispose(); ci1.dispose(); ci2.dispose(); } @Test public void intersectUnequal() { Caps c2 = Caps.fromString("video/x-raw,format=I420,width=20"); Caps c1 = Caps.fromString("video/x-raw,format=I420,width=30"); Caps ci1 = c2.intersect(c1); assertTrue("Intersection of unequal caps should be empty", ci1.isEmpty()); /* with changed order */ Caps ci2 = c1.intersect(c2); assertTrue("Intersection of unequal caps should be empty", ci1.isEmpty()); assertTrue("Intersection should be same in both directions", ci1.isEqual(ci2)); // Force cleanup to bring out any memory bugs c2.dispose(); c1.dispose(); ci1.dispose(); ci2.dispose(); } @Test public void intersectDifferentType() { Caps c2 = Caps.fromString("video/x-raw,format=I420,width=20"); Caps c1 = Caps.fromString("video/x-raw,format=RGB,width=20"); Caps ci1 = c2.intersect(c1); assertTrue("Intersection of different type caps should be empty", ci1.isEmpty()); /* with changed order */ Caps ci2 = c1.intersect(c2); assertTrue("Intersection of different type caps should be empty", ci1.isEmpty()); assertTrue("Intersection should be same in both directions", ci1.isEqual(ci2)); // Force cleanup to bring out any memory bugs c2.dispose(); c1.dispose(); ci1.dispose(); ci2.dispose(); } } ================================================ FILE: test/org/freedesktop/gstreamer/ClockTest.java ================================================ /* * Copyright (c) 2020 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . * */ package org.freedesktop.gstreamer; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * */ public class ClockTest { @BeforeClass public static void beforeClass() { Gst.init(Gst.getVersion()); } @AfterClass public static void afterClass() { Gst.deinit(); } @Test public void calibrationTest() { Pipeline pipe = (Pipeline) Gst.parseLaunch("autovideosrc ! autovideosink"); Clock clock = pipe.getClock(); Clock.Calibration cal1 = clock.getCalibration(); System.out.println(cal1); assertEquals(0, cal1.internal()); assertEquals(0, cal1.external()); assertEquals(1, cal1.rateNum()); assertEquals(1, cal1.rateDenom()); clock.setCalibration(-100, 1000, 8, 5); Clock.Calibration cal2 = clock.getCalibration(); System.out.println(cal2); assertEquals(-100, cal2.internal()); assertEquals(1000, cal2.external()); assertEquals(8, cal2.rateNum()); assertEquals(5, cal2.rateDenom()); Clock.Calibration cal3 = clock.getCalibration(); assertEquals(cal2, cal3); assertEquals(cal2.hashCode(), cal3.hashCode()); assertNotEquals(cal1, cal3); } } ================================================ FILE: test/org/freedesktop/gstreamer/ClockTimeTest.java ================================================ /* * Copyright (c) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import static org.junit.Assert.assertEquals; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; /** * * @author wayne */ public class ClockTimeTest { public ClockTimeTest() { } @BeforeClass public static void setUpClass() throws Exception { } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } @Test public void toSeconds() { final long TIME = TimeUnit.SECONDS.toNanos(0xdeadbeef); assertEquals("toSeconds returned incorrect value", TimeUnit.NANOSECONDS.toSeconds(TIME), ClockTime.toSeconds(TIME)); } @Test public void toMillis() { final long TIME = TimeUnit.SECONDS.toNanos(0xdeadbeef); assertEquals("toMillis returned incorrect value", TimeUnit.NANOSECONDS.toMillis(TIME), ClockTime.toMillis(TIME)); } @Test public void toMicros() { final long TIME = TimeUnit.SECONDS.toNanos(0xdeadbeef); assertEquals("toMillis returned incorrect value", TimeUnit.NANOSECONDS.toMicros(TIME), ClockTime.toMicros(TIME)); } @Test public void toStringRepresentation() { long hours = 3; long minutes = 27; long seconds = 13; long time = TimeUnit.HOURS.toNanos(hours) + TimeUnit.MINUTES.toNanos(minutes) + TimeUnit.SECONDS.toNanos(seconds); assertEquals("ClockTime.toString() incorrect", "03:27:13", ClockTime.toString(time)); } // @Test public void toNanos() { // final long TIME = TimeUnit.SECONDS.toNanos(0xdeadbeef); // ClockTime time = ClockTime.valueOf(TIME, TimeUnit.NANOSECONDS); // assertEquals("toNanos returned incorrect value", // TimeUnit.NANOSECONDS.toNanos(TIME), time.toNanos()); // assertEquals("convertTo returned incorrect value", // TimeUnit.NANOSECONDS.toNanos(TIME), time.convertTo(TimeUnit.NANOSECONDS)); // } // @Test public void compareTo() { // // Collections.sort uses compareTo() // List list = new ArrayList(); // list.add(ClockTime.valueOf(2, TimeUnit.SECONDS)); // list.add(ClockTime.valueOf(3, TimeUnit.SECONDS)); // list.add(ClockTime.valueOf(1, TimeUnit.SECONDS)); // Collections.sort(list); // assertEquals("list not sorted correctly", 1, list.get(0).toSeconds()); // assertEquals("list not sorted correctly", 2, list.get(1).toSeconds()); // assertEquals("list not sorted correctly", 3, list.get(2).toSeconds()); // } // } ================================================ FILE: test/org/freedesktop/gstreamer/ContextTest.java ================================================ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstContextAPI; import org.freedesktop.gstreamer.lowlevel.GstContextPtr; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; public class ContextTest { @BeforeClass public static void setUpClass() throws Exception { Gst.init("test"); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Test public void testConstruction() { GstContextAPI contextApi = GstContextAPI.GSTCONTEXT_API; String contextType = "whatever"; try (Context context = new Context(contextType)) { GstContextPtr gstContextPtr = Natives.getPointer(context).as(GstContextPtr.class, GstContextPtr::new); // Context type. Assert.assertEquals(contextType, context.getContextType()); Assert.assertTrue(contextApi.gst_context_has_context_type(gstContextPtr, contextType)); Assert.assertFalse(contextApi.gst_context_has_context_type(gstContextPtr, contextType + ".something-else")); // Default is persistent. Assert.assertTrue(contextApi.gst_context_is_persistent(gstContextPtr)); Assert.assertNotNull(context.getWritableStructure()); } } } ================================================ FILE: test/org/freedesktop/gstreamer/ElementFactoryTest.java ================================================ /* * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.lang.ref.WeakReference; import java.util.List; import org.freedesktop.gstreamer.ElementFactory.ListType; import org.freedesktop.gstreamer.PluginFeature.Rank; import org.freedesktop.gstreamer.elements.DecodeBin; import org.freedesktop.gstreamer.elements.PlayBin; import org.freedesktop.gstreamer.elements.URIDecodeBin; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; /** * * @author wayne */ @SuppressWarnings("deprecation") public class ElementFactoryTest { public ElementFactoryTest() { } @BeforeClass public static void setUpClass() throws Exception { Gst.init("test", new String[] {}); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { } @Test public void testMakeFakesink() { Element e = ElementFactory.make("fakesink", "sink"); assertNotNull("Failed to create fakesink", e); } @Test public void testMakeFakesrc() { Element e = ElementFactory.make("fakesrc", "source"); assertNotNull("Failed to create fakesrc", e); } @Test public void testMakeFilesink() { Element e = ElementFactory.make("filesink", "sink"); assertNotNull("Failed to create filesink", e); } @Test public void testMakeFilesrc() { Element e = ElementFactory.make("filesrc", "source"); assertNotNull("Failed to create filesrc", e); } @Test public void testMakeBin() { Element e = ElementFactory.make("bin", "bin"); assertNotNull("Failed to create bin", e); assertTrue("Element not a subclass of Bin", e instanceof Bin); } @Test public void testMakePipeline() { Element e = ElementFactory.make(Pipeline.GST_NAME, "bin"); assertNotNull("Failed to create " + Pipeline.GST_NAME, e); assertTrue("Element not a subclass of Bin", e instanceof Bin); assertTrue("Element not a subclass of Pipeline", e instanceof Pipeline); } @Test public void testMakePlaybin() { Element e = ElementFactory.make(PlayBin.GST_NAME, "bin"); assertNotNull("Failed to create " + PlayBin.GST_NAME, e); assertTrue("Element not a subclass of Bin", e instanceof Bin); assertTrue("Element not a subclass of Pipeline", e instanceof Pipeline); assertTrue("Element not a subclass of PlayBin", e instanceof PlayBin); } @Test public void testMakeDecodeBin() { Element e = ElementFactory.make(DecodeBin.GST_NAME, "bin"); assertNotNull("Failed to create " + DecodeBin.GST_NAME, e); assertTrue("Element not a subclass of Bin", e instanceof Bin); assertTrue("Element not a subclass of DecodeBin", e instanceof DecodeBin); } @Test public void testMakeURIDecodeBin() { Element e = ElementFactory.make(URIDecodeBin.GST_NAME, "bin"); assertNotNull("Failed to create " + URIDecodeBin.GST_NAME, e); assertTrue("Element not a subclass of Bin", e instanceof Bin); assertTrue("Element not a subclass of DecodeBin", e instanceof URIDecodeBin); } @Test public void testCreateFakesrc() { ElementFactory factory = ElementFactory.find("fakesrc"); assertNotNull("Could not locate fakesrc factory", factory); Element e = factory.create("source"); assertNotNull("Failed to create fakesrc", e); } @Test public void testCreateBin() { ElementFactory factory = ElementFactory.find("bin"); assertNotNull("Could not locate bin factory", factory); Element e = factory.create("bin"); assertNotNull("Failed to create bin", e); assertTrue("Element not a subclass of Bin", e instanceof Bin); } @Test public void testCreatePipeline() { ElementFactory factory = ElementFactory.find("pipeline"); assertNotNull("Could not locate pipeline factory", factory); Element e = factory.create("bin"); assertNotNull("Failed to create pipeline", e); assertTrue("Element not a subclass of Bin", e instanceof Bin); assertTrue("Element not a subclass of Pipeline", e instanceof Pipeline); } @Test public void testCreatePlaybin() { ElementFactory factory = ElementFactory.find("playbin"); assertNotNull("Could not locate pipeline factory", factory); System.out.println("PlayBin factory name=" + factory.getName()); Element e = factory.create("bin"); assertNotNull("Failed to create playbin", e); assertTrue("Element not a subclass of Bin", e instanceof Bin); assertTrue("Element not a subclass of Pipeline", e instanceof Pipeline); assertTrue("Element not a subclass of PlayBin", e instanceof PlayBin); } @Test public void testGarbageCollection() throws Throwable { ElementFactory factory = ElementFactory.find("fakesrc"); assertNotNull("Could not locate fakesrc factory", factory); WeakReference ref = new WeakReference(factory); factory = null; assertTrue("Factory not garbage collected", GCTracker.waitGC(ref)); } @Test public void testMakeGarbageCollection() throws Throwable { Element e = ElementFactory.make("fakesrc", "test"); WeakReference ref = new WeakReference(e); e = null; assertTrue("Element not garbage collected", GCTracker.waitGC(ref)); } @Test public void testCreateGarbageCollection() throws Throwable { ElementFactory factory = ElementFactory.find("fakesrc"); assertNotNull("Could not locate fakesrc factory", factory); Element e = factory.create("bin"); WeakReference ref = new WeakReference(e); e = null; assertTrue("Element not garbage collected", GCTracker.waitGC(ref)); } @Test public void getStaticPadTemplates() { ElementFactory f = ElementFactory.find("fakesink"); List templates = f.getStaticPadTemplates(); assertTrue("No static pad templates found", !templates.isEmpty()); StaticPadTemplate t = templates.get(0); assertEquals("Not a sink", "sink", t.getName()); assertEquals("Not a sink", PadDirection.SINK, t.getDirection()); } @Test public void listGetElement() { List list = ElementFactory.listGetElements(ListType.ANY, Rank.NONE); assertNotNull("List of factories is null", list); assertTrue("No factories found", !list.isEmpty()); // System.out.println("Factories >>>"); // for (ElementFactory fact : list) { // System.out.println(fact.getName()); // } // System.out.println("<<<"); } // @Test // public void filterList() { // List list = ElementFactory.listGetElements(ListType.ENCODER, // Rank.NONE); // assertNotNull("List of factories is null", list); // assertTrue("No factories found", !list.isEmpty()); // List filterList = ElementFactory.listFilter(list, new Caps("video/x-h263"), // PadDirection.SRC, false); // // assertNotNull("List of factories is null", filterList); // assertTrue("No factories found", !filterList.isEmpty()); //// System.out.println("Filtered factories >>>"); //// for (ElementFactory fact : filterList) { //// System.out.println(fact.getName()); //// } //// System.out.println("<<<"); // } @Test public void filterList2() { List list = ElementFactory.listGetElementsFilter(ListType.ENCODER, Rank.NONE, new Caps("video/x-h263"), PadDirection.SRC, false); assertNotNull("List of factories is null", list); assertTrue("No factories found", !list.isEmpty()); // System.out.println("Factories >>>"); // for (ElementFactory fact : list) { // System.out.println(fact.getName()); // } // System.out.println("<<<"); } @Test public void testMetaData() { ElementFactory f = ElementFactory.find("fakesink"); String klass = f.getKlass(); String longName = f.getLongName(); String description = f.getDescription(); String author = f.getAuthor(); assertNotNull("Klass is null", klass); assertNotNull("Long name is null", longName); assertNotNull("Description is null", description); assertNotNull("Author is null", author); System.out.println("FakeSink MetaData"); System.out.println("Klass : " + f.getKlass()); System.out.println("Long Name : " + f.getLongName()); System.out.println("Description : " + f.getDescription()); System.out.println("Author : " + f.getAuthor()); } } ================================================ FILE: test/org/freedesktop/gstreamer/ElementTest.java ================================================ /* * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.message.Message; import org.freedesktop.gstreamer.message.TagMessage; import org.junit.After; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; /** * * @author wayne */ public class ElementTest { public ElementTest() { } @BeforeClass public static void setUpClass() throws Exception { Gst.init("ElementTest", new String[] {}); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Before public void setUp() { } @After public void tearDown() { } // TODO add test methods here. // The methods must be annotated with annotation @Test. For example: // // @Test // public void hello() {} @Test public void getPads() { Element element = ElementFactory.make("fakesink", "fs"); List pads = element.getPads(); assertTrue("no pads found", !pads.isEmpty()); } @Test public void getSinkPads() { Element element = ElementFactory.make("fakesink", "fs"); List pads = element.getSinkPads(); assertTrue("no pads found", !pads.isEmpty()); } @Test public void getSrcPads() { Element element = ElementFactory.make("fakesrc", "fs"); List pads = element.getSrcPads(); assertTrue("no pads found", !pads.isEmpty()); } @Test public void setState() { Element element = ElementFactory.make("fakesrc", "fs"); // This should exercise EnumMapper.intValue() element.play(); element.stop(); } @Test public void getState() { Element element = ElementFactory.make("fakesrc", "fs"); // This should exercise EnumMapper.intValue() element.play(); State state = element.getState(-1); assertEquals("Element state not set correctly", State.PLAYING, state); element.stop(); } @Test public void postMessage() { final TestPipe pipe = new TestPipe(); final AtomicBoolean signalFired = new AtomicBoolean(false); // // Use a TagMessage, since it is the only type that doesn't get intercepted // by the pipeline // final Message message = new TagMessage(pipe.src, new TagList()); pipe.getBus().connect(new Bus.MESSAGE() { public void busMessage(Bus bus, Message msg) { if (msg.equals(message)) { signalFired.set(true); pipe.quit(); } } }); pipe.sink.postMessage(message); pipe.run(); assertTrue("Message not posted", signalFired.get()); } @Test public void testContext() { Element element = ElementFactory.make("fakesrc", "fs"); Assert.assertEquals(1, element.getRefCount()); Context context = new Context("test"); Assert.assertEquals(1, context.getRefCount()); element.setContext(context); Assert.assertEquals(2, context.getRefCount()); Context anotherContext = element.getContext("test"); Assert.assertEquals(2, anotherContext.getRefCount()); Assert.assertNotNull(anotherContext); Assert.assertEquals(context.getContextType(), anotherContext.getContextType()); Assert.assertNull(element.getContext("test-something-else")); element.dispose(); Assert.assertEquals(0, element.getRefCount()); Assert.assertEquals(1, context.getRefCount()); Assert.assertEquals(1, anotherContext.getRefCount()); } } ================================================ FILE: test/org/freedesktop/gstreamer/EnumTest.java ================================================ /* * Copyright (c) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import static org.junit.Assert.assertEquals; import org.freedesktop.gstreamer.lowlevel.EnumMapper; import org.freedesktop.gstreamer.lowlevel.annotations.DefaultEnumValue; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; /** * * @author wayne */ public class EnumTest { public EnumTest() { } @BeforeClass public static void setUpClass() throws Exception { Gst.init("EnumTest", new String[] {}); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Before public void setUp() { } @After public void tearDown() { } private static enum TestEnum { FOO, @DefaultEnumValue BAR; } // TODO add test methods here. // The methods must be annotated with annotation @Test. For example: // // @Test // public void hello() {} @Test public void valueOfInt() { TestEnum e = EnumMapper.getInstance().valueOf(0xdeadbeef, TestEnum.class); assertEquals("Wrong value returned for the default", TestEnum.BAR, e); } } ================================================ FILE: test/org/freedesktop/gstreamer/ExecutorServiceTest.java ================================================ /* * Copyright (c) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import org.freedesktop.gstreamer.glib.MainContextExecutorService; import org.freedesktop.gstreamer.lowlevel.MainLoop; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; /** * * @author wayne */ public class ExecutorServiceTest { public ExecutorServiceTest() { } private static MainLoop loop; @BeforeClass public static void setUpClass() throws Exception { Gst.init("ExecutorServiceTest", new String[] {}); (loop = new MainLoop()).startInBackground(); } @AfterClass public static void tearDownClass() throws Exception { loop.quit(); Gst.deinit(); } @Before public void setUp() { } @After public void tearDown() { } private static class TestExec { private final CountDownLatch latch = new CountDownLatch(1); final MainContextExecutorService exec = new MainContextExecutorService(Gst.getMainContext()); final AtomicBoolean fired = new AtomicBoolean(false); public TestExec run() { // Create a timer to quit out of the test so it does not hang try { latch.await(250, TimeUnit.MILLISECONDS); } catch (Exception ex) {} return this; } public void execute(Runnable run) { exec.execute(run); } public void quit() { latch.countDown(); } public void fired() { fired.set(true); quit(); } public boolean hasFired() { return fired.get(); } } @Test public void execute() { final TestExec exec = new TestExec(); exec.execute(new Runnable() { public void run() { exec.fired(); } }); exec.run(); assertTrue("Runnable not called", exec.hasFired()); } @Test public void submit() throws Exception { final TestExec exec = new TestExec(); final Integer MAGIC = 0xdeadbeef; Callable callable = new Callable() { public Integer call() throws Exception { exec.fired(); return MAGIC; } }; Future f = exec.exec.submit(callable); exec.run(); assertTrue("Callable not called", exec.hasFired()); assertEquals("Wrong value returned from Callable", MAGIC, f.get()); } @Test public void oneShotTimeout() { final TestExec exec = new TestExec(); exec.exec.schedule(new Runnable() { public void run() { exec.fired(); } }, 100, TimeUnit.MILLISECONDS); exec.run(); assertTrue("Runnable not called", exec.hasFired()); } @Test public void timeoutWithReturnValue() throws Exception { final TestExec exec = new TestExec(); final Integer MAGIC = 0xdeadbeef; Callable callable = new Callable() { public Integer call() throws Exception { exec.fired(); return MAGIC; } }; Future f = exec.exec.schedule(callable, 100, TimeUnit.MILLISECONDS); exec.run(); assertTrue("Runnable not called", exec.hasFired()); assertEquals("Wrong value returned from Callable", MAGIC, f.get()); } @Test public void periodicTimeout() { final TestExec exec = new TestExec(); final AtomicBoolean called = new AtomicBoolean(false); exec.exec.scheduleAtFixedRate(new Runnable() { public void run() { if (called.getAndSet(true)) { exec.fired(); } } }, 10, 10, TimeUnit.MILLISECONDS); exec.run(); assertTrue("Runnable not called", exec.hasFired()); } } ================================================ FILE: test/org/freedesktop/gstreamer/GCTracker.java ================================================ /* * Copyright (C) 2020 Neil C Smith * Copyright (C) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import java.lang.ref.WeakReference; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import com.sun.jna.Pointer; import org.freedesktop.gstreamer.glib.GObject; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstMiniObjectPtr; import org.freedesktop.gstreamer.lowlevel.IntPtr; import static org.freedesktop.gstreamer.lowlevel.GObjectAPI.*; import static org.freedesktop.gstreamer.lowlevel.GstMiniObjectAPI.*; /** * Tracks Java and/or native disposal of GObject and MiniObject derived objects. */ public class GCTracker { private static final Map> OBJ_MAP = Collections.synchronizedMap(new HashMap>()); private final WeakReference ref; private final AtomicBoolean destroyed = new AtomicBoolean(false); public GCTracker(GObject obj) { int identityHashCode = System.identityHashCode(this); ref = new WeakReference<>(obj); OBJ_MAP.put(identityHashCode, new WeakReference<>(this)); GOBJECT_API.g_object_weak_ref(obj, GOBJECT_NOTIFY, new IntPtr(identityHashCode)); } public GCTracker(MiniObject obj) { int identityHashCode = System.identityHashCode(this); ref = new WeakReference<>(obj); OBJ_MAP.put(identityHashCode, new WeakReference<>(this)); GSTMINIOBJECT_API.gst_mini_object_weak_ref( Natives.getPointer(obj).as(GstMiniObjectPtr.class, GstMiniObjectPtr::new), GSTMINIOBJECT_NOTIFY, new IntPtr(identityHashCode)); } public boolean waitGC() { return waitGC(ref); } public boolean waitDestroyed() { for (int i = 0; !destroyed.get() && i < 10; ++i) { try { Thread.sleep(100); } catch (InterruptedException ex) { } } return destroyed.get(); } private static final GWeakNotify GOBJECT_NOTIFY = new GWeakNotify() { @Override public void callback(IntPtr id, Pointer obj) { int identityHashCode = id.intValue(); WeakReference trackerRef = OBJ_MAP.get(identityHashCode); GCTracker tracker = trackerRef.get(); if (tracker != null) { tracker.destroyed.set(true); } } }; private static final GstMiniObjectNotify GSTMINIOBJECT_NOTIFY = new GstMiniObjectNotify() { @Override public void callback(IntPtr id, Pointer obj) { int identityHashCode = id.intValue(); WeakReference trackerRef = OBJ_MAP.get(identityHashCode); GCTracker tracker = trackerRef.get(); if (tracker != null) { tracker.destroyed.set(true); } } }; public static boolean waitGC(WeakReference ref) { System.gc(); for (int i = 0; ref.get() != null && i < 10; ++i) { try { Thread.sleep(10); } catch (InterruptedException ex) { } System.gc(); } return ref.get() == null; } } ================================================ FILE: test/org/freedesktop/gstreamer/GLibTest.java ================================================ /* * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.GLib; import static org.junit.Assert.assertEquals; import org.junit.Test; public class GLibTest { @Test public void getEnv() { String user = GLib.getEnv("USER"); String pwd = GLib.getEnv("PWD"); System.out.println("user: " + user); System.out.println("path: " + pwd); } @Test public void setUnsetEnv() { // set environment GLib.setEnv("TESTVAR", "foo", true); // get environment assertEquals("could not set TESTVAR!", GLib.getEnv("TESTVAR"), "foo"); // unset GLib.unsetEnv("TESTVAR"); assertEquals("could not unset TESTVAR!", GLib.getEnv("TESTVAR"), null); } } ================================================ FILE: test/org/freedesktop/gstreamer/GarbageCollectionEDTTest.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import java.lang.ref.WeakReference; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** * */ public class GarbageCollectionEDTTest { public GarbageCollectionEDTTest() { } @BeforeClass public static void setUpClass() throws Exception { System.setProperty("glib.reapOnEDT", "true"); Gst.init("test", new String[]{}); } @AfterClass public static void tearDownClass() throws Exception { // Gst.deinit(); } @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { } @Test public void testElement() throws Exception { Element e = ElementFactory.make("fakesrc", "test element"); GCTracker tracker = new GCTracker(e); e = null; assertTrue("Element not garbage collected", tracker.waitGC()); assertTrue("GObject not destroyed", tracker.waitDestroyed()); } @Test public void testBin() throws Exception { Bin bin = new Bin("test"); Element e1 = ElementFactory.make("fakesrc", "source"); Element e2 = ElementFactory.make("fakesink", "sink"); bin.addMany(e1, e2); assertEquals("source not returned", e1, bin.getElementByName("source")); assertEquals("sink not returned", e2, bin.getElementByName("sink")); WeakReference binRef = new WeakReference(bin); bin = null; assertTrue("Bin not garbage collected", GCTracker.waitGC(binRef)); WeakReference e1Ref = new WeakReference(e1); WeakReference e2Ref = new WeakReference(e2); e1 = null; e2 = null; assertTrue("First Element not garbage collected", GCTracker.waitGC(e1Ref)); assertTrue("Second Element not garbage collected", GCTracker.waitGC(e2Ref)); } @Test public void testBinRetrieval() throws Exception { Bin bin = new Bin("test"); Element e1 = ElementFactory.make("fakesrc", "source"); Element e2 = ElementFactory.make("fakesink", "sink"); bin.addMany(e1, e2); int id1 = System.identityHashCode(e1); int id2 = System.identityHashCode(e2); e1 = null; e2 = null; System.gc(); Thread.sleep(10); // Should return the same object that was put into the bin assertEquals("source ID does not match", id1, System.identityHashCode(bin.getElementByName("source"))); assertEquals("sink ID does not match", id2, System.identityHashCode(bin.getElementByName("sink"))); } @Test public void pipeline() { Pipeline pipe = new Pipeline("test"); GCTracker pipeTracker = new GCTracker(pipe); pipe = null; assertTrue("Pipe not garbage collected", pipeTracker.waitGC()); System.out.println("checking if pipeline is destroyed"); assertTrue("Pipe not destroyed", pipeTracker.waitDestroyed()); } @Test public void pipelineBus() { Pipeline pipe = new Pipeline("test"); Bus bus = pipe.getBus(); GCTracker busTracker = new GCTracker(bus); GCTracker pipeTracker = new GCTracker(pipe); pipe = null; bus = null; assertTrue("Bus not garbage collected", busTracker.waitGC()); assertTrue("Bus not destroyed", busTracker.waitDestroyed()); assertTrue("Pipe not garbage collected", pipeTracker.waitGC()); assertTrue("Pipe not destroyed", pipeTracker.waitDestroyed()); } @Test public void busWithListeners() { Pipeline pipe = new Pipeline("test"); Bus bus = pipe.getBus(); bus.connect(new Bus.EOS() { public void endOfStream(GstObject source) { } }); GCTracker busTracker = new GCTracker(bus); GCTracker pipeTracker = new GCTracker(pipe); bus = null; pipe = null; assertTrue("Bus not garbage collected", busTracker.waitGC()); assertTrue("Bus not destroyed", busTracker.waitDestroyed()); assertTrue("Pipe not garbage collected", pipeTracker.waitGC()); assertTrue("Pipe not destroyed", pipeTracker.waitDestroyed()); } } ================================================ FILE: test/org/freedesktop/gstreamer/GarbageCollectionTest.java ================================================ /* * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.lang.ref.WeakReference; import java.util.List; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; /** * * @author wayne */ public class GarbageCollectionTest { public GarbageCollectionTest() { } @BeforeClass public static void setUpClass() throws Exception { Gst.init("test", new String[] {}); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { } @Test public void testElement() throws Exception { Element e = ElementFactory.make("fakesrc", "test element"); GCTracker tracker = new GCTracker(e); e = null; assertTrue("Element not garbage collected", tracker.waitGC()); assertTrue("GObject not destroyed", tracker.waitDestroyed()); } @Test public void testBin() throws Exception { Bin bin = new Bin("test"); Element e1 = ElementFactory.make("fakesrc", "source"); Element e2 = ElementFactory.make("fakesink", "sink"); bin.addMany(e1, e2); assertEquals("source not returned", e1, bin.getElementByName("source")); assertEquals("sink not returned", e2, bin.getElementByName("sink")); GCTracker binTracker = new GCTracker(bin); bin = null; assertTrue("Bin not garbage collected", binTracker.waitGC()); assertTrue("Bin not destroyed", binTracker.waitDestroyed()); GCTracker e1Tracker = new GCTracker(e1); GCTracker e2Tracker = new GCTracker(e2); e1 = null; e2 = null; assertTrue("First Element not garbage collected", e1Tracker.waitGC()); assertTrue("First Element not destroyed", e1Tracker.waitDestroyed()); assertTrue("Second Element not garbage collected", e2Tracker.waitGC()); assertTrue("Second Element not destroyed", e2Tracker.waitDestroyed()); } @Test public void testBinParsed() throws Exception { Bin bin = Gst.parseBinFromDescription("fakesrc name=source ! fakesink name=sink", false); int binRefCount = bin.getRefCount(); List children = bin.getElements(); assertEquals("Iteration increased Bin refcount", binRefCount, bin.getRefCount()); assertEquals("Wrong number of child elements", 2, children.size()); Element e1 = children.get(0); Element e2 = children.get(1); GCTracker binTracker = new GCTracker(bin); bin = null; assertTrue("Bin not garbage collected", binTracker.waitGC()); assertTrue("Bin not destroyed", binTracker.waitDestroyed()); GCTracker e1Tracker = new GCTracker(e1); GCTracker e2Tracker = new GCTracker(e2); children = null; e1 = null; e2 = null; assertTrue("First Element not garbage collected", e1Tracker.waitGC()); assertTrue("First Element not destroyed", e1Tracker.waitDestroyed()); assertTrue("Second Element not garbage collected", e2Tracker.waitGC()); assertTrue("Second Element not destroyed", e2Tracker.waitDestroyed()); } @Test public void testBinRetrieval() throws Exception { Bin bin = new Bin("test"); Element e1 = ElementFactory.make("fakesrc", "source"); Element e2 = ElementFactory.make("fakesink", "sink"); bin.addMany(e1, e2); int id1 = System.identityHashCode(e1); int id2 = System.identityHashCode(e2); e1 = null; e2 = null; System.gc(); Thread.sleep(10); // Should return the same object that was put into the bin assertEquals("source ID does not match", id1, System.identityHashCode(bin.getElementByName("source"))); assertEquals("sink ID does not match", id2, System.identityHashCode(bin.getElementByName("sink"))); } @Test public void pipeline() { Pipeline pipe = new Pipeline("test"); GCTracker pipeTracker = new GCTracker(pipe); pipe = null; assertTrue("Pipe not garbage collected", pipeTracker.waitGC()); System.out.println("checking if pipeline is destroyed"); assertTrue("Pipe not destroyed", pipeTracker.waitDestroyed()); } @Test public void pipelineBus() { Pipeline pipe = new Pipeline("test"); Bus bus = pipe.getBus(); GCTracker busTracker = new GCTracker(bus); GCTracker pipeTracker = new GCTracker(pipe); pipe = null; bus = null; assertTrue("Bus not garbage collected", busTracker.waitGC()); assertTrue("Bus not destroyed", busTracker.waitDestroyed()); assertTrue("Pipe not garbage collected", pipeTracker.waitGC()); assertTrue("Pipe not destroyed", pipeTracker.waitDestroyed()); } @Test public void busWithListeners() { Pipeline pipe = new Pipeline("test"); Bus bus = pipe.getBus(); bus.connect(new Bus.EOS() { public void endOfStream(GstObject source) { } }); GCTracker busTracker = new GCTracker(bus); GCTracker pipeTracker = new GCTracker(pipe); bus = null; pipe = null; assertTrue("Bus not garbage collected", busTracker.waitGC()); assertTrue("Bus not destroyed", busTracker.waitDestroyed()); assertTrue("Pipe not garbage collected", pipeTracker.waitGC()); assertTrue("Pipe not destroyed", pipeTracker.waitDestroyed()); } } ================================================ FILE: test/org/freedesktop/gstreamer/GhostPadTest.java ================================================ /* * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; /** * * @author wayne */ public class GhostPadTest { public GhostPadTest() { } @BeforeClass public static void setUpClass() throws Exception { Gst.init("GhostPadTest", new String[] {}); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Before public void setUp() { } @After public void tearDown() { } // TODO add test methods here. // The methods must be annotated with annotation @Test. For example: // // @Test // public void hello() {} @Test public void newGhostPad() { Element fakesink = ElementFactory.make("fakesink", "fs"); @SuppressWarnings("unused") GhostPad gpad = new GhostPad("ghostsink", fakesink.getStaticPad("sink")); } } ================================================ FILE: test/org/freedesktop/gstreamer/GobjectSubclassTest.java ================================================ /* * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.lowlevel.BaseSrcAPI; import org.freedesktop.gstreamer.lowlevel.GObjectAPI; import org.freedesktop.gstreamer.lowlevel.GType; import org.freedesktop.gstreamer.lowlevel.GObjectAPI.GClassInitFunc; import org.freedesktop.gstreamer.lowlevel.GObjectAPI.GInstanceInitFunc; import org.freedesktop.gstreamer.lowlevel.GObjectAPI.GTypeInstance; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import com.sun.jna.Pointer; import static org.junit.Assert.assertEquals; import static org.freedesktop.gstreamer.lowlevel.GObjectAPI.GOBJECT_API; import static org.freedesktop.gstreamer.lowlevel.GstPadTemplateAPI.GSTPADTEMPLATE_API; /** * * @author wayne */ public class GobjectSubclassTest { public GobjectSubclassTest() { } @BeforeClass public static void setUpClass() throws Exception { // GObjectAPI.gobj.g_type_init_with_debug_flags(1 << 0); Gst.init("test", new String[] {}); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { } @Test public void registerNewGObjectClass() throws Exception { final PadTemplate template = new PadTemplate("src", PadDirection.SRC, Caps.anyCaps()); final boolean[] classInitCalled = { false }; final GClassInitFunc classInit = new GClassInitFunc() { public void callback(Pointer g_class, Pointer class_data) { classInitCalled[0] = true; } }; final GObjectAPI.GBaseInitFunc baseInit = new GObjectAPI.GBaseInitFunc() { public void callback(Pointer g_class) { GSTPADTEMPLATE_API.gst_element_class_add_pad_template(g_class, template); } }; final boolean[] instanceInitCalled = { false }; final GInstanceInitFunc instanceInit = new GInstanceInitFunc() { public void callback(GTypeInstance instance, Pointer g_class) { instanceInitCalled[0] = true; } }; final String name = "NewTestClass"; GObjectAPI.GTypeInfo info = new GObjectAPI.GTypeInfo(); info.clear(); info.class_init = classInit; info.instance_init = instanceInit; info.class_size = (short)new BaseSrcAPI.GstBaseSrcClass().size(); info.instance_size = (short)new BaseSrcAPI.GstBaseSrcStruct().size(); info.class_size = 1024; info.base_init = baseInit; info.instance_size = 1024; GType type = GOBJECT_API.g_type_register_static(BaseSrcAPI.BASESRC_API.gst_base_src_get_type(), name, info, 0); System.out.println("New type=" + type); assertEquals("Name incorrect", name, GOBJECT_API.g_type_name(type)); assertEquals("Cannot locate type by name", type, GOBJECT_API.g_type_from_name(name)); //Pointer instance = GOBJECT_API.g_type_create_instance(type); GOBJECT_API.g_object_new(type, new Object[0]); } } ================================================ FILE: test/org/freedesktop/gstreamer/GstTypesTest.java ================================================ /* * Copyright (c) 2016 Christophe Lafolet * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GObjectPtr; import static org.junit.Assert.assertEquals; import org.freedesktop.gstreamer.lowlevel.GType; import org.freedesktop.gstreamer.lowlevel.GstTypes; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; public class GstTypesTest { public GstTypesTest() { } @BeforeClass public static void setUpClass() throws Exception { Gst.init("GstTypesTest", new String[] {}); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Before public void setUp() { } @After public void tearDown() { } @Test public void registeredClassTest() { // check a registered class GType elementType = GType.valueOf(Element.GTYPE_NAME); assertEquals(Element.class, GstTypes.classFor(elementType)); assertEquals(elementType, GstTypes.typeFor(Element.class)); } @Test public void unregisteredClassTest() { GType elementType = GType.valueOf(Element.GTYPE_NAME); // check a unregistered class which derived from Element Element anElement = ElementFactory.make("avidemux", "avidemux"); // assertEquals(Element.class, GstTypes.classFor(anElement.getType())); assertEquals(Element.class, GstTypes.classFor( Natives.getPointer(anElement) .as(GObjectPtr.class, GObjectPtr::new).getGType())); // verify GType has not changed for Element.class assertEquals(elementType, GstTypes.typeFor(Element.class)); } } ================================================ FILE: test/org/freedesktop/gstreamer/InitTest.java ================================================ /* * Copyright (c) 2025 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import static org.junit.Assert.assertTrue; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; /** * */ public class InitTest { public InitTest() { } @Test public void testInit() { Version available = Gst.getVersion(); Version notAvailable = Version.of(available.getMajor(), available.getMinor() + 2); try { Gst.init(notAvailable); assertTrue("Version check exception not thrown!", false); } catch (GstException ex) { System.out.println("Expected init failure"); System.out.println(ex); } String[] args = Gst.init(available, "InitTest", "--gst-debug-no-color"); assertTrue(args.length == 0); assertTrue(Gst.testVersion(available.getMajor(), available.getMinor())); assertTrue(Gst.testVersion(available.getMajor(), available.getMinor() - 2)); assertTrue(!Gst.testVersion(notAvailable.getMajor(), notAvailable.getMinor())); Gst.deinit(); } @BeforeClass public static void setUpClass() throws Exception { } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { } } ================================================ FILE: test/org/freedesktop/gstreamer/MessageTest.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (c) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import org.freedesktop.gstreamer.message.BufferingMessage; import org.freedesktop.gstreamer.message.DurationChangedMessage; import org.freedesktop.gstreamer.message.EOSMessage; import org.freedesktop.gstreamer.message.LatencyMessage; import org.freedesktop.gstreamer.message.Message; import org.freedesktop.gstreamer.message.MessageType; import org.freedesktop.gstreamer.message.SegmentDoneMessage; import org.freedesktop.gstreamer.message.StateChangedMessage; import org.freedesktop.gstreamer.message.TagMessage; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.freedesktop.gstreamer.lowlevel.GstElementAPI.GSTELEMENT_API; import static org.freedesktop.gstreamer.lowlevel.GstMessageAPI.GSTMESSAGE_API; import static org.freedesktop.gstreamer.lowlevel.GstTagListAPI.GSTTAGLIST_API; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; /** * */ public class MessageTest { public MessageTest() { } @BeforeClass public static void setUpClass() throws Exception { Gst.init("MessageTest"); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Before public void setUp() { } @After public void tearDown() { } @Test public void gst_message_new_eos() { Element fakesink = ElementFactory.make("fakesink", "sink"); Message msg = GSTMESSAGE_API.gst_message_new_eos(fakesink); assertTrue("gst_message_new_eos did not return an instance of EOSMessage", msg instanceof EOSMessage); } @Test public void EOSMessage_getSource() { Element fakesink = ElementFactory.make("fakesink", "sink"); Message msg = GSTMESSAGE_API.gst_message_new_eos(fakesink); assertEquals("Wrong source in message", fakesink, msg.getSource()); } @Test public void postEOS() { final TestPipe pipe = new TestPipe(); final AtomicBoolean signalFired = new AtomicBoolean(false); final AtomicReference signalMessage = new AtomicReference<>(null); pipe.getBus().connect("message::eos", new Bus.MESSAGE() { @Override public void busMessage(Bus bus, Message msg) { signalFired.set(true); signalMessage.set(msg); pipe.quit(); } }); pipe.play(); GSTELEMENT_API.gst_element_post_message(pipe.sink, new EOSMessage(pipe.sink)); pipe.run(); Message msg = signalMessage.get(); assertNotNull("No message available on bus", msg); assertEquals("Wrong message type", MessageType.EOS, msg.getType()); assertTrue("Message not intance of EOSMessage", msg instanceof EOSMessage); assertEquals("Wrong source in message", pipe.pipe, msg.getSource()); pipe.dispose(); } @Test public void gst_message_new_percent() { Element fakesink = ElementFactory.make("fakesink", "sink"); Message msg = GSTMESSAGE_API.gst_message_new_buffering(fakesink, 55); assertTrue("gst_message_new_eos did not return an instance of BufferingMessage", msg instanceof BufferingMessage); } @Test public void BufferingMessage_getPercent() { Element fakesink = ElementFactory.make("fakesink", "sink"); BufferingMessage msg = (BufferingMessage) GSTMESSAGE_API.gst_message_new_buffering(fakesink, 55); assertEquals("Wrong source in message", 55, msg.getPercent()); } @Test public void postBufferingMessage() { final TestPipe pipe = new TestPipe(); final AtomicBoolean signalFired = new AtomicBoolean(false); final AtomicReference signalMessage = new AtomicReference<>(null); pipe.getBus().connect("message::buffering", new Bus.MESSAGE() { public void busMessage(Bus bus, Message msg) { signalFired.set(true); signalMessage.set(msg); pipe.quit(); } }); final int PERCENT = 55; GSTELEMENT_API.gst_element_post_message(pipe.sink, new BufferingMessage(pipe.src, PERCENT)); pipe.run(); Message msg = signalMessage.get(); assertNotNull("No message available on bus", msg); assertEquals("Wrong message type", MessageType.BUFFERING, msg.getType()); assertTrue("Message not instance of BufferingMessage", msg instanceof BufferingMessage); assertEquals("Wrong source in message", pipe.src, msg.getSource()); assertEquals("Wrong percent value in message", PERCENT, ((BufferingMessage) msg).getPercent()); pipe.dispose(); } @Test public void gst_message_new_duration() { Element fakesink = ElementFactory.make("fakesink", "sink"); Message msg = GSTMESSAGE_API.gst_message_new_duration_changed(fakesink); assertTrue("gst_message_new_duration did not return an instance of DurationMessage", msg instanceof DurationChangedMessage); } @Test public void postDurationMessage() { final TestPipe pipe = new TestPipe(); final AtomicBoolean signalFired = new AtomicBoolean(false); final AtomicReference signalMessage = new AtomicReference<>(null); pipe.getBus().connect("message::duration-changed", new Bus.MESSAGE() { @Override public void busMessage(Bus bus, Message msg) { signalFired.set(true); signalMessage.set(msg); pipe.quit(); } }); GSTELEMENT_API.gst_element_post_message(pipe.src, new DurationChangedMessage(pipe.src)); pipe.play().run(); Message msg = signalMessage.get(); assertNotNull("No message available on bus", msg); assertEquals("Wrong message type", MessageType.DURATION_CHANGED, msg.getType()); assertTrue("Message not instance of EOSMessage", msg instanceof DurationChangedMessage); assertEquals("Wrong source in message", pipe.src, msg.getSource()); pipe.dispose(); } @Test public void gst_message_new_tag() { Element src = ElementFactory.make("fakesrc", "src"); Message msg = GSTMESSAGE_API.gst_message_new_tag(src, new TagList()); assertTrue("gst_message_new_tag did not return an instance of TagMessage", msg instanceof TagMessage); } @Test public void TagMessage_getTagList() { Element src = ElementFactory.make("fakesrc", "src"); TagList tl = new TagList(); final String MAGIC = "fubar"; GSTTAGLIST_API.gst_tag_list_add(tl, TagMergeMode.APPEND, "artist", MAGIC); TagMessage msg = (TagMessage) GSTMESSAGE_API.gst_message_new_tag(src, tl); tl = msg.getTagList(); assertEquals("Wrong artist in tag list", MAGIC, tl.getString("artist", 0)); } @Test public void gst_message_new_state_changed() { Element src = ElementFactory.make("fakesrc", "src"); Message msg = GSTMESSAGE_API.gst_message_new_state_changed(src, State.READY, State.PLAYING, State.VOID_PENDING); assertTrue("gst_message_new_state_changed did not return an instance of StateChangedMessage", msg instanceof StateChangedMessage); } @Test public void constructStateChanged() { Element src = ElementFactory.make("fakesrc", "src"); new StateChangedMessage(src, State.READY, State.PLAYING, State.VOID_PENDING); } @Test public void StateChanged_get() { Element src = ElementFactory.make("fakesrc", "src"); StateChangedMessage msg = (StateChangedMessage) GSTMESSAGE_API.gst_message_new_state_changed(src, State.READY, State.PLAYING, State.VOID_PENDING); assertEquals("Wrong old state", State.READY, msg.getOldState()); assertEquals("Wrong new state", State.PLAYING, msg.getNewState()); assertEquals("Wrong pending state", State.VOID_PENDING, msg.getPendingState()); } @Test public void postStateChangedMessage() { final TestPipe pipe = new TestPipe(); final AtomicBoolean signalFired = new AtomicBoolean(false); final AtomicReference signalMessage = new AtomicReference(null); pipe.getBus().connect("message::state-changed", new Bus.MESSAGE() { public void busMessage(Bus bus, Message msg) { signalFired.set(true); signalMessage.set(msg); pipe.quit(); } }); GSTELEMENT_API.gst_element_post_message(pipe.src, new StateChangedMessage(pipe.src, State.READY, State.PLAYING, State.VOID_PENDING)); pipe.run(); Message msg = signalMessage.get(); assertNotNull("No message available on bus", msg); assertEquals("Wrong message type", MessageType.STATE_CHANGED, msg.getType()); StateChangedMessage smsg = (StateChangedMessage) msg; assertEquals("Wrong old state", State.READY, smsg.getOldState()); assertEquals("Wrong new state", State.PLAYING, smsg.getNewState()); assertEquals("Wrong pending state", State.VOID_PENDING, smsg.getPendingState()); pipe.dispose(); } @Test public void gst_message_new_segment_done() { Element src = ElementFactory.make("fakesrc", "src"); Message msg = GSTMESSAGE_API.gst_message_new_segment_done(src, Format.TIME, 0xdeadbeef); assertTrue("gst_message_new_segment_done did not return an instance of SegmentDoneMessage", msg instanceof SegmentDoneMessage); } @Test public void constructSegmentDone() { Element src = ElementFactory.make("fakesrc", "src"); new SegmentDoneMessage(src, Format.TIME, 0xdeadbeef); } @Test public void parseSegmentDone() { Element src = ElementFactory.make("fakesrc", "src"); SegmentDoneMessage msg = (SegmentDoneMessage) GSTMESSAGE_API.gst_message_new_segment_done(src, Format.TIME, 0xdeadbeef); assertEquals("Wrong format", Format.TIME, msg.getFormat()); assertEquals("Wrong position", 0xdeadbeef, msg.getPosition()); } @Test public void postSegmentDoneMessage() { final TestPipe pipe = new TestPipe(); final AtomicBoolean signalFired = new AtomicBoolean(false); final AtomicReference signalMessage = new AtomicReference<>(null); pipe.getBus().connect("message::segment-done", new Bus.MESSAGE() { public void busMessage(Bus bus, Message msg) { signalFired.set(true); signalMessage.set(msg); pipe.quit(); } }); final int POSITION = 0xdeadbeef; GSTELEMENT_API.gst_element_post_message(pipe.src, new SegmentDoneMessage(pipe.src, Format.TIME, POSITION)); pipe.run(); Message msg = signalMessage.get(); assertNotNull("No message available on bus", msg); assertEquals("Wrong message type", MessageType.SEGMENT_DONE, msg.getType()); SegmentDoneMessage smsg = (SegmentDoneMessage) msg; assertEquals("Wrong format", Format.TIME, smsg.getFormat()); assertEquals("Wrong position", POSITION, smsg.getPosition()); pipe.dispose(); } @Test public void postLatencyMessage() { final TestPipe pipe = new TestPipe(); final AtomicBoolean signalFired = new AtomicBoolean(false); final AtomicReference signalMessage = new AtomicReference<>(null); pipe.getBus().connect("message::latency", new Bus.MESSAGE() { @Override public void busMessage(Bus bus, Message msg) { signalFired.set(true); signalMessage.set(msg); pipe.quit(); } }); GSTELEMENT_API.gst_element_post_message(pipe.src, new LatencyMessage(pipe.src)); pipe.run(); Message msg = signalMessage.get(); assertNotNull("No message available on bus", msg); assertEquals("Wrong message type", MessageType.LATENCY, msg.getType()); @SuppressWarnings("unused") LatencyMessage smsg = (LatencyMessage) msg; pipe.dispose(); } } ================================================ FILE: test/org/freedesktop/gstreamer/PadProbeTypeTest.java ================================================ /* * Copyright (c) 2020 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import java.lang.reflect.Field; import java.util.Set; import org.freedesktop.gstreamer.glib.NativeFlags; import org.freedesktop.gstreamer.lowlevel.GstPadAPI; import org.junit.Test; import static org.junit.Assert.*; public class PadProbeTypeTest { @Test public void testCombinations() throws Exception { for (Field field : PadProbeType.class.getFields()) { if (Set.class.isAssignableFrom(field.getType())) { Set flags = (Set) field.get(null); // System.out.println(field.getName() + " : " + flags); Field nativeField = GstPadAPI.class.getField("GST_PAD_PROBE_TYPE_" + field.getName()); assertEquals(NativeFlags.toInt(flags), nativeField.get(null)); } } } } ================================================ FILE: test/org/freedesktop/gstreamer/PadTemplateTest.java ================================================ /* * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import org.junit.After; import org.junit.AfterClass; import static org.junit.Assert.assertEquals; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; /** * * @author inx */ public class PadTemplateTest { @BeforeClass public static void setUpClass() throws Exception { Gst.init("test", new String[] {}); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { } @Test public void padTemplate() throws Exception { Element src = ElementFactory.make("fakesrc", "src"); Element sink = ElementFactory.make("fakesink", "sink"); Pad srcPad = src.getStaticPad("src"); Pad sinkPad = sink.getStaticPad("sink"); PadTemplate template; template = srcPad.getTemplate(); assertEquals("wrong name!", template.getTemplateName(), "src"); assertEquals("wrong direction!", template.getDirection(), PadDirection.SRC); assertEquals("wrong presence!", template.getPresence(), PadPresence.ALWAYS); template = sinkPad.getTemplate(); assertEquals("wrong name!", template.getTemplateName(), "sink"); assertEquals("wrong direction!", template.getDirection(), PadDirection.SINK); assertEquals("wrong presence!", template.getPresence(), PadPresence.ALWAYS); } } ================================================ FILE: test/org/freedesktop/gstreamer/PadTest.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.event.Event; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; import java.lang.ref.WeakReference; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import org.freedesktop.gstreamer.event.FlushStopEvent; import org.freedesktop.gstreamer.event.TagEvent; import org.freedesktop.gstreamer.query.AllocationQuery; import org.freedesktop.gstreamer.query.Query; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; /** * */ public class PadTest { public PadTest() { } @BeforeClass public static void setUpClass() throws Exception { Gst.init("test", new String[]{}); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { } @Test public void getPad() throws Exception { Element src = ElementFactory.make("fakesrc", "src"); Element sink = ElementFactory.make("fakesink", "sink"); Pad srcPad = src.getStaticPad("src"); Pad sinkPad = sink.getStaticPad("sink"); assertNotNull("Could not get src pad", srcPad); assertNotNull("Could not get sink pad", sinkPad); src = null; sink = null; WeakReference srcRef = new WeakReference<>(srcPad); WeakReference sinkRef = new WeakReference<>(sinkPad); srcPad = null; sinkPad = null; assertTrue("Src pad not garbage collected", GCTracker.waitGC(srcRef)); assertTrue("Sink pad not garbage collected", GCTracker.waitGC(sinkRef)); } @Test public void padLink() throws Exception { Element src = ElementFactory.make("fakesrc", "src"); Element sink = ElementFactory.make("fakesink", "src"); Pad srcPad = src.getStaticPad("src"); Pad sinkPad = sink.getStaticPad("sink"); srcPad.link(sinkPad); } @Test public void addEventProbe() { Element elem = ElementFactory.make("identity", "src"); Event ev = new TagEvent(new TagList()); Pad sink = elem.getStaticPad("sink"); final AtomicReference e = new AtomicReference(); Pad.EVENT_PROBE event_probe = new Pad.EVENT_PROBE() { public PadProbeReturn eventReceived(Pad pad, Event event) { e.set(event); return PadProbeReturn.OK; } }; sink.setActive(true); sink.sendEvent(new FlushStopEvent()); sink.addEventProbe(event_probe); sink.sendEvent(ev); assertEquals("event_prober.probeEvent() was not called", ev, e.get()); sink.removeEventProbe(event_probe); Event ev2 = new TagEvent(new TagList()); sink.sendEvent(ev2); assertNotSame("event_prober.probeEvent() should not have been called", ev2, e.get()); } @Test public void addEventProbe_Remove() { Element elem = ElementFactory.make("identity", "src"); Event ev = new TagEvent(new TagList()); Pad sink = elem.getStaticPad("sink"); final AtomicReference e = new AtomicReference(); Pad.EVENT_PROBE event_probe = new Pad.EVENT_PROBE() { public PadProbeReturn eventReceived(Pad pad, Event event) { e.set(event); return PadProbeReturn.REMOVE; } }; sink.setActive(true); sink.sendEvent(new FlushStopEvent()); sink.addEventProbe(event_probe); sink.sendEvent(ev); assertEquals("event_prober.probeEvent() was not called", ev, e.get()); Event ev2 = new TagEvent(new TagList()); sink.sendEvent(ev2); assertNotSame("event_prober.probeEvent() should not have been called", ev2, e.get()); WeakReference probeRef = new WeakReference<>(event_probe); event_probe = null; assertTrue("Removed probe not collected", GCTracker.waitGC(probeRef)); } @Test public void addProbe_Event() { Element elem = ElementFactory.make("identity", "src"); Event ev = new TagEvent(new TagList()); Pad sink = elem.getStaticPad("sink"); final AtomicReference e = new AtomicReference<>(); Pad.PROBE probe = (Pad pad, PadProbeInfo info) -> { assertTrue("Info type does not include event downstream", info.getType().contains(PadProbeType.EVENT_DOWNSTREAM)); e.set(info.getEvent()); return PadProbeReturn.OK; }; sink.setActive(true); sink.sendEvent(new FlushStopEvent()); sink.addProbe(PadProbeType.EVENT_BOTH, probe); sink.sendEvent(ev); assertEquals("Probe (Event) was not called", ev, e.get()); sink.removeProbe(probe); Event ev2 = new TagEvent(new TagList()); sink.sendEvent(ev2); assertNotSame("Probe (Event) should not have been called", ev2, e.get()); } @Test public void addProbe_EventRemove() { Element elem = ElementFactory.make("identity", "src"); Event ev = new TagEvent(new TagList()); Pad sink = elem.getStaticPad("sink"); final AtomicReference e = new AtomicReference<>(); Pad.PROBE probe = (Pad pad, PadProbeInfo info) -> { assertTrue("Info type does not include event downstream", info.getType().contains(PadProbeType.EVENT_DOWNSTREAM)); e.set(info.getEvent()); return PadProbeReturn.REMOVE; }; sink.setActive(true); sink.sendEvent(new FlushStopEvent()); sink.addProbe(PadProbeType.EVENT_BOTH, probe); sink.sendEvent(ev); assertEquals("Probe (Event) was not called", ev, e.get()); Event ev2 = new TagEvent(new TagList()); sink.sendEvent(ev2); assertNotSame("Probe (Event) should not have been called", ev2, e.get()); WeakReference probeRef = new WeakReference<>(probe); probe = null; assertTrue("Removed probe not collected", GCTracker.waitGC(probeRef)); Event ev3 = new TagEvent(new TagList()); sink.sendEvent(ev3); assertNotSame("Probe (Event) should not have been called", ev3, e.get()); } @Test public void addDataProbe() { Element elem = ElementFactory.make("identity", "src"); Buffer buf = new Buffer(3); Buffer buf2 = new Buffer(2); final AtomicReference b = new AtomicReference(); Pad src = elem.getStaticPad("src"); Pad.DATA_PROBE data_probe = new Pad.DATA_PROBE() { @Override public PadProbeReturn dataReceived(Pad pad, Buffer buffer) { b.set(buffer); return PadProbeReturn.OK; } }; elem.play(); // add a dataprobe src.addDataProbe(data_probe); // push data FlowReturn res = src.push(buf); assertEquals("data_prober.probeData() was not called", buf, b.get()); // remove the dataprobe src.removeDataProbe(data_probe); // push data res = src.push(buf2); assertNotSame("data_prober.probeData() should not have been called", buf2, b.get()); elem.stop(); } @Test public void addProbe_Data() { Element elem = ElementFactory.make("identity", "src"); Buffer buf = new Buffer(3); Buffer buf2 = new Buffer(2); final AtomicReference b = new AtomicReference<>(); Pad src = elem.getStaticPad("src"); Pad.PROBE probe = (Pad pad, PadProbeInfo info) -> { assertTrue("Info type does not include buffer", info.getType().contains(PadProbeType.BUFFER)); // These cause assertion messages to be logged by GStreamer // assertTrue(info.getEvent() == null); // assertTrue(info.getQuery() == null); b.set(info.getBuffer()); return PadProbeReturn.OK; }; elem.play(); // add a dataprobe src.addProbe(PadProbeType.BUFFER, probe); // push data FlowReturn res = src.push(buf); assertEquals("Probe (Data) was not called", buf, b.get()); // remove the dataprobe src.removeProbe(probe); // push data res = src.push(buf2); assertNotSame("Probe (Data) should not have been called", buf2, b.get()); elem.stop(); } @Test public void addProbe_Idle() { Element elem = ElementFactory.make("identity", "src"); final AtomicBoolean called = new AtomicBoolean(); Pad src = elem.getStaticPad("src"); Pad.PROBE probe = (Pad pad, PadProbeInfo info) -> { called.set(true); return PadProbeReturn.REMOVE; }; src.addProbe(PadProbeType.IDLE, probe); assertTrue("Idle probe not called", called.get()); WeakReference probeRef = new WeakReference<>(probe); probe = null; assertTrue("Idle probe not collected", GCTracker.waitGC(probeRef)); } @Test public void addProbe_Query() { ProbeTester.test(PadProbeType.QUERY_BOTH, info -> { Query q = info.getQuery(); return q instanceof AllocationQuery; }); } } ================================================ FILE: test/org/freedesktop/gstreamer/PipelineTest.java ================================================ /* * Copyright (c) 2018 Neil C Smith * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.GError; import org.freedesktop.gstreamer.glib.GObject; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.lang.ref.WeakReference; import java.util.ArrayList; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GObjectAPI.GObjectStruct; import org.freedesktop.gstreamer.lowlevel.GObjectPtr; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Ignore; import org.junit.Test; /** * * @author wayne */ public class PipelineTest { public PipelineTest() { } @BeforeClass public static void setUpClass() throws Exception { Gst.init("PipelineTest", new String[] {}); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { } public boolean waitRefCnt(GObjectStruct struct, int refcnt) throws InterruptedException { System.gc(); struct.read(); for (int i = 0; struct.ref_count != refcnt && i < 20; ++i) { Thread.sleep(10); System.gc(); struct.read(); } return struct.ref_count == refcnt; } @Test public void testPipelineGC() throws Exception { Pipeline p = new Pipeline("test pipeline"); int refcnt = new GObjectStruct((GObjectPtr) Natives.getPointer(p)).ref_count; assertEquals("Refcount should be 1", refcnt, 1); WeakReference pref = new WeakReference(p); p = null; assertTrue("pipe not disposed", GCTracker.waitGC(pref)); } @Test public void testBusGC() throws Exception { Pipeline pipe = new Pipeline("test playbin"); pipe.play(); Bus bus = pipe.getBus(); GObjectStruct struct = new GObjectStruct((GObjectPtr) Natives.getPointer(bus)); int refcnt = struct.ref_count; assertTrue(refcnt > 1); // reget the Bus - should return the same object and not increment ref count Bus bus2 = pipe.getBus(); assertTrue("Did not get same Bus object", bus == bus2); struct.read(); // update struct fields assertEquals("ref_count not equal", refcnt, struct.ref_count); bus2 = null; WeakReference bref = new WeakReference(bus); bus = null; // Since the pipeline holds a reference to the GstBus, the proxy should not be disposed assertFalse("bus disposed prematurely", GCTracker.waitGC(bref)); assertFalse("ref_count decremented prematurely", waitRefCnt(struct, refcnt - 1)); WeakReference pref = new WeakReference(pipe); pipe.stop(); pipe = null; assertTrue("pipe not disposed", GCTracker.waitGC(pref)); struct.read(); System.out.println("bus ref_count=" + struct.ref_count); bus = null; assertTrue("bus not disposed " + struct.ref_count, GCTracker.waitGC(bref)); // This is a bit dangerous, since that memory could have been reused // assertTrue("ref_count not decremented", waitRefCnt(struct, 0)); } /* Test of getBus method, of class Pipeline. */ @Test public void testParseLaunch() { ArrayList errors = new ArrayList(); Pipeline pipeline = (Pipeline) Gst.parseLaunch("fakesrc ! fakesink", errors); assertNotNull("Pipeline not created", pipeline); assertEquals("parseLaunch with error!", errors.size(), 0); } @Test public void testParseLaunchSingleElement() { ArrayList errors = new ArrayList(); Element element = Gst.parseLaunch("fakesink", errors); assertNotNull("Element not created", element); assertFalse("Single element returned in Pipeline", element instanceof Pipeline); assertEquals("parseLaunch with error!", errors.size(), 0); } @Test public void testParseLaunchElementCount() { ArrayList errors = new ArrayList(); Pipeline pipeline = (Pipeline) Gst.parseLaunch("fakesrc ! fakesink", errors); assertEquals("Number of elements in pipeline incorrect", 2, pipeline.getElements().size()); assertEquals("parseLaunch with error!", errors.size(), 0); } @Test public void testParseLaunchSrcElement() { ArrayList errors = new ArrayList(); Pipeline pipeline = (Pipeline) Gst.parseLaunch("fakesrc ! fakesink", errors); assertEquals("First element not a fakesrc", "fakesrc", pipeline.getSources().get(0).getFactory().getName()); assertEquals("parseLaunch with error!", errors.size(), 0); } @Test public void testParseLaunchSinkElement() { ArrayList errors = new ArrayList(); Pipeline pipeline = (Pipeline) Gst.parseLaunch("fakesrc ! fakesink", errors); assertEquals("First element not a fakesink", "fakesink", pipeline.getSinks().get(0).getFactory().getName()); assertEquals("parseLaunch with error!", errors.size(), 0); } @Test public void testParseLaunchStringArr() { ArrayList errors = new ArrayList(); Pipeline pipeline = (Pipeline) Gst.parseLaunch(new String[] {"fakesrc", "fakesink"}, errors); assertNotNull("Pipeline not created", pipeline); assertEquals("parseLaunch with error!", errors.size(), 0); } @Test public void testParseLaunchStringArrElementCount() { ArrayList errors = new ArrayList(); Pipeline pipeline = (Pipeline) Gst.parseLaunch(new String[] {"fakesrc", "fakesink"}, errors); assertEquals("Number of elements in pipeline incorrect", 2, pipeline.getElements().size()); assertEquals("parseLaunch with error!", errors.size(), 0); } @Test public void testParseLaunchStringArrSrcElement() { ArrayList errors = new ArrayList(); Pipeline pipeline = (Pipeline) Gst.parseLaunch(new String[] {"fakesrc", "fakesink"}, errors); assertEquals("First element not a fakesrc", "fakesrc", pipeline.getSources().get(0).getFactory().getName()); assertEquals("parseLaunch with error!", errors.size(), 0); } @Test public void testParseLaunchStringArrSinkElement() { ArrayList errors = new ArrayList(); Pipeline pipeline = (Pipeline) Gst.parseLaunch(new String[] {"fakesrc", "fakesink"}, errors); assertEquals("First element not a fakesink", "fakesink", pipeline.getSinks().get(0).getFactory().getName()); assertEquals("parseLaunch with error!", errors.size(), 0); } } ================================================ FILE: test/org/freedesktop/gstreamer/PluginFeatureTest.java ================================================ /* * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import org.junit.AfterClass; import org.junit.Test; import static org.junit.Assert.*; import org.junit.BeforeClass; public class PluginFeatureTest { private static PluginFeature decodebinFeature; @BeforeClass public static void setUpClass() throws Exception { Gst.init("PluginTest", new String[] {}); decodebinFeature = Registry.get().lookupFeature("decodebin"); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Test public void testToString() { assertEquals("decodebin", decodebinFeature.toString()); } @Test public void testGetName() { assertEquals("decodebin", decodebinFeature.getName()); } @Test public void testGetRank() { assertEquals(0, decodebinFeature.getRank()); } @Test public void testCheckVersion() { assertTrue(decodebinFeature.checkVersion(0, 0, 1)); } @Test public void testGetPluginName() { assertEquals("playback", decodebinFeature.getPluginName()); } public void testGetPlugin() { Plugin plugin = decodebinFeature.getPlugin(); assertNotNull(plugin); assertEquals("playback", plugin.getName()); } } ================================================ FILE: test/org/freedesktop/gstreamer/PluginTest.java ================================================ /* * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import org.junit.AfterClass; import org.junit.Test; import static org.junit.Assert.*; import org.junit.BeforeClass; public class PluginTest { private static Plugin playbackPlugin; @BeforeClass public static void setUpClass() throws Exception { Gst.init("PluginTest", new String[] {}); playbackPlugin = Plugin.loadByName("playback"); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } public PluginTest() { } @Test public void testLoad_String() { assertNotNull(playbackPlugin); } @Test public void testGetName() { assertTrue(playbackPlugin.getName().equals("playback")); } @Test public void testGetDescription() { assertTrue(playbackPlugin.getDescription().equals("various playback elements")); } @Test public void testGetFilename() { assertTrue(playbackPlugin.getFilename().contains("gstplayback")); } @Test public void testGetVersion() { assertTrue(playbackPlugin.getVersion().matches("^(?:\\d+\\.)*\\d+$")); } @Test public void testGetLicense() { assertTrue(playbackPlugin.getLicense().equals("LGPL")); } @Test public void testGetSource() { assertTrue(playbackPlugin.getSource().equals("gst-plugins-base")); } @Test public void testGetPackage() { String pkg = playbackPlugin.getPackage(); assertTrue(pkg.contains("GStreamer Base") || pkg.contains("Gentoo GStreamer")); } @Test public void testGetOrigin() { assertTrue(playbackPlugin.getOrigin().length() > 0); } @Test public void testGetReleaseDateString() { assertTrue(playbackPlugin.getReleaseDateString().matches(".*\\d{4}-\\d{2}-\\d{2}.*")); } public void testIsLoaded() { assertTrue(playbackPlugin.isLoaded()); } } ================================================ FILE: test/org/freedesktop/gstreamer/ProbeTester.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2020 John Cortell * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import java.util.Set; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.Predicate; /** * Utility class for unit testing API that operates on a Probe. *

* Call {@link ProbeTester#test(Consumer)} and pass a callback which will * perform the test on a PadProbeInfo it is supplied. The callback runs in a Pad * probe. The test uses a simple, ephemeral pipeline that is fed by a video test * source (or custom pipeline). *

* The callback is a {@link Predicate} and should return false if the input info * doesn't match that required by the test. Test exceptions should be thrown as * normal. This is to allow the probe to be called repeatedly until the input * info matches that expected. If the probe never matches the test will time * out. */ public class ProbeTester { /** * Run a probe test on a simple test pipeline. The callback will be called * by the probe until it returns true, allowing for probe callbacks to be * ignored. If the callback never returns true the test will timeout and * fail. *

* The pipeline is videotestsrc ! fakesink name=sink. The probe * will be attached to the sink pad of the sink element. * * @param mask PadProbeType mask to use when attaching probe to sink pad * @param callback probe callback */ public static void test(Set mask, Predicate callback) { test("videotestsrc ! fakesink name=sink", mask, callback); } /** * Run a probe test on a simple test pipeline. The callback will be called * by the probe until it returns true, allowing for probe callbacks to be * ignored. If the callback never returns true the test will timeout and * fail. *

* The pipeline must have a sink element named sink. The probe will be * attached to the sink pad of the sink element. * * @param pipeline custom pipeline with named sink element * @param mask PadProbeType mask to use when attaching probe to sink pad * @param callback probe callback */ public static void test(String pipeline, Set mask, Predicate callback) { assertNotNull("Pipeline description can not be null", pipeline); assertFalse("Pipeline description can not be empty", pipeline.isEmpty()); Pipeline pipe = (Pipeline) Gst.parseLaunch(pipeline); assertNotNull("Unable to create Pipeline from pipeline description: ", pipe); Element sink = pipe.getElementByName("sink"); Pad pad = sink.getStaticPad("sink"); PadProbe probe = new PadProbe(callback); pad.addProbe(mask, probe); pipe.play(); // Wait for the probe to complete try { probe.await(5000); } catch (TimeoutException ex) { fail("Timed out waiting for probe condition\n" + ex); } catch (Exception ex) { fail("Unexpected exception waiting for probe\n" + ex); } finally { pipe.stop(); } // If the test threw an exception on the sample listener thread, throw it here // (on the main thread) if (probe.exception != null) { throw new AssertionError(probe.exception); } } private static class PadProbe implements Pad.PROBE { private final CountDownLatch latch; private final Predicate callback; private Throwable exception; PadProbe(Predicate callback) { this.callback = callback; latch = new CountDownLatch(1); } @Override public PadProbeReturn probeCallback(Pad pad, PadProbeInfo info) { if (latch.getCount() > 0) { try { if (callback.test(info)) { latch.countDown(); } } catch (Throwable exc) { exception = exc; latch.countDown(); } } return PadProbeReturn.OK; } void await(long millis) throws InterruptedException, TimeoutException { if (!latch.await(millis, TimeUnit.MILLISECONDS)) { throw new TimeoutException(); } } } } ================================================ FILE: test/org/freedesktop/gstreamer/PromiseTest.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2019 Kezhu Wang * Copyright (c) 2018 Antonio Morales * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import java.util.concurrent.atomic.AtomicBoolean; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GPointer; import org.freedesktop.gstreamer.lowlevel.GType; import org.freedesktop.gstreamer.util.TestAssumptions; import org.junit.BeforeClass; import org.junit.AfterClass; import org.junit.Test; public class PromiseTest { public PromiseTest() { } @BeforeClass public static void setUpClass() throws Exception { Gst.init(Gst.getVersion(), "PromiseTest"); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Test public void testReply() { TestAssumptions.requireGstVersion(1, 14); Promise promise = new Promise(); promise.reply(null); PromiseResult promiseStatus = promise.waitResult(); assertEquals("promise reply state not correct", promiseStatus, PromiseResult.REPLIED); } @Test public void testInterrupt() { TestAssumptions.requireGstVersion(1, 14); Promise promise = new Promise(); promise.interrupt(); PromiseResult promiseStatus = promise.waitResult(); assertEquals("promise reply state not correct", promiseStatus, PromiseResult.INTERRUPTED); } @Test public void testExpire() { TestAssumptions.requireGstVersion(1, 14); Promise promise = new Promise(); promise.expire(); PromiseResult promiseStatus = promise.waitResult(); assertEquals("promise reply state not correct", promiseStatus, PromiseResult.EXPIRED); } @Test public void testInvalidateReply() { TestAssumptions.requireGstVersion(1, 14); Promise promise = new Promise(); Structure data = new Structure("data"); assertTrue(Natives.ownsReference(data)); promise.reply(data); assertFalse(Natives.ownsReference(data)); assertFalse(Natives.validReference(data)); } @Test public void testReplyData() { TestAssumptions.requireGstVersion(1, 14); Promise promise = new Promise(); Structure data = new Structure("data", "test", GType.UINT, 1); GPointer pointer = Natives.getPointer(data); promise.reply(data); assertEquals("promise state not in replied", promise.waitResult(), PromiseResult.REPLIED); Structure result = promise.getReply(); assertEquals("result of promise does not match reply", pointer, Natives.getPointer(result)); } @Test public void testDispose() { TestAssumptions.requireGstVersion(1, 14); Promise promise = new Promise(); promise.interrupt(); promise.dispose(); } @Test public void testDisposeWithChangeFunc() { TestAssumptions.requireGstVersion(1, 14); Promise promise = new Promise(new Promise.PROMISE_CHANGE() { @Override public void onChange(Promise promise) { } }); promise.interrupt(); promise.dispose(); } @Test public void testChangeFunctionGC() { TestAssumptions.requireGstVersion(1, 14); final AtomicBoolean onChangeFired = new AtomicBoolean(false); Promise promise = new Promise(new Promise.PROMISE_CHANGE() { @Override public void onChange(Promise promise) { onChangeFired.set(true); } }); System.gc(); System.gc(); promise.interrupt(); assertTrue("Promise Change callback GC'd", onChangeFired.get()); promise.dispose(); } } ================================================ FILE: test/org/freedesktop/gstreamer/PropertyTypeTest.java ================================================ /* * Copyright (c) 2020 Peter Körner * Copyright (c) 2020 Neil C Smith * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.NativeEnum; import org.freedesktop.gstreamer.util.TestAssumptions; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; public class PropertyTypeTest { private Element audiotestsrc; private Element filesink; private Element convert; @BeforeClass public static void setUpClass() { Gst.init(Gst.getVersion(), "PropertyTypeTest"); } @AfterClass public static void tearDownClass() { Gst.deinit(); } @Before public void createElements() { audiotestsrc = ElementFactory.make("audiotestsrc", null); filesink = ElementFactory.make("filesink", null); convert = ElementFactory.make("audioconvert", null); } @After public void disposeElements() { audiotestsrc.dispose(); filesink.dispose(); convert.dispose(); } @Test public void setBool() { audiotestsrc.set("do-timestamp", true); assertEquals(true, audiotestsrc.get("do-timestamp")); audiotestsrc.set("do-timestamp", false); assertEquals(false, audiotestsrc.get("do-timestamp")); audiotestsrc.setAsString("do-timestamp", "true"); assertEquals("true", audiotestsrc.getAsString("do-timestamp")); } @Test public void setDouble() { audiotestsrc.set("freq", 42.23); assertEquals(42.23, audiotestsrc.get("freq")); audiotestsrc.set("freq", 5_000_000.); assertEquals(5_000_000., audiotestsrc.get("freq")); audiotestsrc.setAsString("freq", "42.23"); assertEquals(42.23, audiotestsrc.get("freq")); } @Test public void setInt() { audiotestsrc.set("num-buffers", 0); assertEquals(0, audiotestsrc.get("num-buffers")); audiotestsrc.set("num-buffers", 42); assertEquals(42, audiotestsrc.get("num-buffers")); audiotestsrc.set("num-buffers", 2147483647); assertEquals(2147483647, audiotestsrc.get("num-buffers")); } @Test public void setUInt() { audiotestsrc.set("blocksize", 0); assertEquals(0, audiotestsrc.get("blocksize")); audiotestsrc.set("blocksize", 42); assertEquals(42, audiotestsrc.get("blocksize")); int maxUnsignedInt = Integer.parseUnsignedInt("4294967295"); audiotestsrc.set("blocksize", maxUnsignedInt); assertEquals(maxUnsignedInt, audiotestsrc.get("blocksize")); } @Test public void setLong() { audiotestsrc.set("timestamp-offset", 0L); assertEquals(0L, audiotestsrc.get("timestamp-offset")); audiotestsrc.set("timestamp-offset", 42L); assertEquals(42L, audiotestsrc.get("timestamp-offset")); audiotestsrc.set("timestamp-offset", -42L); assertEquals(-42L, audiotestsrc.get("timestamp-offset")); audiotestsrc.set("timestamp-offset", 9223372036854775807L); assertEquals(9223372036854775807L, audiotestsrc.get("timestamp-offset")); audiotestsrc.set("timestamp-offset", -9223372036854775808L); assertEquals(-9223372036854775808L, audiotestsrc.get("timestamp-offset")); } @Test public void setULong() { filesink.set("max-bitrate", 0L); assertEquals(0L, filesink.get("max-bitrate")); long maxUnsignedLong = Long.parseUnsignedLong("18446744073709551615"); filesink.set("max-bitrate", maxUnsignedLong); assertEquals(maxUnsignedLong, filesink.get("max-bitrate")); filesink.set("max-bitrate", 42L); assertEquals(42L, filesink.get("max-bitrate")); filesink.setAsString("max-bitrate", "18446744073709551615"); assertEquals(maxUnsignedLong, filesink.get("max-bitrate")); } @Test public void setString() { filesink.set("location", ""); assertEquals("", filesink.get("location")); filesink.set("location", null); assertNull(filesink.get("location")); filesink.set("location", "foobar"); assertEquals("foobar", filesink.get("location")); } @Test public void setEnum() { audiotestsrc.set("wave", 8); assertEquals(8, audiotestsrc.get("wave")); audiotestsrc.setAsString("wave", "Silence"); assertEquals(4, audiotestsrc.get("wave")); // unfortunately returned strings do not seem to be consistent across // different OS / builds - comment out pending a fix or removal // assertEquals("Silence", audiotestsrc.getAsString("wave")); audiotestsrc.setAsString("wave", "square"); assertEquals(1, audiotestsrc.get("wave")); // assertEquals("Square", audiotestsrc.getAsString("wave")); audiotestsrc.setAsString("wave", "red-noise"); assertEquals(10, audiotestsrc.get("wave")); String redNoise = audiotestsrc.getAsString("wave"); // assertEquals("Red (brownian) noise", redNoise); audiotestsrc.setAsString("wave", redNoise); assertEquals(10, audiotestsrc.get("wave")); // invalid value audiotestsrc.set("wave", -256); assertEquals(0, audiotestsrc.get("wave")); // native enum audiotestsrc.set("wave", AudioTestSrcWave.SILENCE); assertEquals(AudioTestSrcWave.SILENCE.intValue(), audiotestsrc.get("wave")); // assertEquals("Silence", audiotestsrc.getAsString("wave")); } @Test(expected = IllegalArgumentException.class) public void setEnumInvalidString() { audiotestsrc.setAsString("wave", "FOO"); } @Test public void setValueArrayFromString() { TestAssumptions.requireGstVersion(1, 14); convert.setAsString("mix-matrix", "<<(float)0.25, (float)0.45>,<(float)0.65, (float)0.85>>"); String mixMatrix = convert.getAsString("mix-matrix"); assertTrue(mixMatrix.contains("0.2")); assertTrue(mixMatrix.contains("0.4")); assertTrue(mixMatrix.contains("0.6")); assertTrue(mixMatrix.contains("0.8")); } private static enum AudioTestSrcWave implements NativeEnum{ SINE(0), SQUARE(1), SAW(2), TRIANGLE(3), SILENCE(4), WHITE_NOISE(5), PINK_NOISE(6), SINE_TABLE(7), TICKS(8), GAUSSIAN_NOISE(9), RED_NOISE(10), BLUE_NOISE(11), VIOLET_NOISE(12); private final int value; private AudioTestSrcWave(int value) { this.value = value; } @Override public int intValue() { return value; } } } ================================================ FILE: test/org/freedesktop/gstreamer/QueryTest.java ================================================ /* * Copyright (c) 2009 Levente Farkas * Copyright (c) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.query.Query; import org.freedesktop.gstreamer.query.QueryType; import static org.freedesktop.gstreamer.lowlevel.GstMiniObjectAPI.GSTMINIOBJECT_API; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.List; import java.util.concurrent.TimeUnit; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstQueryAPI; import org.freedesktop.gstreamer.query.AllocationQuery; import org.freedesktop.gstreamer.query.DurationQuery; import org.freedesktop.gstreamer.query.FormatsQuery; import org.freedesktop.gstreamer.query.LatencyQuery; import org.freedesktop.gstreamer.query.PositionQuery; import org.freedesktop.gstreamer.query.SeekingQuery; import org.freedesktop.gstreamer.query.SegmentQuery; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; /** * * @author wayne */ public class QueryTest { @BeforeClass public static void setUpClass() throws Exception { Gst.init("QueryTest", new String[] {}); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Test public void gst_query_new_position() { Query query = GstQueryAPI.GSTQUERY_API.gst_query_new_position(Format.TIME); assertNotNull("Query.newPosition returned null", query); assertTrue("Returned query not instance of PositionQuery", query instanceof PositionQuery); } @Test public void getPositionQueryFormat() { for (Format format : Format.values()) { PositionQuery query = new PositionQuery(format); assertEquals("Format returned from getFormat() is incorrect" , format, query.getFormat()); } } @Test public void getPosition() { PositionQuery query = new PositionQuery(Format.TIME); final long POSITION = 0xdeadbeef; query.setPosition(Format.TIME, POSITION); assertEquals("Incorrect position returned", POSITION, query.getPosition()); } @Test public void positionQueryToString() { PositionQuery query = new PositionQuery(Format.TIME); query.setPosition(Format.TIME, 1234); String s = query.toString(); assertTrue("toString() did not return format", s.contains("format=TIME")); assertTrue("toString() did not return position", s.contains("position=1234")); } @Test public void newDurationQuery() { Query query = new DurationQuery(Format.TIME); assertNotNull("Query.newDuration returned null", query); assertTrue("Returned query not instance of DurationQuery", query instanceof DurationQuery); } @Test public void gst_query_new_duration() { Query query = GstQueryAPI.GSTQUERY_API.gst_query_new_duration(Format.TIME); assertNotNull("Query.newDuration returned null", query); assertTrue("Returned query not instance of DurationQuery", query instanceof DurationQuery); } @Test public void getDurationQueryFormat() { for (Format format : Format.values()) { DurationQuery query = new DurationQuery(format); assertEquals("Format returned from getFormat() is incorrect" , format, query.getFormat()); } } @Test public void getDuration() { DurationQuery query = new DurationQuery(Format.TIME); final long DURATION = 0xdeadbeef; query.setDuration(Format.TIME, DURATION); assertEquals("Incorrect duration returned", DURATION, query.getDuration()); } @Test public void durationQueryToString() { DurationQuery query = new DurationQuery(Format.TIME); query.setDuration(Format.TIME, 1234); String s = query.toString(); assertTrue("toString() did not return format", s.contains("format=TIME")); assertTrue("toString() did not return duration", s.contains("duration=1234")); } @Test public void gst_query_new_latency() { Query query = GstQueryAPI.GSTQUERY_API.gst_query_new_latency(); assertNotNull("gst_query_new_latency() returned null", query); assertTrue("Returned query not instance of LatencyQuery", query instanceof LatencyQuery); } @Test public void latencyIsLive() { LatencyQuery query = new LatencyQuery(); query.setLatency(true, 0, 0); assertTrue("isLive not set to true", query.isLive()); query.setLatency(false, 0, 0); assertFalse("isLive not set to true", query.isLive()); } @Test public void getMinimumLatency() { LatencyQuery query = new LatencyQuery(); // final ClockTime MIN = ClockTime.fromMillis(13000); final long MIN = TimeUnit.MILLISECONDS.toNanos(13000); query.setLatency(false, MIN, ~0); assertEquals("Min latency not set", MIN, query.getMinimumLatency()); } @Test public void getMaximumLatency() { LatencyQuery query = new LatencyQuery(); // final ClockTime MAX = ClockTime.fromMillis(123000); final long MAX = TimeUnit.MILLISECONDS.toNanos(123000); query.setLatency(false, 0, MAX); assertEquals("Min latency not set", MAX, query.getMaximumLatency()); } @Test public void latencyQueryToString() { LatencyQuery query = new LatencyQuery(); long minLatency = TimeUnit.MILLISECONDS.toNanos(13000); //ClockTime.fromMillis(13000); long maxLatency = TimeUnit.MILLISECONDS.toNanos(200000);//ClockTime.fromMillis(200000); query.setLatency(true, minLatency, maxLatency); String s = query.toString(); assertTrue("toString() did not return isLive", s.contains("live=true")); assertTrue("toString() did not return minLatency", s.contains("min=" + minLatency)); assertTrue("toString() did not return minLatency", s.contains("max=" + maxLatency)); } @Test public void segmentQuery() { SegmentQuery query = new SegmentQuery(Format.TIME); // ClockTime end = ClockTime.fromMillis(1000); long end = TimeUnit.MILLISECONDS.toNanos(1000); query.setSegment(1.0, Format.TIME, 0, end); assertEquals("Format not set correctly", Format.TIME, query.getFormat()); assertEquals("Start time not set correctly", 0, query.getStart()); assertEquals("End time not set correctly", end, query.getEnd()); } @Test public void seekingQuery() { SeekingQuery query = new SeekingQuery(Format.TIME); long start = 0; long end = TimeUnit.MILLISECONDS.toNanos(1000); query.setSeeking(Format.TIME, true, start, end); assertEquals("Format not set", Format.TIME, query.getFormat()); assertEquals("Start time not set", start, query.getStart()); assertEquals("End time not set", end, query.getEnd()); } @Test public void formatsQuery() { Query query = GstQueryAPI.GSTQUERY_API.gst_query_new_formats(); assertNotNull("gst_query_new_latency() returned null", query); assertTrue("Returned query not instance of LatencyQuery", query instanceof FormatsQuery); } @Test public void formatsQueryCount() { FormatsQuery query = new FormatsQuery(); query.setFormats(Format.TIME, Format.PERCENT); assertEquals("Wrong formats count", 2, query.getCount()); } @Test public void formatsQueryFormats() { FormatsQuery query = new FormatsQuery(); query.setFormats(Format.TIME, Format.PERCENT); assertEquals("First format incorrect", Format.TIME, query.getFormat(0)); assertEquals("Second format incorrect", Format.PERCENT, query.getFormat(1)); List formats = query.getFormats(); assertEquals("First format incorrect", Format.TIME, formats.get(0)); assertEquals("Second format incorrect", Format.PERCENT, formats.get(1)); } @Test public void makeWriteable() { Query query = new SegmentQuery(Format.TIME); assertTrue("New query is not writable", query.isWritable()); // Bumping the ref count makes this instance non writable // GSTMINIOBJECT_API.gst_mini_object_ref(query); Natives.ref(query); assertFalse("Query with multiple references should not be writable", query.isWritable()); // Now get a new reference that is writable query = query.makeWritable(); assertTrue("Query not writable after makeWritable", query.isWritable()); } // @Test public void testQueryTypeGetName() { // assertEquals(QueryType.JITTER.getName(), "jitter"); // } @Test public void gst_query_new_allocation() { Query query = GstQueryAPI.GSTQUERY_API.gst_query_new_allocation(Caps.fromString("video/x-raw, format=I420"), true); assertNotNull("gst_query_new_allocation returned null", query); assertTrue("Returned query not instance of AllocationQuery", query instanceof AllocationQuery); } @Test public void newAllocationQuery() { Query query = new AllocationQuery(Caps.fromString("video/x-raw, format=I420"), true); assertNotNull("Query.newAllocationQuery returned null", query); assertTrue("Returned query not instance of AllocationQuery", query instanceof AllocationQuery); } @Test public void getCapsAllocationQuery() { Caps caps = Caps.fromString("video/x-raw, format=I420"); AllocationQuery query = new AllocationQuery(caps, true); assertEquals(caps, query.getCaps()); } @Test public void needPoolAllocationQuery() { Caps caps = Caps.fromString("video/x-raw, format=I420"); AllocationQuery query = new AllocationQuery(caps, true); assertEquals(true, query.isPoolNeeded()); query.dispose(); query = new AllocationQuery(caps, false); assertEquals(false, query.isPoolNeeded()); } } ================================================ FILE: test/org/freedesktop/gstreamer/RegistryTest.java ================================================ /* * Copyright (c) 2007 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.util.List; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; /** * * @author wayne */ public class RegistryTest { public RegistryTest() { } @BeforeClass public static void setUpClass() throws Exception { Gst.init("RegistryTest", new String[] {}); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Test public void testGet() { Registry registry = Registry.get(); assertNotNull("Registry.getDefault() returned null", registry); } @Test public void testGetPluginList() { final String PLUGIN = "vorbis"; // Use something that is likely to be there Registry registry = Registry.get(); List plugins = registry.getPluginList(); assertFalse("No plugins found", plugins.isEmpty()); boolean pluginFound = false; for (Plugin p : plugins) { if (p.getName().equals(PLUGIN)) { pluginFound = true; } } assertTrue(PLUGIN + " plugin not found", pluginFound); } @Test public void testGetPluginListFiltered() { final String PLUGIN = "vorbis"; // Use something that is likely to be there Registry registry = Registry.get(); final boolean[] filterCalled = { false }; List plugins = registry.getPluginList(new Registry.PluginFilter() { @Override public boolean accept(Plugin plugin) { filterCalled[0] = true; return plugin.getName().equals(PLUGIN); } }); assertFalse("No plugins found", plugins.isEmpty()); assertTrue("PluginFilter not called", filterCalled[0]); assertEquals("Plugin list should contain 1 item", 1, plugins.size()); assertEquals(PLUGIN + " plugin not found", PLUGIN, plugins.get(0).getName()); } @Test public void testGetPluginFeatureListByPlugin() { final String PLUGIN = "vorbis"; // Use something that is likely to be there final String FEATURE = "vorbisdec"; Registry registry = Registry.get(); List features = registry.getPluginFeatureListByPlugin(PLUGIN); assertFalse("No plugin features found", features.isEmpty()); boolean pluginFound = false; for (PluginFeature p : features) { if (p.getName().equals(FEATURE)) { pluginFound = true; } } assertTrue(PLUGIN + " plugin not found", pluginFound); } @Test public void testFindPluginFeature() { PluginFeature f = Registry.get().lookupFeature("decodebin"); assertNotNull(f); } @Test public void testFindPlugin() { Plugin f = Registry.get().findPlugin("playback"); assertNotNull(f); } } ================================================ FILE: test/org/freedesktop/gstreamer/SampleTest.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2020 John Cortell * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import static org.junit.Assert.*; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.util.TestAssumptions; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; public class SampleTest { public SampleTest() { } @BeforeClass public static void setUpClass() throws Exception { Gst.init(Gst.getVersion(), "SampleTest"); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Test public void testGetCaps() { SampleTester.test((Sample sample) -> { Caps caps = sample.getCaps(); Structure struct = caps.getStructure(0); String name = struct.getName(); assertEquals("video/x-raw", name); }); } @Test public void testGetBuffer() { SampleTester.test((Sample sample) -> { Buffer buffer = sample.getBuffer(); assertEquals(1, buffer.getMemoryCount()); }); } @Test public void testSetBuffer() { // since gst 1.16, the sample is recycled and keep a reference on the last buffer received TestAssumptions.requireGstVersion(1, 16); SampleTester.test((Sample sample) -> { Buffer buffer = sample.getBuffer(); int refCount = buffer.getRefCount(); assertEquals(2, sample.getRefCount()); // make sample writable Natives.unref(sample); // force sample to release the buffer sample.setBuffer(null); Natives.ref(sample); assertEquals(2, sample.getRefCount()); assertEquals(refCount - 1, buffer.getRefCount()); }); } @Test public void testSampleTester() { try { SampleTester.test(sample -> { throw new IllegalStateException(); }); } catch (Throwable t) { assertTrue(t instanceof AssertionError); assertTrue(t.getCause() instanceof IllegalStateException); return; } fail("No exception thrown"); } } ================================================ FILE: test/org/freedesktop/gstreamer/SampleTester.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2020 John Cortell * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.function.Consumer; import org.freedesktop.gstreamer.elements.AppSink; /** * Utility class for unit testing API that operates on a Sample. *

* Call {@link SampleTester#test(Consumer)} and pass a callback which will * perform the test on a Sample it is supplied. The callback runs on the * AppSink.NEW_SAMPLE thread. The sample is produced by a simple, ephemeral * pipeline that is fed by a video test source. */ public class SampleTester { public static void test(Consumer callback) { test(callback, "videotestsrc ! videoconvert ! appsink name=myappsink"); } public static void test(Consumer callback, String pipelineDescription) { test(callback, pipelineDescription, 0); } public static void test(Consumer callback, String pipelineDescription, int skipFrames) { assertNotNull("Pipeline description can not be null", pipelineDescription); assertFalse("Pipeline description can not be empty", pipelineDescription.isEmpty()); Pipeline pipe = (Pipeline) Gst.parseLaunch(pipelineDescription); assertNotNull("Unable to create Pipeline from pipeline description: ", pipe); AppSink appSink = (AppSink) pipe.getElementByName("myappsink"); appSink.set("emit-signals", true); NewSampleListener sampleListener = new NewSampleListener(callback, skipFrames); appSink.connect(sampleListener); pipe.play(); // Wait for the sample to arrive and for the client supplied test function to // complete try { sampleListener.await(5000); } catch (Exception ex) { fail("Unexpected exception waiting for sample\n" + ex); } finally { pipe.stop(); appSink.disconnect(sampleListener); } // If the test threw an exception on the sample listener thread, throw it here // (on the main thread) if (sampleListener.exception != null) { throw new AssertionError(sampleListener.exception); } } private static class NewSampleListener implements AppSink.NEW_SAMPLE { private final Consumer callback; private final int skipFrames; private final CountDownLatch latch; private Throwable exception; private int counter = 0; NewSampleListener(Consumer callback) { this(callback, 0); } NewSampleListener(Consumer callback, int skip) { this.callback = callback; skipFrames = skip; latch = new CountDownLatch(1); } @Override public FlowReturn newSample(AppSink appSink) { if (latch.getCount() > 0) { Sample sample = appSink.pullSample(); if (counter < skipFrames) { counter++; sample.dispose(); return FlowReturn.OK; } try { // Run the client's test logic on the sample (only once) try { callback.accept(sample); } catch (Throwable exc) { exception = exc; } } finally { latch.countDown(); sample.dispose(); } } return FlowReturn.OK; } void await(long millis) throws InterruptedException, TimeoutException { if (!latch.await(millis, TimeUnit.MILLISECONDS)) { throw new TimeoutException(); } } } } ================================================ FILE: test/org/freedesktop/gstreamer/StreamInfoTest.java ================================================ package org.freedesktop.gstreamer; ================================================ FILE: test/org/freedesktop/gstreamer/StructureTest.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2009 Levente Farkas * Copyright (C) 2009 Tamas Korodi * Copyright (C) 2007 Wayne Meissner * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . */ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.GCancellable; import org.freedesktop.gstreamer.lowlevel.GType; import org.freedesktop.gstreamer.lowlevel.GValueAPI; import org.junit.AfterClass; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import java.util.Arrays; import java.util.List; import org.freedesktop.gstreamer.util.TestAssumptions; import static org.junit.Assert.*; public class StructureTest { private Structure structure; @BeforeClass public static void setUpClass() throws Exception { Gst.init(Gst.getVersion(), "StructureTest"); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Before public void setUp() { structure = new Structure("nazgul"); } @Test public void testGetName() { assertEquals("nazgul", structure.getName()); } @Test public void testGetValue() { structure.setValue("uint", GType.UINT, 9); assertEquals(9, structure.getValue("uint")); try { structure.getValue("noexist"); fail("Structure.InvalidFieldException should have been thrown"); } catch (Structure.InvalidFieldException e) { } structure.setDouble("double", 9.0); assertEquals(9.0, structure.getValue("double")); structure.setValue("bool", GType.BOOLEAN, true); assertEquals(true, structure.getValue("bool")); } @Test public void testGetValues() { GValueAPI.GValueArray ar = new GValueAPI.GValueArray(2); ar.append(new GValueAPI.GValue(GType.DOUBLE, 7.5)); ar.append(new GValueAPI.GValue(GType.DOUBLE, 14.3)); structure.setValue("valuearray", GType.valueOf(GValueAPI.GValueArray.GTYPE_NAME), ar); List doubles = structure.getValues(Double.class, "valuearray"); assertEquals(7.5, doubles.get(0), 0.001); assertEquals(14.3, doubles.get(1), 0.001); try { List strings = structure.getValues(String.class, "valuearray"); fail("Trying to extract the wrong type from GValueArray not throwing exception"); } catch (Structure.InvalidFieldException ex) { } try { List strings = structure.getValues(Double.class, "non_existent"); fail("Trying to extract a non-existent GValueArray field"); } catch (Structure.InvalidFieldException ex) { } } @Test public void testGetInteger() { structure.setInteger("int", 9); assertEquals(9, structure.getInteger("int")); structure.setInteger("int", -9); assertEquals(-9, structure.getInteger("int")); } @Test public void testGetIntegers() { GValueAPI.GValueArray ar = new GValueAPI.GValueArray(2); ar.append(new GValueAPI.GValue(GType.INT, 32)); ar.append(new GValueAPI.GValue(GType.INT, -49)); structure.setValue("integers", GType.valueOf(GValueAPI.GValueArray.GTYPE_NAME), ar); int[] in = new int[2]; int[] ints = structure.getIntegers("integers", in); assertTrue(in == ints); assertEquals(32, ints[0]); assertEquals(-49, ints[1]); in = new int[1]; ints = structure.getIntegers("integers", in); assertFalse(in == ints); assertEquals(32, ints[0]); assertEquals(-49, ints[1]); structure.setInteger("single_integer", 18); int[] single = structure.getIntegers("single_integer", in); assertTrue(in == single); assertEquals(18, single[0]); } @Test public void testGetDouble() { structure.setDouble("double", 9.0); assertEquals(9.0, structure.getDouble("double"), 0); structure.setDouble("double", -9.0); assertEquals(-9.0, structure.getDouble("double"), 0); } @Test public void testGetDoubles() { GValueAPI.GValueArray ar = new GValueAPI.GValueArray(2); ar.append(new GValueAPI.GValue(GType.DOUBLE, 3.25)); ar.append(new GValueAPI.GValue(GType.DOUBLE, 79.6)); structure.setValue("doubles", GType.valueOf(GValueAPI.GValueArray.GTYPE_NAME), ar); double[] in = new double[2]; double[] doubles = structure.getDoubles("doubles", in); assertTrue(in == doubles); assertEquals(3.25, doubles[0], 0.001); assertEquals(79.6, doubles[1], 0.001); in = new double[1]; doubles = structure.getDoubles("doubles", in); assertFalse(in == doubles); assertEquals(3.25, doubles[0], 0.001); assertEquals(79.6, doubles[1], 0.001); structure.setDouble("single_double", 18.2); double[] single = structure.getDoubles("single_double", in); assertTrue(in == single); assertEquals(18.2, single[0], 0.001); } @Test public void testFraction() { structure.setFraction("fraction", 10, 1); assertEquals(true, structure.hasField("fraction")); assertEquals(10, structure.getFraction("fraction").getNumerator()); assertEquals(1, structure.getFraction("fraction").getDenominator()); structure.setFraction("fraction", 17, 10); assertEquals(17, structure.getFraction("fraction").getNumerator()); assertEquals(10, structure.getFraction("fraction").getDenominator()); } @Test public void testValueListInteger() { Caps caps = Caps.fromString("audio/x-raw,rate={44100,48000}"); List rates = caps.getStructure(0).getValues(Integer.class, "rate"); assertEquals(Arrays.asList(44100, 48000), rates); } @Test public void testValueListStrings() { Caps caps = Caps.fromString("video/x-raw,format={RGB, BGR, RGBx, BGRx}"); List formats = caps.getStructure(0).getValues(String.class, "format"); assertEquals(Arrays.asList("RGB", "BGR", "RGBx", "BGRx"), formats); } @Test(expected = Structure.InvalidFieldException.class) public void testValueListChecksType() { Caps caps = Caps.fromString("video/x-raw,format={RGB, BGR, RGBx, BGRx}"); caps.getStructure(0).getValues(Integer.class, "format"); } @Test(expected = IllegalArgumentException.class) public void testSetMistypedObject() { GCancellable notACapsInstance = new GCancellable(); structure.setObject("whatever", Caps.GTYPE_NAME, notACapsInstance); } @Test public void testSetUntypedObject() { GCancellable anyKindOfObject = new GCancellable(); structure.setObject("whatever", GType.OBJECT.getTypeName(), anyKindOfObject); Object value = structure.getValue("whatever"); Assert.assertSame(anyKindOfObject, value); } @Test public void testSetObject() { GCancellable anyKindOfObject = new GCancellable(); structure.setObject("whatever", GCancellable.GTYPE_NAME, anyKindOfObject); Object value = structure.getValue("whatever"); Assert.assertSame(anyKindOfObject, value); } @Test(expected = IllegalArgumentException.class) public void testSetNullObject() { structure.setObject("whatever", GCancellable.GTYPE_NAME, null); Object value = structure.getValue("whatever"); Assert.assertNull(value); } @Test public void testIssue173() { TestAssumptions.requireGstVersion(1, 16); TestAssumptions.requireElement("srtsink"); Element srtsink = ElementFactory.make("srtsink", "srtsink"); srtsink.set("uri", "srt://:8888/"); Object stats = srtsink.get("stats"); assertTrue(stats instanceof Structure); } } ================================================ FILE: test/org/freedesktop/gstreamer/TestPipe.java ================================================ /* * Copyright (c) 2007, 2008 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; class TestPipe { public final Pipeline pipe = new Pipeline("pipe"); public final Element src = ElementFactory.make("fakesrc", "src"); public final Element sink = ElementFactory.make("fakesink", "sink"); public final String name; private final CountDownLatch latch = new CountDownLatch(1); public TestPipe() { this(getInvokingMethod()); } private static String getInvokingMethod() { try { throw new Exception(); } catch (Exception ex) { return ex.getStackTrace()[2].getMethodName(); } } public TestPipe(String name) { this.name = name; pipe.addMany(src, sink); Element.linkMany(src, sink); } public TestPipe run() { try { latch.await(250, TimeUnit.MILLISECONDS); } catch (Exception ex) { } return this; } public TestPipe play() { pipe.play(); return this; } public Bus getBus() { return pipe.getBus(); } public void quit() { latch.countDown(); } public void dispose() { pipe.stop(); } } ================================================ FILE: test/org/freedesktop/gstreamer/WebRTCBinTest.java ================================================ package org.freedesktop.gstreamer; import org.freedesktop.gstreamer.glib.NativeEnum; import org.freedesktop.gstreamer.webrtc.WebRTCICEGatheringState; import org.freedesktop.gstreamer.webrtc.WebRTCPeerConnectionState; import org.junit.Test; import static org.junit.Assert.assertEquals; public class WebRTCBinTest { @Test public void connectionStateTest() { assertEquals(NativeEnum.fromInt(WebRTCPeerConnectionState.class, 0), WebRTCPeerConnectionState.NEW); assertEquals(NativeEnum.fromInt(WebRTCPeerConnectionState.class, 1), WebRTCPeerConnectionState.CONNECTING); assertEquals(NativeEnum.fromInt(WebRTCPeerConnectionState.class, 2), WebRTCPeerConnectionState.CONNECTED); assertEquals(NativeEnum.fromInt(WebRTCPeerConnectionState.class, 3), WebRTCPeerConnectionState.DISCONNECTED); assertEquals(NativeEnum.fromInt(WebRTCPeerConnectionState.class, 4), WebRTCPeerConnectionState.FAILED); assertEquals(NativeEnum.fromInt(WebRTCPeerConnectionState.class, 5), WebRTCPeerConnectionState.CLOSED); } @Test public void iceGatheringStateTest() { assertEquals(NativeEnum.fromInt(WebRTCICEGatheringState.class, 0), WebRTCICEGatheringState.NEW); assertEquals(NativeEnum.fromInt(WebRTCICEGatheringState.class, 1), WebRTCICEGatheringState.GATHERING); assertEquals(NativeEnum.fromInt(WebRTCICEGatheringState.class, 2), WebRTCICEGatheringState.COMPLETE); } } ================================================ FILE: test/org/freedesktop/gstreamer/controller/InterpolationControlSourceTest.java ================================================ package org.freedesktop.gstreamer.controller; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; import org.freedesktop.gstreamer.ClockTime; import org.freedesktop.gstreamer.ControlBinding; import org.freedesktop.gstreamer.ControlSource; import org.freedesktop.gstreamer.Element; import org.freedesktop.gstreamer.ElementFactory; import org.freedesktop.gstreamer.GCTracker; import org.freedesktop.gstreamer.Gst; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * */ public class InterpolationControlSourceTest { public InterpolationControlSourceTest() { } @BeforeClass public static void setUpClass() { Gst.init("InterpolationControlSourceTest"); } @AfterClass public static void tearDownClass() { } @Before public void setUp() { } @After public void tearDown() { } /** * Test of setMode method, of class InterpolationControlSource. */ @Test public void testMode() { InterpolationControlSource controller = new InterpolationControlSource(); InterpolationMode[] modes = InterpolationMode.values(); for (InterpolationMode mode : modes) { controller.setMode(mode); assertEquals(mode, controller.getMode()); } } @Test public void testSetValue() { List timedValue = Collections.singletonList( new ControlSource.TimedValue(ClockTime.fromSeconds(10), 0.5) ); InterpolationControlSource controller = new InterpolationControlSource(); controller.set(timedValue.get(0).timestamp, timedValue.get(0).value); assertEquals(timedValue, controller.getAll()); } @Test public void testSetValues() { List timedValues = Stream.of( new ControlSource.TimedValue(ClockTime.fromSeconds(0), 0.0), new ControlSource.TimedValue(ClockTime.fromSeconds(1), 0.5), new ControlSource.TimedValue(ClockTime.fromSeconds(2), 0.2), new ControlSource.TimedValue(ClockTime.fromSeconds(4), 0.8) ).collect(Collectors.toList()); InterpolationControlSource controller = new InterpolationControlSource(); controller.setFromList(timedValues); assertEquals(timedValues, controller.getAll()); } @Test public void testLinearInterpolation() { List timedValues = Stream.of( new ControlSource.TimedValue(ClockTime.fromSeconds(0), 0.0), new ControlSource.TimedValue(ClockTime.fromSeconds(1), 1.0) ).collect(Collectors.toList()); InterpolationControlSource controller = new InterpolationControlSource(); controller.setMode(InterpolationMode.LINEAR); controller.setFromList(timedValues); Element volume = ElementFactory.make("volume", "volume"); volume.addControlBinding(DirectControlBinding.create(volume, "volume", controller)); volume.syncValues(0); assertEquals(0, ((Double) volume.get("volume")).doubleValue(), 0.001); volume.syncValues(ClockTime.fromMillis(500)); assertEquals(5, ((Double) volume.get("volume")).doubleValue(), 0.001); volume.syncValues(ClockTime.fromSeconds(1)); assertEquals(10, ((Double) volume.get("volume")).doubleValue(), 0.001); } @Test public void testLinearInterpolationAbsolute() { List timedValues = Stream.of( new ControlSource.TimedValue(ClockTime.fromSeconds(0), 0.0), new ControlSource.TimedValue(ClockTime.fromSeconds(1), 5.0) ).collect(Collectors.toList()); InterpolationControlSource controller = new InterpolationControlSource(); controller.setMode(InterpolationMode.LINEAR); controller.setFromList(timedValues); Element volume = ElementFactory.make("volume", "volume"); ControlBinding binding = DirectControlBinding.createAbsolute(volume, "volume", controller); assertEquals(2.5, (Double) binding.getValue(ClockTime.fromMillis(500)), 0.01); Object[] values = new Object[3]; binding.getValueArray(0, ClockTime.fromMillis(500), values); assertEquals(0, (Double) values[0], 0.01); assertEquals(2.5, (Double) values[1], 0.01); assertEquals(5, (Double) values[2], 0.01); volume.addControlBinding(binding); volume.syncValues(0); assertEquals(0, ((Double) volume.get("volume")), 0.001); volume.syncValues(ClockTime.fromMillis(500)); assertEquals(2.5, ((Double) volume.get("volume")), 0.001); volume.syncValues(ClockTime.fromSeconds(1)); assertEquals(5, ((Double) volume.get("volume")), 0.001); } @Test public void testGC() { InterpolationControlSource controller = new InterpolationControlSource(); Element volume = ElementFactory.make("volume", "volume"); ControlBinding binding = DirectControlBinding.create(volume, "volume", controller); volume.addControlBinding(binding); GCTracker tracker = new GCTracker(controller); controller = null; binding = null; volume = null; assertTrue("Controller not garbage collected", tracker.waitGC()); assertTrue("Controller not destroyed", tracker.waitDestroyed()); } } ================================================ FILE: test/org/freedesktop/gstreamer/controller/TriggerControlSourceTest.java ================================================ package org.freedesktop.gstreamer.controller; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; import org.freedesktop.gstreamer.ClockTime; import org.freedesktop.gstreamer.ControlBinding; import org.freedesktop.gstreamer.ControlSource; import org.freedesktop.gstreamer.Element; import org.freedesktop.gstreamer.ElementFactory; import org.freedesktop.gstreamer.GCTracker; import org.freedesktop.gstreamer.Gst; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * */ public class TriggerControlSourceTest { public TriggerControlSourceTest() { } @BeforeClass public static void setUpClass() { Gst.init("InterpolationControlSourceTest"); } @AfterClass public static void tearDownClass() { } @Before public void setUp() { } @After public void tearDown() { } @Test public void testTolerance() { List timedValues = Stream.of( new ControlSource.TimedValue(ClockTime.fromSeconds(0), 0.5), new ControlSource.TimedValue(ClockTime.fromSeconds(2), 1.0) ).collect(Collectors.toList()); TriggerControlSource controller = new TriggerControlSource(); controller.setFromList(timedValues); Element volume = ElementFactory.make("volume", "volume"); volume.addControlBinding(DirectControlBinding.create(volume, "volume", controller)); volume.syncValues(0); assertEquals(5, ((Double) volume.get("volume")), 0.001); volume.set("volume", 0); volume.syncValues(ClockTime.fromSeconds(1)); assertEquals(0, ((Double) volume.get("volume")), 0.001); volume.syncValues(ClockTime.fromSeconds(2)); assertEquals(10, ((Double) volume.get("volume")), 0.001); controller.setTolerance(ClockTime.fromMillis(500)); volume.syncValues(ClockTime.fromMillis(450)); assertEquals(5, ((Double) volume.get("volume")), 0.001); volume.set("volume", 0); volume.syncValues(ClockTime.fromMillis(550)); assertEquals(0, ((Double) volume.get("volume")), 0.001); volume.syncValues(ClockTime.fromMillis(1650)); assertEquals(10, ((Double) volume.get("volume")), 0.001); } @Test public void testGC() { TriggerControlSource controller = new TriggerControlSource(); Element volume = ElementFactory.make("volume", "volume"); ControlBinding binding = DirectControlBinding.create(volume, "volume", controller); volume.addControlBinding(binding); GCTracker tracker = new GCTracker(controller); controller = null; binding = null; volume = null; assertTrue("Controller not garbage collected", tracker.waitGC()); assertTrue("Controller not destroyed", tracker.waitDestroyed()); } } ================================================ FILE: test/org/freedesktop/gstreamer/elements/PlayBinTest.java ================================================ /* * Copyright (c) 2021 Neil C Smith * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer.elements; import java.net.URI; import java.util.EnumSet; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.ElementFactory; import org.freedesktop.gstreamer.GCTracker; import org.freedesktop.gstreamer.Gst; import org.freedesktop.gstreamer.util.TestAssumptions; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * Tests for PlayBin. */ public class PlayBinTest { @BeforeClass public static void setUpClass() throws Exception { Gst.init(Gst.getVersion(), "PlayBinTest"); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Test public void testFlags() { PlayBin playbin = new PlayBin("playbin"); Set defaultFlags = EnumSet.of( PlayFlags.SOFT_COLORBALANCE, PlayFlags.DEINTERLACE, PlayFlags.SOFT_VOLUME, PlayFlags.TEXT, PlayFlags.AUDIO, PlayFlags.VIDEO ); Set flags = playbin.getFlags(); assertEquals("PlayBin flags not expected defaults", defaultFlags, flags); flags.add(PlayFlags.VIS); flags.remove(PlayFlags.DEINTERLACE); playbin.setFlags(flags); flags = playbin.getFlags(); assertTrue("VIS flag not set", flags.contains(PlayFlags.VIS)); assertFalse("Deinterlace not removed from playbin flags", flags.contains(PlayFlags.DEINTERLACE)); playbin.dispose(); } @Test public void testSourceSetupSignal() throws Exception { PlayBin playbin = new PlayBin("playbin", URI.create("appsrc:/")); AtomicReference sourceRef = new AtomicReference<>(null); playbin.connect((PlayBin.SOURCE_SETUP) ((p, e) -> { if (e instanceof AppSrc) { AppSrc appSrc = (AppSrc) e; appSrc.setCaps(Caps.fromString("video/x-raw, format=xRGB, width=640, height=480")); sourceRef.set(appSrc); } })); playbin.setVideoSink(ElementFactory.make("fakesink", "videosink")); playbin.play(); playbin.getState(200, TimeUnit.MILLISECONDS); AppSrc src = sourceRef.getAndSet(null); assertNotNull(src); GCTracker sourceTracker = new GCTracker(src); GCTracker playbinTracker = new GCTracker(playbin); playbin.stop(); src = null; playbin = null; assertTrue("AppSrc not garbage collected", sourceTracker.waitGC()); assertTrue("AppSrc not destroyed", sourceTracker.waitDestroyed()); assertTrue("PlayBin not garbage collected", playbinTracker.waitGC()); assertTrue("PlayBin not destroyed", playbinTracker.waitDestroyed()); } @Test public void testElementSetupSignal() throws Exception { TestAssumptions.requireGstVersion(1, 10); PlayBin playbin = new PlayBin("playbin", URI.create("appsrc:/")); AtomicReference sourceRef = new AtomicReference<>(null); playbin.connect((PlayBin.ELEMENT_SETUP) ((p, e) -> { if (e instanceof AppSrc) { AppSrc appSrc = (AppSrc) e; sourceRef.set(appSrc); } })); playbin.setVideoSink(ElementFactory.make("fakesink", "videosink")); playbin.play(); playbin.getState(200, TimeUnit.MILLISECONDS); AppSrc src = sourceRef.getAndSet(null); assertNotNull(src); GCTracker sourceTracker = new GCTracker(src); GCTracker playbinTracker = new GCTracker(playbin); playbin.stop(); src = null; playbin = null; assertTrue("AppSrc not garbage collected", sourceTracker.waitGC()); assertTrue("AppSrc not destroyed", sourceTracker.waitDestroyed()); assertTrue("PlayBin not garbage collected", playbinTracker.waitGC()); assertTrue("PlayBin not destroyed", playbinTracker.waitDestroyed()); } } ================================================ FILE: test/org/freedesktop/gstreamer/event/EventTest.java ================================================ /* * Copyright (c) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer.event; import org.freedesktop.gstreamer.event.QOSType; import org.freedesktop.gstreamer.event.Event; import org.freedesktop.gstreamer.event.EventType; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.lang.ref.WeakReference; import java.util.EnumSet; import java.util.concurrent.TimeUnit; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.ClockTime; import org.freedesktop.gstreamer.Format; import org.freedesktop.gstreamer.GCTracker; import org.freedesktop.gstreamer.Gst; import org.freedesktop.gstreamer.Structure; import org.freedesktop.gstreamer.TagList; import org.freedesktop.gstreamer.event.BufferSizeEvent; import org.freedesktop.gstreamer.event.CapsEvent; import org.freedesktop.gstreamer.event.EOSEvent; import org.freedesktop.gstreamer.event.FlushStartEvent; import org.freedesktop.gstreamer.event.FlushStopEvent; import org.freedesktop.gstreamer.event.LatencyEvent; import org.freedesktop.gstreamer.event.QOSEvent; import org.freedesktop.gstreamer.event.ReconfigureEvent; import org.freedesktop.gstreamer.event.SeekEvent; import org.freedesktop.gstreamer.event.SegmentEvent; import org.freedesktop.gstreamer.event.StepEvent; import org.freedesktop.gstreamer.event.StreamStartEvent; import org.freedesktop.gstreamer.event.TagEvent; import org.freedesktop.gstreamer.lowlevel.GstAPI; import static org.freedesktop.gstreamer.lowlevel.GstEventAPI.GSTEVENT_API; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; /** * * @author wayne */ public class EventTest { public EventTest() { } @BeforeClass public static void setUpClass() throws Exception { Gst.init("EventTest", new String[] {}); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Test public void verifyFlags() { // Verify that the flags in the enum match the native ones. EventType[] types = EventType.values(); for (EventType t : types) { int flags = GSTEVENT_API.gst_event_type_get_flags(t); assertEquals("Incorrect flags for: " + t.name(), flags, t.intValue() & 0xFF); } } @Test public void createEOSEvent() throws Exception { new EOSEvent(); } @Test public void createFlushStartEvent() throws Exception { new FlushStartEvent(); } @Test public void createFlushStopEvent() throws Exception { new FlushStopEvent(); } @Test public void createLatencyEvent() throws Exception { new LatencyEvent(ClockTime.ZERO); } @Test public void createSegmentEvent() throws Exception { GstAPI.GstSegmentStruct struct = new GstAPI.GstSegmentStruct(); struct.flags = 0; struct.rate = 1.0; struct.applied_rate = 1.0; struct.format = Format.TIME; new SegmentEvent(struct); } @Test public void createCapsEvent() throws Exception { new CapsEvent(Caps.fromString("video/x-raw,format=I420")); } @Test public void createReconfigureEvent() throws Exception { new ReconfigureEvent(); } @Test public void createStreamStartEvent() throws Exception { new StreamStartEvent("a stream_id"); } @Test public void createStepEvent() throws Exception { new StepEvent(Format.BUFFERS, 1, 1, true, false); } @Test public void gst_event_new_eos() { Event eos = GSTEVENT_API.gst_event_new_eos(); assertNotNull("gst_event_new_eos returned null", eos); assertTrue("gst_event_new_eos returned a non-EOS event", eos instanceof EOSEvent); } @Test public void gst_event_new_flush_start() { Event ev = GSTEVENT_API.gst_event_new_flush_start(); assertNotNull("gst_event_new_flush_start returned null", ev); assertTrue("gst_event_new_flush_start returned a non-FLUSH_START event", ev instanceof FlushStartEvent); } @Test public void gst_event_new_flush_stop() { Event ev = GSTEVENT_API.gst_event_new_flush_stop(); assertNotNull("gst_event_new_flush_stop returned null", ev); assertTrue("gst_event_new_flush_stop returned a non-FLUSH_STOP event", ev instanceof FlushStopEvent); } @Test public void gst_event_new_latency() { Event ev = GSTEVENT_API.gst_event_new_latency(0); assertNotNull("gst_event_new_latency returned null", ev); assertTrue("gst_event_new_latency returned a non-LATENCY event", ev instanceof LatencyEvent); } @Test public void gst_event_new_new_segment() { GstAPI.GstSegmentStruct struct = new GstAPI.GstSegmentStruct(); struct.flags = 0; struct.rate = 1.0; struct.applied_rate = 1.0; struct.format = Format.TIME; Event ev = GSTEVENT_API.gst_event_new_segment(struct); assertNotNull("gst_event_new_latency returned null", ev); assertTrue("gst_event_new_latency returned a non-NEWSEGMENT event", ev instanceof SegmentEvent); } @Test public void getLatency() { // final ClockTime MAGIC = ClockTime.valueOf(0xdeadbeef, TimeUnit.NANOSECONDS); long MAGIC = 0xdeadbeef; LatencyEvent ev = new LatencyEvent(MAGIC); assertEquals("Incorrect latency returned", MAGIC, ev.getLatency()); } @Test public void NewSegment_getRate() { final double RATE = (double) 0xdeadbeef; SegmentEvent ev = new SegmentEvent(new GstAPI.GstSegmentStruct(0, RATE, RATE, Format.TIME, 0, 0, 0, 0, 0, 0, 0)); assertEquals("Incorrect rate returned from getRate", RATE, ev.getSegment().rate, 0.0); } @Test public void NewSegment_getStart() { final long START = 0xdeadbeefL; SegmentEvent ev = new SegmentEvent(new GstAPI.GstSegmentStruct(0, 0.1, 0.1, Format.TIME, 0, 0, START, -1L, 0, 0, 0)); assertEquals("Incorrect rate returned from getStart", START, ev.getSegment().start); } @Test public void NewSegment_getStop() { final long STOP = 0xdeadbeefL; SegmentEvent ev = new SegmentEvent(new GstAPI.GstSegmentStruct(0, 0.1, 0.1, Format.TIME, 0, 0, 0L, STOP, 0, 0, 0)); assertEquals("Incorrect rate returned from getRate", STOP, ev.getSegment().stop); } @Test public void gst_event_new_tag() { Event ev = GSTEVENT_API.gst_event_new_tag(new TagList()); assertNotNull("gst_event_new_tag returned null", ev); assertTrue("gst_event_new_tag returned a non-TAG event", ev instanceof TagEvent); } @Test public void TagEvent_testGC() throws Exception { TagEvent ev = new TagEvent(new TagList()); @SuppressWarnings("unused") TagList tl = ev.getTagList(); WeakReference evRef = new WeakReference(ev); ev = null; assertFalse("Event ref collected before TagList is unreferenced", GCTracker.waitGC(evRef)); tl = null; assertTrue("Event ref not collected after TagList is unreferenced", GCTracker.waitGC(evRef)); } @Test public void Event_testGC() throws Exception { Event ev = new LatencyEvent(100); @SuppressWarnings("unused") Structure s = ev.getStructure(); WeakReference evRef = new WeakReference(ev); ev = null; assertFalse("Event ref collected before Structure is unreferenced", GCTracker.waitGC(evRef)); s = null; assertTrue("Event ref not collected after Structure is unreferenced", GCTracker.waitGC(evRef)); } @Test public void gst_event_new_buffer_size() { final long MIN = 0x1234; final long MAX = 0xdeadbeef; final boolean ASYNC = false; Event ev = GSTEVENT_API.gst_event_new_buffer_size(Format.BYTES, MIN, MAX, ASYNC); assertNotNull("gst_event_new_buffer_size returned null", ev); assertTrue("gst_event_new_buffer_size returned a non-BUFFERSIZE event", ev instanceof BufferSizeEvent); } @Test public void BufferSize_getMinimumSize() { final long MIN = 0x1234; final long MAX = 0xdeadbeef; final boolean ASYNC = false; BufferSizeEvent ev = (BufferSizeEvent) GSTEVENT_API.gst_event_new_buffer_size(Format.BYTES, MIN, MAX, ASYNC); assertEquals("Wrong minimum size stored", MIN, ev.getMinimumSize()); } @Test public void BufferSize_getMaximumSize() { final long MIN = 0x1234; final long MAX = 0xdeadbeef; final boolean ASYNC = false; BufferSizeEvent ev = (BufferSizeEvent) GSTEVENT_API.gst_event_new_buffer_size(Format.BYTES, MIN, MAX, ASYNC); assertEquals("Wrong minimum size stored", MAX, ev.getMaximumSize()); } @Test public void BufferSize_isAsync() { final long MIN = 0x1234; final long MAX = 0xdeadbeef; final boolean ASYNC = false; BufferSizeEvent ev = (BufferSizeEvent) GSTEVENT_API.gst_event_new_buffer_size(Format.BYTES, MIN, MAX, ASYNC); assertEquals("Wrong minimum size stored", ASYNC, ev.isAsync()); BufferSizeEvent ev2 = (BufferSizeEvent) GSTEVENT_API.gst_event_new_buffer_size(Format.BYTES, MIN, MAX, !ASYNC); assertEquals("Wrong minimum size stored", !ASYNC, ev2.isAsync()); } @Test public void gst_event_new_qos() { Event ev = GSTEVENT_API.gst_event_new_qos(QOSType.THROTTLE, 0.0, 0, ClockTime.NONE); assertNotNull("gst_event_new_qos returned null", ev); assertTrue("gst_event_new_qos returned a non-QOS event", ev instanceof QOSEvent); } @Test public void QOS_getProportion() { final double PROPORTION = (double) 0xdeadbeef; QOSEvent ev = new QOSEvent(QOSType.THROTTLE, PROPORTION, 0, ClockTime.ZERO); assertEquals("Wrong proportion", PROPORTION, ev.getProportion(), 0d); } @Test public void QOS_getDifference() { long DIFF = 0x4096; QOSEvent ev = new QOSEvent(QOSType.THROTTLE, 0d, DIFF, ClockTime.ZERO); assertEquals("Wrong difference", DIFF, ev.getDifference()); } @Test public void QOS_getTimestamp() { final long STAMP = 0xdeadbeef; QOSEvent ev = new QOSEvent(QOSType.THROTTLE, 0d, 0, STAMP); assertEquals("Wrong timestamp", STAMP, ev.getTimestamp()); } @Test public void QOS_getType() { final long STAMP = 0xdeadbeef; QOSEvent ev = new QOSEvent(QOSType.THROTTLE, 0d, 0, STAMP); assertEquals("Wrong QOSType", QOSType.THROTTLE, ev.getType()); } @Test public void gst_event_new_seek() { Event ev = GSTEVENT_API.gst_event_new_seek(1.0, Format.TIME, 0, SeekType.SET, 0, SeekType.SET, 0); assertNotNull("gst_event_new_seek returned null", ev); assertTrue("gst_event_new_seek returned a non-SEEK event", ev instanceof SeekEvent); } @Test public void Seek_getFormat() { for (Format FORMAT : new Format[] { Format.TIME, Format.BYTES }) { SeekEvent ev = new SeekEvent(1.0, FORMAT, EnumSet.noneOf(SeekFlags.class), SeekType.SET, 0, SeekType.SET, 0); assertEquals("Wrong format in SeekEvent", FORMAT, ev.getFormat()); } } @Test public void Seek_getStartType() { for (SeekType TYPE : new SeekType[] { SeekType.SET, SeekType.END }) { SeekEvent ev = new SeekEvent(1.0, Format.TIME, EnumSet.noneOf(SeekFlags.class), TYPE, 0, SeekType.NONE, 0); assertEquals("Wrong startType in SeekEvent", TYPE, ev.getStartType()); } } @Test public void Seek_getStopType() { for (SeekType TYPE : new SeekType[] { SeekType.SET, SeekType.END }) { SeekEvent ev = new SeekEvent(1.0, Format.TIME, EnumSet.noneOf(SeekFlags.class), SeekType.NONE, 0, TYPE, 0); assertEquals("Wrong stopType in SeekEvent", TYPE, ev.getStopType()); } } @Test public void Seek_getStart() { final long START = 0xdeadbeef; SeekEvent ev = new SeekEvent(1.0, Format.TIME, EnumSet.noneOf(SeekFlags.class), SeekType.SET, START, SeekType.SET, -1); assertEquals("Wrong start in SeekEvent", START, ev.getStart()); } @Test public void Seek_getStop() { final long STOP = 0xdeadbeef; SeekEvent ev = new SeekEvent(1.0, Format.TIME, EnumSet.noneOf(SeekFlags.class), SeekType.SET, 0, SeekType.SET, STOP); assertEquals("Wrong stop in SeekEvent", STOP, ev.getStop()); } @Test public void Seek_rateZero() { try { new SeekEvent(0.0, Format.TIME, EnumSet.noneOf(SeekFlags.class), SeekType.SET, 0, SeekType.SET, -1); fail("A rate of 0.0 should throw an exception"); } catch (IllegalArgumentException ex) { } } @Test public void gst_event_new_caps() { Event ev = GSTEVENT_API.gst_event_new_caps(Caps.fromString("video/x-raw,format=I420")); assertNotNull("gst_event_new_caps returned null", ev); assertTrue("gst_event_new_caps returned a non-CAPS event", ev instanceof CapsEvent); } @Test public void gst_event_new_reconfigure() { Event ev = GSTEVENT_API.gst_event_new_reconfigure(); assertNotNull("gst_event_new_reconfigure returned null", ev); assertTrue("gst_event_new_reconfigure returned a non-RECONFIGURE event", ev instanceof ReconfigureEvent); } @Test public void gst_event_new_stream_start() { Event ev = GSTEVENT_API.gst_event_new_stream_start("a stream id"); assertNotNull("gst_event_new_stream_start returned null", ev); assertTrue("gst_event_new_stream_start returned a non-STREAM-START event", ev instanceof StreamStartEvent); } @Test public void gst_event_new_step() { Event ev = GSTEVENT_API.gst_event_new_step(Format.BUFFERS, 1, 1, true, false); assertNotNull("gst_event_new_step returned null", ev); assertTrue("gst_event_new_step returned a non-STEP event", ev instanceof StepEvent); } } ================================================ FILE: test/org/freedesktop/gstreamer/lowlevel/GValueTest.java ================================================ /* * Copyright (c) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.lowlevel.GNative; import org.freedesktop.gstreamer.lowlevel.GValueAPI; import org.freedesktop.gstreamer.lowlevel.GType; import org.freedesktop.gstreamer.lowlevel.GstElementFactoryAPI; import static org.junit.Assert.*; import java.util.HashMap; import org.freedesktop.gstreamer.Element; import org.freedesktop.gstreamer.ElementFactory; import org.freedesktop.gstreamer.Gst; import org.freedesktop.gstreamer.lowlevel.GValueAPI.GValue; import org.freedesktop.gstreamer.lowlevel.GValueAPI.GValueArray; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import com.sun.jna.Library; import com.sun.jna.Pointer; /** * */ public class GValueTest { private static final GValueAPI api = GValueAPI.GVALUE_API; public interface GValueTestAPI extends Library { @SuppressWarnings("serial") GValueTestAPI API = GNative.loadLibrary("gobject-2.0", GValueTestAPI.class, new HashMap() { }); void g_value_set_object(Pointer value, Pointer obj); Pointer g_value_get_object(Pointer pointer); } public GValueTest() { } @BeforeClass public static void setUpClass() throws Exception { Gst.init("GValueTest", new String[] {}); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Before public void setUp() { } @After public void tearDown() { } @Test public void testGValueArray() throws Exception { testGValueArray(new GValueArray()); testGValueArray(new GValueArray(2)); testGValueArray(new GValueArray(5)); } private void testGValueArray(GValueArray gva) throws Exception { gva.append(new GValue(GType.INT, 5)); gva.append(new GValue(GType.DOUBLE, 5.0)); gva.append(new GValue(GType.STRING, "omanipadmihoom")); assertEquals("vrong n_value", 3, gva.getNValues()); assertEquals("value mismatch", 5, gva.getValue(0)); assertEquals("value mismatch", 5.0, gva.getValue(1)); assertEquals("value mismatch", "omanipadmihoom", gva.getValue(2)); gva.free(); } @Test public void testInitSet() throws Exception { GValue v = new GValue(GType.INT); assertEquals("type mismatch", GType.INT, v.getType()); try { v.setValue(null); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException e) {} try { v.setValue(0.2); fail("IllegalArgumentException should have been thrown"); } catch (ClassCastException e) {} v.setValue(42); assertEquals("wrong value", 42, v.getValue()); } @Test public void testInitValue() throws Exception { GValue v; try { v = new GValue(GType.INT, null); fail("IllegalArgumentException should have been thrown"); } catch (IllegalArgumentException e) {} try { v = new GValue(GType.INT, 0.2); fail("IllegalArgumentException should have been thrown"); } catch (ClassCastException e) {} v = new GValue(GType.DOUBLE, 42.0); assertEquals("type mismatch", GType.DOUBLE, v.getType()); assertEquals("wrong value", 42.0, v.getValue()); } @Test public void testInt() throws Exception { GValue v = new GValue(); api.g_value_init(v, GType.INT); api.g_value_set_int(v, 5); assertEquals("int value mismatch", 5, v.getValue()); api.g_value_set_int(v, 6); assertEquals("int value mismatch", 6, v.getValue()); assertTrue("type mismatch", v.getValue() instanceof Integer); } /** * Test type conversion of object value when using * an object created 'the proper way' */ @Test public void testObjectPtrRef() throws Exception { // the following probably puts 'e' into the object reference map Element e = ElementFactory.make("fakesink", "fakesink"); GValue v = new GValue(); api.g_value_init(v, GType.OBJECT); api.g_value_set_object(v, e); Object obj = v.getValue(); assertTrue("type mismatch", obj instanceof Element); assertEquals("object mismatch", e, obj); } /** * Test type conversion of object value trying to bypass the object reference map */ @Test public void testObjectTypeMap() throws Exception { Pointer p; { /* * Not using ElementFactory.make() here probably prevents the element * from being placed in the object reference map and therefore forces * type mapper conversion - what we want to test */ ElementFactory factory = GstElementFactoryAPI.GSTELEMENTFACTORY_API.gst_element_factory_find("videotestsrc"); p = GstElementFactoryAPI.GSTELEMENTFACTORY_API.ptr_gst_element_factory_create(factory, "videotestsrc"); } GValue v = new GValue(); api.g_value_init(v, GType.OBJECT); GValueTestAPI.API.g_value_set_object(v.getPointer(), p); Object obj = v.getValue(); assertTrue("type mismatch", obj instanceof Element); } } ================================================ FILE: test/org/freedesktop/gstreamer/lowlevel/LowLevelStructureTest.java ================================================ package org.freedesktop.gstreamer.lowlevel; import static org.junit.Assert.assertTrue; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import com.sun.jna.Structure; import java.util.Arrays; import org.freedesktop.gstreamer.Gst; public class LowLevelStructureTest { private final static Logger LOG = Logger.getLogger(LowLevelStructureTest.class.getName()); private static List> structs; private static List> untestable; public LowLevelStructureTest() { } @BeforeClass public static void setUpClass() { initStructList(); } @AfterClass public static void tearDownClass() { } @Before public void setUp() { if (untestable == null) { untestable = new ArrayList>(); } } @After public void tearDown() { } @Test public void runTest() { for (Class struct : structs) { testStruct(struct); } if (!untestable.isEmpty()) { StringBuilder builder = new StringBuilder("UNTESTABLE:\n"); for (Class struct : untestable) { builder.append(struct.getName()); builder.append("\n"); } LOG.log(Level.WARNING, builder.toString()); } } @SuppressWarnings("unchecked") private void testStruct(Class struct) { LOG.log(Level.INFO, "Testing {0}", struct.getName()); Structure inst = null; List fields = null; try { inst = struct.newInstance(); } catch (Exception ex) { // try { // Constructor con = struct.getConstructor(Pointer.class); // inst = con.newInstance(Pointer.NULL); // } catch (Exception ex1) { untestable.add(struct); // assertTrue(false); return; } try { Structure.FieldOrder fieldOrder = inst.getClass().getAnnotation(Structure.FieldOrder.class); if (fieldOrder != null) { fields = Arrays.asList(fieldOrder.value()); } else { Method getFieldOrder = inst.getClass().getDeclaredMethod("getFieldOrder"); getFieldOrder.setAccessible(true); fields = (List) getFieldOrder.invoke(inst); } } catch (Exception ex) { LOG.log(Level.SEVERE, "Can't find getFieldOrder() method", ex); assertTrue(false); } testFields(inst, fields); } private void testFields(Structure inst, List expectedFields) { Field[] fields = inst.getClass().getFields(); List fieldNames = new ArrayList(); for (Field field : fields) { if (!Modifier.isStatic(field.getModifiers())) { fieldNames.add(field.getName()); } } assertTrue(expectedFields.equals(fieldNames)); } private static void initStructList() { structs = new ArrayList<>(); structs.add(BaseSinkAPI.GstBaseSinkStruct.class); structs.add(BaseSinkAPI.GstBaseSinkClass.class); structs.add(BaseSrcAPI.GstBaseSrcStruct.class); structs.add(BaseSrcAPI.GstBaseSrcAbi.class); structs.add(BaseSrcAPI.GstBaseSrcClass.class); structs.add(BaseTransformAPI.GstBaseTransformStruct.class); structs.add(BaseTransformAPI.GstBaseTransformClass.class); structs.add(GObjectAPI.GTypeClass.class); structs.add(GObjectAPI.GTypeInstance.class); structs.add(GObjectAPI.GObjectStruct.class); structs.add(GObjectAPI.GObjectClass.class); structs.add(GObjectAPI.GTypeInfo.class); structs.add(GObjectAPI.GParamSpec.class); structs.add(GObjectAPI.GParamSpecBoolean.class); structs.add(GObjectAPI.GParamSpecChar.class); structs.add(GObjectAPI.GParamSpecDouble.class); structs.add(GObjectAPI.GParamSpecFloat.class); structs.add(GObjectAPI.GParamSpecInt.class); structs.add(GObjectAPI.GParamSpecInt64.class); structs.add(GObjectAPI.GParamSpecLong.class); structs.add(GObjectAPI.GParamSpecString.class); structs.add(GObjectAPI.GParamSpecUChar.class); structs.add(GObjectAPI.GParamSpecUInt.class); structs.add(GSignalAPI.GSignalQuery.class); structs.add(GValueAPI.GValue.class); structs.add(GValueAPI.GValueArray.class); structs.add(GValueStruct.class); structs.add(GlibAPI.GList.class); structs.add(GlibAPI.GSList.class); structs.add(GstAPI.GstSegmentStruct.class); structs.add(GstAPI.GErrorStruct.class); structs.add(GstBufferAPI.BufferStruct.class); structs.add(GstColorBalanceAPI.ColorBalanceChannelStruct.class); // structs.add(GstControlSourceAPI.TimedValue.class); // structs.add(GstControlSourceAPI.GstControlSourceStruct.class); // structs.add(GstControlSourceAPI.GstControlSourceClass.class); structs.add(GstElementAPI.GstElementStruct.class); structs.add(GstElementAPI.GstElementClass.class); structs.add(GstEventAPI.EventStruct.class); structs.add(GstVideoAPI.GstVideoTimeCodeMetaStruct.class); structs.add(GstVideoAPI.GstVideoTimeCodeStruct.class); structs.add(GstMetaAPI.GstMetaInfoStruct.class); structs.add(GstMetaAPI.GstMetaStruct.class); // structs.add(GstInterpolationControlSourceAPI.GstInterpolationControlSourceStruct.class); // structs.add(GstInterpolationControlSourceAPI.GstInterpolationControlSourceClass.class); // // structs.add(GstLFOControlSourceAPI.GstLFOControlSourceStruct.class); // structs.add(GstLFOControlSourceAPI.GstLFOControlSourceClass.class); structs.add(GstMessageAPI.MessageStruct.class); structs.add(GstMiniObjectAPI.MiniObjectStruct.class); structs.add(GstObjectAPI.GstObjectStruct.class); structs.add(GstObjectAPI.GstObjectClass.class); structs.add(GstQueryAPI.QueryStruct.class); if (Gst.getVersion().getMinor() >= 14) { structs.add(GstWebRTCSessionDescriptionAPI.WebRTCSessionDescriptionStruct.class); structs.add(GstSDPMessageAPI.SDPMessageStruct.class); structs.add(GstPromiseAPI.PromiseStruct.class); } } } ================================================ FILE: test/org/freedesktop/gstreamer/lowlevel/ReferenceManagerTest.java ================================================ /* * Copyright (c) 2008 Wayne Meissner * * This file is part of gstreamer-java. * * gstreamer-java is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * gstreamer-java is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with gstreamer-java. If not, see . */ package org.freedesktop.gstreamer.lowlevel; import org.freedesktop.gstreamer.lowlevel.ReferenceManager; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.lang.ref.Reference; import java.lang.ref.WeakReference; import org.freedesktop.gstreamer.Caps; import org.freedesktop.gstreamer.Gst; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; /** * */ public class ReferenceManagerTest { public ReferenceManagerTest() { } @BeforeClass public static void setUpClass() throws Exception { Gst.init("ReferenceManagerTest", new String[] {}); } @AfterClass public static void tearDownClass() throws Exception { Gst.deinit(); } @Before public void setUp() { } @After public void tearDown() { } public boolean waitGC(Reference ref) throws InterruptedException { System.gc(); for (int i = 0; ref.get() != null && i < 20; ++i) { Thread.sleep(10); System.gc(); } return ref.get() == null; } @Test public void testReference() throws Exception { Object ref = new Object(); Caps target = new Caps("video/x-raw"); ReferenceManager.addKeepAliveReference(ref, target); WeakReference targetRef = new WeakReference(target); target = null; assertFalse("target collected prematurely", waitGC(targetRef)); ref = null; assertTrue("target not collected when ref is collected", waitGC(targetRef)); } @Test public void testMultipleReferences() throws Exception { Object ref1 = new Object(); Object ref2 = new Object(); Caps target = new Caps("video/x-raw"); ReferenceManager.addKeepAliveReference(ref1, target); ReferenceManager.addKeepAliveReference(ref2, target); WeakReference targetRef = new WeakReference(target); target = null; assertFalse("target collected prematurely", waitGC(targetRef)); ref1 = null; assertFalse("target collected after only one ref disposed", waitGC(targetRef)); ref2 = null; assertTrue("target not collected when ref is dispose", waitGC(targetRef)); } } ================================================ FILE: test/org/freedesktop/gstreamer/util/TestAssumptions.java ================================================ package org.freedesktop.gstreamer.util; import org.freedesktop.gstreamer.ElementFactory; import org.freedesktop.gstreamer.Gst; import org.junit.Assume; /** * These Assumptions skip Tests if the environmental Properties do not meet the Assumption. */ public class TestAssumptions { /** * Assume a GStreamer-Installation of at least the specified Version, ignore the Test if not met. * * @param major Required Major Version * @param minor Required Minor Version */ public static void requireGstVersion(int major, int minor) { Assume.assumeTrue(Gst.testVersion(major, minor)); } /** * Assume a GStreamer installation has the required element. * * @param elementType element type */ public static void requireElement(String elementType) { ElementFactory factory = null; try { factory = ElementFactory.find(elementType); } catch (Exception ex) {} Assume.assumeNotNull(factory); } } ================================================ FILE: test/org/freedesktop/gstreamer/video/VideoCropMetaTest.java ================================================ /* * Copyright (c) 2020 Neil C Smith * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . * */ package org.freedesktop.gstreamer.video; import org.freedesktop.gstreamer.BufferProbeTester; import org.freedesktop.gstreamer.Gst; import org.freedesktop.gstreamer.glib.Natives; import org.freedesktop.gstreamer.lowlevel.GstMetaPtr; import org.freedesktop.gstreamer.util.TestAssumptions; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; public class VideoCropMetaTest { @BeforeClass public static void beforeClass() { Gst.init(Gst.getVersion()); } @AfterClass public static void afterClass() { Gst.deinit(); } @Test public void testIterateWithCrop() { TestAssumptions.requireGstVersion(1, 14); TestAssumptions.requireElement("fakevideosink"); BufferProbeTester.test(buffer -> { buffer.iterateMeta().forEachRemaining(meta -> { GstMetaPtr ptr = Natives.getPointer(meta).as(GstMetaPtr.class, GstMetaPtr::new); System.out.println(ptr.getGType().getTypeName()); System.out.println(ptr.getAPIGType().getTypeName()); }); }, "videotestsrc ! videocrop top=10 left=10 bottom=50 right=50 ! fakevideosink name=sink"); } } ================================================ FILE: test/org/freedesktop/gstreamer/video/VideoTimeCodeConfigTest.java ================================================ /* * Copyright (c) 2020 Petr Lastovka * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . * */ package org.freedesktop.gstreamer.video; import org.freedesktop.gstreamer.glib.NativeFlags; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; import org.freedesktop.gstreamer.lowlevel.GstVideoAPI; public class VideoTimeCodeConfigTest { private GstVideoAPI.GstVideoTimeCodeConfigStruct origStruct; private VideoTimeCodeConfig codeConfig; @Before public void setUp() { origStruct = new GstVideoAPI.GstVideoTimeCodeConfigStruct(); origStruct.fps_d = 25; origStruct.fps_n = 1; origStruct.flags = VideoTimeCodeFlags.GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME.intValue(); origStruct.write(); codeConfig = new VideoTimeCodeConfig(origStruct); } @Test public void testGetTimeCodeFlags() { assertEquals(origStruct.flags, NativeFlags.toInt(codeConfig.getFlags())); } @Test public void testGetFramerateNumerator() { assertEquals(origStruct.fps_n, codeConfig.getNumerator()); } @Test public void testGetFramerateDenominator() { assertEquals(origStruct.fps_d, codeConfig.getDenominator()); } } ================================================ FILE: test/org/freedesktop/gstreamer/video/VideoTimeCodeFlagsTest.java ================================================ /* * Copyright (c) 2020 Petr Lastovka * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . * */ package org.freedesktop.gstreamer.video; import java.util.Arrays; import java.util.Collection; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import static org.junit.Assert.assertEquals; @RunWith(Parameterized.class) public class VideoTimeCodeFlagsTest { private final VideoTimeCodeFlags flags; private final int intValue; @Parameterized.Parameters public static Collection data() { return Arrays.asList( new Object[][]{ // {VideoTimeCodeFlags.GST_VIDEO_TIME_CODE_FLAGS_NONE, 0}, {VideoTimeCodeFlags.GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME, 1}, {VideoTimeCodeFlags.GST_VIDEO_TIME_CODE_FLAGS_INTERLACED, 2} }); } public VideoTimeCodeFlagsTest(VideoTimeCodeFlags flags, int intValue) { this.flags = flags; this.intValue = intValue; } @Test public void testIntValue() { assertEquals(intValue,flags.intValue()); } } ================================================ FILE: test/org/freedesktop/gstreamer/video/VideoTimeCodeMetaTest.java ================================================ /* * Copyright (c) 2025 Neil C Smith * Copyright (c) 2020 Petr Lastovka * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . * */ package org.freedesktop.gstreamer.video; import org.freedesktop.gstreamer.Buffer; import org.freedesktop.gstreamer.Gst; import org.freedesktop.gstreamer.SampleTester; import org.freedesktop.gstreamer.util.TestAssumptions; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import static org.freedesktop.gstreamer.video.VideoTimeCodeFlags.GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; public class VideoTimeCodeMetaTest { @BeforeClass public static void beforeClass() { Gst.init(Gst.getVersion()); } @AfterClass public static void afterClass() { Gst.deinit(); } @Test public void testVideoWithoutTimeCodeMeta() { // method containsMetadata is available since 1.14 TestAssumptions.requireGstVersion(1, 14); SampleTester.test(sample -> { Buffer buffer = sample.getBuffer(); assertFalse("Default video not contains timecode metadata", buffer.hasMeta(VideoTimeCodeMeta.API)); }, "videotestsrc do-timestamp=true ! appsink name=myappsink"); } @Test public void testVideoTimeCodeMetaPal() { // timecodestamper is available since 1.10 TestAssumptions.requireGstVersion(1, 10); TestAssumptions.requireElement("timecodestamper"); SampleTester.test(sample -> { Buffer buffer = sample.getBuffer(); if (Gst.testVersion(1, 14)) { assertTrue("Video should contains timecode meta", buffer.hasMeta(VideoTimeCodeMeta.API)); } try (VideoTimeCodeMeta meta = buffer.getMeta(VideoTimeCodeMeta.API)) { assertNotNull(meta); VideoTimeCode timeCode = meta.getTimeCode(); //first frame 00:00:00:00 assertEquals(0, timeCode.getHours()); assertEquals(0, timeCode.getMinutes()); assertEquals(0, timeCode.getSeconds()); assertEquals(0, timeCode.getFrames()); VideoTimeCodeConfig timeCodeConfig = timeCode.getConfig(); // PAL standard 25/1 assertEquals(25, timeCodeConfig.getNumerator()); assertEquals(1, timeCodeConfig.getDenominator()); assertTrue(timeCodeConfig.getFlags().isEmpty()); } }, "videotestsrc ! video/x-raw,framerate=25/1 ! timecodestamper ! videoconvert ! appsink name=myappsink"); } @Test public void testVideoTimeCodeNTSCDrop() { // timecodestamper is available since 1.10 TestAssumptions.requireGstVersion(1, 10); TestAssumptions.requireElement("timecodestamper"); SampleTester.test(sample -> { Buffer buffer = sample.getBuffer(); if (Gst.testVersion(1, 14)) { assertTrue("Video should contains timecode meta", buffer.hasMeta(VideoTimeCodeMeta.API)); } try (VideoTimeCodeMeta meta = buffer.getMeta(VideoTimeCodeMeta.API)) { assertNotNull(meta); VideoTimeCode timeCode = meta.getTimeCode(); //first frame 00:00:00;00 assertEquals(0, timeCode.getHours()); assertEquals(0, timeCode.getMinutes()); assertEquals(0, timeCode.getSeconds()); assertEquals(0, timeCode.getFrames()); VideoTimeCodeConfig timeCodeConfig = timeCode.getConfig(); // NTSC drop standard 30000/1001 assertEquals(30000, timeCodeConfig.getNumerator()); assertEquals(1001, timeCodeConfig.getDenominator()); assertTrue(timeCodeConfig.getFlags().contains(GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME)); } }, "videotestsrc ! video/x-raw,framerate=30000/1001 ! timecodestamper drop-frame=true ! videoconvert ! appsink name=myappsink"); } /** * Handle last frame of first minute */ @Test public void testVideoTimeCodeNTSCDropFrame() { // timecodestamper is available since 1.10 TestAssumptions.requireGstVersion(1, 10); TestAssumptions.requireElement("timecodestamper"); SampleTester.test(sample -> { Buffer buffer = sample.getBuffer(); if (Gst.testVersion(1, 14)) { assertTrue("Video should contains timecode meta", buffer.hasMeta(VideoTimeCodeMeta.API)); } try (VideoTimeCodeMeta meta = buffer.getMeta(VideoTimeCodeMeta.API)) { assertNotNull(meta); VideoTimeCode timeCode = meta.getTimeCode(); //first frame 00:00:00;29 assertEquals(0, timeCode.getHours()); assertEquals(0, timeCode.getMinutes()); assertEquals(0, timeCode.getSeconds()); assertEquals(29, timeCode.getFrames()); VideoTimeCodeConfig timeCodeConfig = timeCode.getConfig(); // NTSC drop standard 30000/1001 assertEquals(30000, timeCodeConfig.getNumerator()); assertEquals(1001, timeCodeConfig.getDenominator()); assertTrue(timeCodeConfig.getFlags().contains(GST_VIDEO_TIME_CODE_FLAGS_DROP_FRAME)); } }, "videotestsrc ! video/x-raw,framerate=30000/1001 ! videoconvert ! timecodestamper drop-frame=true ! videoconvert ! appsink name=myappsink", 29); } @Test public void testVideoTimeCodeNTSCNonDrop() { // timecodestamper is available since 1.10 TestAssumptions.requireGstVersion(1, 10); TestAssumptions.requireElement("timecodestamper"); SampleTester.test(sample -> { Buffer buffer = sample.getBuffer(); if (Gst.testVersion(1, 14)) { assertTrue("Video should contains timecode meta", buffer.hasMeta(VideoTimeCodeMeta.API)); } try (VideoTimeCodeMeta meta = buffer.getMeta(VideoTimeCodeMeta.API)) { assertNotNull(meta); VideoTimeCode timeCode = meta.getTimeCode(); //first frame 00:00:00:00 assertEquals(0, timeCode.getHours()); assertEquals(0, timeCode.getMinutes()); assertEquals(0, timeCode.getSeconds()); assertEquals(0, timeCode.getFrames()); VideoTimeCodeConfig timeCodeConfig = timeCode.getConfig(); // NTSC drop standard 30/1 assertEquals(30, timeCodeConfig.getNumerator()); assertEquals(1, timeCodeConfig.getDenominator()); assertTrue(timeCodeConfig.getFlags().isEmpty()); } }, "videotestsrc ! video/x-raw,framerate=30/1 ! timecodestamper ! videoconvert ! appsink name=myappsink"); } } ================================================ FILE: test/org/freedesktop/gstreamer/video/VideoTimeCodeTest.java ================================================ /* * Copyright (c) 2020 Neil C Smith * Copyright (c) 2020 Petr Lastovka * * This file is part of gstreamer-java. * * This code is free software: you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License version 3 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * version 3 for more details. * * You should have received a copy of the GNU Lesser General Public License * version 3 along with this work. If not, see . * */ package org.freedesktop.gstreamer.video; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import org.freedesktop.gstreamer.lowlevel.GstVideoAPI; public class VideoTimeCodeTest { private GstVideoAPI.GstVideoTimeCodeStruct timeCodeStruct; private GstVideoAPI.GstVideoTimeCodeConfigStruct.ByValue configStruct; private VideoTimeCode timeCode; @Before public void setUp() { timeCodeStruct = new GstVideoAPI.GstVideoTimeCodeStruct(); configStruct = new GstVideoAPI.GstVideoTimeCodeConfigStruct.ByValue(); // 01:02:03:04 timeCodeStruct.hours = 1; timeCodeStruct.minutes = 2; timeCodeStruct.seconds = 3; timeCodeStruct.frames = 4; timeCodeStruct.field_count = 55; // config timeCodeStruct.config = configStruct; timeCodeStruct.write(); timeCode = new VideoTimeCode(timeCodeStruct); } @Test public void testGetTCConfig() { assertNotNull(timeCode.getConfig()); } @Test public void testGetHours() { assertEquals(1,timeCode.getHours()); } @Test public void testGetMinutes() { assertEquals(2,timeCode.getMinutes()); } @Test public void testGetSeconds() { assertEquals(3,timeCode.getSeconds()); } @Test public void testGetFrames() { assertEquals(4,timeCode.getFrames()); } }